Separate kernel code from test code
Eventually I want the kernel to be loaded from the SD card as well, but it still needs to separate from user programs. At some point there should be a folder just for the BIOS, which should read from the boot block of the SD card and start executing, and thats it.
This commit is contained in:
16
sw/kernel/devices/board_io.h
Normal file
16
sw/kernel/devices/board_io.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _BOARD_IO_H
|
||||
#define _BOARD_IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t hex_set_8(uint8_t val, uint8_t idx);
|
||||
uint8_t hex_set_16(uint16_t val);
|
||||
uint8_t hex_set_24(uint32_t val);
|
||||
|
||||
void hex_enable(uint8_t mask);
|
||||
|
||||
uint8_t sw_read();
|
||||
|
||||
void led_set(uint8_t val);
|
||||
|
||||
#endif
|
||||
71
sw/kernel/devices/board_io.s
Normal file
71
sw/kernel/devices/board_io.s
Normal file
@@ -0,0 +1,71 @@
|
||||
.include "io.inc65"
|
||||
|
||||
.importzp sp, sreg
|
||||
|
||||
.export _hex_set_8
|
||||
.export _hex_set_16
|
||||
.export _hex_set_24
|
||||
.export _hex_enable
|
||||
.export _sw_read
|
||||
.export _led_set
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
; @in A: idx Stack[0]: val
|
||||
; @out A: 0 for success, 1 for failure.
|
||||
; Sets one of the 3 pairs of hex digits.
|
||||
_hex_set_8:
|
||||
phx
|
||||
cmp #$3 ; If idx >= 3 then fail
|
||||
bcc @1
|
||||
plx
|
||||
lda #$1
|
||||
rts
|
||||
@1: tax ; Move idx into x
|
||||
jsr popa ; put val into a
|
||||
sta SEVEN_SEG,x ; write to val
|
||||
lda #$0
|
||||
plx
|
||||
rts
|
||||
|
||||
; @in A/X: val
|
||||
; @out A: 0 for success, 1 for failure
|
||||
; Sets the low 2 pairs of hex digits
|
||||
_hex_set_16:
|
||||
sta SEVEN_SEG
|
||||
stx SEVEN_SEG+1
|
||||
lda #$0
|
||||
rts
|
||||
|
||||
; @in A/X/sreg: val
|
||||
; @out A: 0 for success, 1 for failure
|
||||
; Sets the 3 pairs of hex digits for a 24 bit value
|
||||
_hex_set_24:
|
||||
sta SEVEN_SEG
|
||||
stx SEVEN_SEG+1
|
||||
lda sreg
|
||||
sta SEVEN_SEG+2
|
||||
lda #$0
|
||||
rts
|
||||
|
||||
; @in A: mask
|
||||
; Set the mask for seven seg enables
|
||||
_hex_enable:
|
||||
sta SEVEN_SEG+3
|
||||
rts
|
||||
|
||||
; @out A: The Value of the switches
|
||||
; Reads the current values of the switches.
|
||||
_sw_read:
|
||||
lda SW
|
||||
ldx #$0
|
||||
rts
|
||||
|
||||
; @in A: val
|
||||
; @out A: 0 for success, 1 for failure
|
||||
; Sets the LEDs
|
||||
_led_set:
|
||||
sta LED
|
||||
rts
|
||||
60
sw/kernel/devices/conio.s
Normal file
60
sw/kernel/devices/conio.s
Normal file
@@ -0,0 +1,60 @@
|
||||
.importzp sp, sreg
|
||||
|
||||
.import _uart_txb_block
|
||||
.import _lastchar
|
||||
|
||||
.export _cputc
|
||||
.export gotoxy
|
||||
.export _clrscr
|
||||
.export _cgetc
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
; void __fastcall__ cputc (char c);
|
||||
_cputc:
|
||||
jsr _uart_txb_block
|
||||
cmp #$0a
|
||||
bne @1
|
||||
lda #$0d
|
||||
jsr _uart_txb_block
|
||||
@1: rts
|
||||
|
||||
; void __fastcall__ gotoxy (unsigned char x, unsigned char y);
|
||||
gotoxy:
|
||||
phx
|
||||
phy
|
||||
tay ; Move y position to y
|
||||
lda (sp)
|
||||
tax ; Move x position to x
|
||||
lda #$1b
|
||||
jsr _uart_txb_block
|
||||
lda #'['
|
||||
jsr _uart_txb_block
|
||||
tya
|
||||
jsr _uart_txb_block
|
||||
lda #';'
|
||||
jsr _uart_txb_block
|
||||
txa
|
||||
jsr _uart_txb_block
|
||||
lda #'H'
|
||||
jsr _uart_txb_block
|
||||
ply
|
||||
plx
|
||||
rts
|
||||
|
||||
_clrscr:
|
||||
phx
|
||||
lda #$1b
|
||||
jsr _uart_txb_block
|
||||
lda #'c'
|
||||
jsr _uart_txb_block
|
||||
pla
|
||||
rts
|
||||
|
||||
_cgetc:
|
||||
@2: lda _lastchar
|
||||
beq @2
|
||||
stz _lastchar
|
||||
rts
|
||||
15
sw/kernel/devices/interrupt.h
Normal file
15
sw/kernel/devices/interrupt.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _INTERRUPT_H
|
||||
#define _INTERRUPT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BUTTON (1 << 0)
|
||||
#define UART (1 << 1)
|
||||
|
||||
void irq_int();
|
||||
void nmi_int();
|
||||
|
||||
uint8_t irq_get_status();
|
||||
void irq_set_status(uint8_t);
|
||||
|
||||
#endif
|
||||
58
sw/kernel/devices/interrupt.s
Normal file
58
sw/kernel/devices/interrupt.s
Normal file
@@ -0,0 +1,58 @@
|
||||
; ---------------------------------------------------------------------------
|
||||
; interrupt.s
|
||||
; ---------------------------------------------------------------------------
|
||||
;
|
||||
; Interrupt handler.
|
||||
;
|
||||
; Checks for a BRK instruction and returns from all valid interrupts.
|
||||
|
||||
.import _handle_irq
|
||||
|
||||
.export _irq_int, _nmi_int
|
||||
.export _irq_get_status, _irq_set_status
|
||||
|
||||
.include "io.inc65"
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
.PC02 ; Force 65C02 assembly mode
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Non-maskable interrupt (NMI) service routine
|
||||
|
||||
_nmi_int: RTI ; Return from all NMI interrupts
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Maskable interrupt (IRQ) service routine
|
||||
|
||||
_irq_int: PHX ; Save X register contents to stack
|
||||
TSX ; Transfer stack pointer to X
|
||||
PHA ; Save accumulator contents to stack
|
||||
INX ; Increment X so it points to the status
|
||||
INX ; register value saved on the stack
|
||||
LDA $100,X ; Load status register contents
|
||||
AND #$10 ; Isolate B status bit
|
||||
BNE break ; If B = 1, BRK detected
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; IRQ detected, return
|
||||
|
||||
irq: PLA ; Restore accumulator contents
|
||||
PLX ; Restore X register contents
|
||||
jsr _handle_irq ; Handle the IRQ
|
||||
RTI ; Return from all IRQ interrupts
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; BRK detected, stop
|
||||
|
||||
break: JMP break ; If BRK is detected, something very bad
|
||||
; has happened, so stop running
|
||||
|
||||
_irq_get_status:
|
||||
lda IRQ_STATUS
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
_irq_set_status:
|
||||
sta IRQ_STATUS
|
||||
rts
|
||||
18
sw/kernel/devices/io.inc65
Normal file
18
sw/kernel/devices/io.inc65
Normal file
@@ -0,0 +1,18 @@
|
||||
SEVEN_SEG = $7ff0
|
||||
|
||||
UART = $7ff4
|
||||
UART_TXB = UART
|
||||
UART_RXB = UART
|
||||
UART_STATUS = UART + 1
|
||||
|
||||
LED = $7ff6
|
||||
SW = LED
|
||||
|
||||
MM_CTRL = $7ff7
|
||||
MM_DATA = $7fe0
|
||||
|
||||
SD_ARG = $7ff8
|
||||
SD_CMD = $7ffc
|
||||
SD_DATA = $7ffd
|
||||
|
||||
IRQ_STATUS = $7fff
|
||||
12
sw/kernel/devices/mapper.h
Normal file
12
sw/kernel/devices/mapper.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _MAPPER_H
|
||||
#define _MAPPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void mapper_enable(uint8_t en);
|
||||
|
||||
uint8_t mapper_read(uint8_t addr);
|
||||
void mapper_write(uint8_t data, uint8_t addr);
|
||||
|
||||
#endif
|
||||
|
||||
32
sw/kernel/devices/mapper.s
Normal file
32
sw/kernel/devices/mapper.s
Normal file
@@ -0,0 +1,32 @@
|
||||
.include "io.inc65"
|
||||
|
||||
.importzp sp, sreg
|
||||
|
||||
.export _mapper_enable
|
||||
.export _mapper_read, _mapper_write
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
|
||||
; void mapper_enable(uint8_t en)
|
||||
_mapper_enable:
|
||||
sta MM_CTRL
|
||||
rts
|
||||
|
||||
_mapper_read:
|
||||
phx
|
||||
tax
|
||||
lda MM_DATA,x
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
_mapper_write:
|
||||
phx
|
||||
tax
|
||||
jsr popa
|
||||
sta MM_DATA,x
|
||||
plx
|
||||
rts
|
||||
|
||||
75
sw/kernel/devices/sd_card.c
Normal file
75
sw/kernel/devices/sd_card.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "devices/sd_card.h"
|
||||
|
||||
void sd_init() {
|
||||
uint32_t resp;
|
||||
sd_card_command(0, 0);
|
||||
|
||||
sd_card_command(0x000001aa, 8);
|
||||
sd_card_resp(&resp);
|
||||
//cprintf("CMD8: %lx\n", resp);
|
||||
|
||||
sd_card_command(0, 55);
|
||||
sd_card_command(0x40180000, 41);
|
||||
sd_card_resp(&resp);
|
||||
//cprintf("CMD41: %lx\n", resp);
|
||||
|
||||
sd_card_command(0, 55);
|
||||
sd_card_command(0x40180000, 41);
|
||||
sd_card_resp(&resp);
|
||||
//cprintf("CMD41: %lx\n", resp);
|
||||
|
||||
sd_card_command(0, 2);
|
||||
sd_card_resp(&resp);
|
||||
//cprintf("CMD2: %lx\n", resp);
|
||||
}
|
||||
|
||||
uint16_t sd_get_rca() {
|
||||
uint32_t resp;
|
||||
|
||||
sd_card_command(0, 3);
|
||||
resp = 0;
|
||||
sd_card_resp(&resp);
|
||||
|
||||
//cprintf("CMD3: %lx\n", resp);
|
||||
|
||||
return resp >> 16;
|
||||
}
|
||||
|
||||
uint16_t sd_select_card(uint16_t rca) {
|
||||
uint32_t resp;
|
||||
|
||||
sd_card_command((uint32_t)rca << 16, 7);
|
||||
sd_card_resp(&resp);
|
||||
|
||||
return (uint16_t) resp;
|
||||
}
|
||||
|
||||
uint16_t sd_get_status(uint16_t rca) {
|
||||
uint32_t resp;
|
||||
|
||||
sd_card_command((uint32_t)rca << 16, 13);
|
||||
sd_card_resp(&resp);
|
||||
|
||||
return (uint16_t) resp;
|
||||
}
|
||||
|
||||
void sd_readblock(uint32_t addr, void* buf) {
|
||||
uint32_t resp;
|
||||
int i;
|
||||
|
||||
sd_card_command(addr, 17);
|
||||
sd_card_resp(&resp);
|
||||
//cprintf("CMD17: %lx\n", resp);
|
||||
|
||||
sd_card_wait_for_data();
|
||||
|
||||
//cprintf("Read data: \n");
|
||||
for (i = 0; i < 512; i++){
|
||||
((uint8_t*)buf)[i] = sd_card_read_byte();
|
||||
}
|
||||
|
||||
//cprintf("\n");
|
||||
}
|
||||
18
sw/kernel/devices/sd_card.h
Normal file
18
sw/kernel/devices/sd_card.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _SD_CARD_H
|
||||
#define _SD_CARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void sd_init();
|
||||
uint16_t sd_get_rca();
|
||||
uint16_t sd_select_card(uint16_t rca);
|
||||
uint16_t sd_get_status(uint16_t rca);
|
||||
void sd_readblock(uint32_t addr, void* buf);
|
||||
|
||||
void sd_card_command(uint32_t arg, uint8_t cmd);
|
||||
|
||||
void sd_card_resp(uint32_t* resp);
|
||||
uint8_t sd_card_read_byte();
|
||||
void sd_card_wait_for_data();
|
||||
|
||||
#endif
|
||||
66
sw/kernel/devices/sd_card_asm.s
Normal file
66
sw/kernel/devices/sd_card_asm.s
Normal file
@@ -0,0 +1,66 @@
|
||||
.include "io.inc65"
|
||||
|
||||
.importzp sp, sreg, ptr1
|
||||
|
||||
.export _sd_card_command
|
||||
.export _sd_card_resp
|
||||
.export _sd_card_read_byte
|
||||
.export _sd_card_wait_for_data
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
; Send sd card command.
|
||||
; command is in A register, the args are on the stack
|
||||
; I think the order is high byte first?
|
||||
_sd_card_command:
|
||||
pha
|
||||
|
||||
jsr popeax
|
||||
sta SD_ARG
|
||||
stx SD_ARG+1
|
||||
lda sreg
|
||||
sta SD_ARG+2
|
||||
lda sreg+1
|
||||
sta SD_ARG+3
|
||||
|
||||
pla
|
||||
sta SD_CMD
|
||||
rts
|
||||
|
||||
; void sd_card_resp(uint32_t* resp);
|
||||
_sd_card_resp:
|
||||
phy
|
||||
sta ptr1 ; store pointer
|
||||
stx ptr1+1
|
||||
@1: lda SD_CMD ; wait for status flag
|
||||
and #$01
|
||||
beq @1
|
||||
lda SD_ARG
|
||||
ldy #$0
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+1
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+2
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+3
|
||||
iny
|
||||
sta (ptr1),y
|
||||
ply
|
||||
rts
|
||||
|
||||
_sd_card_read_byte:
|
||||
lda SD_DATA
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
_sd_card_wait_for_data:
|
||||
pha
|
||||
@1: lda SD_CMD ; wait for status flag
|
||||
and #$02
|
||||
beq @1
|
||||
pla
|
||||
rts
|
||||
13
sw/kernel/devices/uart.h
Normal file
13
sw/kernel/devices/uart.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef _UART_H
|
||||
#define _UART_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void uart_txb(uint8_t val);
|
||||
void uart_txb_block(uint8_t val);
|
||||
|
||||
uint8_t uart_rxb();
|
||||
|
||||
uint8_t uart_status();
|
||||
|
||||
#endif
|
||||
36
sw/kernel/devices/uart.s
Normal file
36
sw/kernel/devices/uart.s
Normal file
@@ -0,0 +1,36 @@
|
||||
.include "io.inc65"
|
||||
|
||||
.importzp sp, sreg
|
||||
|
||||
.export _uart_txb, _uart_txb_block
|
||||
.export _uart_rxb
|
||||
.export _uart_status
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
; @in A: byte to transmit
|
||||
; Transmits a byte over the UART
|
||||
_uart_txb:
|
||||
sta UART_TXB ; Just write value, don't wait
|
||||
rts
|
||||
|
||||
_uart_txb_block:
|
||||
pha
|
||||
sta UART_TXB ; Write value
|
||||
@1: lda UART_STATUS ; Wait for status[0] to be 0
|
||||
bit #$01
|
||||
bne @1
|
||||
pla
|
||||
rts
|
||||
|
||||
_uart_rxb:
|
||||
lda UART_RXB ; Read value
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
_uart_status:
|
||||
lda UART_STATUS
|
||||
ldx #$00
|
||||
rts
|
||||
Reference in New Issue
Block a user