Restart kernel

This commit is contained in:
Byron Lathi
2023-08-12 11:59:45 -07:00
parent 069ae5db4b
commit 7ad1079289
30 changed files with 98 additions and 1140 deletions

View File

@@ -15,6 +15,7 @@ buf = $8200
addrh = $0000
addrl = $0001
.segment "BOOTSECTOR"
_start:
@@ -51,9 +52,20 @@ _main:
ldx #>buf
jsr _SD_printBuf
lda #<_reserved_sect
ldx #>_reserved_sect
jsr pushax
lda $800E
ldx $800F
jsr pushax
ldy #$04
jsr _cprintf
@end: bra @end
_reserved_sect:
.asciiz "Reserved Sectors: %x\r\n"
str: .asciiz "Hello from the bootloader!\r\n"
_end:

View File

@@ -1,7 +1,8 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $200, size = $7e00, type = rw, define = yes;
KERNEL: start = $1000, size = $7000, type = rw, define = yes;
SDRAM: start = $9000, size = $5000, type = rw, define = yes;
BOOTLOADER: start = $8000, size = $1000, type = rw, define = yes, file = "bootloader.bin";
ROM: start = $F000, size = $1000, file = %O;
}

Submodule sw/cc65 updated: 9dc33cff22...1045eed9af

View File

@@ -1,46 +1,24 @@
CC=../cc65/bin/cl65
CFLAGS=-T -t super6502 -I. --cpu "65C02"
test: CFLAGS=-T -t sim65c02 -I.
LD=../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
SIM=../cc65/bin/sim65
SIMARGS=-v -c -x 1000000
FSDIR=../fsdir
NAME=kernel
TEST_BIN=test.bin
BIN=$(NAME).bin
HEX=$(NAME).hex
O65 = $(NAME).o65
LISTS=lists
TESTS=tests
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c))
SRCS+=$(wildcard **/*.s) $(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))))
# Make sure the kernel linked to correct address, no relocation!
all: $(O65)
all: $(BIN)
cp $(BIN) $(FSDIR)
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)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
$(O65): $(OBJS)
$(LD) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
@@ -50,11 +28,7 @@ $(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)
rm -rf $(FSDIR)/$(BIN)
rm -rf $(OBJS) $(O65) $(LISTS) $(NAME).map

View File

@@ -8,7 +8,7 @@
.import _main
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import __SDRAM_START__, __SDRAM_SIZE__ ; Linker generated
.import __STACKSTART__, __STACKSIZE__ ; Linker generated
.import copydata, zerobss, initlib, donelib
@@ -29,10 +29,9 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF
; ---------------------------------------------------------------------------
; Set cc65 argument stack pointer
;LDA #<(__SDRAM_START__ + __SDRAM_SIZE__)
lda #<($200 + $7cf0)
LDA #<(__STACKSTART__ + __STACKSIZE__)
STA sp
LDA #>($200 + $7cf0)
LDA #>(__STACKSTART__ + __STACKSIZE__)
STA sp+1
; ---------------------------------------------------------------------------

View File

@@ -1,16 +0,0 @@
#ifndef _BOARD_IO_H
#define _BOARD_IO_H
#include <stdint.h>
uint8_t hex_set_8(uint8_t val, uint8_t idx);
uint8_t hex_set_16(uint16_t val);
uint8_t hex_set_24(uint32_t val);
void hex_enable(uint8_t mask);
uint8_t sw_read();
void led_set(uint8_t val);
#endif

View File

@@ -1,71 +0,0 @@
.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

View File

@@ -6,7 +6,7 @@
.export _cputc
.export gotoxy
.export _clrscr
.export _cgetc
;.export _cgetc
.autoimport on
@@ -53,8 +53,8 @@ _clrscr:
pla
rts
_cgetc:
@2: lda _lastchar
beq @2
stz _lastchar
rts
;_cgetc:
;@2: lda _lastchar
; beq @2
; stz _lastchar
; rts

View File

@@ -1,15 +0,0 @@
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include <stdint.h>
#define BUTTON (1 << 0)
#define UART (1 << 1)
void irq_int();
void nmi_int();
uint8_t irq_get_status();
void irq_set_status(uint8_t);
#endif

View File

@@ -1,58 +0,0 @@
; ---------------------------------------------------------------------------
; 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

View File

@@ -1,18 +1,13 @@
SEVEN_SEG = $7ff0
UART = $7ff4
UART = $efe6
UART_TXB = UART
UART_RXB = UART
UART_STATUS = UART + 1
LED = $7ff6
LED = $efff
SW = LED
MM_CTRL = $7ff7
MM_DATA = $7fe0
SD_ARG = $7ff8
SD_CMD = $7ffc
SD_DATA = $7ffd
IRQ_STATUS = $7fff
SPI_BAUD = $efd8
SPI_INPUT = $efd9
SPI_OUTPUT = $efda
SPI_CTRL = $efdb
SPI_STATUS = SPI_CTRL

View File

@@ -1,12 +0,0 @@
#ifndef _MAPPER_H
#define _MAPPER_H
#include <stdint.h>
void mapper_enable(uint8_t en);
uint8_t mapper_read(uint8_t addr);
void mapper_write(uint8_t data, uint8_t addr);
#endif

View File

@@ -1,32 +0,0 @@
.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

View File

@@ -1,75 +0,0 @@
#include <stdint.h>
#include <conio.h>
#include "devices/sd_card.h"
void sd_init() {
uint32_t resp;
sd_card_command(0, 0);
sd_card_command(0x000001aa, 8);
sd_card_resp(&resp);
//cprintf("CMD8: %lx\n", resp);
sd_card_command(0, 55);
sd_card_command(0x40180000, 41);
sd_card_resp(&resp);
//cprintf("CMD41: %lx\n", resp);
sd_card_command(0, 55);
sd_card_command(0x40180000, 41);
sd_card_resp(&resp);
//cprintf("CMD41: %lx\n", resp);
sd_card_command(0, 2);
sd_card_resp(&resp);
//cprintf("CMD2: %lx\n", resp);
}
uint16_t sd_get_rca() {
uint32_t resp;
sd_card_command(0, 3);
resp = 0;
sd_card_resp(&resp);
//cprintf("CMD3: %lx\n", resp);
return resp >> 16;
}
uint16_t sd_select_card(uint16_t rca) {
uint32_t resp;
sd_card_command((uint32_t)rca << 16, 7);
sd_card_resp(&resp);
return (uint16_t) resp;
}
uint16_t sd_get_status(uint16_t rca) {
uint32_t resp;
sd_card_command((uint32_t)rca << 16, 13);
sd_card_resp(&resp);
return (uint16_t) resp;
}
void sd_readblock(uint32_t addr, void* buf) {
uint32_t resp;
int i;
sd_card_command(addr, 17);
sd_card_resp(&resp);
//cprintf("CMD17: %lx\n", resp);
sd_card_wait_for_data();
//cprintf("Read data: \n");
for (i = 0; i < 512; i++){
((uint8_t*)buf)[i] = sd_card_read_byte();
}
//cprintf("\n");
}

View File

@@ -1,18 +0,0 @@
#ifndef _SD_CARD_H
#define _SD_CARD_H
#include <stdint.h>
void sd_init();
uint16_t sd_get_rca();
uint16_t sd_select_card(uint16_t rca);
uint16_t sd_get_status(uint16_t rca);
void sd_readblock(uint32_t addr, void* buf);
void sd_card_command(uint32_t arg, uint8_t cmd);
void sd_card_resp(uint32_t* resp);
uint8_t sd_card_read_byte();
void sd_card_wait_for_data();
#endif

View File

@@ -1,66 +0,0 @@
.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

View File

@@ -19,8 +19,8 @@ _uart_txb:
_uart_txb_block:
pha
sta UART_TXB ; Write value
@1: lda UART_STATUS ; Wait for status[0] to be 0
bit #$01
@1: lda UART_STATUS ; Wait for status[1] to be 0
bit #$02
bne @1
pla
rts

View File

@@ -1,61 +0,0 @@
#include <stdint.h>
#include <conio.h>
#include <string.h>
#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);
}
}

View File

@@ -1,6 +0,0 @@
#ifndef _EXEC_H
#define _EXEC_H
void exec(char* filename);
#endif

View File

@@ -1,246 +0,0 @@
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#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);
}
//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;
}

View File

@@ -1,122 +0,0 @@
#ifndef _FAT_H
#define _FAT_H
#include <stdint.h>
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);
#endif

View File

@@ -1,28 +0,0 @@
#include <conio.h>
#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");
}

View File

@@ -1,65 +0,0 @@
#ifndef _O65_H
#define _O65_H
#include <stdint.h>
#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

View File

@@ -1,24 +0,0 @@
#include <stdint.h>
#include <conio.h>
#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);
}
}

9
sw/kernel/kernel.c Normal file
View File

@@ -0,0 +1,9 @@
#include <conio.h>
int main() {
cprintf("Hello, world!\r\n");
while(1);
return 0;
}

View File

@@ -1,20 +1,35 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $200, size = $7cf0, type = rw, define = yes;
ROM: start = $D000, size = $3000, type = rw, define = yes, file = %O;
ZP: start = $0, size = $100, type = rw, define = yes;
STACK: start = $200, size = $E00, type = rw, define = yes;
KERNEL: start = $1000, size = $7000, type = rw, define = yes, file = %O;
USER: start = $8000, size = $6000, type = rw, define = yes;
IO: start = $E000, size = $1000, type = rw, define = yes;
ROM: start = $f000, size = $1000, type = rw, define = yes; #rw for vectors
}
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;
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = KERNEL, type = rw, define = yes;
BSS: load = KERNEL, type = rw, define = yes;
HEAP: load = KERNEL, type = rw, define = yes, optional = yes;
STARTUP: load = KERNEL, type = ro;
ONCE: load = KERNEL, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FILES
{
%O: format = o65;
}
FORMATS
{
o65: os = super, version = 0, type = small,
import = LUNIXKERNEL,
export = _init;
}
FEATURES {
@@ -29,7 +44,6 @@ FEATURES {
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}
__STACKSIZE__: value = $0E00, type = weak;
__STACKSTART__: type = weak, value = $0800;
}

View File

@@ -1,45 +0,0 @@
#include <stdint.h>
#include <conio.h>
#include <string.h>
#include <stdlib.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"
uint8_t buf[512];
int main() {
uint16_t rca;
char* filename;
clrscr();
cprintf("Hello, world! Modified\n");
sd_init();
rca = sd_get_rca();
cprintf("rca: %x\n", rca);
sd_select_card(rca);
fat_init();
filename = (char*)malloc(FAT_MAX_FILE_NAME);
for(;;) {
cprintf("Filename: ");
cscanf("%s", filename);
cprintf("\n");
fat_parse_path_to_cluster(filename);
}
//exec("/test.o65");
cprintf("Done!\n");
return 0;
}

View File

@@ -1,89 +0,0 @@
#include <stdio.h>
#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;
}

View File

@@ -1,14 +1,16 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector
.addr _na ; Reset vector (Doesn't matter, will go back to ROM)
.addr _irq_int ; IRQ/BRK vector
.segment "CODE"
_na:
rti
_nmi_int:
rti
_irq_int:
rti

View File

@@ -6,7 +6,8 @@ TMPBOOTSECT=/tmp/bootsect
TMPMOUNT=/tmp/sd
V=-v
STATUS="status=none"
# STATUS="status=none"
STATUS=
echo "$(tput bold setaf 11)Creating Filesystem$(tput sgr 0)"
sudo mkfs.vfat -F32 $DEVICE -n SUPER6502 $V