Add serial driver and irq support

This commit is contained in:
Byron Lathi
2023-11-28 22:54:26 -08:00
parent 3524892f80
commit fd9ccdbce4
5 changed files with 135 additions and 7 deletions

View File

@@ -339,12 +339,16 @@ token = 0xFF - response timeout
*******************************************************************************/
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
{
(void)addr;
(void)buf;
(void)token;
/*
uint16_t readAttempts;
uint8_t res1, read;
uint16_t i;
/*
// set token to none
*token = 0xFF;
@@ -391,9 +395,11 @@ uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
spi_deselect(0);
spi_exchange(0xFF);
return res1;
*/
return res1;
return 0;
}
/*******************************************************************************

View File

@@ -0,0 +1,17 @@
#ifndef _SERIAL_H
#define _SERIAL_H
#include <stdint.h>
void serial_handle_irq();
void serial_init();
void serial_putc(char c);
void serial_puts(char* s);
char serial_getc();
char serial_getc_nb();
#endif

View File

@@ -0,0 +1,94 @@
.MACPACK generic
.autoimport
.import _enable_irq, _send_eoi, _uart_txb_block
.importzp tmp1, ptr1
.export _serial_init
.export _serial_handle_irq
.export _serial_putc, _serial_puts, _serial_getc, _serial_get_nb
.zeropage
last_char: .res 1
.code
UART = $efe6
UART_TXB = UART
UART_RXB = UART
UART_STATUS = UART + 1
; Initialize Serial Port
; No initialization needed, just register irq handler.
.proc _serial_init
lda #<_serial_handle_irq
ldx #>_serial_handle_irq
jsr pushax
lda #$01
jsr _register_irq
stz last_char
rts
.endproc
; Serial Port IRQ Handler
; Get the character and store it.
.proc _serial_handle_irq
lda UART_RXB
sta last_char
ora #$80 ; set msb
jsr _send_eoi
rti
.endproc
; Serial Port Get Character
; If a character has not been received, block until one is.
.proc _serial_getc
L1: lda last_char
bpl L1
and #$7f
sta last_char
rts
.endproc
; Serial Port Get Character Non-Blocking
; return last character, even if it has already been read.
; If the character is new, we still clear the new flag.
.proc _serial_get_nb
lda last_char
bpl L1
and #$7f
sta last_char
L1: rts
.endproc
; Serial Port Put Character
; send a single character over the serial port.
.proc _serial_putc
jsr _uart_txb_block
cmp #$0a
bne @1
lda #$0d
jsr _uart_txb_block
@1: rts
.endproc
; Send a string over the serial port. Needs stlen
.proc _serial_puts
sta ptr1 ; Store pointer in ptr1
stx ptr1+1
ldy #$00 ; initialize y to 0
L1: lda (ptr1),y ; load character from string
beq L2 ; Quit if NULL
jsr _uart_txb_block ; send character (does not change y or ptr1)
iny ; increment y
bne L1 ; If Y == 0, increment high byte of pointer
inc ptr1+1
bne L1 ; if high byte wraps around, give up
L2: rts
.endproc

View File

@@ -48,7 +48,7 @@ rti
sta IRQ_CMD_ADDR
lda IRQ_DAT_ADDR
; shift by 2 (oh so only 128 interrupts are supported lol)
lsr
asl
tax
jmp (irq_table,x)
; use that to index jump table
@@ -56,6 +56,7 @@ rti
; void register_irq(void* addr, uint8_t irqn);
.proc _register_irq
asl
tax
jsr popa
sta irq_table,x
@@ -65,6 +66,7 @@ rti
lda #$00
jsr pusha
txa
lsr
jsr _enable_irq
rts
.endproc

View File

@@ -3,6 +3,7 @@
#include "interrupts/interrupt.h"
#include "devices/mapper.h"
#include "devices/rtc.h"
#include "devices/serial.h"
void handle_rtc_interrupt() {
@@ -14,6 +15,8 @@ void handle_rtc_interrupt() {
int main() {
uint8_t c;
cputs("Kernel\n");
cputs("Init Mapper\n");
@@ -32,9 +35,15 @@ int main() {
asm volatile("cli");
// cputs("Initialize Serial\n");
// // init_serial();
// enable_irq(2, IRQ_EDGE);
cputs("Initialize Serial\n");
serial_init();
serial_puts("Hello from serial!\n");
c = serial_getc();
serial_puts("Got a character!: ");
serial_putc(c);
while(1);