Initial commit

This commit is contained in:
Joppe Blondel
2026-09-28 13:17:35 +02:00
commit 67ec3c9a65
7 changed files with 403 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
#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);
}
}
}