new memory and project layout

This commit is contained in:
Joppe Blondel
2026-10-01 12:17:47 +02:00
parent 9b1fcac8ee
commit d19ffc70a1
10 changed files with 397 additions and 272 deletions
+113
View File
@@ -0,0 +1,113 @@
#include <stdint.h>
#include "bios.h"
#include "circ_buf.h"
#define UART_CTC_CARD_BASE 0x20
#define CTC_BASE (UART_CTC_CARD_BASE + 0x00)
#define CTC_CHANNEL_0 (CTC_BASE + 0)
#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)
static volatile uint8_t uart_tx_busy;
static volatile circular_buffer_t rx_buf;
static volatile circular_buffer_t tx_buf;
static void uart_kick(void)
{
char c;
disable_interrupts();
if (!uart_tx_busy && buffer_dequeue(&tx_buf, &c)) {
uart_tx_busy = 1;
io_out(UART_DATA, c);
io_out(UART_CONTROL, 0b10110101);
}
enable_interrupts();
}
void bios_putc(char c)
{
uint8_t queued;
do {
disable_interrupts();
queued = buffer_enqueue(&tx_buf, c);
enable_interrupts();
if (!queued) uart_kick();
} while (!queued);
uart_kick();
}
void bios_puts(const char *s)
{
while (*s) bios_putc(*s++);
}
uint8_t bios_try_getc(void)
{
char c;
uint8_t received;
disable_interrupts();
received = buffer_dequeue(&rx_buf, &c);
enable_interrupts();
return received ? (uint8_t)c : 0;
}
char bios_getc(void)
{
uint8_t c;
do {
c = bios_try_getc();
} while (!c);
return (char)c;
}
void bios_flush(void)
{
while (uart_tx_busy || !buffer_is_empty(&tx_buf)) uart_kick();
}
void bios_init(void)
{
buffer_init(&rx_buf);
buffer_init(&tx_buf);
io_out(CTC_CHANNEL_0, 0x57);
io_out(CTC_CHANNEL_0, 13);
io_out(CTC_CHANNEL_3, 0b11001111);
io_out(CTC_CHANNEL_3, 1);
io_out(CTC_CHANNEL_0, 0x00);
io_out(CTC_CHANNEL_0, 0x40);
uart_tx_busy = 0;
io_out(UART_CONTROL, 0b00000011);
io_out(UART_CONTROL, 0b10010101);
enable_interrupts();
}
void uart_interrupt(void)
{
uint8_t status = io_in(UART_CONTROL);
if ((status & 0x21) != 0) {
char c = io_in(UART_DATA);
if ((status & 0x01) != 0) buffer_enqueue(&rx_buf, c);
}
if ((status & 0x02) != 0 && uart_tx_busy) {
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)
{
}