diff --git a/hw/efinix_fpga/.gitignore b/hw/efinix_fpga/.gitignore index 849df8d..5c4a7b4 100644 --- a/hw/efinix_fpga/.gitignore +++ b/hw/efinix_fpga/.gitignore @@ -7,4 +7,4 @@ outflow *.gtkw *.vvp -.mem \ No newline at end of file +*.mem \ No newline at end of file diff --git a/sw/kernel/devices/mapper.h b/sw/kernel/devices/mapper.h new file mode 100644 index 0000000..55adb2a --- /dev/null +++ b/sw/kernel/devices/mapper.h @@ -0,0 +1,10 @@ +#ifndef _MAPPER_H +#define _MAPPER_H + +#include + +void init_mapper(); + +void map(uint16_t p_page, uint8_t v_page); + +#endif \ No newline at end of file diff --git a/sw/kernel/devices/mapper.s b/sw/kernel/devices/mapper.s new file mode 100644 index 0000000..260323d --- /dev/null +++ b/sw/kernel/devices/mapper.s @@ -0,0 +1,38 @@ +.MACPACK generic + +.autoimport + +.export _init_mapper +.export _map + +MAPPER_BASE = $200 + +.code + +; void init_paging(); +; This should be identity mapped at reset, but we can do it again anyway +.proc _init_mapper + ldx #$00 +L1: + txa + lsr + sta MAPPER_BASE,x + lda #$00 + sta MAPPER_BASE+1,x + inx + inx + cpx #$20 + blt L1 + rts +.endproc + +; void map(uint16_t p_page, uint8_t v_page); +.proc _map + asl + tax ; x = v_page * 2 + jsr popa ; low byte of p_page + sta MAPPER_BASE,x ; write low byte to mm_low + jsr popa ; high byte of p_page + sta MAPPER_BASE+1,x ; write high byte to mm_high + rts +.endproc diff --git a/sw/kernel/interrupts/interrupt.h b/sw/kernel/interrupts/interrupt.h index 6aeadc2..9520205 100644 --- a/sw/kernel/interrupts/interrupt.h +++ b/sw/kernel/interrupts/interrupt.h @@ -6,6 +6,8 @@ #define BUTTON (1 << 0) #define UART (1 << 1) +void init_interrupts(); + void register_irq(void* addr, uint8_t irqn); uint8_t irq_get_status(); diff --git a/sw/kernel/interrupts/interrupt.s b/sw/kernel/interrupts/interrupt.s index 89e56ce..0344b0a 100644 --- a/sw/kernel/interrupts/interrupt.s +++ b/sw/kernel/interrupts/interrupt.s @@ -3,15 +3,38 @@ .autoimport .import _enable_irq +.import _map .export irq_int, nmi_int .export _register_irq +.export _init_interrupts IRQ_CMD_ADDR = $effc IRQ_DAT_ADDR = $effd IRQ_CMD_READIRQ = $00 +; void init_interrupts(); +; remap the upper page into ram, +; then load the new vector addresses. +.proc _init_interrupts + ; map(001f, f); + lda #$1f + jsr pushax + lda #$f + jsr _map + + lda #irq_int + sta $ffff + + lda #nmi_int + sta $fffb + rts +.endproc .proc nmi_int rti diff --git a/sw/kernel/kernel.c b/sw/kernel/kernel.c index b4a8f4a..766c18c 100644 --- a/sw/kernel/kernel.c +++ b/sw/kernel/kernel.c @@ -1,6 +1,7 @@ #include #include "devices/interrupt_controller.h" #include "interrupts/interrupt.h" +#include "devices/mapper.h" #include "devices/rtc.h" @@ -13,11 +14,11 @@ int main() { cputs("Kernel\n"); - // cputs("Init Paging\n") - // init_paging() + cputs("Init Mapper\n"); + init_mapper(); - // cputs("Initialize Interrupts\n"); - // init_interrupts(); + cputs("Initialize Interrupts\n"); + init_interrupts(); cputs("Initialize Interrupt Controller\n"); init_interrupt_controller();