aboutsummaryrefslogtreecommitdiff
#include <tft.h>
#include <tty.h>
#include <i2c.h>
#include <zeta.h>
#include <input.h>

void
uart_putchar(char c);

static inline void
enable_input_fifo(void)
{
}

static inline void
disable_input_fifo(void)
{
}

static inline void
init_pio(void)
{
	// Control mode - i.e. no parallel port communication
	port_b_ctrl = PIO_MODE_3;
	// A, B and five keys as inputs
	port_b_ctrl = 0x7F;
	// Load interrupt vector
	port_b_ctrl = ISR_ADDRESS(port_b_isr_ptr);
	// Interrupt word - interrupt if any pin goes low, mask follows
	port_b_ctrl = PIO_INT_CTRL(PIO_INT_EN | PIO_OR | PIO_LOW | PIO_MASK);
	// Mask - 0 means to check line
	port_b_ctrl = 0x80;

	// Control mode - i.e. no parallel port communication
	/* port_a_ctrl = PIO_MODE_3; */
	/* port_a_ctrl = 0x7C; */
	/* SDA and SCL high */
	/* port_a_data = 0x03; */
}

static inline void
init_ctc(void)
{
	// Init CTC with known state (disable posible non-defined interrupts)
	ctc_channel_0 = CTC_CTRL(0);
	ctc_channel_1 = CTC_CTRL(0);

	/* 200Hz clock */
	ctc_channel_2 = CTC_CTRL(CTC_INT_BIT | CTC_PRESCALER_BIT
				 | CTC_TIME_CONST_BIT | CTC_RST_BIT);
	ctc_channel_2 = 0;

	/* ctc_channel_3 = (CPU_FREQ / 256 / 144); */

	ctc_channel_3 = CTC_CTRL(CTC_INT_BIT | CTC_PRESCALER_BIT
				 | CTC_TIME_CONST_BIT | CTC_RST_BIT);
	ctc_channel_3 = 0; // 256

	// Interrupt table for CTC
	// Final address is (Ireg << 8) | ctc_isr_ptr | {00/01/10/11} | 0
	ctc_channel_0 = ISR_ADDRESS(ctc0_isr_ptr);
}

static inline void
init_sio(void)
{
	static const u8 sio_a_cfg[] = {
		0b00011000,                      // Reset channel
		4         ,                      // wr4
		0b01000100,                      // X16 clock (115200), one stop bit, no parity
		1         ,                      // wr1
		SIO_RX_INT_MD0 | SIO_RX_INT_MD1, // interrupt on every Rx, no wait function
		3         ,                      // wr3
		0b11000001,                      // enable Rx - 8 bit char
		5         ,                      // wr5
		0b01101000                       // enable Tx - 8 bit char
	};

	static const u8 sio_b_cfg[] = {
		0b00011000,                     // Reset channel
		2         ,                     // load interrupt vector
		ISR_ADDRESS(rx_isr_ptr)         // int_table_rx
	};

	for (u8 i = 0; i < LENGTH(sio_a_cfg); ++i)
		sio_a_ctrl = sio_a_cfg[i];

	for (u8 i = 0; i < LENGTH(sio_b_cfg); ++i)
		sio_b_ctrl = sio_b_cfg[i];
}

// copy code to ram, so function pointer is modifyable

static uint8_t tick = 0;

void
timer(void) __critical __interrupt(5)
{
	static int prescale = 0;

	if (++prescale == 150) {
		prescale = 0;
		tick = 1;
	}
}

/* i2c_start_condition(); */
/* i2c_send(0xA0); */
/* i2c_send(0x00); */
/* i2c_send(0x00); */
/* i2c_restart_condition(); */
/* i2c_send(0xA1); */
/* b = i2c_recv(NACK); */
/* i2c_stop_condition(); */

void
main(void)
{
	tft_init();

	init_ctc();
	init_pio();
	init_sio();

	// Interrupt mode 2
	IM(2);
	// Enable interrupts
	EI;

	addstr("Starting system ...\r\n");
	_menu();

	while (1)
		;
}