diff --git a/sw/exec.c b/sw/exec.c new file mode 100644 index 0000000..911d22a --- /dev/null +++ b/sw/exec.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#include "fat.h" +#include "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); + + + } +} \ No newline at end of file diff --git a/sw/exec.h b/sw/exec.h new file mode 100644 index 0000000..37bd21a --- /dev/null +++ b/sw/exec.h @@ -0,0 +1,6 @@ +#ifndef _EXEC_H +#define _EXEC_H + +void exec(char* filename); + +#endif \ No newline at end of file diff --git a/sw/fat.c b/sw/fat.c new file mode 100644 index 0000000..eadeb96 --- /dev/null +++ b/sw/fat.c @@ -0,0 +1,73 @@ +#include +#include + +#include "fat.h" +#include "sd_card.h" + +uint8_t fat_buf[512]; + +static full_bpb_t bpb; + +static uint32_t data_region_start; + +void fat_print_pbp_info(ebpb_t* epbp){ + cprintf("Bytes per sector: %d\n", epbp->bpb3.bpb2.bytes_per_sector); + cprintf("Sectors per cluster: %d\n", epbp->bpb3.bpb2.sectors_per_cluster); + cprintf("Reserved Sectors: %d\n", epbp->bpb3.bpb2.reserved_sectors); + cprintf("Fat Count: %d\n", epbp->bpb3.bpb2.fat_count); + cprintf("Max Dir Entries: %d\n", epbp->bpb3.bpb2.max_dir_entries); + cprintf("Total Sector Count: %d\n", epbp->bpb3.bpb2.total_sector_count); + cprintf("Media Descriptor: 0x%x\n", epbp->bpb3.bpb2.media_descriptor); + cprintf("Sectors per Fat: %d\n", epbp->bpb3.bpb2.sectors_per_fat); + cprintf("\n"); + + cprintf("Sectors per track: %d\n", epbp->bpb3.sectors_per_track); + cprintf("Head Count: %d\n", epbp->bpb3.head_count); + cprintf("Hidden Sector Count: %ld\n", epbp->bpb3.hidden_sector_count); + cprintf("Logical Sector Count: %ld\n", epbp->bpb3.logical_sector_count); + cprintf("Sectors per Fat: %ld\n", epbp->bpb3.sectors_per_fat); + cprintf("Extended Flags: 0x%x\n", epbp->bpb3.extended_flags); + cprintf("Version: %d\n", epbp->bpb3.version); + cprintf("Root Cluster: 0x%lx\n", epbp->bpb3.root_cluster); + cprintf("System Information: 0x%x\n", epbp->bpb3.system_information); + cprintf("Backup Boot Sector: 0x%x\n", epbp->bpb3.backup_boot_sector); + cprintf("\n"); + + cprintf("Drive Number: %d\n", epbp->drive_num); + cprintf("Extended Signature: 0x%x\n", epbp->extended_signature); + cprintf("Volume ID: 0x%lx\n", epbp->volume_id); + cprintf("Partition Label: %.11s\n", &epbp->partition_label); + cprintf("Partition Label: %.8s\n", &epbp->filesystem_type); + cprintf("\n"); +} + +void fat_init(){ + sd_readblock(0, fat_buf); + + memcpy(&bpb, &fat_buf[11], sizeof(ebpb_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; +} + +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); +} \ No newline at end of file diff --git a/sw/fat.h b/sw/fat.h index c61b152..5e9ee54 100644 --- a/sw/fat.h +++ b/sw/fat.h @@ -3,6 +3,8 @@ #include +extern uint8_t fat_buf[]; + typedef struct { uint16_t bytes_per_sector; uint8_t sectors_per_cluster; @@ -39,6 +41,34 @@ typedef struct { 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]; @@ -74,4 +104,8 @@ typedef struct { uint32_t file_size; } dos_dentry_t; +void fat_print_pbp_info(ebpb_t* epbp); +void fat_init(); +void fat_read(char* filename, void* buf); + #endif \ No newline at end of file diff --git a/sw/main.c b/sw/main.c index 39423a6..23cdb63 100644 --- a/sw/main.c +++ b/sw/main.c @@ -8,96 +8,13 @@ #include "sd_card.h" #include "fat.h" #include "o65.h" +#include "exec.h" uint8_t buf[512]; -void sd_readblock(uint32_t addr) { - 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++){ - buf[i] = sd_card_read_byte(); - } - - /* - for (i = 0; i < 512; i++){ - if (i % 16 == 0) - cprintf("\n %2x: ", i); - cprintf("%2x ", buf[i]); - } - */ - - cprintf("\n"); -} - -void print_pbp_info(ebpb_t* epbp){ - cprintf("Bytes per sector: %d\n", epbp->bpb3.bpb2.bytes_per_sector); - cprintf("Sectors per cluster: %d\n", epbp->bpb3.bpb2.sectors_per_cluster); - cprintf("Reserved Sectors: %d\n", epbp->bpb3.bpb2.reserved_sectors); - cprintf("Fat Count: %d\n", epbp->bpb3.bpb2.fat_count); - cprintf("Max Dir Entries: %d\n", epbp->bpb3.bpb2.max_dir_entries); - cprintf("Total Sector Count: %d\n", epbp->bpb3.bpb2.total_sector_count); - cprintf("Media Descriptor: 0x%x\n", epbp->bpb3.bpb2.media_descriptor); - cprintf("Sectors per Fat: %d\n", epbp->bpb3.bpb2.sectors_per_fat); - cprintf("\n"); - - cprintf("Sectors per track: %d\n", epbp->bpb3.sectors_per_track); - cprintf("Head Count: %d\n", epbp->bpb3.head_count); - cprintf("Hidden Sector Count: %ld\n", epbp->bpb3.hidden_sector_count); - cprintf("Logical Sector Count: %ld\n", epbp->bpb3.logical_sector_count); - cprintf("Sectors per Fat: %ld\n", epbp->bpb3.sectors_per_fat); - cprintf("Extended Flags: 0x%x\n", epbp->bpb3.extended_flags); - cprintf("Version: %d\n", epbp->bpb3.version); - cprintf("Root Cluster: 0x%lx\n", epbp->bpb3.root_cluster); - cprintf("System Information: 0x%x\n", epbp->bpb3.system_information); - cprintf("Backup Boot Sector: 0x%x\n", epbp->bpb3.backup_boot_sector); - cprintf("\n"); - - cprintf("Drive Number: %d\n", epbp->drive_num); - cprintf("Extended Signature: 0x%x\n", epbp->extended_signature); - cprintf("Volume ID: 0x%lx\n", epbp->volume_id); - cprintf("Partition Label: %.11s\n", &epbp->partition_label); - cprintf("Partition Label: %.8s\n", &epbp->filesystem_type); - cprintf("\n"); -} - int main() { int i; - uint8_t sw; - uint32_t resp; - ebpb_t* epbp; - fs_info_sector_t* fsis; - vfat_dentry_t* vfat_dentry; - 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; - uint8_t fat_count; - - uint32_t data_region_start; - - char s[16]; - s[15] = 0; + uint16_t rca; clrscr(); cprintf("Hello, world!\n"); @@ -110,218 +27,17 @@ int main() { cprintf("Enabling Mapper\n"); mapper_enable(1); + sd_init(); - // This will read a 512 block from the sd card. - // The RCA is hard coded for the one that I have on hand as responses - // are not implemented yet. - sd_card_command(0, 0); + rca = sd_get_rca(); + cprintf("rca: %x\n", rca); - 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); - - sd_card_command(0, 3); - sd_card_resp(&resp); - cprintf("CMD3: %lx\n", resp); - - sd_card_command(0x59b40000, 7); - sd_card_resp(&resp); - cprintf("CMD7: %lx\n", resp); - - sd_card_command(0x59b41000, 13); - sd_card_resp(&resp); - cprintf("CMD13: %lx\n", resp); - - sd_readblock(0); - - epbp = (ebpb_t*)&buf[11]; - - print_pbp_info(epbp); - - cprintf("Boot Signature: %x %x\n", buf[510], buf[511]); - - reserved_count = epbp->bpb3.bpb2.reserved_sectors; - fat_count = epbp->bpb3.bpb2.fat_count; - sectors_per_fat = epbp->bpb3.sectors_per_fat; - - sd_readblock(1); - - fsis = (fs_info_sector_t*)&buf[0]; - - cprintf("Free Data clusters: %ld\n", fsis->free_data_clusters); - cprintf("Last allocated data cluster: %ld\n", fsis->last_allocated_data_cluster); - - cprintf("32 reserved sectors, reading from sector 32...\n"); - sd_readblock(32); - cprintf("CLUST_0: %08lx\n", *(uint32_t*)&buf[0]); - cprintf("CLUST_1: %08lx\n", *(uint32_t*)&buf[1*4]); - - cprintf("Root cluster: %08lx\n", *(uint32_t*)&buf[2*4]); - - data_region_start = reserved_count + fat_count*sectors_per_fat; - cprintf("Data Region starting sector: %lx\n", data_region_start); - cprintf("Reading root directory entry...\n"); - - cprintf("%ld\n", data_region_start*512); - - sd_readblock(data_region_start); - - vfat_dentry = (vfat_dentry_t*)buf; - while(vfat_dentry->sequence_number == 0xe5) - vfat_dentry++; - - - cprintf("Sequence: %x\n", vfat_dentry->sequence_number); - cprintf("Name: "); - for (i = 0;; i++) { // this will not work for proper vfat names - if (i < 5) { - if (!vfat_dentry->filename0[i]) - break; - cprintf("%c", vfat_dentry->filename0[i]); - } else if (i < 11) { - if (!vfat_dentry->filename0[i]) - break; - cprintf("%c", vfat_dentry->filename1[i-5]); - } else { - break; - } - } - cprintf("\n"); - dos_dentry = (dos_dentry_t*)(vfat_dentry + 1); - - cprintf("DOS name: %.8s.%.3s\n", &dos_dentry->filename, &dos_dentry->extension); - - 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); - - 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); - - - } + sd_select_card(rca); + fat_init(); + exec("/test.o65"); cprintf("Done!\n"); - - - while (1) { - - sw = sw_read(); - led_set(sw); - - cscanf("%15s", s); - cprintf("\n"); - for (i = 0; i < 16; i++) - cprintf("s[%d]=%c ", i, s[i]); - cprintf("\n"); - cprintf("Read string: %s\n", s); - } - return 0; } diff --git a/sw/o65.c b/sw/o65.c new file mode 100644 index 0000000..cc908a9 --- /dev/null +++ b/sw/o65.c @@ -0,0 +1,28 @@ +#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"); +} \ No newline at end of file diff --git a/sw/o65.h b/sw/o65.h index 1871ec9..88d1845 100644 --- a/sw/o65.h +++ b/sw/o65.h @@ -60,6 +60,8 @@ typedef struct { 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/sd_card.c b/sw/sd_card.c new file mode 100644 index 0000000..24646df --- /dev/null +++ b/sw/sd_card.c @@ -0,0 +1,75 @@ +#include +#include + +#include "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"); +} diff --git a/sw/sd_card.h b/sw/sd_card.h index 8dbe972..b28d75a 100644 --- a/sw/sd_card.h +++ b/sw/sd_card.h @@ -3,6 +3,12 @@ #include +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);