diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index 6bb6682..8098232 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,5 +1,5 @@ - + diff --git a/sw/bios/Makefile b/sw/bios/Makefile index 65a5116..e5efbe0 100644 --- a/sw/bios/Makefile +++ b/sw/bios/Makefile @@ -11,7 +11,7 @@ LISTS=lists TESTS=tests SRCS=$(wildcard *.s) $(wildcard *.c) -SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*) $(wildcard filesystem/*), $(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))) diff --git a/sw/bios/bootloader.s b/sw/bios/bootloader.s new file mode 100644 index 0000000..47ef646 --- /dev/null +++ b/sw/bios/bootloader.s @@ -0,0 +1,41 @@ +.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 + +.autoimport on + +.feature string_escapes + +.MACPACK generic + +_console_clear = $0 +_console_read_char = $2 +_console_write_char = $4 +_sd_readblock = $6 + +.segment "BOOTSECTOR" + +_start: + jmp _main + +.byte "SUPR6502" + +_main: + lda #str + jsr _cputs +@end: bra @end + + +str: .asciiz "Hello from the bootloader!\r\n" + +_end: + +.res (446+_start-_end) + +.res 16 +.res 16 +.res 16 +.res 16 + +.byte $55 +.byte $AA + diff --git a/sw/bios/filesystem/fat.c b/sw/bios/filesystem/fat.c deleted file mode 100644 index fbbd50f..0000000 --- a/sw/bios/filesystem/fat.c +++ /dev/null @@ -1,208 +0,0 @@ -#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_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); - - 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); -} - - -// 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/bios/filesystem/fat.h b/sw/bios/filesystem/fat.h deleted file mode 100644 index 2f7a640..0000000 --- a/sw/bios/filesystem/fat.h +++ /dev/null @@ -1,122 +0,0 @@ -#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_init(); - -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/bios/filesystem/o65.c b/sw/bios/filesystem/o65.c deleted file mode 100644 index 9e76dc0..0000000 --- a/sw/bios/filesystem/o65.c +++ /dev/null @@ -1,28 +0,0 @@ -#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/bios/filesystem/o65.h b/sw/bios/filesystem/o65.h deleted file mode 100644 index 719305c..0000000 --- a/sw/bios/filesystem/o65.h +++ /dev/null @@ -1,65 +0,0 @@ -#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/bios/link.ld b/sw/bios/link.ld index 53ef73c..25ad7c2 100644 --- a/sw/bios/link.ld +++ b/sw/bios/link.ld @@ -2,7 +2,7 @@ MEMORY { ZP: start = $0, size = $100, type = rw, define = yes; SDRAM: start = $200, size = $7e00, type = rw, define = yes; - BOOTLOADER: start = $8000, size = $1000, type = rw, define = yes; + BOOTLOADER: start = $8000, size = $1000, type = rw, define = yes, file = "bootloader.bin"; ROM: start = $F000, size = $1000, file = %O; } @@ -16,6 +16,7 @@ SEGMENTS { CODE: load = ROM, type = ro; RODATA: load = ROM, type = ro; VECTORS: load = ROM, type = ro, start = $FFFA; + BOOTSECTOR: load = BOOTLOADER, type = rw, start = $8000; } FEATURES { diff --git a/sw/bios/main.c b/sw/bios/main.c index 75dff9f..27a701d 100644 --- a/sw/bios/main.c +++ b/sw/bios/main.c @@ -7,7 +7,6 @@ #include "devices/uart.h" #include "devices/sd_card.h" #include "devices/sd_print.h" -#include "filesystem/fat.h" #define KERNEL_LOAD_ADDR 0xD000 diff --git a/sw/bootloader/Makefile b/sw/bootloader/Makefile deleted file mode 100644 index 006cf3a..0000000 --- a/sw/bootloader/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -CC=../cc65/bin/cl65 -CFLAGS=-T -t none -I. --cpu "65C02" -LDFLAGS=-C link.ld -m $(NAME).map - -NAME=bootloader - -BIN=$(NAME).bin -HEX=$(NAME).hex - -LISTS=lists - -SRCS=$(wildcard *.s) $(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/bootloader.s b/sw/bootloader/bootloader.s deleted file mode 100644 index f05685e..0000000 --- a/sw/bootloader/bootloader.s +++ /dev/null @@ -1,27 +0,0 @@ -.segment "BOOTSECTOR" - - -_start: - jmp _main - -.byte "SUPR6502" - -_main: - ldx #$04 - lda #'A' - brk - nop ; This byte available for something - @1: jmp @1 - -_end: - -.res (446+_start-_end) - -.res 16 -.res 16 -.res 16 -.res 16 - -.byte $55 -.byte $AA - diff --git a/sw/bootloader/link.ld b/sw/bootloader/link.ld deleted file mode 100644 index d0725d6..0000000 --- a/sw/bootloader/link.ld +++ /dev/null @@ -1,8 +0,0 @@ -MEMORY -{ - BOOT: start = $8000, size = $200, file = %O; -} - -SEGMENTS { - BOOTSECTOR: load = BOOT, start = $8000; -} diff --git a/sw/script/format_disk.sh b/sw/script/format_disk.sh index 9cd6c8f..9aed55d 100644 --- a/sw/script/format_disk.sh +++ b/sw/script/format_disk.sh @@ -1,6 +1,6 @@ #!/bin/bash -BOOTLOADER=../bootloader/bootloader.bin +BOOTLOADER=../bios/bootloader.bin DEVICE=/dev/mmcblk0 TMPBOOTSECT=/tmp/bootsect TMPMOUNT=/tmp/sd