110 lines
2.6 KiB
C
110 lines
2.6 KiB
C
#include <stdint.h>
|
|
#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);
|
|
}
|
|
}
|
|
}
|