From 2ff3caccc6a524c04b2e8a24bb67cf2a19e53d8f Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 12:12:43 -0500 Subject: [PATCH 01/26] Change user programs to use super6502 target The target library is a copy of `none` right now but will be built out later. --- sw/test_exec/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw/test_exec/Makefile b/sw/test_exec/Makefile index cfcfe6d..a02cbfe 100644 --- a/sw/test_exec/Makefile +++ b/sw/test_exec/Makefile @@ -1,5 +1,5 @@ CC=cl65 -CFLAGS=-T -t none -I. --cpu "65C02" +CFLAGS=-T -t super6502 -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map SIM=sim65 From 12284d19a97364db0ab33a6228cd1d292f3670d6 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 12:43:29 -0500 Subject: [PATCH 02/26] Create boot environment The boot environment will read the boot sector from the sd card, verify that it has the boot signature at the end, then jump to the start of it. From there, there should be a bootloader written to the boot segment that can handle the rest. It might be tight to fit everything into the boot sector but do remember that you do not have to initialize or select the sd card, and those functions take up a lot of space. --- sw/boot/Makefile | 42 +++++++++++++++++++++++++++++++++++ sw/boot/boot.s | 17 ++++++++++++++ sw/boot/devices/io.inc65 | 1 + sw/boot/devices/sd_card.c | 1 + sw/boot/devices/sd_card.h | 1 + sw/boot/devices/sd_card_asm.s | 1 + sw/boot/link.ld | 18 +++++++++++++++ sw/boot/load_bootsect.c | 29 ++++++++++++++++++++++++ 8 files changed, 110 insertions(+) create mode 100644 sw/boot/Makefile create mode 100644 sw/boot/boot.s create mode 120000 sw/boot/devices/io.inc65 create mode 120000 sw/boot/devices/sd_card.c create mode 120000 sw/boot/devices/sd_card.h create mode 120000 sw/boot/devices/sd_card_asm.s create mode 100644 sw/boot/link.ld create mode 100644 sw/boot/load_bootsect.c diff --git a/sw/boot/Makefile b/sw/boot/Makefile new file mode 100644 index 0000000..a8b4fde --- /dev/null +++ b/sw/boot/Makefile @@ -0,0 +1,42 @@ +CC=cl65 +CFLAGS=-T -t none -I. --cpu "65C02" +test: CFLAGS=-T -t sim65c02 -I. +LDFLAGS=-C link.ld -m $(NAME).map +SIM=sim65 +SIMARGS=-v -c -x 1000000 + +NAME=bootrom + +TEST_BIN=test.bin +BIN=$(NAME).bin +HEX=$(NAME).hex + +LISTS=lists + +SRCS=$(wildcard *.s) $(wildcard *.c) +SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c)) +OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) +OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) + +all: $(HEX) + +$(HEX): $(BIN) + objcopy --input-target=binary --output-target=ihex $(BIN) $(HEX) + + +$(BIN): $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ + +%.o: %.c $(LISTS) + $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ + +%.o: %.s $(LISTS) + $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ + +$(LISTS): + mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) + +.PHONY: clean +clean: + rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map + diff --git a/sw/boot/boot.s b/sw/boot/boot.s new file mode 100644 index 0000000..1cd5448 --- /dev/null +++ b/sw/boot/boot.s @@ -0,0 +1,17 @@ +; We need to to read the boot sector from the +; SD card, verify the last 2 bytes, then jump to the +; beginning of it. + +.include "zeropage.inc" + +.segment "STARTUP" + +.import _load_bootsect + +_init: ldx #$ff + txs + cld + + jsr _load_bootsect + jmp $1000 + \ No newline at end of file diff --git a/sw/boot/devices/io.inc65 b/sw/boot/devices/io.inc65 new file mode 120000 index 0000000..14ef1f5 --- /dev/null +++ b/sw/boot/devices/io.inc65 @@ -0,0 +1 @@ +../../kernel/devices/io.inc65 \ No newline at end of file diff --git a/sw/boot/devices/sd_card.c b/sw/boot/devices/sd_card.c new file mode 120000 index 0000000..c20d8c7 --- /dev/null +++ b/sw/boot/devices/sd_card.c @@ -0,0 +1 @@ +../../kernel/devices/sd_card.c \ No newline at end of file diff --git a/sw/boot/devices/sd_card.h b/sw/boot/devices/sd_card.h new file mode 120000 index 0000000..7955199 --- /dev/null +++ b/sw/boot/devices/sd_card.h @@ -0,0 +1 @@ +../../kernel/devices/sd_card.h \ No newline at end of file diff --git a/sw/boot/devices/sd_card_asm.s b/sw/boot/devices/sd_card_asm.s new file mode 120000 index 0000000..a25313c --- /dev/null +++ b/sw/boot/devices/sd_card_asm.s @@ -0,0 +1 @@ +../../kernel/devices/sd_card_asm.s \ No newline at end of file diff --git a/sw/boot/link.ld b/sw/boot/link.ld new file mode 100644 index 0000000..33de787 --- /dev/null +++ b/sw/boot/link.ld @@ -0,0 +1,18 @@ +MEMORY +{ + ZP: start = $0, size = $100, type = rw, define = yes; + SDRAM: start = $1000, size = $6ef0, type = rw, define = yes; + ROM: start = $8000, size = $8000, fill = yes, fillval = $ff, file = %O; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + DATA: load = ROM, type = rw, define = yes, run = SDRAM; + BSS: load = SDRAM, type = bss, define = yes; + HEAP: load = SDRAM, type = bss, optional = yes; + STARTUP: load = ROM, type = ro; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro; + RODATA: load = ROM, type = ro; +} + diff --git a/sw/boot/load_bootsect.c b/sw/boot/load_bootsect.c new file mode 100644 index 0000000..6fe0ba2 --- /dev/null +++ b/sw/boot/load_bootsect.c @@ -0,0 +1,29 @@ +#include + +#include "devices/sd_card.h" + +#define BOOTSECTOR_LOAD_ADDRESS 0x1000 + +#define BOOTSIG_0 0x55 +#define BOOTSIG_1 0xaa + +//Should probably do this in asm +void load_bootsect() { + uint32_t rca; + uint8_t sig[2]; + + sd_init(); + rca = sd_get_rca(); + sd_select_card(rca); + + sd_readblock(0, (uint8_t*)BOOTSECTOR_LOAD_ADDRESS); + + sig[0] = ((uint8_t*)BOOTSECTOR_LOAD_ADDRESS)[510]; + sig[1] = ((uint8_t*)BOOTSECTOR_LOAD_ADDRESS)[511]; + + if (sig[0] != BOOTSIG_0 || sig[1] != BOOTSIG_1) { + for(;;); //maybe figure out a way to have an error message here + } + + return; +} \ No newline at end of file From 64f6f0b39729ab425fed48cb188db9a4a0544c28 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 12:50:19 -0500 Subject: [PATCH 03/26] Add top level makefile for sw --- sw/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 sw/Makefile diff --git a/sw/Makefile b/sw/Makefile new file mode 100644 index 0000000..57f62b1 --- /dev/null +++ b/sw/Makefile @@ -0,0 +1,9 @@ +TOPTARGETS := all clean + +SUBDIRS := $(wildcard */.) + +$(TOPTARGETS): $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) + +.PHONY: $(TOPTARGETS) $(SUBDIRS) \ No newline at end of file From 54328722ab44666da14b1b68b55b84903b79b1b0 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:24:29 -0500 Subject: [PATCH 04/26] Rename boot to bios, add sd call Adds a call that you can make to the BIOS to read sd blocks. Useful for the bootloader where there is not much space --- sw/{boot => bios}/Makefile | 6 +-- sw/{boot => bios}/boot.s | 5 +-- sw/bios/devices/interrupt.s | 55 +++++++++++++++++++++++++ sw/{boot => bios}/devices/io.inc65 | 0 sw/{boot => bios}/devices/sd_card.c | 0 sw/{boot => bios}/devices/sd_card.h | 0 sw/{boot => bios}/devices/sd_card_asm.s | 0 sw/{boot => bios}/link.ld | 1 + sw/{boot => bios}/load_bootsect.c | 0 sw/bios/vectors.s | 14 +++++++ 10 files changed, 72 insertions(+), 9 deletions(-) rename sw/{boot => bios}/Makefile (92%) rename sw/{boot => bios}/boot.s (57%) create mode 100644 sw/bios/devices/interrupt.s rename sw/{boot => bios}/devices/io.inc65 (100%) rename sw/{boot => bios}/devices/sd_card.c (100%) rename sw/{boot => bios}/devices/sd_card.h (100%) rename sw/{boot => bios}/devices/sd_card_asm.s (100%) rename sw/{boot => bios}/link.ld (91%) rename sw/{boot => bios}/load_bootsect.c (100%) create mode 100644 sw/bios/vectors.s diff --git a/sw/boot/Makefile b/sw/bios/Makefile similarity index 92% rename from sw/boot/Makefile rename to sw/bios/Makefile index a8b4fde..caa77c0 100644 --- a/sw/boot/Makefile +++ b/sw/bios/Makefile @@ -2,12 +2,8 @@ CC=cl65 CFLAGS=-T -t none -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map -SIM=sim65 -SIMARGS=-v -c -x 1000000 +NAME=bios -NAME=bootrom - -TEST_BIN=test.bin BIN=$(NAME).bin HEX=$(NAME).hex diff --git a/sw/boot/boot.s b/sw/bios/boot.s similarity index 57% rename from sw/boot/boot.s rename to sw/bios/boot.s index 1cd5448..4a26770 100644 --- a/sw/boot/boot.s +++ b/sw/bios/boot.s @@ -1,11 +1,8 @@ -; We need to to read the boot sector from the -; SD card, verify the last 2 bytes, then jump to the -; beginning of it. - .include "zeropage.inc" .segment "STARTUP" +.export _init .import _load_bootsect _init: ldx #$ff diff --git a/sw/bios/devices/interrupt.s b/sw/bios/devices/interrupt.s new file mode 100644 index 0000000..f555c1c --- /dev/null +++ b/sw/bios/devices/interrupt.s @@ -0,0 +1,55 @@ +.include "io.inc65" + +.export _irq_int, _nmi_int + +.importzp sreg, ptr1 + +.segment "CODE" + +; IRQ +_irq_int: + jmp (irqmap,x) + +_nmi_int: + rti + +irqmap: + .addr handle_invalid + .addr handle_sd_read + +handle_invalid: + rti + +; sreg is the pointer to store the data +; a/y is the block address +; send command 17 with the block address of 00/y/a +handle_sd_read: + sta SD_ARG ; send command + sty SD_ARG+1 + stz SD_ARG+2 + stz SD_ARG+3 + lda #$11 + sta SD_CMD + +@1: lda SD_CMD ; wait for status flag + and #$01 + beq @1 + +@2: lda SD_CMD ; wait for data + and #$02 + beq @2 + + ldy #$00 +@loop: lda SD_DATA ; copy first 256 bytes + sta (sreg),y + iny + bne @loop + + ldy #$00 ; copy second 256 bytes + inc sreg+1 +@loop2: lda SD_DATA + sta (sreg),y + iny + bne @loop2 + + rti \ No newline at end of file diff --git a/sw/boot/devices/io.inc65 b/sw/bios/devices/io.inc65 similarity index 100% rename from sw/boot/devices/io.inc65 rename to sw/bios/devices/io.inc65 diff --git a/sw/boot/devices/sd_card.c b/sw/bios/devices/sd_card.c similarity index 100% rename from sw/boot/devices/sd_card.c rename to sw/bios/devices/sd_card.c diff --git a/sw/boot/devices/sd_card.h b/sw/bios/devices/sd_card.h similarity index 100% rename from sw/boot/devices/sd_card.h rename to sw/bios/devices/sd_card.h diff --git a/sw/boot/devices/sd_card_asm.s b/sw/bios/devices/sd_card_asm.s similarity index 100% rename from sw/boot/devices/sd_card_asm.s rename to sw/bios/devices/sd_card_asm.s diff --git a/sw/boot/link.ld b/sw/bios/link.ld similarity index 91% rename from sw/boot/link.ld rename to sw/bios/link.ld index 33de787..0fe59b7 100644 --- a/sw/boot/link.ld +++ b/sw/bios/link.ld @@ -14,5 +14,6 @@ SEGMENTS { ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; RODATA: load = ROM, type = ro; + VECTORS: load = ROM, type = ro, start = $FFFA; } diff --git a/sw/boot/load_bootsect.c b/sw/bios/load_bootsect.c similarity index 100% rename from sw/boot/load_bootsect.c rename to sw/bios/load_bootsect.c diff --git a/sw/bios/vectors.s b/sw/bios/vectors.s new file mode 100644 index 0000000..81ae6e0 --- /dev/null +++ b/sw/bios/vectors.s @@ -0,0 +1,14 @@ +; --------------------------------------------------------------------------- +; vectors.s +; --------------------------------------------------------------------------- +; +; Defines the interrupt vector table. + +.import _init +.import _nmi_int, _irq_int + +.segment "VECTORS" + +.addr _nmi_int ; NMI vector +.addr _init ; Reset vector +.addr _irq_int ; IRQ/BRK vector \ No newline at end of file From 9dd460a47fc6246c8f375878a44fc50cbd7241d8 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:25:08 -0500 Subject: [PATCH 05/26] Add preliminary bootloader This bootloader right now just prints the letter A, but should be capable of reading blocks from the SD card into memory. --- sw/bootloader/Makefile | 41 ++++++++++++++++++++++++++++++++++++++ sw/bootloader/bios_calls | 0 sw/bootloader/bios_calls.h | 8 ++++++++ sw/bootloader/bios_calls.s | 23 +++++++++++++++++++++ sw/bootloader/boot.s | 26 ++++++++++++++++++++++++ sw/bootloader/io.inc65 | 1 + sw/bootloader/link.ld | 17 ++++++++++++++++ sw/bootloader/main.c | 11 ++++++++++ sw/bootloader/uart.h | 1 + sw/bootloader/uart.s | 1 + 10 files changed, 129 insertions(+) create mode 100644 sw/bootloader/Makefile create mode 100644 sw/bootloader/bios_calls create mode 100644 sw/bootloader/bios_calls.h create mode 100644 sw/bootloader/bios_calls.s create mode 100644 sw/bootloader/boot.s create mode 120000 sw/bootloader/io.inc65 create mode 100644 sw/bootloader/link.ld create mode 100644 sw/bootloader/main.c create mode 120000 sw/bootloader/uart.h create mode 120000 sw/bootloader/uart.s diff --git a/sw/bootloader/Makefile b/sw/bootloader/Makefile new file mode 100644 index 0000000..2365468 --- /dev/null +++ b/sw/bootloader/Makefile @@ -0,0 +1,41 @@ +CC=cl65 +CFLAGS=-T -t none -I. --cpu "65C02" -DNO_SD_INIT +test: CFLAGS=-T -t sim65c02 -I. +LDFLAGS=-C link.ld -m $(NAME).map +SIM=sim65 +SIMARGS=-v -c -x 1000000 + +NAME=bootloader + +BIN=$(NAME).bin +HEX=$(NAME).hex + +LISTS=lists + +SRCS=$(wildcard *.s) $(wildcard *.c) +SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c)) +OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) +OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) + +all: $(HEX) + +$(HEX): $(BIN) + objcopy --input-target=binary --output-target=ihex $(BIN) $(HEX) + + +$(BIN): $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ + +%.o: %.c $(LISTS) + $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ + +%.o: %.s $(LISTS) + $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ + +$(LISTS): + mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) + +.PHONY: clean +clean: + rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map + diff --git a/sw/bootloader/bios_calls b/sw/bootloader/bios_calls new file mode 100644 index 0000000..e69de29 diff --git a/sw/bootloader/bios_calls.h b/sw/bootloader/bios_calls.h new file mode 100644 index 0000000..88ed750 --- /dev/null +++ b/sw/bootloader/bios_calls.h @@ -0,0 +1,8 @@ +#ifndef _BIOS_CALLS_H +#define _BIOS_CALLS_H + +#include + +void sd_readblock(uint16_t addr, void* buf); + +#endif \ No newline at end of file diff --git a/sw/bootloader/bios_calls.s b/sw/bootloader/bios_calls.s new file mode 100644 index 0000000..a1964a3 --- /dev/null +++ b/sw/bootloader/bios_calls.s @@ -0,0 +1,23 @@ +.export _sd_readblock + +.autoimport + +.importzp sreg + +; sreg is the pointer to store the data +; a/y is the block address +; send command 17 with the block address of 00/y/a + +; void sd_readblock(uint16_t addr, void* buf); + +_sd_readblock: + sta sreg ; move buf pointer to sreg + stx sreg+1 + + jsr popax ; move addr to a/y + tya + + ldx #$1 ; call interrupt 1 + brk + + rts \ No newline at end of file diff --git a/sw/bootloader/boot.s b/sw/bootloader/boot.s new file mode 100644 index 0000000..47eaf07 --- /dev/null +++ b/sw/bootloader/boot.s @@ -0,0 +1,26 @@ +; We need to to read the boot sector from the +; SD card, verify the last 2 bytes, then jump to the +; beginning of it. + +.include "zeropage.inc" + +.import _load_bootsect + +.export _init, _boot + +.segment "STARTUP" + +_init: jmp _boot + +.segment "CODE" + +_boot: ldx #$ff + txs + cld + + jsr _load_bootsect + jmp $1000 + +.segment "SIGN" +.byte $55 +.byte $aa diff --git a/sw/bootloader/io.inc65 b/sw/bootloader/io.inc65 new file mode 120000 index 0000000..52851e4 --- /dev/null +++ b/sw/bootloader/io.inc65 @@ -0,0 +1 @@ +../kernel/devices/io.inc65 \ No newline at end of file diff --git a/sw/bootloader/link.ld b/sw/bootloader/link.ld new file mode 100644 index 0000000..6860602 --- /dev/null +++ b/sw/bootloader/link.ld @@ -0,0 +1,17 @@ +MEMORY +{ + ZP: start = $0, size = $100, type = rw, define = yes; + BOOTSECT: start = $1000, size = $200, file = %O; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + DATA: load = BOOTSECT, type = rw, define = yes; + BSS: load = BOOTSECT, type = bss, define = yes; + HEAP: load = BOOTSECT, type = bss, optional = yes; + STARTUP: load = BOOTSECT, type = ro, start = $1000; + CODE: load = BOOTSECT, type = ro, start = $105a; + RODATA: load = BOOTSECT, type = ro; + SIGN: load = BOOTSECT, type = ro, start = $11fe; +} + diff --git a/sw/bootloader/main.c b/sw/bootloader/main.c new file mode 100644 index 0000000..e69fb86 --- /dev/null +++ b/sw/bootloader/main.c @@ -0,0 +1,11 @@ +#include + +#include "bios_calls.h" +#include "uart.h" + +//Should probably do this in asm +void load_bootsect() { + uart_txb_block('A'); + for (;;); + return; +} \ No newline at end of file diff --git a/sw/bootloader/uart.h b/sw/bootloader/uart.h new file mode 120000 index 0000000..bdfeb82 --- /dev/null +++ b/sw/bootloader/uart.h @@ -0,0 +1 @@ +../kernel/devices/uart.h \ No newline at end of file diff --git a/sw/bootloader/uart.s b/sw/bootloader/uart.s new file mode 120000 index 0000000..aa91b87 --- /dev/null +++ b/sw/bootloader/uart.s @@ -0,0 +1 @@ +../kernel/devices/uart.s \ No newline at end of file From 72b83d739d2f7d28c2326abecc70752f114f89e2 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:26:59 -0500 Subject: [PATCH 06/26] Remove unused define --- sw/bootloader/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw/bootloader/Makefile b/sw/bootloader/Makefile index 2365468..3e4a963 100644 --- a/sw/bootloader/Makefile +++ b/sw/bootloader/Makefile @@ -1,5 +1,5 @@ CC=cl65 -CFLAGS=-T -t none -I. --cpu "65C02" -DNO_SD_INIT +CFLAGS=-T -t none -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map SIM=sim65 From 0fadc6a80f728a97cf3c835420e61349aae75ffa Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:27:05 -0500 Subject: [PATCH 07/26] Add sw makefile which compiles all subtargets Usefull now that we have like 4 different folders that need to be compiled slightly differently --- sw/Makefile | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/sw/Makefile b/sw/Makefile index 57f62b1..d362cdb 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -1,9 +1,22 @@ -TOPTARGETS := all clean +.PHONY: all install bios bootloader kernel clean -SUBDIRS := $(wildcard */.) +all: bios bootloader kernel -$(TOPTARGETS): $(SUBDIRS) -$(SUBDIRS): - $(MAKE) -C $@ $(MAKECMDGOALS) +install: all + sh script/format_disk.sh + sh script/copy_files.sh -.PHONY: $(TOPTARGETS) $(SUBDIRS) \ No newline at end of file +bios: + @$(MAKE) -C bios + +bootloader: + @$(MAKE) -C bootloader + +kernel: + @$(MAKE) -C kernel + + +clean: + @$(MAKE) -C bios --no-print-directory $@ + @$(MAKE) -C bootloader --no-print-directory $@ + @$(MAKE) -C kernel --no-print-directory $@ \ No newline at end of file From 9f1d527a7c9e6e40b85faf42b59aee026b396469 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:27:48 -0500 Subject: [PATCH 08/26] Change kernel link type Kernel is now compiled and linked into a raw binary instead of intel hex. This raw binary can be loaded into the correct address by the bootloader. I wanted this to be an o65 file, but ld65 kept complaining about it. Honestly though having this be a straight binary makes it easier to load, but we can't relocate it. --- sw/kernel/Makefile | 6 +++--- sw/kernel/link.ld | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sw/kernel/Makefile b/sw/kernel/Makefile index a84801d..d733175 100644 --- a/sw/kernel/Makefile +++ b/sw/kernel/Makefile @@ -1,11 +1,11 @@ CC=cl65 -CFLAGS=-T -t none -I. --cpu "65C02" +CFLAGS=-T -t super6502 -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map SIM=sim65 SIMARGS=-v -c -x 1000000 -NAME=bootrom +NAME=kernel TEST_BIN=test.bin BIN=$(NAME).bin @@ -24,7 +24,7 @@ TEST_OBJS+=$(patsubst %.s,%.o,$(filter %s,$(TEST_SRCS))) TEST_OBJS+=$(patsubst %.c,%.o,$(filter %c,$(TEST_SRCS))) TEST_OBJS+=$(filter-out boot.o,$(filter-out main.o,$(filter-out vectors.o,$(OBJS)))) -all: $(HEX) +all: $(BIN) test: $(TEST_BIN) $(SIM) $(SIMARGS) $(TEST_BIN) diff --git a/sw/kernel/link.ld b/sw/kernel/link.ld index 172f0a5..1fd8d3f 100644 --- a/sw/kernel/link.ld +++ b/sw/kernel/link.ld @@ -2,7 +2,7 @@ MEMORY { ZP: start = $0, size = $100, type = rw, define = yes; SDRAM: start = $200, size = $7cf0, type = rw, define = yes; - ROM: start = $8000, size = $8000, fill = yes, fillval = $ff, file = %O; + ROM: start = $D000, size = $3000, file = %O; } SEGMENTS { From 24d5a8c8ac8141cf1e69773e3f09def3508b9f2c Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:29:00 -0500 Subject: [PATCH 09/26] Add fsdir --- sw/fsdir/hello.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 sw/fsdir/hello.txt diff --git a/sw/fsdir/hello.txt b/sw/fsdir/hello.txt new file mode 100644 index 0000000..270c611 --- /dev/null +++ b/sw/fsdir/hello.txt @@ -0,0 +1 @@ +hello, world! From 4e2e030e5208a3aeb7977b66f2116868d07180ed Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:29:10 -0500 Subject: [PATCH 10/26] Add scripts automates the process of overwriting the boot sector of the SD card and copying over the filesystem. --- sw/script/copy_files.sh | 19 +++++++++++++++++++ sw/script/format_disk.sh | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 sw/script/copy_files.sh create mode 100644 sw/script/format_disk.sh diff --git a/sw/script/copy_files.sh b/sw/script/copy_files.sh new file mode 100644 index 0000000..17bc144 --- /dev/null +++ b/sw/script/copy_files.sh @@ -0,0 +1,19 @@ +DEVICE=/dev/mmcblk0 +TMPMOUNT=/tmp/sd +FSDIR=fsdir + +V= + +echo "$(tput bold setaf 11)Mounting Device$(tput sgr 0)" +mkdir $V -p $TMPMOUNT +sudo mount $V $DEVICE $TMPMOUNT +echo + +echo "$(tput bold setaf 11)Copying Files$(tput sgr 0)" +sudo cp $V -r $FSDIR/* $TMPMOUNT +echo + +echo "$(tput bold setaf 11)Unmounting Device$(tput sgr 0)" +sudo umount $V $DEVICE +rmdir $V $TMPMOUNT +echo \ No newline at end of file diff --git a/sw/script/format_disk.sh b/sw/script/format_disk.sh new file mode 100644 index 0000000..99b82a6 --- /dev/null +++ b/sw/script/format_disk.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +BOOTLOADER=bootloader/bootloader.bin +DEVICE=/dev/mmcblk0 +TMPBOOTSECT=/tmp/bootsect +TMPMOUNT=/tmp/sd + +V= +STATUS="status=none" + +echo "$(tput bold setaf 11)Creating Filesystem$(tput sgr 0)" +sudo mkfs.vfat -F32 $DEVICE -n SUPER6502 $V +echo + +echo "$(tput bold setaf 11)Modifying Boot Sector$(tput sgr 0)" +sudo dd if=$DEVICE of=$TMPBOOTSECT bs=512 count=1 $STATUS +sudo dd conv=notrunc if=$BOOTLOADER of=$DEVICE bs=512 skip=0 count=1 $STATUS +sudo dd conv=notrunc if=$TMPBOOTSECT of=$DEVICE bs=1 skip=0 count=90 iflag=skip_bytes,count_bytes $STATUS +sudo dd conv=notrunc if=$BOOTLOADER of=$DEVICE bs=1 skip=0 count=3 iflag=skip_bytes,count_bytes $STATUS +echo + +echo "$(tput bold setaf 10)Done!$(tput sgr 0)" + From 15a0917bb4b66bb64626e4cfa7d81bff9a873bdf Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 18 Apr 2022 20:31:11 -0500 Subject: [PATCH 11/26] Change kernel to use none target I forgot that the CI still uses the stock cc65 which doesn't support my target. The kernel doesn't really need this target though, only the user programs. --- sw/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw/kernel/Makefile b/sw/kernel/Makefile index d733175..627fb45 100644 --- a/sw/kernel/Makefile +++ b/sw/kernel/Makefile @@ -1,5 +1,5 @@ CC=cl65 -CFLAGS=-T -t super6502 -I. --cpu "65C02" +CFLAGS=-T -t none -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map SIM=sim65 From f664d594974023bbac57ba63a180ba1822761e17 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 10:33:27 -0500 Subject: [PATCH 12/26] Copy kernel into root folder after build This way it gets copied over to the SD card when installing. --- sw/kernel/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sw/kernel/Makefile b/sw/kernel/Makefile index 627fb45..bd2124e 100644 --- a/sw/kernel/Makefile +++ b/sw/kernel/Makefile @@ -5,6 +5,8 @@ LDFLAGS=-C link.ld -m $(NAME).map SIM=sim65 SIMARGS=-v -c -x 1000000 +FSDIR=../fsdir + NAME=kernel TEST_BIN=test.bin @@ -25,6 +27,7 @@ TEST_OBJS+=$(patsubst %.c,%.o,$(filter %c,$(TEST_SRCS))) TEST_OBJS+=$(filter-out boot.o,$(filter-out main.o,$(filter-out vectors.o,$(OBJS)))) all: $(BIN) + cp $(BIN) $(FSDIR) test: $(TEST_BIN) $(SIM) $(SIMARGS) $(TEST_BIN) @@ -53,4 +56,5 @@ $(LISTS): clean: rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map rm -rf $(TEST_OBJS) $(TEST_BIN) + rm -rf $(FSDIR)/$(BIN) From f3c7ac9696855bd8a28c4be4f9e99bc7a6d4825e Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 10:34:19 -0500 Subject: [PATCH 13/26] Replace bios with bootloader, don't use bootsector Instead of using the bootsector to load a bootloader, just put the bootloader in the ROM and call it a day. It looks for a file on the SD card in the root directory named `kernel.bin` and loads it into memory. This is not a perfect solution, as the kernel will grow larger and the kernel load address will have to change. At this point I could add back the bootloader, but that is for later. Also the bootloader is just a copy of the kernel, so that can be trimmed down a lot. --- sw/Makefile | 8 +- sw/bios/Makefile | 38 ---- sw/bios/boot.s | 14 -- sw/bios/devices/interrupt.s | 55 ------ sw/bios/devices/io.inc65 | 1 - sw/bios/devices/sd_card.c | 1 - sw/bios/devices/sd_card.h | 1 - sw/bios/devices/sd_card_asm.s | 1 - sw/bios/link.ld | 19 -- sw/bios/load_bootsect.c | 29 ---- sw/bootloader/Makefile | 15 ++ sw/bootloader/bios_calls | 0 sw/bootloader/bios_calls.h | 8 - sw/bootloader/bios_calls.s | 23 --- sw/bootloader/boot.s | 62 +++++-- sw/bootloader/devices/board_io.h | 16 ++ sw/bootloader/devices/board_io.s | 71 ++++++++ sw/bootloader/devices/conio.s | 60 +++++++ sw/bootloader/devices/interrupt.h | 15 ++ sw/bootloader/devices/interrupt.s | 58 +++++++ sw/bootloader/devices/io.inc65 | 18 ++ sw/bootloader/devices/mapper.h | 12 ++ sw/bootloader/devices/mapper.s | 32 ++++ sw/bootloader/devices/sd_card.c | 75 ++++++++ sw/bootloader/devices/sd_card.h | 18 ++ sw/bootloader/devices/sd_card_asm.s | 66 +++++++ sw/bootloader/devices/uart.h | 13 ++ sw/bootloader/devices/uart.s | 36 ++++ sw/bootloader/exec.c | 61 +++++++ sw/bootloader/exec.h | 6 + sw/bootloader/filesystem/fat.c | 260 ++++++++++++++++++++++++++++ sw/bootloader/filesystem/fat.h | 124 +++++++++++++ sw/bootloader/filesystem/o65.c | 28 +++ sw/bootloader/filesystem/o65.h | 65 +++++++ sw/bootloader/io.inc65 | 1 - sw/bootloader/irq.c | 24 +++ sw/bootloader/link.ld | 34 +++- sw/bootloader/main.c | 68 +++++++- sw/bootloader/tests/test_main.c | 89 ++++++++++ sw/bootloader/uart.h | 1 - sw/bootloader/uart.s | 1 - sw/{bios => bootloader}/vectors.s | 0 42 files changed, 1295 insertions(+), 232 deletions(-) delete mode 100644 sw/bios/Makefile delete mode 100644 sw/bios/boot.s delete mode 100644 sw/bios/devices/interrupt.s delete mode 120000 sw/bios/devices/io.inc65 delete mode 120000 sw/bios/devices/sd_card.c delete mode 120000 sw/bios/devices/sd_card.h delete mode 120000 sw/bios/devices/sd_card_asm.s delete mode 100644 sw/bios/link.ld delete mode 100644 sw/bios/load_bootsect.c delete mode 100644 sw/bootloader/bios_calls delete mode 100644 sw/bootloader/bios_calls.h delete mode 100644 sw/bootloader/bios_calls.s create mode 100644 sw/bootloader/devices/board_io.h create mode 100644 sw/bootloader/devices/board_io.s create mode 100644 sw/bootloader/devices/conio.s create mode 100644 sw/bootloader/devices/interrupt.h create mode 100644 sw/bootloader/devices/interrupt.s create mode 100644 sw/bootloader/devices/io.inc65 create mode 100644 sw/bootloader/devices/mapper.h create mode 100644 sw/bootloader/devices/mapper.s create mode 100644 sw/bootloader/devices/sd_card.c create mode 100644 sw/bootloader/devices/sd_card.h create mode 100644 sw/bootloader/devices/sd_card_asm.s create mode 100644 sw/bootloader/devices/uart.h create mode 100644 sw/bootloader/devices/uart.s create mode 100644 sw/bootloader/exec.c create mode 100644 sw/bootloader/exec.h create mode 100644 sw/bootloader/filesystem/fat.c create mode 100644 sw/bootloader/filesystem/fat.h create mode 100644 sw/bootloader/filesystem/o65.c create mode 100644 sw/bootloader/filesystem/o65.h delete mode 120000 sw/bootloader/io.inc65 create mode 100644 sw/bootloader/irq.c create mode 100644 sw/bootloader/tests/test_main.c delete mode 120000 sw/bootloader/uart.h delete mode 120000 sw/bootloader/uart.s rename sw/{bios => bootloader}/vectors.s (100%) diff --git a/sw/Makefile b/sw/Makefile index d362cdb..ee3f485 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -1,14 +1,11 @@ -.PHONY: all install bios bootloader kernel clean +.PHONY: all install bootloader kernel clean -all: bios bootloader kernel +all: bootloader kernel install: all sh script/format_disk.sh sh script/copy_files.sh -bios: - @$(MAKE) -C bios - bootloader: @$(MAKE) -C bootloader @@ -17,6 +14,5 @@ kernel: clean: - @$(MAKE) -C bios --no-print-directory $@ @$(MAKE) -C bootloader --no-print-directory $@ @$(MAKE) -C kernel --no-print-directory $@ \ No newline at end of file diff --git a/sw/bios/Makefile b/sw/bios/Makefile deleted file mode 100644 index caa77c0..0000000 --- a/sw/bios/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -CC=cl65 -CFLAGS=-T -t none -I. --cpu "65C02" -test: CFLAGS=-T -t sim65c02 -I. -LDFLAGS=-C link.ld -m $(NAME).map -NAME=bios - -BIN=$(NAME).bin -HEX=$(NAME).hex - -LISTS=lists - -SRCS=$(wildcard *.s) $(wildcard *.c) -SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c)) -OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) -OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) - -all: $(HEX) - -$(HEX): $(BIN) - objcopy --input-target=binary --output-target=ihex $(BIN) $(HEX) - - -$(BIN): $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ - -%.o: %.c $(LISTS) - $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ - -%.o: %.s $(LISTS) - $(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@ - -$(LISTS): - mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) - -.PHONY: clean -clean: - rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map - diff --git a/sw/bios/boot.s b/sw/bios/boot.s deleted file mode 100644 index 4a26770..0000000 --- a/sw/bios/boot.s +++ /dev/null @@ -1,14 +0,0 @@ -.include "zeropage.inc" - -.segment "STARTUP" - -.export _init -.import _load_bootsect - -_init: ldx #$ff - txs - cld - - jsr _load_bootsect - jmp $1000 - \ No newline at end of file diff --git a/sw/bios/devices/interrupt.s b/sw/bios/devices/interrupt.s deleted file mode 100644 index f555c1c..0000000 --- a/sw/bios/devices/interrupt.s +++ /dev/null @@ -1,55 +0,0 @@ -.include "io.inc65" - -.export _irq_int, _nmi_int - -.importzp sreg, ptr1 - -.segment "CODE" - -; IRQ -_irq_int: - jmp (irqmap,x) - -_nmi_int: - rti - -irqmap: - .addr handle_invalid - .addr handle_sd_read - -handle_invalid: - rti - -; sreg is the pointer to store the data -; a/y is the block address -; send command 17 with the block address of 00/y/a -handle_sd_read: - sta SD_ARG ; send command - sty SD_ARG+1 - stz SD_ARG+2 - stz SD_ARG+3 - lda #$11 - sta SD_CMD - -@1: lda SD_CMD ; wait for status flag - and #$01 - beq @1 - -@2: lda SD_CMD ; wait for data - and #$02 - beq @2 - - ldy #$00 -@loop: lda SD_DATA ; copy first 256 bytes - sta (sreg),y - iny - bne @loop - - ldy #$00 ; copy second 256 bytes - inc sreg+1 -@loop2: lda SD_DATA - sta (sreg),y - iny - bne @loop2 - - rti \ No newline at end of file diff --git a/sw/bios/devices/io.inc65 b/sw/bios/devices/io.inc65 deleted file mode 120000 index 14ef1f5..0000000 --- a/sw/bios/devices/io.inc65 +++ /dev/null @@ -1 +0,0 @@ -../../kernel/devices/io.inc65 \ No newline at end of file diff --git a/sw/bios/devices/sd_card.c b/sw/bios/devices/sd_card.c deleted file mode 120000 index c20d8c7..0000000 --- a/sw/bios/devices/sd_card.c +++ /dev/null @@ -1 +0,0 @@ -../../kernel/devices/sd_card.c \ No newline at end of file diff --git a/sw/bios/devices/sd_card.h b/sw/bios/devices/sd_card.h deleted file mode 120000 index 7955199..0000000 --- a/sw/bios/devices/sd_card.h +++ /dev/null @@ -1 +0,0 @@ -../../kernel/devices/sd_card.h \ No newline at end of file diff --git a/sw/bios/devices/sd_card_asm.s b/sw/bios/devices/sd_card_asm.s deleted file mode 120000 index a25313c..0000000 --- a/sw/bios/devices/sd_card_asm.s +++ /dev/null @@ -1 +0,0 @@ -../../kernel/devices/sd_card_asm.s \ No newline at end of file diff --git a/sw/bios/link.ld b/sw/bios/link.ld deleted file mode 100644 index 0fe59b7..0000000 --- a/sw/bios/link.ld +++ /dev/null @@ -1,19 +0,0 @@ -MEMORY -{ - ZP: start = $0, size = $100, type = rw, define = yes; - SDRAM: start = $1000, size = $6ef0, type = rw, define = yes; - ROM: start = $8000, size = $8000, fill = yes, fillval = $ff, file = %O; -} - -SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - DATA: load = ROM, type = rw, define = yes, run = SDRAM; - BSS: load = SDRAM, type = bss, define = yes; - HEAP: load = SDRAM, type = bss, optional = yes; - STARTUP: load = ROM, type = ro; - ONCE: load = ROM, type = ro, optional = yes; - CODE: load = ROM, type = ro; - RODATA: load = ROM, type = ro; - VECTORS: load = ROM, type = ro, start = $FFFA; -} - diff --git a/sw/bios/load_bootsect.c b/sw/bios/load_bootsect.c deleted file mode 100644 index 6fe0ba2..0000000 --- a/sw/bios/load_bootsect.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#include "devices/sd_card.h" - -#define BOOTSECTOR_LOAD_ADDRESS 0x1000 - -#define BOOTSIG_0 0x55 -#define BOOTSIG_1 0xaa - -//Should probably do this in asm -void load_bootsect() { - uint32_t rca; - uint8_t sig[2]; - - sd_init(); - rca = sd_get_rca(); - sd_select_card(rca); - - sd_readblock(0, (uint8_t*)BOOTSECTOR_LOAD_ADDRESS); - - sig[0] = ((uint8_t*)BOOTSECTOR_LOAD_ADDRESS)[510]; - sig[1] = ((uint8_t*)BOOTSECTOR_LOAD_ADDRESS)[511]; - - if (sig[0] != BOOTSIG_0 || sig[1] != BOOTSIG_1) { - for(;;); //maybe figure out a way to have an error message here - } - - return; -} \ No newline at end of file diff --git a/sw/bootloader/Makefile b/sw/bootloader/Makefile index 3e4a963..bd08961 100644 --- a/sw/bootloader/Makefile +++ b/sw/bootloader/Makefile @@ -7,18 +7,31 @@ SIMARGS=-v -c -x 1000000 NAME=bootloader +TEST_BIN=test.bin BIN=$(NAME).bin HEX=$(NAME).hex LISTS=lists +TESTS=tests SRCS=$(wildcard *.s) $(wildcard *.c) SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c)) OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) +TEST_SRCS=$(wildcard $(TESTS)/*.s) $(wildcard $(TESTS)/*.c) +TEST_OBJS+=$(patsubst %.s,%.o,$(filter %s,$(TEST_SRCS))) +TEST_OBJS+=$(patsubst %.c,%.o,$(filter %c,$(TEST_SRCS))) +TEST_OBJS+=$(filter-out boot.o,$(filter-out main.o,$(filter-out vectors.o,$(OBJS)))) + all: $(HEX) +test: $(TEST_BIN) + $(SIM) $(SIMARGS) $(TEST_BIN) + +$(TEST_BIN): $(OBJS) $(TEST_OBJS) + $(CC) $(CFLAGS) $(TEST_OBJS) -o $@ + $(HEX): $(BIN) objcopy --input-target=binary --output-target=ihex $(BIN) $(HEX) @@ -34,8 +47,10 @@ $(BIN): $(OBJS) $(LISTS): mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) + mkdir $(LISTS)/$(sort $(dir $(TEST_SRCS))) .PHONY: clean clean: rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map + rm -rf $(TEST_OBJS) $(TEST_BIN) diff --git a/sw/bootloader/bios_calls b/sw/bootloader/bios_calls deleted file mode 100644 index e69de29..0000000 diff --git a/sw/bootloader/bios_calls.h b/sw/bootloader/bios_calls.h deleted file mode 100644 index 88ed750..0000000 --- a/sw/bootloader/bios_calls.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _BIOS_CALLS_H -#define _BIOS_CALLS_H - -#include - -void sd_readblock(uint16_t addr, void* buf); - -#endif \ No newline at end of file diff --git a/sw/bootloader/bios_calls.s b/sw/bootloader/bios_calls.s deleted file mode 100644 index a1964a3..0000000 --- a/sw/bootloader/bios_calls.s +++ /dev/null @@ -1,23 +0,0 @@ -.export _sd_readblock - -.autoimport - -.importzp sreg - -; sreg is the pointer to store the data -; a/y is the block address -; send command 17 with the block address of 00/y/a - -; void sd_readblock(uint16_t addr, void* buf); - -_sd_readblock: - sta sreg ; move buf pointer to sreg - stx sreg+1 - - jsr popax ; move addr to a/y - tya - - ldx #$1 ; call interrupt 1 - brk - - rts \ No newline at end of file diff --git a/sw/bootloader/boot.s b/sw/bootloader/boot.s index 47eaf07..00b87b1 100644 --- a/sw/bootloader/boot.s +++ b/sw/bootloader/boot.s @@ -1,26 +1,54 @@ -; We need to to read the boot sector from the -; SD card, verify the last 2 bytes, then jump to the -; beginning of it. +; --------------------------------------------------------------------------- +; crt0.s +; --------------------------------------------------------------------------- +; +; Startup code for cc65 (Single Board Computer version) -.include "zeropage.inc" +.export _init, _exit +.import _main -.import _load_bootsect +.export __STARTUP__ : absolute = 1 ; Mark as startup +.import __SDRAM_START__, __SDRAM_SIZE__ ; Linker generated -.export _init, _boot +.import copydata, zerobss, initlib, donelib -.segment "STARTUP" +.include "zeropage.inc" -_init: jmp _boot +; --------------------------------------------------------------------------- +; Place the startup code in a special segment -.segment "CODE" +.segment "STARTUP" -_boot: ldx #$ff - txs - cld +; --------------------------------------------------------------------------- +; A little light 6502 housekeeping - jsr _load_bootsect - jmp $1000 +_init: LDX #$FF ; Initialize stack pointer to $01FF + TXS + CLD ; Clear decimal mode -.segment "SIGN" -.byte $55 -.byte $aa +; --------------------------------------------------------------------------- +; Set cc65 argument stack pointer + + LDA #<(__SDRAM_START__ + __SDRAM_SIZE__) + STA sp + LDA #>(__SDRAM_START__ + __SDRAM_SIZE__) + STA sp+1 + +; --------------------------------------------------------------------------- +; Initialize memory storage + + JSR zerobss ; Clear BSS segment + JSR copydata ; Initialize DATA segment + JSR initlib ; Run constructors + +; --------------------------------------------------------------------------- +; Call main() + cli + JSR _main + jmp ($fffc) + +; --------------------------------------------------------------------------- +; Back from main (this is also the _exit entry): force a software break + +_exit: JSR donelib ; Run destructors + BRK diff --git a/sw/bootloader/devices/board_io.h b/sw/bootloader/devices/board_io.h new file mode 100644 index 0000000..c55c7a5 --- /dev/null +++ b/sw/bootloader/devices/board_io.h @@ -0,0 +1,16 @@ +#ifndef _BOARD_IO_H +#define _BOARD_IO_H + +#include + +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 \ No newline at end of file diff --git a/sw/bootloader/devices/board_io.s b/sw/bootloader/devices/board_io.s new file mode 100644 index 0000000..95656fe --- /dev/null +++ b/sw/bootloader/devices/board_io.s @@ -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 \ No newline at end of file diff --git a/sw/bootloader/devices/conio.s b/sw/bootloader/devices/conio.s new file mode 100644 index 0000000..30b4d6a --- /dev/null +++ b/sw/bootloader/devices/conio.s @@ -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 \ No newline at end of file diff --git a/sw/bootloader/devices/interrupt.h b/sw/bootloader/devices/interrupt.h new file mode 100644 index 0000000..d0231aa --- /dev/null +++ b/sw/bootloader/devices/interrupt.h @@ -0,0 +1,15 @@ +#ifndef _INTERRUPT_H +#define _INTERRUPT_H + +#include + +#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 \ No newline at end of file diff --git a/sw/bootloader/devices/interrupt.s b/sw/bootloader/devices/interrupt.s new file mode 100644 index 0000000..f87f81d --- /dev/null +++ b/sw/bootloader/devices/interrupt.s @@ -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 \ No newline at end of file diff --git a/sw/bootloader/devices/io.inc65 b/sw/bootloader/devices/io.inc65 new file mode 100644 index 0000000..bad732c --- /dev/null +++ b/sw/bootloader/devices/io.inc65 @@ -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 diff --git a/sw/bootloader/devices/mapper.h b/sw/bootloader/devices/mapper.h new file mode 100644 index 0000000..8276b60 --- /dev/null +++ b/sw/bootloader/devices/mapper.h @@ -0,0 +1,12 @@ +#ifndef _MAPPER_H +#define _MAPPER_H + +#include + +void mapper_enable(uint8_t en); + +uint8_t mapper_read(uint8_t addr); +void mapper_write(uint8_t data, uint8_t addr); + +#endif + diff --git a/sw/bootloader/devices/mapper.s b/sw/bootloader/devices/mapper.s new file mode 100644 index 0000000..2ed1bc0 --- /dev/null +++ b/sw/bootloader/devices/mapper.s @@ -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 + diff --git a/sw/bootloader/devices/sd_card.c b/sw/bootloader/devices/sd_card.c new file mode 100644 index 0000000..752cd0e --- /dev/null +++ b/sw/bootloader/devices/sd_card.c @@ -0,0 +1,75 @@ +#include +#include + +#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"); +} diff --git a/sw/bootloader/devices/sd_card.h b/sw/bootloader/devices/sd_card.h new file mode 100644 index 0000000..7e3cb00 --- /dev/null +++ b/sw/bootloader/devices/sd_card.h @@ -0,0 +1,18 @@ +#ifndef _SD_CARD_H +#define _SD_CARD_H + +#include + +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 diff --git a/sw/bootloader/devices/sd_card_asm.s b/sw/bootloader/devices/sd_card_asm.s new file mode 100644 index 0000000..fe4f4e2 --- /dev/null +++ b/sw/bootloader/devices/sd_card_asm.s @@ -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 \ No newline at end of file diff --git a/sw/bootloader/devices/uart.h b/sw/bootloader/devices/uart.h new file mode 100644 index 0000000..e8f06db --- /dev/null +++ b/sw/bootloader/devices/uart.h @@ -0,0 +1,13 @@ +#ifndef _UART_H +#define _UART_H + +#include + +void uart_txb(uint8_t val); +void uart_txb_block(uint8_t val); + +uint8_t uart_rxb(); + +uint8_t uart_status(); + +#endif \ No newline at end of file diff --git a/sw/bootloader/devices/uart.s b/sw/bootloader/devices/uart.s new file mode 100644 index 0000000..c852f7e --- /dev/null +++ b/sw/bootloader/devices/uart.s @@ -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 diff --git a/sw/bootloader/exec.c b/sw/bootloader/exec.c new file mode 100644 index 0000000..0824eb6 --- /dev/null +++ b/sw/bootloader/exec.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#include "filesystem/fat.h" +#include "filesystem/o65.h" + +void exec(char* filename) { + o65_header_t* header; + o65_opt_t* o65_opt; + uint8_t* seg_ptr; + + uint8_t* code_base; + uint8_t* data_base; + uint16_t code_len; + uint16_t data_len; + + uint8_t (*exec)(void); + uint8_t ret; + + fat_read(filename, fat_buf); + + header = (o65_header_t*)fat_buf; + + if (header->c64_marker == O65_NON_C64 && + header->magic[0] == O65_MAGIC_0 && + header->magic[1] == O65_MAGIC_1 && + header->magic[2] == O65_MAGIC_2) { + + code_base = (uint8_t*)header->tbase; + data_base = (uint8_t*)header->dbase; + code_len = header->tlen; + data_len = header->dlen; + + + o65_opt = (o65_opt_t*)(fat_buf + sizeof(o65_header_t)); + while (o65_opt->olen) + { + o65_print_option(o65_opt); + o65_opt = (o65_opt_t*)((uint8_t*)o65_opt + o65_opt->olen); + } + + seg_ptr = (uint8_t*)o65_opt + 1; + + memcpy((uint8_t*)code_base, seg_ptr, code_len); + + seg_ptr+=code_len; + + memcpy((uint8_t*)data_base, seg_ptr, data_len); + + exec = (uint8_t (*)(void))code_base; + + ret = 0; + + ret = (*exec)(); + + cprintf("ret: %x\n", ret); + + + } +} diff --git a/sw/bootloader/exec.h b/sw/bootloader/exec.h new file mode 100644 index 0000000..9ed3941 --- /dev/null +++ b/sw/bootloader/exec.h @@ -0,0 +1,6 @@ +#ifndef _EXEC_H +#define _EXEC_H + +void exec(char* filename); + +#endif diff --git a/sw/bootloader/filesystem/fat.c b/sw/bootloader/filesystem/fat.c new file mode 100644 index 0000000..bd353d1 --- /dev/null +++ b/sw/bootloader/filesystem/fat.c @@ -0,0 +1,260 @@ +#include +#include +#include + +#include "fat.h" +#include "devices/sd_card.h" + +uint8_t fat_buf[512]; + +static uint32_t fat_end_of_chain; + +static full_bpb_t bpb; + +static uint32_t data_region_start; + +void fat_print_pbp_info(full_bpb_t* bpb){ + cprintf("Bytes per sector: %d\n", bpb->bytes_per_sector); + cprintf("Sectors per cluster: %d\n", bpb->sectors_per_cluster); + cprintf("Reserved Sectors: %d\n", bpb->reserved_sectors); + cprintf("Fat Count: %d\n", bpb->fat_count); + cprintf("Max Dir Entries: %d\n", bpb->max_dir_entries); + cprintf("Total Sector Count: %d\n", bpb->total_sector_count); + cprintf("Media Descriptor: 0x%x\n", bpb->media_descriptor); + cprintf("Sectors per Fat: %d\n", bpb->sectors_per_fat_16); + cprintf("\n"); + + cprintf("Sectors per track: %d\n", bpb->sectors_per_track); + cprintf("Head Count: %d\n", bpb->head_count); + cprintf("Hidden Sector Count: %ld\n", bpb->hidden_sector_count); + cprintf("Logical Sector Count: %ld\n", bpb->logical_sector_count); + cprintf("Sectors per Fat: %ld\n", bpb->sectors_per_fat_32); + cprintf("Extended Flags: 0x%x\n", bpb->extended_flags); + cprintf("Version: %d\n", bpb->version); + cprintf("Root Cluster: 0x%lx\n", bpb->root_cluster); + cprintf("System Information: 0x%x\n", bpb->system_information); + cprintf("Backup Boot Sector: 0x%x\n", bpb->backup_boot_sector); + cprintf("\n"); + + cprintf("Drive Number: %d\n", bpb->drive_num); + cprintf("Extended Signature: 0x%x\n", bpb->extended_signature); + cprintf("Volume ID: 0x%lx\n", bpb->volume_id); + cprintf("Partition Label: %.11s\n", &bpb->partition_label); + cprintf("Partition Label: %.8s\n", &bpb->filesystem_type); + cprintf("\n"); +} + +void fat_init(){ + int i; + + sd_readblock(0, fat_buf); + + memcpy(&bpb, &fat_buf[11], sizeof(full_bpb_t)); + + sd_readblock(1, fat_buf); + sd_readblock(32, fat_buf); + + fat_print_pbp_info(&bpb); + + data_region_start = bpb.reserved_sectors + bpb.fat_count*bpb.sectors_per_fat_32; + + sd_readblock(bpb.reserved_sectors, fat_buf); + + //uncomment to view start of FAT + + /* + for (i = 0; i < FAT_CLUSTERS_PER_SECTOR; i++) { + cprintf("%lx ", ((uint32_t*)fat_buf)[i]); + } + cprintf("\n\n"); + */ + + fat_end_of_chain = ((uint32_t*)fat_buf)[1] & FAT_EOC_CLUSTERMASK; + cprintf("End of chain indicator: %lx\n", fat_end_of_chain); +} + +void fat_read(char* filename, void* buf) { + vfat_dentry_t* vfat_dentry; + dos_dentry_t* dos_dentry; + uint32_t cluster; + + (void)filename; //just ignore filename + + sd_readblock(data_region_start, buf); + + vfat_dentry = (vfat_dentry_t*)buf; + while(vfat_dentry->sequence_number == 0xe5) + vfat_dentry++; + + dos_dentry = (dos_dentry_t*)(vfat_dentry + 1); + + cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; + + sd_readblock(data_region_start + (cluster - 2) * 8, buf); +} + +// make sure you have enough space. +void fat_read_cluster(uint16_t cluster, uint8_t* buf) { + uint8_t i; + + for (i = 0; i < bpb.sectors_per_cluster; i++) { + sd_readblock(data_region_start + i + (cluster - 2) * 8, buf+i*bpb.bytes_per_sector); + } +} + +uint32_t fat_get_chain_value(uint16_t cluster) { + sd_readblock(bpb.reserved_sectors, fat_buf); + return ((uint32_t*)fat_buf)[cluster]; +} + +//the dentry is a double pointer because we need to increment it. +void fat_parse_vfat_filenamename(vfat_dentry_t** vfat_dentry, char* name, uint32_t cluster) { + uint8_t i; + uint8_t overflows; + uint8_t done; + char* shift_name; + uint8_t sequence_number = (*vfat_dentry)->sequence_number; + overflows = 0; + + for (;;){ + shift_name = name + 13*((sequence_number & FAT_LFN_ENTRY_MASK) - 1); + + done = 0; + for(i = 0; i < 5; i++) { + shift_name[i] = (*vfat_dentry)->filename0[i]; + if (!shift_name[i]) { + done = 1; + break; + } + } + + if (!done) { + for(i = 0; i < 6; i++) { + shift_name[i+5] = (*vfat_dentry)->filename1[i]; + if (!shift_name[i+5]) { + done = 1; + break; + } + } + } + + if (!done) { + for(i = 0; i < 2; i++) { + shift_name[i+11] = (*vfat_dentry)->filename2[i]; + if (!shift_name[i+11]) { + done = 1; + break; + } + } + } + + if ((sequence_number & FAT_LFN_ENTRY_MASK) == 1) { + break; + } else { + do { + (*vfat_dentry)++; + if ((uint8_t*)*vfat_dentry >= fat_buf + sizeof(fat_buf)) { + overflows++; + if (overflows == bpb.sectors_per_cluster) { + cprintf("Too many overflows, go back to fat!\n"); //TODO this + return; + } + sd_readblock(data_region_start + (cluster - 2) * 8 + overflows, fat_buf); + *vfat_dentry = (vfat_dentry_t*)fat_buf; + } + } while((*vfat_dentry)->sequence_number == 0xe5); + sequence_number = (*vfat_dentry)->sequence_number; + } + } + +} + +uint32_t fat_find_cluster_num(char* name, uint32_t cluster) { + vfat_dentry_t* vfat_dentry; + dos_dentry_t* dos_dentry; + char* vfat_name; + + cprintf("Looking for file %s\n", name); + + sd_readblock(data_region_start + (cluster - 2) * 8, fat_buf); + vfat_dentry = (vfat_dentry_t*)fat_buf; + + vfat_name = (char*)malloc(FAT_MAX_FILE_NAME); + + while(vfat_dentry->sequence_number == 0xe5) + vfat_dentry++; + + vfat_name[0] = '\0'; + + while(vfat_dentry->sequence_number) { + fat_parse_vfat_filenamename(&vfat_dentry, vfat_name, cluster); + cprintf("Parsed filename: %s\n", vfat_name); + + if (!strcmp(vfat_name, name)) { //TODO this is probably unsafe, use strncmp + cprintf("Found file %s\n", vfat_name); + break; + } else { + vfat_dentry += 2; + while(vfat_dentry->sequence_number == 0xe5) + vfat_dentry++; + } + } + + free(vfat_name); + + if (!vfat_dentry->sequence_number) { + cprintf("File not found.\n"); + return -1; + } + + dos_dentry = (dos_dentry_t*) vfat_dentry + 1; //dos entry follows last vfat entry + + cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; + cprintf("Cluster: %ld\n", cluster); + + return cluster; +} + +uint16_t fat_parse_path_to_cluster(char* filename) { + //basically start at the root folder and search through it + int i; + int len; + uint8_t dirs = 0; + + char* spaced_filename; + char* fragment; + + uint32_t cluster = 2; //root chain is chain 2 + + if (filename[0] != '/') { + cprintf("Filename does not begin with '/'\n"); + return 0; + } + + filename++; + len = strlen(filename); + spaced_filename = (char*)malloc(len+1); //need to account for null byte + + for (i = 0; i <= len; i++) { + if (filename[i] == '/') { + spaced_filename[i] = '\0'; + dirs++; + } else { + spaced_filename[i] = filename[i]; + } + } + + fragment = spaced_filename; + + cprintf("Dirs: %d\n", dirs); + + for (i = 0; i <= dirs; i++) { + cprintf("Fragment: %s\n", fragment); + cluster = fat_find_cluster_num(fragment, cluster); + fragment = spaced_filename + strlen(fragment) + 1; + } + + free(spaced_filename); + + return cluster; +} diff --git a/sw/bootloader/filesystem/fat.h b/sw/bootloader/filesystem/fat.h new file mode 100644 index 0000000..732e179 --- /dev/null +++ b/sw/bootloader/filesystem/fat.h @@ -0,0 +1,124 @@ +#ifndef _FAT_H +#define _FAT_H + +#include + +extern uint8_t fat_buf[]; + +#define FAT_MAX_FILE_NAME 255 +#define FAT_CLUSTERS_PER_SECTOR 128 + +#define FAT_CLUSTERMASK 0x0fffffff +#define FAT_EOC_CLUSTERMASK 0x0ffffff8 + +#define FAT_LAST_LFN_MASK (1 << 6) +#define FAT_LFN_ENTRY_MASK 0x1f + +typedef struct { + uint16_t bytes_per_sector; + uint8_t sectors_per_cluster; + uint16_t reserved_sectors; + uint8_t fat_count; + uint16_t max_dir_entries; + uint16_t total_sector_count; + uint8_t media_descriptor; + uint16_t sectors_per_fat; +} dos_2_bpb_t; + +typedef struct { + dos_2_bpb_t bpb2; + uint16_t sectors_per_track; + uint16_t head_count; + uint32_t hidden_sector_count; + uint32_t logical_sector_count; + uint32_t sectors_per_fat; + uint16_t extended_flags; + uint16_t version; + uint32_t root_cluster; + uint16_t system_information; + uint16_t backup_boot_sector; + uint8_t reserved[12]; +} dos_3_bpb_t; + +typedef struct { + dos_3_bpb_t bpb3; + uint8_t drive_num; + uint8_t reserved; + uint8_t extended_signature; + uint32_t volume_id; + uint8_t partition_label[11]; + uint8_t filesystem_type[8]; +} ebpb_t; + +typedef struct { + uint16_t bytes_per_sector; + uint8_t sectors_per_cluster; + uint16_t reserved_sectors; + uint8_t fat_count; + uint16_t max_dir_entries; + uint16_t total_sector_count; + uint8_t media_descriptor; + uint16_t sectors_per_fat_16; + uint16_t sectors_per_track; + uint16_t head_count; + uint32_t hidden_sector_count; + uint32_t logical_sector_count; + uint32_t sectors_per_fat_32; + uint16_t extended_flags; + uint16_t version; + uint32_t root_cluster; + uint16_t system_information; + uint16_t backup_boot_sector; + uint8_t reserved[12]; + uint8_t drive_num; + uint8_t reserved2; + uint8_t extended_signature; + uint32_t volume_id; + uint8_t partition_label[11]; + uint8_t filesystem_type[8]; +} full_bpb_t; + +typedef struct { + uint32_t sig; + uint8_t reserved[480]; + uint32_t sig2; + uint32_t free_data_clusters; + uint32_t last_allocated_data_cluster; + uint32_t reserved2; + uint32_t sig3; +} fs_info_sector_t; + +typedef struct { + uint8_t sequence_number; + uint16_t filename0[5]; + uint8_t attributes; + uint8_t type; + uint8_t checksum; + uint16_t filename1[6]; + uint16_t reserved; + uint16_t filename2[2]; +} vfat_dentry_t; + +typedef struct { + uint8_t filename[8]; + uint8_t extension[3]; + uint8_t attributes; + uint8_t reserved; + uint8_t create_time_10ms; + uint32_t create_date; + uint16_t access_date; + uint16_t first_cluster_h; + uint32_t modify_cluster; + uint16_t first_cluster_l; + uint32_t file_size; +} dos_dentry_t; + +void fat_print_pbp_info(full_bpb_t* bpb); +void fat_init(); +void fat_read(char* filename, void* buf); + +uint16_t fat_parse_path_to_cluster(char* filename); +void fat_read_cluster(uint16_t cluster, uint8_t* buf); +uint32_t fat_get_chain_value(uint16_t cluster); + +#endif diff --git a/sw/bootloader/filesystem/o65.c b/sw/bootloader/filesystem/o65.c new file mode 100644 index 0000000..9e76dc0 --- /dev/null +++ b/sw/bootloader/filesystem/o65.c @@ -0,0 +1,28 @@ +#include + +#include "o65.h" + +void o65_print_option(o65_opt_t* opt) { + int i; + + cprintf("Option Length: %d\n", opt->olen); + cprintf("Option Type: %x ", opt->type); + + switch (opt->type) { + case O65_OPT_FILENAME: cprintf("Filename\n"); break; + case O65_OPT_OS: cprintf("OS\n"); break; + case O65_OPT_ASSEMBLER: cprintf("Assembler\n"); break; + case O65_OPT_AUTHOR: cprintf("Author\n"); break; + case O65_OPT_DATE: cprintf("Creation Date\n"); break; + default: cprintf("Invalid\n"); break; + } + + if (opt->type != O65_OPT_OS) { + for (i = 0; i < opt->olen - 2; i++) { + cprintf("%c", opt->data[i]); + } + } else { + cprintf("%x", opt->data[0]); + } + cprintf("\n\n"); +} diff --git a/sw/bootloader/filesystem/o65.h b/sw/bootloader/filesystem/o65.h new file mode 100644 index 0000000..719305c --- /dev/null +++ b/sw/bootloader/filesystem/o65.h @@ -0,0 +1,65 @@ +#ifndef _O65_H +#define _O65_H + +#include + +#define O65_NON_C64 0x0001 +#define O65_MAGIC_0 0x6f +#define O65_MAGIC_1 0x36 +#define O65_MAGIC_2 0x35 + +#define O65_OPT_FILENAME 0 +#define O65_OPT_OS 1 +#define O65_OPT_ASSEMBLER 2 +#define O65_OPT_AUTHOR 3 +#define O65_OPT_DATE 4 + +#define O65_OS_OSA65 1 +#define O65_OS_LUNIX 2 +#define O65_OS_CC65 3 +#define O65_OS_OPENCBM 4 +#define O65_OS_SUPER6502 5 + +typedef union { + struct { + int cpu : 1; + int reloc : 1; + int size : 1; + int obj : 1; + int simple : 1; + int chain : 1; + int bsszero : 1; + int cpu2 : 4; + int align : 2; + }; + uint16_t _mode; +} o65_mode_t; + +typedef struct { + uint16_t c64_marker; + uint8_t magic[3]; + uint8_t version; + + o65_mode_t mode; + + uint16_t tbase; + uint16_t tlen; + uint16_t dbase; + uint16_t dlen; + uint16_t bbase; + uint16_t blen; + uint16_t zbase; + uint16_t zlen; + uint16_t stack; + +} o65_header_t; + +typedef struct { + uint8_t olen; + uint8_t type; + uint8_t data[1]; //This is actually variable length +} o65_opt_t; + +void o65_print_option(o65_opt_t* opt); + +#endif diff --git a/sw/bootloader/io.inc65 b/sw/bootloader/io.inc65 deleted file mode 120000 index 52851e4..0000000 --- a/sw/bootloader/io.inc65 +++ /dev/null @@ -1 +0,0 @@ -../kernel/devices/io.inc65 \ No newline at end of file diff --git a/sw/bootloader/irq.c b/sw/bootloader/irq.c new file mode 100644 index 0000000..4d2c0d8 --- /dev/null +++ b/sw/bootloader/irq.c @@ -0,0 +1,24 @@ + +#include +#include + +#include "devices/interrupt.h" +#include "devices/uart.h" + +char lastchar; + + +void handle_irq() { + uint8_t status; + + status = irq_get_status(); + + if (status & BUTTON) { + cputs("Button Interrupt!\n"); + irq_set_status(status & ~BUTTON); + } + if (status & UART) { + lastchar = uart_rxb(); + irq_set_status(status & ~UART); + } +} \ No newline at end of file diff --git a/sw/bootloader/link.ld b/sw/bootloader/link.ld index 6860602..46ee428 100644 --- a/sw/bootloader/link.ld +++ b/sw/bootloader/link.ld @@ -1,17 +1,35 @@ MEMORY { ZP: start = $0, size = $100, type = rw, define = yes; - BOOTSECT: start = $1000, size = $200, file = %O; + SDRAM: start = $200, size = $7cf0, type = rw, define = yes; + ROM: start = $8000, size = $8000, file = %O; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; - DATA: load = BOOTSECT, type = rw, define = yes; - BSS: load = BOOTSECT, type = bss, define = yes; - HEAP: load = BOOTSECT, type = bss, optional = yes; - STARTUP: load = BOOTSECT, type = ro, start = $1000; - CODE: load = BOOTSECT, type = ro, start = $105a; - RODATA: load = BOOTSECT, type = ro; - SIGN: load = BOOTSECT, type = ro, start = $11fe; + DATA: load = ROM, type = rw, define = yes, run = SDRAM; + BSS: load = SDRAM, type = bss, define = yes; + HEAP: load = SDRAM, type = bss, optional = yes; + STARTUP: load = ROM, type = ro; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro; + RODATA: load = ROM, type = ro; + VECTORS: load = ROM, type = ro, start = $FFFA; } +FEATURES { + CONDES: segment = STARTUP, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = STARTUP, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; +} + +SYMBOLS { + # Define the stack size for the application + __STACKSIZE__: value = $0200, type = weak; + __STACKSTART__: type = weak, value = $0800; # 2k stack +} diff --git a/sw/bootloader/main.c b/sw/bootloader/main.c index e69fb86..66d399f 100644 --- a/sw/bootloader/main.c +++ b/sw/bootloader/main.c @@ -1,11 +1,63 @@ #include +#include +#include +#include -#include "bios_calls.h" -#include "uart.h" +#include "devices/board_io.h" +#include "devices/uart.h" +#include "devices/mapper.h" +#include "devices/sd_card.h" +#include "filesystem/fat.h" +#include "exec.h" -//Should probably do this in asm -void load_bootsect() { - uart_txb_block('A'); - for (;;); - return; -} \ No newline at end of file +#define KERNEL_LOAD_ADDR 0xD000 + +uint8_t buf[512]; + +int main() { + int i; + uint16_t rca; + char* filename; + uint32_t cluster; + uint8_t* kernel_load; + + clrscr(); + cprintf("boot\n"); + + for (i = 0; i < 16; i++){ + //cprintf("Mapping %1xxxx to %2xxxx\n", i, i); + mapper_write(i, i); + } + + cprintf("Enabling Mapper\n"); + mapper_enable(1); + + mapper_write(0x10, 0xd); + mapper_write(0x11, 0xe); + mapper_write(0x12, 0xf); + + sd_init(); + + rca = sd_get_rca(); + cprintf("rca: %x\n", rca); + + sd_select_card(rca); + + fat_init(); + + filename = (char*)malloc(FAT_MAX_FILE_NAME); + + cluster = fat_parse_path_to_cluster("/kernel.bin"); + for (kernel_load = (uint8_t*)KERNEL_LOAD_ADDR; cluster < FAT_CLUSTERMASK; kernel_load+=(8*512)) { + cprintf("cluster: %lx\n", cluster); + cprintf("Writing to %p\n", kernel_load); + fat_read_cluster(cluster, kernel_load); + cluster = fat_get_chain_value(cluster); + } + + cprintf("Done!\n"); + + cprintf("Reset vector: %x\n", *((uint16_t*)0xfffc)); + + return 0; +} diff --git a/sw/bootloader/tests/test_main.c b/sw/bootloader/tests/test_main.c new file mode 100644 index 0000000..99e3dd8 --- /dev/null +++ b/sw/bootloader/tests/test_main.c @@ -0,0 +1,89 @@ +#include + +#include "devices/board_io.h" +#include "devices/uart.h" +#include "devices/interrupt.h" + +int main(void) +{ + int retval = 0; + + int i; + + printf("\nStarting tests...\n\n"); + + printf("Testing hex_set_8...\n"); + for (i = 0; i < 3; i++) { + if (hex_set_8(i+1, i)) { + printf("Failed to write to idx %d!\n", i); + retval++; + } + if (*(uint8_t*)0x7ff0+i != i+1) { + printf("Incorrect value at idx %d!\n", i); + retval++; + } + } + + if (!hex_set_8(0xab, 3)) { + printf("Writing to idx 3 should fail!\n"); + retval++; + } + printf("Done!\n\n"); + + printf("Testing hex_set_16...\n"); + if (hex_set_16(0xabcd)){ + printf("Failed to write!\n"); + } + if (*(uint16_t*)0x7ff0 != 0xabcd) { + printf("Incorrect value!\n", i); + retval++; + } + printf("Done!\n\n"); + + printf("Testing hex_set_24...\n"); + if (hex_set_24(0xabcdef)){ + printf("Failed to write!\n"); + } + if (*(uint16_t*)0x7ff0 != 0xcdef && *(uint8_t*)0x7ff2 != 0xab) { + printf("Incorrect value!\n", i); + retval++; + } + printf("Done!\n\n"); + + printf("Testing hex_enable...\n"); + hex_enable(0xa5); + if (*(uint8_t*)0x7ff3 != 0xa5) { + printf("Incorrect value!\n", i); + retval++; + } + printf("Done!\n\n"); + + printf("Testing uart_txb_block...\n"); + *(uint8_t*)0x7ff5 = 0; + uart_txb_block(0xa5); + if (*(uint8_t*)0x7ff4 != 0xa5) { + printf("Incorrect value!\n", i); + retval++; + } + printf("Done!\n\n"); + + printf("Testing uart_status...\n"); + *(uint8_t*)0x7ff5 = 0xa5; + if (uart_status() != 0xa5) { + printf("Incorrect value!\n", i); + retval++; + } + printf("Done!\n\n"); + + + printf("Testing irq_get_status...\n"); + *(uint8_t*)0x7fff = 0xa5; + if (irq_get_status() != 0xa5) { + printf("Incorrect value!\n", i); + retval++; + } + printf("Done!\n\n"); + + + return retval != 0; +} \ No newline at end of file diff --git a/sw/bootloader/uart.h b/sw/bootloader/uart.h deleted file mode 120000 index bdfeb82..0000000 --- a/sw/bootloader/uart.h +++ /dev/null @@ -1 +0,0 @@ -../kernel/devices/uart.h \ No newline at end of file diff --git a/sw/bootloader/uart.s b/sw/bootloader/uart.s deleted file mode 120000 index aa91b87..0000000 --- a/sw/bootloader/uart.s +++ /dev/null @@ -1 +0,0 @@ -../kernel/devices/uart.s \ No newline at end of file diff --git a/sw/bios/vectors.s b/sw/bootloader/vectors.s similarity index 100% rename from sw/bios/vectors.s rename to sw/bootloader/vectors.s From ff8078fac71c79aae5bed19c19cde14f12ac179b Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 13:46:57 -0500 Subject: [PATCH 14/26] Program ROM with bootloader Replaces the ROM image with the bootloader instead of bootrom, which no longer exists. --- hw/fpga/rom.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/fpga/rom.v b/hw/fpga/rom.v index 24d9df9..80a7515 100644 --- a/hw/fpga/rom.v +++ b/hw/fpga/rom.v @@ -84,9 +84,9 @@ module rom ( altsyncram_component.clock_enable_input_a = "BYPASS", altsyncram_component.clock_enable_output_a = "BYPASS", `ifdef NO_PLI - altsyncram_component.init_file = "../../sw/bootrom.rif" + altsyncram_component.init_file = "../../sw/bootloader/bootloader.rif" `else - altsyncram_component.init_file = "../../sw/bootrom.hex" + altsyncram_component.init_file = "../../sw/bootloader/bootloader.hex" `endif , altsyncram_component.intended_device_family = "MAX 10", @@ -123,7 +123,7 @@ endmodule // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "1" // Retrieval info: PRIVATE: JTAG_ID STRING "ROM0" // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" -// Retrieval info: PRIVATE: MIFfilename STRING "../../sw/bootrom.hex" +// Retrieval info: PRIVATE: MIFfilename STRING "../../sw/bootloader/bootloader.hex" // Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "32768" // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" // Retrieval info: PRIVATE: RegAddr NUMERIC "1" @@ -138,7 +138,7 @@ endmodule // Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" -// Retrieval info: CONSTANT: INIT_FILE STRING "../../sw/bootrom.hex" +// Retrieval info: CONSTANT: INIT_FILE STRING "../../sw/bootloader/bootloader.hex" // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10" // Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=ROM0" // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" From a836643807bc0ada1b49dab56054881733b6978e Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 14:47:19 -0500 Subject: [PATCH 15/26] Disable in system memory editor for ROM Now that the ROM is just a bootloader and the kernel is stored on the SD card, we do not need to be constantly changing the ROM. Disabling the memory editor dramatically reduces compilation time which will be useful when implementing FPGA features in the future. --- hw/fpga/rom.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/fpga/rom.v b/hw/fpga/rom.v index 80a7515..c4f311c 100644 --- a/hw/fpga/rom.v +++ b/hw/fpga/rom.v @@ -90,7 +90,7 @@ module rom ( `endif , altsyncram_component.intended_device_family = "MAX 10", - altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=ROM0", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", altsyncram_component.lpm_type = "altsyncram", altsyncram_component.numwords_a = 32768, altsyncram_component.operation_mode = "ROM", @@ -120,7 +120,7 @@ endmodule // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10" -// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "1" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" // Retrieval info: PRIVATE: JTAG_ID STRING "ROM0" // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" // Retrieval info: PRIVATE: MIFfilename STRING "../../sw/bootloader/bootloader.hex" @@ -140,7 +140,7 @@ endmodule // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" // Retrieval info: CONSTANT: INIT_FILE STRING "../../sw/bootloader/bootloader.hex" // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10" -// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=ROM0" +// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "32768" // Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" From 04346ed6253758e4a2f01c431d52ac638581b5b7 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 20:05:53 +0000 Subject: [PATCH 16/26] Update .gitlab-ci.yml file Add bootloader.hex as an artifact for the FPGA build --- .gitlab-ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3a766bf..a58a23a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,10 +8,15 @@ build-kernel: script: - cd sw/kernel - make + artifacts: + paths: + - sw/bootloader/bootloader.hex build-fpga: stage: build + dependencies: + - build-kernel image: bslathi19/modelsim_18.1:lite script: - cd hw/fpga/ From bd748cab86f196fc96cadb218ce89bfa5a872e7f Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 20:08:10 +0000 Subject: [PATCH 17/26] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a58a23a..c5546d5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,9 +8,17 @@ build-kernel: script: - cd sw/kernel - make + +build-bootloader: + stage: build + image: a2geek/cc65-pipeline + script: + - cd sw/bootloader + - make artifacts: paths: - - sw/bootloader/bootloader.hex + - bootloader.hex + build-fpga: From 25883aa3ccde869e25ff45f484a0b72cc05bad61 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 20:09:32 +0000 Subject: [PATCH 18/26] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c5546d5..a5cbbfb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,14 +17,14 @@ build-bootloader: - make artifacts: paths: - - bootloader.hex + - sw/bootloader/bootloader.hex build-fpga: stage: build dependencies: - - build-kernel + - build-bootloader image: bslathi19/modelsim_18.1:lite script: - cd hw/fpga/ From 7b84d8a9c23ce599a98c068c98bc4874c5d724ec Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 20:27:25 +0000 Subject: [PATCH 19/26] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a5cbbfb..2e2e0bd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,6 +18,7 @@ build-bootloader: artifacts: paths: - sw/bootloader/bootloader.hex + expire_in: 1 week From c7ff69a1a0fef6a53ff1e41b96dc9c6680c4b979 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 20:30:27 +0000 Subject: [PATCH 20/26] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2e2e0bd..e23d983 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,15 +2,20 @@ default: tags: - docker +stages: + - build_sw + - build_hw + - test + build-kernel: - stage: build + stage: build_sw image: a2geek/cc65-pipeline script: - cd sw/kernel - make build-bootloader: - stage: build + stage: build_sw image: a2geek/cc65-pipeline script: - cd sw/bootloader @@ -23,7 +28,7 @@ build-bootloader: build-fpga: - stage: build + stage: build_hw dependencies: - build-bootloader image: bslathi19/modelsim_18.1:lite From 686630e79fd10109871397ee2e1fa98ada8d4fd1 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Tue, 19 Apr 2022 15:35:22 -0500 Subject: [PATCH 21/26] Remove unused code to make code smaller These might need to be added back eventually. --- sw/bootloader/exec.c | 61 ---------------------------------- sw/bootloader/exec.h | 6 ---- sw/bootloader/filesystem/fat.c | 52 ----------------------------- sw/bootloader/filesystem/fat.h | 2 -- sw/bootloader/main.c | 1 - sw/kernel/filesystem/fat.c | 2 +- sw/kernel/main.c | 11 +----- 7 files changed, 2 insertions(+), 133 deletions(-) delete mode 100644 sw/bootloader/exec.c delete mode 100644 sw/bootloader/exec.h diff --git a/sw/bootloader/exec.c b/sw/bootloader/exec.c deleted file mode 100644 index 0824eb6..0000000 --- a/sw/bootloader/exec.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include - -#include "filesystem/fat.h" -#include "filesystem/o65.h" - -void exec(char* filename) { - o65_header_t* header; - o65_opt_t* o65_opt; - uint8_t* seg_ptr; - - uint8_t* code_base; - uint8_t* data_base; - uint16_t code_len; - uint16_t data_len; - - uint8_t (*exec)(void); - uint8_t ret; - - fat_read(filename, fat_buf); - - header = (o65_header_t*)fat_buf; - - if (header->c64_marker == O65_NON_C64 && - header->magic[0] == O65_MAGIC_0 && - header->magic[1] == O65_MAGIC_1 && - header->magic[2] == O65_MAGIC_2) { - - code_base = (uint8_t*)header->tbase; - data_base = (uint8_t*)header->dbase; - code_len = header->tlen; - data_len = header->dlen; - - - o65_opt = (o65_opt_t*)(fat_buf + sizeof(o65_header_t)); - while (o65_opt->olen) - { - o65_print_option(o65_opt); - o65_opt = (o65_opt_t*)((uint8_t*)o65_opt + o65_opt->olen); - } - - seg_ptr = (uint8_t*)o65_opt + 1; - - memcpy((uint8_t*)code_base, seg_ptr, code_len); - - seg_ptr+=code_len; - - memcpy((uint8_t*)data_base, seg_ptr, data_len); - - exec = (uint8_t (*)(void))code_base; - - ret = 0; - - ret = (*exec)(); - - cprintf("ret: %x\n", ret); - - - } -} diff --git a/sw/bootloader/exec.h b/sw/bootloader/exec.h deleted file mode 100644 index 9ed3941..0000000 --- a/sw/bootloader/exec.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _EXEC_H -#define _EXEC_H - -void exec(char* filename); - -#endif diff --git a/sw/bootloader/filesystem/fat.c b/sw/bootloader/filesystem/fat.c index bd353d1..fbbd50f 100644 --- a/sw/bootloader/filesystem/fat.c +++ b/sw/bootloader/filesystem/fat.c @@ -13,37 +13,6 @@ static full_bpb_t bpb; static uint32_t data_region_start; -void fat_print_pbp_info(full_bpb_t* bpb){ - cprintf("Bytes per sector: %d\n", bpb->bytes_per_sector); - cprintf("Sectors per cluster: %d\n", bpb->sectors_per_cluster); - cprintf("Reserved Sectors: %d\n", bpb->reserved_sectors); - cprintf("Fat Count: %d\n", bpb->fat_count); - cprintf("Max Dir Entries: %d\n", bpb->max_dir_entries); - cprintf("Total Sector Count: %d\n", bpb->total_sector_count); - cprintf("Media Descriptor: 0x%x\n", bpb->media_descriptor); - cprintf("Sectors per Fat: %d\n", bpb->sectors_per_fat_16); - cprintf("\n"); - - cprintf("Sectors per track: %d\n", bpb->sectors_per_track); - cprintf("Head Count: %d\n", bpb->head_count); - cprintf("Hidden Sector Count: %ld\n", bpb->hidden_sector_count); - cprintf("Logical Sector Count: %ld\n", bpb->logical_sector_count); - cprintf("Sectors per Fat: %ld\n", bpb->sectors_per_fat_32); - cprintf("Extended Flags: 0x%x\n", bpb->extended_flags); - cprintf("Version: %d\n", bpb->version); - cprintf("Root Cluster: 0x%lx\n", bpb->root_cluster); - cprintf("System Information: 0x%x\n", bpb->system_information); - cprintf("Backup Boot Sector: 0x%x\n", bpb->backup_boot_sector); - cprintf("\n"); - - cprintf("Drive Number: %d\n", bpb->drive_num); - cprintf("Extended Signature: 0x%x\n", bpb->extended_signature); - cprintf("Volume ID: 0x%lx\n", bpb->volume_id); - cprintf("Partition Label: %.11s\n", &bpb->partition_label); - cprintf("Partition Label: %.8s\n", &bpb->filesystem_type); - cprintf("\n"); -} - void fat_init(){ int i; @@ -54,8 +23,6 @@ void fat_init(){ sd_readblock(1, fat_buf); sd_readblock(32, fat_buf); - fat_print_pbp_info(&bpb); - data_region_start = bpb.reserved_sectors + bpb.fat_count*bpb.sectors_per_fat_32; sd_readblock(bpb.reserved_sectors, fat_buf); @@ -73,25 +40,6 @@ void fat_init(){ cprintf("End of chain indicator: %lx\n", fat_end_of_chain); } -void fat_read(char* filename, void* buf) { - vfat_dentry_t* vfat_dentry; - dos_dentry_t* dos_dentry; - uint32_t cluster; - - (void)filename; //just ignore filename - - sd_readblock(data_region_start, buf); - - vfat_dentry = (vfat_dentry_t*)buf; - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - - dos_dentry = (dos_dentry_t*)(vfat_dentry + 1); - - cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; - - sd_readblock(data_region_start + (cluster - 2) * 8, buf); -} // make sure you have enough space. void fat_read_cluster(uint16_t cluster, uint8_t* buf) { diff --git a/sw/bootloader/filesystem/fat.h b/sw/bootloader/filesystem/fat.h index 732e179..2f7a640 100644 --- a/sw/bootloader/filesystem/fat.h +++ b/sw/bootloader/filesystem/fat.h @@ -113,9 +113,7 @@ typedef struct { uint32_t file_size; } dos_dentry_t; -void fat_print_pbp_info(full_bpb_t* bpb); void fat_init(); -void fat_read(char* filename, void* buf); uint16_t fat_parse_path_to_cluster(char* filename); void fat_read_cluster(uint16_t cluster, uint8_t* buf); diff --git a/sw/bootloader/main.c b/sw/bootloader/main.c index 66d399f..e6e8407 100644 --- a/sw/bootloader/main.c +++ b/sw/bootloader/main.c @@ -8,7 +8,6 @@ #include "devices/mapper.h" #include "devices/sd_card.h" #include "filesystem/fat.h" -#include "exec.h" #define KERNEL_LOAD_ADDR 0xD000 diff --git a/sw/kernel/filesystem/fat.c b/sw/kernel/filesystem/fat.c index e5187f3..cdcbdfd 100644 --- a/sw/kernel/filesystem/fat.c +++ b/sw/kernel/filesystem/fat.c @@ -45,7 +45,7 @@ void fat_print_pbp_info(full_bpb_t* bpb){ } void fat_init(){ - int i; + //int i; sd_readblock(0, fat_buf); diff --git a/sw/kernel/main.c b/sw/kernel/main.c index 21850fd..1039619 100644 --- a/sw/kernel/main.c +++ b/sw/kernel/main.c @@ -13,20 +13,11 @@ uint8_t buf[512]; int main() { - int i; uint16_t rca; char* filename; clrscr(); - cprintf("Hello, world!\n"); - - for (i = 0; i < 16; i++){ - //cprintf("Mapping %1xxxx to %2xxxx\n", i, i); - mapper_write(i, i); - } - - cprintf("Enabling Mapper\n"); - mapper_enable(1); + cprintf("Hello, world! Modified\n"); sd_init(); From aa717685e3e0aa5ea1153ff4aeab2553b4f2ea68 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 20 Apr 2022 12:39:40 -0500 Subject: [PATCH 22/26] Use our own toolchain instead of the one in the image Now that we are adding our own target we can compile our own toolchain instead of using the stock one. This does mean that there isn't really a purpose to using the alpine cc65 image though --- .gitlab-ci.yml | 18 +++++++++++++++--- .gitmodules | 3 +++ sw/Makefile | 8 ++++++-- sw/bootloader/Makefile | 2 +- sw/cc65 | 1 + sw/kernel/Makefile | 4 ++-- sw/kernel/boot.s | 5 +++-- sw/kernel/exec.c | 2 +- sw/kernel/link.ld | 8 ++++++-- 9 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 .gitmodules create mode 160000 sw/cc65 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e23d983..896d1bb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,20 +3,32 @@ default: - docker stages: + - build_toolchain - build_sw - build_hw - test +build-cc65: + stage: build_toolchain + image: gcc + script: + - cd sw + - make toolchain + build-kernel: stage: build_sw - image: a2geek/cc65-pipeline + image: gcc script: - cd sw/kernel - make + artifacts: + paths: + - sw/cc65/bin + - sw/cc65/lib build-bootloader: stage: build_sw - image: a2geek/cc65-pipeline + image: gcc script: - cd sw/bootloader - make @@ -53,7 +65,7 @@ test_bb_spi: test-sw: stage: test - image: a2geek/cc65-pipeline + image: gcc script: - cd sw/kernel - make test diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..21b2181 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sw/cc65"] + path = sw/cc65 + url = https://git.byronlathi.com/bslathi19/cc65 diff --git a/sw/Makefile b/sw/Makefile index ee3f485..c379713 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -1,11 +1,14 @@ .PHONY: all install bootloader kernel clean -all: bootloader kernel +all: toolchain bootloader kernel install: all sh script/format_disk.sh sh script/copy_files.sh +toolchain: + @$(MAKE) -j4 -C cc65 + bootloader: @$(MAKE) -C bootloader @@ -15,4 +18,5 @@ kernel: clean: @$(MAKE) -C bootloader --no-print-directory $@ - @$(MAKE) -C kernel --no-print-directory $@ \ No newline at end of file + @$(MAKE) -C kernel --no-print-directory $@ + @$(MAKE) -C cc65 --no-print-directory $@ \ No newline at end of file diff --git a/sw/bootloader/Makefile b/sw/bootloader/Makefile index bd08961..6f3db2c 100644 --- a/sw/bootloader/Makefile +++ b/sw/bootloader/Makefile @@ -1,4 +1,4 @@ -CC=cl65 +CC=../cc65/bin/cl65 CFLAGS=-T -t none -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map diff --git a/sw/cc65 b/sw/cc65 new file mode 160000 index 0000000..23a984f --- /dev/null +++ b/sw/cc65 @@ -0,0 +1 @@ +Subproject commit 23a984f0ddd00712bb29bc0568e2e14cca637ed8 diff --git a/sw/kernel/Makefile b/sw/kernel/Makefile index bd2124e..5c6da0e 100644 --- a/sw/kernel/Makefile +++ b/sw/kernel/Makefile @@ -1,5 +1,5 @@ -CC=cl65 -CFLAGS=-T -t none -I. --cpu "65C02" +CC=../cc65/bin/cl65 +CFLAGS=-T -t super6502 -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map SIM=sim65 diff --git a/sw/kernel/boot.s b/sw/kernel/boot.s index 8cb6a79..a30963b 100644 --- a/sw/kernel/boot.s +++ b/sw/kernel/boot.s @@ -29,9 +29,10 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF ; --------------------------------------------------------------------------- ; Set cc65 argument stack pointer - LDA #<(__SDRAM_START__ + __SDRAM_SIZE__) + ;LDA #<(__SDRAM_START__ + __SDRAM_SIZE__) + lda #<($200 + $7cf0) STA sp - LDA #>(__SDRAM_START__ + __SDRAM_SIZE__) + LDA #>($200 + $7cf0) STA sp+1 ; --------------------------------------------------------------------------- diff --git a/sw/kernel/exec.c b/sw/kernel/exec.c index 0824eb6..cbf1ccb 100644 --- a/sw/kernel/exec.c +++ b/sw/kernel/exec.c @@ -52,7 +52,7 @@ void exec(char* filename) { ret = 0; - ret = (*exec)(); + //ret = (*exec)(); cprintf("ret: %x\n", ret); diff --git a/sw/kernel/link.ld b/sw/kernel/link.ld index 1fd8d3f..806c93f 100644 --- a/sw/kernel/link.ld +++ b/sw/kernel/link.ld @@ -2,12 +2,16 @@ MEMORY { ZP: start = $0, size = $100, type = rw, define = yes; SDRAM: start = $200, size = $7cf0, type = rw, define = yes; - ROM: start = $D000, size = $3000, file = %O; + ROM: start = $C000, size = $4000, type = rw, define = yes; +} + +FILES { + %O: format = o65; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; - DATA: load = ROM, type = rw, define = yes, run = SDRAM; + DATA: load = SDRAM, type = rw, define = yes; BSS: load = SDRAM, type = bss, define = yes; HEAP: load = SDRAM, type = bss, optional = yes; STARTUP: load = ROM, type = ro; From 0e98f7536b5dcdb91079a2a5667cffd2435a4a24 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 20 Apr 2022 12:46:45 -0500 Subject: [PATCH 23/26] update ci --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 896d1bb..9c1aeb7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,9 @@ default: tags: - docker +variables: + GIT_SUBMODULE_STRATEGY: recursive + stages: - build_toolchain - build_sw From 9de3c5b1fa110336aa7ef917030a614bc3641df9 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 20 Apr 2022 12:49:23 -0500 Subject: [PATCH 24/26] update ci --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c1aeb7..7b89111 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,6 +17,10 @@ build-cc65: script: - cd sw - make toolchain + artifacts: + paths: + - sw/cc65/bin + - sw/cc65/lib build-kernel: stage: build_sw @@ -24,10 +28,6 @@ build-kernel: script: - cd sw/kernel - make - artifacts: - paths: - - sw/cc65/bin - - sw/cc65/lib build-bootloader: stage: build_sw From 1b08d25ce1f8228e301de8337655f165d755e143 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 20 Apr 2022 12:59:32 -0500 Subject: [PATCH 25/26] Update makefile for tests use the local sim65 instead of the installed one which doesn't exist --- sw/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw/kernel/Makefile b/sw/kernel/Makefile index 5c6da0e..ce9ac23 100644 --- a/sw/kernel/Makefile +++ b/sw/kernel/Makefile @@ -2,7 +2,7 @@ CC=../cc65/bin/cl65 CFLAGS=-T -t super6502 -I. --cpu "65C02" test: CFLAGS=-T -t sim65c02 -I. LDFLAGS=-C link.ld -m $(NAME).map -SIM=sim65 +SIM=../cc65/bin/sim65 SIMARGS=-v -c -x 1000000 FSDIR=../fsdir From 1a64fa4d62474c22d0480ebcab90ec634c38485e Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 20 Apr 2022 13:54:07 -0500 Subject: [PATCH 26/26] Change kernel format to bin for merge We don't have the bootloader reading o65 files right now, so we need to keep the kernel as a bin file until that is added. --- sw/kernel/link.ld | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sw/kernel/link.ld b/sw/kernel/link.ld index 806c93f..96adc89 100644 --- a/sw/kernel/link.ld +++ b/sw/kernel/link.ld @@ -2,11 +2,11 @@ MEMORY { ZP: start = $0, size = $100, type = rw, define = yes; SDRAM: start = $200, size = $7cf0, type = rw, define = yes; - ROM: start = $C000, size = $4000, type = rw, define = yes; + ROM: start = $D000, size = $3000, type = rw, define = yes; } FILES { - %O: format = o65; + %O: format = bin; } SEGMENTS {