diff --git a/sw/kernel/devices/io.inc65 b/sw/kernel/devices/io.inc65 index 42b0910..56ccdc1 100644 --- a/sw/kernel/devices/io.inc65 +++ b/sw/kernel/devices/io.inc65 @@ -10,4 +10,21 @@ SPI_BAUD = $efd8 SPI_INPUT = $efd9 SPI_OUTPUT = $efda SPI_CTRL = $efdb -SPI_STATUS = SPI_CTRL \ No newline at end of file +SPI_STATUS = SPI_CTRL + +MULTIPLIER_BASE = $eff0 + +MULTIPLIER_AL = MULTIPLIER_BASE + 0 +MULTIPLIER_AH = MULTIPLIER_BASE + 1 +MULTIPLIER_BL = MULTIPLIER_BASE + 2 +MULTIPLIER_BH = MULTIPLIER_BASE + 3 + +MULTIPLIER_OLL = MULTIPLIER_BASE + 4 +MULTIPLIER_OLH = MULTIPLIER_BASE + 5 +MULTIPLIER_OHL = MULTIPLIER_BASE + 6 +MULTIPLIER_OHH = MULTIPLIER_BASE + 7 + +GOLDEN_OUTPUT_0 = $03 +GOLDEN_OUTPUT_1 = $0a +GOLDEN_OUTPUT_2 = $08 +GOLDEN_OUTPUT_3 = $00 \ No newline at end of file diff --git a/sw/kernel/devices/multiplier.h b/sw/kernel/devices/multiplier.h new file mode 100644 index 0000000..e60764f --- /dev/null +++ b/sw/kernel/devices/multiplier.h @@ -0,0 +1,12 @@ +#ifndef _MULTIPLER_H +#define _MULTIPLER_H + +#include + +/* Multiply 2 integers into 1 long */ +uint32_t lmulii(uint16_t a, uint16_t b); + +/* Multiply 2 integers into 1 integer, discarding upper bits. */ +uint16_t imulii(uint16_t a, uint16_t b); + +#endif \ No newline at end of file diff --git a/sw/kernel/devices/multiplier.s b/sw/kernel/devices/multiplier.s new file mode 100644 index 0000000..7c3d6a3 --- /dev/null +++ b/sw/kernel/devices/multiplier.s @@ -0,0 +1,36 @@ +.include "io.inc65" + +.MACPACK generic + +.import popax +.importzp sreg + +.export _lmulii, _imulii + +.code + +.proc _lmulii + sta MULTIPLIER_BL + stx MULTIPLIER_BH + jsr popax + sta MULTIPLIER_AL + stx MULTIPLIER_AH + lda MULTIPLIER_OHL + sta sreg + lda MULTIPLIER_OHH + sta sreg+1 + lda MULTIPLIER_OLL + ldx MULTIPLIER_OLH + rts +.endproc + +.proc _imulii + sta MULTIPLIER_BL + stx MULTIPLIER_BH + jsr popax + sta MULTIPLIER_AL + stx MULTIPLIER_AH + lda MULTIPLIER_OLL + ldx MULTIPLIER_OLH + rts +.endproc \ No newline at end of file diff --git a/sw/kernel/filesystems/fat32.h b/sw/kernel/filesystems/fat32.h new file mode 100644 index 0000000..fcdd45f --- /dev/null +++ b/sw/kernel/filesystems/fat32.h @@ -0,0 +1,34 @@ +#ifndef _FAT32_H +#define _FAT32_H + +#include + +void fat32_init(); + +struct fat32_directory_entry { + char file_name[8]; + char file_ext[3]; + uint8_t attr1; + uint8_t create_time_10ms; + uint16_t create_time; + uint16_t create_date; + uint16_t access_date; + uint16_t cluster_high; + uint16_t modified_time; + uint16_t modified_date; + uint16_t cluster_low; + uint32_t file_size; +}; + +struct lfn_entry { + uint8_t sequence_number; + uint16_t name_0[5]; + uint8_t attributes; + uint8_t type; + uint8_t checksum; + uint16_t name_1[6]; + uint16_t cluster_low; + uint16_t name_2[2]; +}; + +#endif diff --git a/sw/kernel/filesystems/fat32.s b/sw/kernel/filesystems/fat32.s new file mode 100644 index 0000000..267d570 --- /dev/null +++ b/sw/kernel/filesystems/fat32.s @@ -0,0 +1,115 @@ +.MACPACK generic + +.autoimport +.feature string_escapes + +.importzp ptr1, sreg + +.import _SD_readSingleBlock + +.export _fat32_init + + +.data +fat_start_sector: .res 2 +data_start_sector: .res 2 +sd_buf: .res 512 + +bps_val_str: .asciiz "Bytes Per Sector: 0x%x\n" +sps_val_str: .asciiz "Sectors Per Cluster: 0x%x\n" +rsv_val_str: .asciiz "Reserved Sectors: 0x%x\n" +fat_count_str: .asciiz "FAT count: 0x%x\n" +fat_sect_str: .asciiz "Sectors per FAT: 0x%x\n" +fat_size_tot_str: .asciiz "Total fat size: 0x%lx\n" +rsv_sect_bytes_str: .asciiz "Total reserved bytes: 0x%x\n" +rsv_sd_sectors: .asciiz "Reserved SD Sectors: 0x%x\n" + +.code + +bytes_per_sector = sd_buf + $0B +sectors_per_cluster = sd_buf + $0D +reserved_sectors = sd_buf + $0E +fat_count = sd_buf + $10 +sectors_per_fat = sd_buf + $24 + +.proc _fat32_init + ; load sector 0 into sd_buf + lda #$00 + ldx #$00 + stz sreg + stz sreg+1 + jsr pusheax + lda #sd_buf + jsr pushax + lda #ptr1 + jsr _SD_readSingleBlock + + lda #bps_val_str + jsr pushax + lda bytes_per_sector + ldx bytes_per_sector+1 + jsr pushax + ldy #$4 + jsr _printf + + lda #sps_val_str + jsr pushax + lda sectors_per_cluster + ldx #$00 + jsr pushax + ldy #$4 + jsr _cprintf + + lda #rsv_val_str + jsr pushax + lda reserved_sectors + ldx #$00 + jsr pushax + ldy #$4 + jsr _cprintf + + lda #fat_count_str + jsr pushax + lda fat_count + ldx #$00 + jsr pushax + ldy #$4 + jsr _cprintf + + + lda #rsv_sect_bytes_str + jsr pushax + + lda reserved_sectors + jsr pusha0 + lda bytes_per_sector + ldx bytes_per_sector+1 + jsr _imulii + jsr pushax + ldy #$4 + jsr _cprintf + + lda #fat_size_tot_str + jsr pushax + + ; multiply fat size and number of fats + + lda fat_count + jsr pusha0 + lda sectors_per_fat + ldx sectors_per_fat+1 + jsr _lmulii + jsr pusheax + ldy #$6 + jsr _cprintf + + rts +.endproc diff --git a/sw/kernel/filesystems/fs.h b/sw/kernel/filesystems/fs.h new file mode 100644 index 0000000..b1e738b --- /dev/null +++ b/sw/kernel/filesystems/fs.h @@ -0,0 +1,19 @@ +#ifndef _FS_H +#define _FS_H + +#include + +/* syscalls for files */ +int8_t file_read(int8_t fd, void* buf, int8_t nbytes); +int8_t file_write(int8_t fd, const void* buf, int8_t nbytes); +int8_t file_open(const uint8_t* filename); +int8_t file_close(int8_t fd); + +/* syscalls for directories */ +int8_t directory_read(int8_t fd, void* buf, int8_t nbytes); +int8_t directory_write(int8_t fd, const void* buf, int8_t nbytes); +int8_t directory_open(const uint8_t* filename); +int8_t directory_close(int8_t fd); + + +#endif \ No newline at end of file diff --git a/sw/kernel/kernel.c b/sw/kernel/kernel.c index e81a8fc..b9e56e0 100644 --- a/sw/kernel/kernel.c +++ b/sw/kernel/kernel.c @@ -6,9 +6,10 @@ #include "devices/mapper.h" #include "devices/rtc.h" #include "devices/serial.h" - #include "devices/terminal.h" +#include "filesystems/fat32.h" + void handle_rtc_interrupt() { // cputs("In IRQ interrupt!\n"); @@ -22,16 +23,16 @@ char buf[128]; int main() { cputs("Kernel\n"); - // cputs("Init Mapper\n"); + cputs("Init Mapper\n"); init_mapper(); - // cputs("Initialize Interrupts\n"); + cputs("Initialize Interrupts\n"); init_interrupts(); - // cputs("Initialize Interrupt Controller\n"); + cputs("Initialize Interrupt Controller\n"); init_interrupt_controller(); - // cputs("Initialize RTC\n"); + cputs("Initialize RTC\n"); init_rtc(); register_irq(&handle_rtc_interrupt, 0); @@ -41,10 +42,12 @@ int main() { asm volatile("cli"); - // cputs("Initialize Serial\n"); + cputs("Initialize Serial\n"); serial_init(); serial_puts("Hello from serial!\n"); + + fat32_init(); terminal_open(NULL); terminal_write(0, "Terminal Write\n", 15); diff --git a/sw/test_code/fs_test/Makefile b/sw/test_code/fs_test/Makefile new file mode 100644 index 0000000..2405c9c --- /dev/null +++ b/sw/test_code/fs_test/Makefile @@ -0,0 +1,48 @@ +CC=../../cc65/bin/cl65 +LD=../../cc65/bin/cl65 +SIM=../../cc65/bin/sim65 +CFLAGS=-T -t sim65c02 -I. +LDFLAGS=-m $(NAME).map + +NAME=fs_test + +BIN=$(NAME).bin + +FS=$(REPO_TOP)/sw/script/fs.fat + +LISTS=lists + +EXT_SRCS=$(REPO_TOP)/sw/kernel/filesystems/fat32.s + +SRCS=$(wildcard *.s) $(wildcard *.c) +SRCS+=$(wildcard **/*.s) $(wildcard **/*.c) +OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS))) +OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS))) + +run: all + $(SIM) $(BIN) + +all: fs.fat fat32.s $(BIN) + +$(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 $@ + +fat32.s: $(EXT_SRCS) + cp $^ . + +fs.fat: $(FS) + cp $^ . + +$(LISTS): + mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS)))) + +.PHONY: clean +clean: + rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map fat32.s + diff --git a/sw/test_code/fs_test/asm_harness.s b/sw/test_code/fs_test/asm_harness.s new file mode 100644 index 0000000..c227854 --- /dev/null +++ b/sw/test_code/fs_test/asm_harness.s @@ -0,0 +1,5 @@ +.import _printf +.export _cprintf + +_cprintf: + jmp _printf \ No newline at end of file diff --git a/sw/test_code/fs_test/harness.c b/sw/test_code/fs_test/harness.c new file mode 100644 index 0000000..5fcb855 --- /dev/null +++ b/sw/test_code/fs_test/harness.c @@ -0,0 +1,21 @@ +#include +#include +#include + +#define FILE_PATH "fs.fat" + +uint32_t lmulii(uint16_t a, uint16_t b) { + printf("lmulii: %x * %x = %x\n", a, b, a*b); + return a * b; +} + +uint16_t imulii(uint16_t a, uint16_t b) { + printf("imulii: %x * %x = %x\n", a, b, a*b); + return a * b; +} + +uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *error) { + FILE* f = fopen(FILE_PATH, "rb"); + // fseek(f, addr * 512, SEEK_SET); + fread(buf, 512, 1, f); +} diff --git a/sw/test_code/fs_test/main.c b/sw/test_code/fs_test/main.c new file mode 100644 index 0000000..93d9085 --- /dev/null +++ b/sw/test_code/fs_test/main.c @@ -0,0 +1,9 @@ +#include + +void fat32_init(void); + +int main(void) { + printf("Hello, world!\n"); + fat32_init(); + return 0; +} \ No newline at end of file