Add serial driver and irq support
This commit is contained in:
@@ -339,12 +339,16 @@ token = 0xFF - response timeout
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
|
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
(void)addr;
|
||||||
|
(void)buf;
|
||||||
|
(void)token;
|
||||||
|
|
||||||
|
/*
|
||||||
uint16_t readAttempts;
|
uint16_t readAttempts;
|
||||||
uint8_t res1, read;
|
uint8_t res1, read;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// set token to none
|
// set token to none
|
||||||
*token = 0xFF;
|
*token = 0xFF;
|
||||||
|
|
||||||
@@ -391,9 +395,11 @@ uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
|
|||||||
spi_deselect(0);
|
spi_deselect(0);
|
||||||
spi_exchange(0xFF);
|
spi_exchange(0xFF);
|
||||||
|
|
||||||
|
return res1;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return res1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|||||||
17
sw/kernel/devices/serial.h
Normal file
17
sw/kernel/devices/serial.h
Normal 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
|
||||||
94
sw/kernel/devices/serial.s
Normal file
94
sw/kernel/devices/serial.s
Normal 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
|
||||||
@@ -48,7 +48,7 @@ rti
|
|||||||
sta IRQ_CMD_ADDR
|
sta IRQ_CMD_ADDR
|
||||||
lda IRQ_DAT_ADDR
|
lda IRQ_DAT_ADDR
|
||||||
; shift by 2 (oh so only 128 interrupts are supported lol)
|
; shift by 2 (oh so only 128 interrupts are supported lol)
|
||||||
lsr
|
asl
|
||||||
tax
|
tax
|
||||||
jmp (irq_table,x)
|
jmp (irq_table,x)
|
||||||
; use that to index jump table
|
; use that to index jump table
|
||||||
@@ -56,6 +56,7 @@ rti
|
|||||||
|
|
||||||
; void register_irq(void* addr, uint8_t irqn);
|
; void register_irq(void* addr, uint8_t irqn);
|
||||||
.proc _register_irq
|
.proc _register_irq
|
||||||
|
asl
|
||||||
tax
|
tax
|
||||||
jsr popa
|
jsr popa
|
||||||
sta irq_table,x
|
sta irq_table,x
|
||||||
@@ -65,6 +66,7 @@ rti
|
|||||||
lda #$00
|
lda #$00
|
||||||
jsr pusha
|
jsr pusha
|
||||||
txa
|
txa
|
||||||
|
lsr
|
||||||
jsr _enable_irq
|
jsr _enable_irq
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "interrupts/interrupt.h"
|
#include "interrupts/interrupt.h"
|
||||||
#include "devices/mapper.h"
|
#include "devices/mapper.h"
|
||||||
#include "devices/rtc.h"
|
#include "devices/rtc.h"
|
||||||
|
#include "devices/serial.h"
|
||||||
|
|
||||||
|
|
||||||
void handle_rtc_interrupt() {
|
void handle_rtc_interrupt() {
|
||||||
@@ -14,6 +15,8 @@ void handle_rtc_interrupt() {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
|
uint8_t c;
|
||||||
|
|
||||||
cputs("Kernel\n");
|
cputs("Kernel\n");
|
||||||
|
|
||||||
cputs("Init Mapper\n");
|
cputs("Init Mapper\n");
|
||||||
@@ -32,9 +35,15 @@ int main() {
|
|||||||
|
|
||||||
asm volatile("cli");
|
asm volatile("cli");
|
||||||
|
|
||||||
// cputs("Initialize Serial\n");
|
cputs("Initialize Serial\n");
|
||||||
// // init_serial();
|
serial_init();
|
||||||
// enable_irq(2, IRQ_EDGE);
|
|
||||||
|
serial_puts("Hello from serial!\n");
|
||||||
|
|
||||||
|
c = serial_getc();
|
||||||
|
|
||||||
|
serial_puts("Got a character!: ");
|
||||||
|
serial_putc(c);
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user