#include #include "boot.h" #include "circ_buf.h" #define CPUREG 0x00 #define CPUREG_ROM_DISABLE 0x01 #define CPUREG_BANK_SELECT 0x02 #define CPUREG_BANK_ENABLE 0x04 #define CPUREG_GPO_0 0x08 #define CPUREG_GPO_1 0x10 #define CPUREG_GPO_2 0x20 #define CPUREG_GPO_3 0x40 #define CPUREG_GPO_4 0x80 #define CPUREG_GPO_MASK 0xf8 #define UART_CTC_CARD_BASE 0x20 #define CTC_BASE (UART_CTC_CARD_BASE+0x00) #define CTC_CHANNEL_0 (CTC_BASE+0) #define CTC_CHANNEL_1 (CTC_BASE+1) #define CTC_CHANNEL_2 (CTC_BASE+2) #define CTC_CHANNEL_3 (CTC_BASE+3) #define UART_BASE (UART_CTC_CARD_BASE+0x04) #define UART_CONTROL (UART_BASE+0) #define UART_DATA (UART_BASE+1) volatile uint8_t v; volatile uint8_t uart_tx_busy; volatile circular_buffer_t rx_buf; volatile circular_buffer_t tx_buf; void uart_puts(char * c){ while(*c){ // fill tx buffer till it is full while(*c && buffer_enqueue(&tx_buf, *c)){ c++; } // if uart not busy kick off if(!uart_tx_busy){ disable_interrupts(); char cc; if(buffer_dequeue(&tx_buf, &cc)){ uart_tx_busy = 1; io_out(UART_DATA, cc); io_out(UART_CONTROL, 0b10110101); } enable_interrupts(); } } } void uart_interrupt(){ uint8_t status = io_in(UART_CONTROL); if((status&0x21)!=0){ // RDRF or OVRN char c = io_in(UART_DATA); if((status&0x01)!=0){ // RDRF buffer_enqueue(&rx_buf, c); } } if((status&0x02)!=0 && uart_tx_busy){ //TXRE char c; if(buffer_dequeue(&tx_buf, &c)){ io_out(UART_DATA, c); }else{ io_out(UART_CONTROL, 0b10010101); uart_tx_busy = 0; } } } void ctc_interrupt(){ } void main(){ buffer_init(&rx_buf); buffer_init(&tx_buf); io_out(CTC_CHANNEL_0, 0x57); // no int, counter @ rising, value follows, soft reset, control word io_out(CTC_CHANNEL_0, 13); // 38.462 kHz out; io_out(CTC_CHANNEL_3, 0b11001111); // int, counter @ falling, ext trig, value follows, soft reset, control word io_out(CTC_CHANNEL_3, 1); io_out(CTC_CHANNEL_0, 0x00); // vector follows io_out(CTC_CHANNEL_0, 0x40); uart_tx_busy = 0; io_out(UART_CONTROL, 0b00000011); // master reset io_out(UART_CONTROL, 0b10010101); // recv int, 8N1, /16 -> 2403.85 baud enable_interrupts(); uart_puts("Z80 monitor - v1\r\n"); uart_puts("----------------\r\n"); v = 0; for(;;){ char c[2] = {0, 0}; while(buffer_dequeue(&rx_buf, c)){ uart_puts(c); } } }