Merge branch 'exec' into 'master'

Add reading, parsing, and basic executing of o65 files

See merge request bslathi19/super6502!13
This commit is contained in:
Byron Lathi
2022-04-17 00:34:40 +00:00
7 changed files with 260 additions and 3 deletions

1
sw/.gitignore vendored
View File

@@ -3,6 +3,7 @@
# Object files
*.o
*.o65
*.ko
*.obj
*.elf

View File

@@ -10,7 +10,6 @@ char lastchar;
void handle_irq() {
uint8_t status;
char c;
status = irq_get_status();

109
sw/main.c
View File

@@ -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");

65
sw/o65.h Normal file
View File

@@ -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

41
sw/test_exec/Makefile Normal file
View File

@@ -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)

43
sw/test_exec/link.ld Normal file
View File

@@ -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;
}

3
sw/test_exec/main.c Normal file
View File

@@ -0,0 +1,3 @@
int main() {
return 0x41;
}