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:
1
sw/.gitignore
vendored
1
sw/.gitignore
vendored
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
|
*.o65
|
||||||
*.ko
|
*.ko
|
||||||
*.obj
|
*.obj
|
||||||
*.elf
|
*.elf
|
||||||
|
|||||||
1
sw/irq.c
1
sw/irq.c
@@ -10,7 +10,6 @@ char lastchar;
|
|||||||
|
|
||||||
void handle_irq() {
|
void handle_irq() {
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
char c;
|
|
||||||
|
|
||||||
status = irq_get_status();
|
status = irq_get_status();
|
||||||
|
|
||||||
|
|||||||
109
sw/main.c
109
sw/main.c
@@ -1,11 +1,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "board_io.h"
|
#include "board_io.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "mapper.h"
|
#include "mapper.h"
|
||||||
#include "sd_card.h"
|
#include "sd_card.h"
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
|
#include "o65.h"
|
||||||
|
|
||||||
uint8_t buf[512];
|
uint8_t buf[512];
|
||||||
|
|
||||||
@@ -76,6 +78,17 @@ int main() {
|
|||||||
dos_dentry_t* dos_dentry;
|
dos_dentry_t* dos_dentry;
|
||||||
uint32_t cluster;
|
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;
|
uint16_t reserved_count;
|
||||||
uint32_t sectors_per_fat;
|
uint32_t sectors_per_fat;
|
||||||
@@ -192,14 +205,106 @@ int main() {
|
|||||||
|
|
||||||
cprintf("DOS name: %.8s.%.3s\n", &dos_dentry->filename, &dos_dentry->extension);
|
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("Cluster: %ld\n", cluster);
|
||||||
|
|
||||||
cprintf("File location: %lx\n", data_region_start + (cluster - 2) * 8);
|
cprintf("File location: %lx\n", data_region_start + (cluster - 2) * 8);
|
||||||
|
|
||||||
sd_readblock(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");
|
cprintf("Done!\n");
|
||||||
|
|
||||||
|
|||||||
65
sw/o65.h
Normal file
65
sw/o65.h
Normal 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
41
sw/test_exec/Makefile
Normal 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
43
sw/test_exec/link.ld
Normal 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
3
sw/test_exec/main.c
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
int main() {
|
||||||
|
return 0x41;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user