diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..fe3da0e --- /dev/null +++ b/src/main.c @@ -0,0 +1,185 @@ +#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; + + /* port_a_ctrl = PIO_MODE_3; */ + + /* port_a_ctrl = 0x7C; */ + + /* // Load interrupt vector */ + /* port_a_ctrl = ISR_ADDRESS(port_a_isr_ptr); */ + + /* port_a_ctrl = PIO_INT_CTRL(PIO_INT_EN | PIO_OR | PIO_HIGH | PIO_MASK); */ + /* port_a_ctrl = 0x83; */ + + /* // SDA and SCL high */ + /* port_a_data = 0x03; */ +} + +static inline void +init_ctc(void) +{ + /* 200Hz clock */ + ctc_channel_1 = CTC_CTRL(CTC_INT_BIT | CTC_PRESCALER_BIT + | CTC_TIME_CONST_BIT | CTC_RST_BIT); + ctc_channel_1 = 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; + + // Boot menu + addstr("1) Programming mode\r\n"); + addstr("2) Normal boot (default)\r\n"); + addstr("3) Boot address 0xC000\r\n"); + + for (int i = 5; i > 0; --i) { + addch('\r'); + addch(i + '0'); + + while (!tick) { + u8 keys = poll_keys(); + + if (!(keys & KEY2)) { + addch('\r'); + bootloader(); + } + + if (!(keys & KEY3)) { + goto boot; + } + + if (!(keys & KEY4)) { + // Definitely safe looking C code ... + void (*ptr)(void) = (void (*)(void))0xC000; + ptr(); + } + } + + DI; + tick = 0; + EI; + } + + addch('\r'); + +boot: + addstr("Starting system ...\r\n"); + // 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; + _menu(); + + while (1) + ; +} |