diff --git a/sw/.gitignore b/sw/.gitignore index 3e1502e129eaed5ec082f67ed43377b86f87602b..ec73f2bb3c2750f223d6c0435f53cd5dcbcd5d40 100644 --- a/sw/.gitignore +++ b/sw/.gitignore @@ -3,6 +3,7 @@ # Object files *.o +*.o65 *.ko *.obj *.elf diff --git a/sw/irq.c b/sw/irq.c index f1baddc0bb486ebf1ae73006d268bf053556b8a2..313ea7d9ca42473676aeae2d642d7cb423ffda34 100644 --- a/sw/irq.c +++ b/sw/irq.c @@ -10,7 +10,6 @@ char lastchar; void handle_irq() { uint8_t status; - char c; status = irq_get_status(); diff --git a/sw/main.c b/sw/main.c index 30332d048133507e5d77d973e1e58c01b22ca932..39423a66240c309e9b824175963faec666220407 100644 --- a/sw/main.c +++ b/sw/main.c @@ -1,11 +1,13 @@ #include <stdint.h> #include <conio.h> +#include <string.h> #include "board_io.h" #include "uart.h" #include "mapper.h" #include "sd_card.h" #include "fat.h" +#include "o65.h" uint8_t buf[512]; @@ -76,6 +78,17 @@ int main() { dos_dentry_t* dos_dentry; uint32_t cluster; + 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; uint16_t reserved_count; uint32_t sectors_per_fat; @@ -192,14 +205,106 @@ int main() { cprintf("DOS name: %.8s.%.3s\n", &dos_dentry->filename, &dos_dentry->extension); - cluster = (dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; + cluster = ((uint32_t)dos_dentry->first_cluster_h << 16) + dos_dentry->first_cluster_l; cprintf("Cluster: %ld\n", cluster); cprintf("File location: %lx\n", data_region_start + (cluster - 2) * 8); sd_readblock(data_region_start + (cluster - 2) * 8); - cprintf("File contents: %s\n", buf); + header = (o65_header_t*)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) { + cprintf("Found a valid o65 file!\n\n"); + + cprintf("tbase: %x\n", header->tbase); + cprintf("tlen: %x\n", header->tlen); + cprintf("dbase: %x\n", header->dbase); + cprintf("dlen: %x\n", header->dlen); + cprintf("bbase: %x\n", header->bbase); + cprintf("blen: %x\n", header->blen); + cprintf("zbase: %x\n", header->zbase); + cprintf("zlen: %x\n", header->zlen); + cprintf("stack: %x\n", header->stack); + cprintf("\n"); + + 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*)(buf + sizeof(o65_header_t)); + while (o65_opt->olen) + { + cprintf("Option Length: %d\n", o65_opt->olen); + cprintf("Option Type: %x ", o65_opt->type); + switch (o65_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 (o65_opt->type != O65_OPT_OS) { + for (i = 0; i < o65_opt->olen - 2; i++) { + cprintf("%c", o65_opt->data[i]); + } + } else { + cprintf("%x", o65_opt->data[0]); + } + cprintf("\n\n"); + o65_opt = (o65_opt_t*)((uint8_t*)o65_opt + o65_opt->olen); + } + + seg_ptr = (uint8_t*)o65_opt + 1; + + cprintf("Code: \n"); + for (i = 0; i < code_len; i++) { + cprintf("%x ", seg_ptr[i]); + } + cprintf("\n\n"); + + memcpy((uint8_t*)code_base, seg_ptr, code_len); + + seg_ptr+=code_len; + + cprintf("Data: \n"); + for (i = 0; i < data_len; i++) { + cprintf("%x ", seg_ptr[i]); + } + cprintf("\n\n"); + + memcpy((uint8_t*)data_base, seg_ptr, data_len); + + cprintf("Memory Copied!\n"); + cprintf("Code: \n"); + for (i = 0; i < code_len; i++) { + cprintf("%x ", code_base[i]); + } + cprintf("\n\n"); + cprintf("Data: \n"); + for (i = 0; i < data_len; i++) { + cprintf("%x ", data_base[i]); + } + cprintf("\n\n"); + + exec = (uint8_t (*)(void))code_base; + + ret = 0; + + ret = (*exec)(); + + cprintf("ret: %x\n", ret); + + + } + cprintf("Done!\n"); diff --git a/sw/o65.h b/sw/o65.h new file mode 100644 index 0000000000000000000000000000000000000000..1871ec91f20817fa3181e46a2650808a311b1a09 --- /dev/null +++ b/sw/o65.h @@ -0,0 +1,65 @@ +#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; + +#endif + + diff --git a/sw/test_exec/Makefile b/sw/test_exec/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cfcfe6d37a9a1ba1f7dc18478f5c20e318de0952 --- /dev/null +++ b/sw/test_exec/Makefile @@ -0,0 +1,41 @@ +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=test + +BIN=$(NAME).o65 +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: $(BIN) + +$(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 + rm -rf $(TEST_OBJS) $(TEST_BIN) + diff --git a/sw/test_exec/link.ld b/sw/test_exec/link.ld new file mode 100644 index 0000000000000000000000000000000000000000..ade4e99ac06c63a24c5da88e15c44016cc41f7f1 --- /dev/null +++ b/sw/test_exec/link.ld @@ -0,0 +1,43 @@ +MEMORY +{ + ZP: start = $0, size = $100, type = rw, define = yes; + SDRAM: start = $1000, size = $6ef0, type = rw, define = yes; +} + +FILES { + %O: format = o65; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + DATA: load = SDRAM, type = rw, define = yes, run = SDRAM; + BSS: load = SDRAM, type = bss, define = yes; + HEAP: load = SDRAM, type = bss, optional = yes; + STARTUP: load = SDRAM, type = ro; + ONCE: load = SDRAM, type = ro, optional = yes; + CODE: load = SDRAM, type = ro; + RODATA: load = SDRAM, type = ro; +} + +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 + +} + +FORMATS { + o65: os = 5, version = 0, type = small, + export = _main; + } diff --git a/sw/test_exec/main.c b/sw/test_exec/main.c new file mode 100644 index 0000000000000000000000000000000000000000..ad40be35a6eacf99b0ca7f3bb26f4349c4d1ef5f --- /dev/null +++ b/sw/test_exec/main.c @@ -0,0 +1,3 @@ +int main() { + return 0x41; +} \ No newline at end of file