diff --git a/Makefile b/Makefile index 3d26841..0eb6dd8 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,10 @@ -CC = clang -CFLAGS = -O3 -arch i386 -arch x86_64 -Wno-deprecated-declarations -LFLAGS = -framework OpenGL -framework GLUT - all: shoebill shoebill: make_core -# shoebill: make_core test.c -# $(CC) $(LFLAGS) $(CFLAGS) -L intermediates -l shoebill_core test.c -o shoebill make_core: $(MAKE) -C core -j 4 clean: rm -rf intermediates - rm -f shoebill diff --git a/core/coff.c b/core/coff.c index 7fbef60..eb9db2a 100644 --- a/core/coff.c +++ b/core/coff.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "shoebill.h" #include "coff.h" @@ -40,25 +41,37 @@ void symb_inorder(rb_node *cur) { symb_inorder(cur->right); } +#define _coff_buf_seek(__len) ({ \ + uint32_t _result = 1, _len=(__len); \ + if (_len > buflen) _result = 0; \ + else bufptr = _len; \ + _result; \ +}) + +#define _coff_buf_read(_dst, __len) ({\ + uint32_t _result = 1, _len=(__len); \ + if ((bufptr + _len) > buflen) \ + _result = 0; \ + else {\ + memcpy((_dst), buf+bufptr, _len); \ + bufptr += _len; \ + } \ + _result; \ +}) + + // Given a path to a COFF binary, create a coff_file structure and return a pointer. // God help you if you want to free it. -coff_file* coff_parser(const char *path) +coff_file* coff_parse(uint8_t *buf, uint32_t buflen) { - FILE *f; uint8_t rawhead[20], *ptr; uint32_t i; coff_file *cf = NULL; - - // Open the file - f = fopen(path, "r"); - if (!f) { - printf("coff_parser: I couldn't open that binary for reading (%s)\n", path); - goto fail; - } + uint32_t bufptr = 0; // Pull out 20 bytes (the file header) - if (fread(rawhead, 20, 1, f) != 1) { - printf("coff_parser: error: this binary is missing its file header\n"); + if (!_coff_buf_read(rawhead, 20)) { + printf("coff_parse: error: this binary is missing its file header\n"); goto fail; } @@ -86,7 +99,7 @@ coff_file* coff_parser(const char *path) // pull out cf->opt_header bytes (a.out-format header, I guess?) if (cf->opt_header_len > 0) { uint8_t *opt = malloc(cf->opt_header_len); - if (fread(opt, cf->opt_header_len, 1, f) != 1) { + if (!_coff_buf_read(opt, cf->opt_header_len)) { printf("coff_parse: I ran out of data pulling the optional header (%u bytes)\n", cf->opt_header_len); free(opt); goto fail; @@ -99,7 +112,7 @@ coff_file* coff_parser(const char *path) for (i=0; inum_sections; i++) { // read the header uint8_t rawsec[40]; - if (fread(rawsec, 40, 1, f) != 1) { + if (!_coff_buf_read(rawsec, 40)) { printf("coff_parse: I ran out of data pulling section #%u\n", i+1); goto fail; } @@ -139,14 +152,14 @@ coff_file* coff_parser(const char *path) } // seek to the position in the binary that holds this section's raw data - if (fseek(f, cf->sections[i].data_ptr, SEEK_SET) != 0) { + if (!_coff_buf_seek(cf->sections[i].data_ptr)) { printf("coff_parse: I couldn't seek to 0x%x in section %u\n", cf->sections[i].data_ptr, i+1); goto fail; } // load the data and attach it to the section struct data = malloc(cf->sections[i].sz); // FIXME: sz might not be a sane value - if (fread(data, cf->sections[i].sz, 1, f) != 1) { + if (!_coff_buf_read(data, cf->sections[i].sz)) { printf("coff_parse: I couldn't fread section %u (%s)'s data (%u bytes)\n", i+1, cf->sections[i].name, cf->sections[i].sz); free(data); goto fail; @@ -164,14 +177,14 @@ coff_file* coff_parser(const char *path) cf->symbols = (coff_symbol*)calloc(sizeof(coff_symbol), cf->num_symbols); // Seek to the symbol table - if (fseek(f, cf->symtab_offset, SEEK_SET) != 0) { + if (!_coff_buf_seek(cf->symtab_offset)) { printf("coff_parse: I couldn't seek to symtab_offset, 0x%x\n", cf->symtab_offset); goto fail; } for (i=0; i < cf->num_symbols; i++) { uint8_t raw_symb[18]; - if (fread(raw_symb, 18, 1, f) != 1) { + if (!_coff_buf_read(raw_symb, 18)) { printf("coff_parse: I ran out of data pulling symbol #%u\n", i+1); goto fail; } @@ -185,11 +198,11 @@ coff_file* coff_parser(const char *path) // printf("Loading from external: base idx=0x%x, offset=%u, addr=0x%x\n", idx-offset, offset, idx); - if (fseek(f, idx, SEEK_SET) != 0) { + if (!_coff_buf_seek(idx)) { printf("coff_parse: I ran out of data pulling symbol %u's name (idx=0x%x)\n", i+1, idx); goto fail; } - for (j=0; (fread(&tmp_name[j], 1, 1, f)==1) && tmp_name[j]; j++) { + for (j=0; (_coff_buf_read(&tmp_name[j], 1)) && tmp_name[j]; j++) { if (j >= 255) { // printf("coff_parse: this symbol's name is too long: %u\n", i+1); goto fail; @@ -198,10 +211,7 @@ coff_file* coff_parser(const char *path) cf->symbols[i].name = malloc(j+1); memcpy(cf->symbols[i].name, tmp_name, j); cf->symbols[i].name[j] = 0; - fseek(f, cf->symtab_offset + (i+1)*18, SEEK_SET); - //printf("cf->symtab_offset = 0x%x, i=%u, (i+1)*18 = %u\n", - //cf->symtab_offset, i, (i+1)*18); - //printf("seeking back to 0x%x\n", cf->symtab_offset + (i+1)*18); + _coff_buf_seek(cf->symtab_offset + (i+1)*18); } else { uint8_t tmp_name[9]; @@ -257,6 +267,28 @@ fail: return NULL; } +coff_file* coff_parse_from_path(const char *path) +{ + FILE *f = fopen(path, "r"); + uint8_t *buf = malloc(1); + uint32_t i=0, tmp; + coff_file *coff; + + do { + buf = realloc(buf, i + 128*1024); + assert(buf); + tmp = fread(buf+i, 1, 128*1024, f); + i += tmp; + + // don't load more than 64mb - there are surely no 64MB A/UX kernels + } while ((tmp > 0) && (i < 64*1024*1024)); + + + coff = coff_parse(buf, i); + free(buf); + return coff; +} + // dump some data about a coff_file structure void print_coff_info(coff_file *coff) { diff --git a/core/coff.h b/core/coff.h index 75ae594..8bace64 100644 --- a/core/coff.h +++ b/core/coff.h @@ -76,7 +76,8 @@ typedef struct { coff_symbol* coff_find_func(coff_file *coff, uint32_t addr); coff_symbol* coff_find_symbol(coff_file *coff, const char *name); -coff_file* coff_parser(const char *path); +coff_file* coff_parse(uint8_t *buf, uint32_t buflen); +coff_file* coff_parse_from_path(const char *path); uint32_t be2native (uint8_t **dat, uint32_t bytes); void print_coff_info(coff_file *coff); diff --git a/core/core_api.c b/core/core_api.c index 3bfee7f..8ea2886 100644 --- a/core/core_api.c +++ b/core/core_api.c @@ -641,8 +641,8 @@ uint32_t shoebill_initialize(shoebill_control_t *control) uint32_t i, j, pc = 0xffffffff; coff_file *coff = NULL; scsi_device_t disks[8]; - uint8_t *rom_data = NULL; - uint32_t rom_size = 0; + uint8_t *rom_data = NULL, *kernel_data = NULL; + uint32_t rom_size = 0, kernel_size; memset(&disks[0], 0, 8 * sizeof(scsi_device_t)); memset(&shoe, 0, sizeof(global_shoebill_context_t)); @@ -657,16 +657,26 @@ uint32_t shoebill_initialize(shoebill_control_t *control) else if (!_load_rom(control, &rom_data, &rom_size)) goto fail; - // Try to open the disk images - if (!_open_disk_images(control, disks)) - goto fail; - // Try to load the A/UX kernel if (control->aux_kernel_path == NULL) { sprintf(control->error_msg, "No A/UX kernel specified\n"); goto fail; } - coff = coff_parser(control->aux_kernel_path); + else if (!control->scsi_devices[0].path || strlen((char*)control->scsi_devices[0].path)==0) { + sprintf(control->error_msg, "The root A/UX disk needs to be at scsi ID 0\n"); + goto fail; + } + + // Load the kernel from the disk at scsi id #0 + kernel_data = shoebill_extract_kernel((char*)control->scsi_devices[0].path, + control->aux_kernel_path, + control->error_msg, + &kernel_size); + if (!kernel_data) + goto fail; + + coff = coff_parse(kernel_data, kernel_size); + free(kernel_data); if (coff == NULL) { sprintf(control->error_msg, "Can't open that A/UX kernel [%s]\n", @@ -675,15 +685,13 @@ uint32_t shoebill_initialize(shoebill_control_t *control) } shoe.coff = coff; + // Try to open the disk images + if (!_open_disk_images(control, disks)) + goto fail; // Allocate and configure the rom and memory space - /*if (control->ram_size > (256 * 1024 * 1024)) { - // I think A/UX will go insane if you give it >256MB of memory - sprintf(control->error_msg, "%u bytes is too much memory\n", control->ram_size); - goto fail; - } - else */if (control->ram_size < (1024*1024)) { + if (control->ram_size < (1024*1024)) { sprintf(control->error_msg, "%u bytes is too little ram\n", control->ram_size); goto fail; } @@ -712,12 +720,6 @@ uint32_t shoebill_initialize(shoebill_control_t *control) if (!_load_aux_kernel(control, coff, &pc)) goto fail; - // HACK: -// for (i=0; i<0x4000; i++) { -// uint8_t c = pget(AUX_LOMEM_OFFSET + i, 1); -// pset(i, 1, c); -// } - /* * Load it all into the internal global shoebill state * (Can't fail after this point) diff --git a/core/filesystem.c b/core/filesystem.c index 74eab03..89280be 100644 --- a/core/filesystem.c +++ b/core/filesystem.c @@ -919,7 +919,7 @@ static uint8_t ufs_load_cylinder_group(ufs_t *mount, uint32_t frag_offset, ufs_c uint32_t numfrags = sizeof(ufs_cylinder_group_t) / mount->frag_size; numfrags += ((sizeof(ufs_cylinder_group_t) % mount->frag_size) != 0); - uint8_t *buf = p_alloc(mount->pool, numfrags * mount->frag_size); + uint8_t *buf = p_alloc(mount->pool, (numfrags+1) * mount->frag_size); uint32_t i; for (i=0; i <= numfrags; i++) diff --git a/core/mem.c b/core/mem.c index 3d4b535..6c69d81 100644 --- a/core/mem.c +++ b/core/mem.c @@ -32,23 +32,19 @@ static void translate_logical_addr(); -void _logical_get (void); -void logical_get (void) { - const uint32_t addr = shoe.logical_addr; - // uint8_t super = sr_s(); - - _logical_get(); - -// if ((addr >= 0x100) && (addr < 0x2000)) { -// printf("LOMEM READ: 0x%08x = 0x%llx\n", addr, shoe.logical_dat); -// } -} - void physical_get (void) { - switch (shoe.physical_addr) { - case 0 ... 0x3FFFFFFF: { - void *addr = &shoe.physical_mem_base[shoe.physical_addr & (shoe.physical_mem_size-1)]; + switch (shoe.physical_addr >> 28) { + case 0: + case 1: + case 2: + case 3: { // RAM + void *addr; + if (shoe.physical_addr >= shoe.physical_mem_size) + addr = &shoe.physical_mem_base[shoe.physical_addr % shoe.physical_mem_size]; + else + addr = &shoe.physical_mem_base[shoe.physical_addr]; + switch (shoe.physical_size) { case 4: shoe.physical_dat = ntohl(*(uint32_t*)addr); @@ -72,7 +68,7 @@ void physical_get (void) { } assert(!"never get here"); } - case 0x40000000 ... 0x4FFFFFFF: { // ROM + case 4: { // ROM void *addr = &shoe.physical_rom_base[shoe.physical_addr & (shoe.physical_rom_size-1)]; switch (shoe.physical_size) { case 4: @@ -96,7 +92,7 @@ void physical_get (void) { } assert(!"never get here"); } - case 0x50000000 ... 0x50ffffff: { // IO + case 5: { // IO switch (shoe.physical_addr & 0x5003ffff) { case 0x50000000 ... 0x50001fff: // VIA1 via_reg_read(); @@ -129,18 +125,28 @@ void physical_get (void) { // assert(!"physical_get: got read to SCSI hi\n"); return ; case 0x50014000 ... 0x50015fff: // Sound - printf("physical_get: got read to sound\n"); + //printf("physical_get: got read to sound\n"); return ; case 0x50016000 ... 0x50017fff: // SWIM (IWM?) // printf("physical_get: got read to IWM\n"); shoe.physical_dat = iwm_dma_read(); return ; default: - printf("physical_get: got read to UNKNOWN IO ADDR %x\n", shoe.physical_addr); + //printf("physical_get: got read to UNKNOWN IO ADDR %x\n", shoe.physical_addr); return ; } } - case 0x60000000 ... 0xefffffff: { // Nubus super slot space + case 0xf: { // Nubus standard slot space + const uint32_t slot = (shoe.physical_addr >> 24) & 0xf; + if (shoe.slots[slot].connected) + shoe.physical_dat = shoe.slots[slot].read_func(shoe.physical_addr, + shoe.physical_size, + slot); + else + shoe.abort = 1; // throw a bus error for reads to disconnected slots + return ; + } + default: { // Nubus super slot space const uint32_t slot = shoe.physical_addr >> 28; if (shoe.slots[slot].connected) shoe.physical_dat = shoe.slots[slot].read_func(shoe.physical_addr, @@ -151,32 +157,22 @@ void physical_get (void) { // XXX: Do super slot accesses raise bus errors? return ; } - case 0xf0000000 ... 0xffffffff: { - const uint32_t slot = (shoe.physical_addr >> 24) & 0xf; - if (shoe.slots[slot].connected) - shoe.physical_dat = shoe.slots[slot].read_func(shoe.physical_addr, - shoe.physical_size, - slot); - else - shoe.abort = 1; // throw a bus error for reads to disconnected slots - return ; - } - - default: { - printf("physical_get: I got an access to 0x%x (sz=%u), but I don't know how to handle it...\n", - shoe.physical_addr, shoe.physical_size); - shoe.physical_dat = 0; - return ; - } } } void physical_set (void) { - switch (shoe.physical_addr) { - case 0 ... 0x3FFFFFFF: { // The first RAM bank (64MB) + switch (shoe.physical_addr >> 28) { + case 0: + case 1: + case 2: + case 3: { // RAM const uint32_t dat = htonl(shoe.physical_dat) >> ((4-shoe.physical_size)*8); - void *addr = &shoe.physical_mem_base[shoe.physical_addr & (shoe.physical_mem_size-1)]; + void *addr; + if (shoe.physical_addr >= shoe.physical_mem_size) + addr = &shoe.physical_mem_base[shoe.physical_addr % shoe.physical_mem_size]; + else + addr = &shoe.physical_mem_base[shoe.physical_addr]; switch (shoe.physical_size) { case 4: *((uint32_t*)addr) = dat; @@ -201,11 +197,11 @@ void physical_set (void) } assert(!"never get here"); } - case 0x40000000 ... 0x4FFFFFFF: { // ROM + case 4: { // ROM // Nothing happens when you try to modify ROM return ; } - case 0x50000000 ... 0x50ffffff: { // IO + case 5: { // IO switch (shoe.physical_addr & 0x5003ffff) { case 0x50000000 ... 0x50001fff: // VIA1 via_reg_write(); @@ -239,20 +235,11 @@ void physical_set (void) iwm_dma_write(); return ; default: - printf("physical_set: got write to UNKNOWN IO ADDR %x\n", shoe.physical_addr); + //printf("physical_set: got write to UNKNOWN IO ADDR %x\n", shoe.physical_addr); return ; } } - case 0x60000000 ... 0xefffffff: { // Nubus super slot space - const uint32_t slot = shoe.physical_addr >> 28; - if (shoe.slots[slot].connected) - shoe.slots[slot].write_func(shoe.physical_addr, - shoe.physical_size, - shoe.physical_dat, - slot); - return ; - } - case 0xf0000000 ... 0xffffffff: { // Nubus standard slot space + case 0xf: { // Nubus standard slot space const uint32_t slot = (shoe.physical_addr >> 24) & 0xf; if (shoe.slots[slot].connected) shoe.slots[slot].write_func(shoe.physical_addr, @@ -262,16 +249,19 @@ void physical_set (void) return ; // Writing to a disconnected slot won't cause a bus error on macii } - - default: { - printf("physical_set: I got a write (addr=0x%x) (val=0x%llx) (sz=%u), but I don't know how to handle it...\n", - shoe.physical_addr, shoe.physical_dat, shoe.physical_size); + default: { // Nubus super slot space + const uint32_t slot = shoe.physical_addr >> 28; + if (shoe.slots[slot].connected) + shoe.slots[slot].write_func(shoe.physical_addr, + shoe.physical_size, + shoe.physical_dat, + slot); return ; } } } -void _logical_get (void) +void logical_get (void) { // If address translation isn't enabled, this is a physical address @@ -298,15 +288,15 @@ void _logical_get (void) shoe.logical_is_write = 0; - // If the the data access will wrap across multiple pages, then fuck + // This read crosses a page boundary if ((pageoffset + logical_size - 1) >> ps) { const uint32_t addr_a = shoe.logical_addr; const uint32_t size_b = (pageoffset + logical_size) & pagemask; const uint32_t size_a = shoe.logical_size - size_b; const uint32_t addr_b = addr_a + size_a; - printf("ps = %u, pagesize=%u, pagemask=%x, pageoffset=%x\n", ps, pagesize, pagemask, pageoffset); - printf("multiple page get: addr_a=0x%08x size_a=%u addr_b=0x%08x size_b=%u\n", addr_a, size_a, addr_b, size_b); + // printf("ps = %u, pagesize=%u, pagemask=%x, pageoffset=%x\n", ps, pagesize, pagemask, pageoffset); + // printf("multiple page get: addr_a=0x%08x size_a=%u addr_b=0x%08x size_b=%u\n", addr_a, size_a, addr_b, size_b); shoe.logical_addr = addr_a; shoe.logical_size = size_a; translate_logical_addr(); @@ -338,11 +328,11 @@ void _logical_get (void) return ; } - printf("multiple_page_get: p_addr_a = 0x%08x, p_addr_b = 0x%08x\n", p_addr_a, p_addr_b); + // printf("multiple_page_get: p_addr_a = 0x%08x, p_addr_b = 0x%08x\n", p_addr_a, p_addr_b); shoe.logical_dat = (fetch_a << (size_b*8)) | shoe.physical_dat; - printf("multiple_page_get: logical_dat = (%llx | %llx) = %llx\n", fetch_a, shoe.physical_dat, shoe.logical_dat); + // printf("multiple_page_get: logical_dat = (%llx | %llx) = %llx\n", fetch_a, shoe.physical_dat, shoe.logical_dat); return ; } @@ -365,16 +355,6 @@ void _logical_get (void) void logical_set (void) { - if ((shoe.logical_addr >= 0xaf2) && (shoe.logical_addr < 0xaf6) && (shoe.logical_size == 1) && ((shoe.logical_dat&0xff) == 0xff)) { - shoe.logical_dat = 0; - } -// if ((shoe.logical_addr >= 0x12fffff6) && (shoe.logical_addr <= 0x12ffffff)) -// printf("aux3: setting 0x%08x = 0x%x\n", shoe.logical_addr, (uint32_t)shoe.logical_dat); -// -// if ((shoe.logical_addr >= 0x100) && (shoe.logical_addr < 0x2000)) { -// printf("LOMEM WRITE: 0x%08x = 0x%x\n", shoe.logical_addr, (uint32_t) shoe.logical_dat); -// } - // If address translation isn't enabled, this is a physical address if (!tc_enable()) { shoe.physical_addr = shoe.logical_addr; @@ -395,7 +375,7 @@ void logical_set (void) // Make the translate function fail if the page is write-protected shoe.logical_is_write = 1; - // If the the data access will wrap across multiple pages, then fuck + // This write crosses a page boundary if ((pageoffset + logical_size - 1) >> ps) { const uint32_t addr_a = shoe.logical_addr; const uint32_t size_b = (pageoffset + logical_size) & pagemask; @@ -404,8 +384,8 @@ void logical_set (void) const uint64_t data_a = shoe.logical_dat >> (size_b*8); const uint64_t data_b = bitchop_64(shoe.logical_dat, size_b*8); - printf("ps = %u, pagesize=%u, pagemask=%x, pageoffset=%x\n", ps, pagesize, pagemask, pageoffset); - printf("multiple page set: addr_a=0x%08x size_a=%u addr_b=0x%08x size_b=%u\n", addr_a, size_a, addr_b, size_b); + // printf("ps = %u, pagesize=%u, pagemask=%x, pageoffset=%x\n", ps, pagesize, pagemask, pageoffset); + // printf("multiple page set: addr_a=0x%08x size_a=%u addr_b=0x%08x size_b=%u\n", addr_a, size_a, addr_b, size_b); shoe.logical_addr = addr_a; shoe.logical_size = size_a; @@ -421,7 +401,7 @@ void logical_set (void) return ; const uint32_t p_addr_b = shoe.physical_addr; - printf("multiple page set: paddr_a=0x%08x (data_a=0x%llx) paddr_b=0x%08x (data_b=0x%llx) (orig_dat=0x%llx)\n", p_addr_a, data_a, p_addr_b, data_b, shoe.logical_dat); + // printf("multiple page set: paddr_a=0x%08x (data_a=0x%llx) paddr_b=0x%08x (data_b=0x%llx) (orig_dat=0x%llx)\n", p_addr_a, data_a, p_addr_b, data_b, shoe.logical_dat); shoe.physical_addr = p_addr_a; shoe.physical_size = size_a; @@ -483,9 +463,8 @@ struct { static void translate_logical_addr() { const uint8_t use_srp = (tc_sre() && (shoe.logical_fc >= 4)); - - uint32_t debug_predicted = 0; - // First check for an entry in pmmu_cache + +/* --- First check for an entry in pmmu_cache --- */ // logical addr [is]xxxxxxxxxxxx[ps] -> value xxxxxxxxxxxx const uint32_t value = (shoe.logical_addr << tc_is()) >> (tc_is() + tc_ps()); @@ -507,7 +486,6 @@ static void translate_logical_addr() const uint32_t ps_mask = 0xffffffff >> entry.used_bits; const uint32_t v_mask = ~~ps_mask; shoe.physical_addr = ((entry.physical_addr<<8) & v_mask) + (shoe.logical_addr & ps_mask); - // debug_predicted = ((entry.physical_addr<<8) & v_mask) + (shoe.logical_addr & ps_mask); return ; } // This should be rare, just let the lookup handle it @@ -517,6 +495,7 @@ static void translate_logical_addr() // Values don't match, this is a different address } +/* --- pmmu_cache miss, manually traverse the page tables to do the translation */ uint64_t *rootp_ptr = (use_srp ? (&shoe.srp) : (&shoe.crp)); const uint64_t rootp = *rootp_ptr; @@ -549,7 +528,8 @@ static void translate_logical_addr() if (rp_dt(rootp) == 1) goto search_done; - for (i=0; i < 4; i++) { // (the condition is unnecessary - just leaving it in for clarity) + // for (i=0; i < 4; i++) { // (the condition is unnecessary - just leaving it in for clarity) + for (i=0; 1; i++) { // desc must be a table descriptor here const uint8_t ti = tc_ti(i); @@ -562,8 +542,6 @@ static void translate_logical_addr() logical_addr <<= ti; // load the child descriptor - if (shoe.logical_addr == 0) - printf("Loading descriptor s=%llu from addr=0x%08x\n", desc_dt(desc, desc_size) & 1, (uint32_t)desc_table_addr(desc)); const uint32_t table_base_addr = desc_table_addr(desc); const uint8_t s = desc_dt(desc, desc_size) & 1; @@ -571,11 +549,9 @@ static void translate_logical_addr() get_desc(table_base_addr + (4 << s)*index, (4 << s)); desc_size = s; - // Desc may be a table descriptor, page descriptor, or indirect descriptor + // Desc may be a table descriptor, page descriptor, indirect descriptor, or invalid descriptor const uint8_t dt = desc_dt(desc, desc_size); - if (shoe.logical_addr == 0) - printf("i=%u desc = 0x%llx dt=%u\n", i, desc, dt); // If this descriptor is invalid, throw a bus error if (dt == 0) { @@ -620,6 +596,7 @@ search_done: // Desc must be a page descriptor // NOTE: The limit checks have been done already + // (or would be, if they were implemented yet) // TODO: update U (used) bit @@ -643,11 +620,11 @@ search_done: const uint32_t paddr = (desc_page_addr(desc) & v_mask) + (shoe.logical_addr & ps_mask); shoe.physical_addr = paddr; - if (shoe.logical_addr == 0) { + /*if (shoe.logical_addr == 0) { printf("Success! desc = 0x%llx sz=%u bytes\n", desc, 4<>3)&7, reg = (shoe.mr&7); switch (mode) { - case 0: { // Data register direct mode + case 0: // Data register direct mode + case 1: // address register direct mode + case 2: // address register indirect mode return ; // nothing to do - } - case 1: { // address register direct mode - return ; // nothing to do - } - case 2: { // address register indirect mode - return ; // nothing to do - } + case 3: { // address register indirect with postincrement mode const uint8_t delta = ((reg==7) && (shoe.sz==1))?2:shoe.sz; shoe.a[reg] += delta; @@ -954,9 +926,7 @@ void ea_read_commit() return ; } case 6: { - //printf("ea_read_commit(): %u %u not implemented\n", mode, reg); - ea_decode_extended(); - if (shoe.abort) return ; + // shoe.extended_len was set in the previous ea_read() call. shoe.pc += shoe.extended_len; return ; } @@ -985,10 +955,9 @@ void ea_read_commit() else shoe.pc += shoe.sz; return ; } - case 5 ... 7: { + default: throw_illegal_instruction(); return ; - } } } } @@ -1004,7 +973,6 @@ void ea_write() } case 1: { // address register direct mode assert(shoe.sz==4); - //set_a(reg, shoe.dat, shoe.sz); shoe.a[reg] = shoe.dat; return ; } @@ -1034,13 +1002,13 @@ void ea_write() return ; } case 6: { - //printf("ea_write(): %u %u not implemented\n", mode, reg); ea_decode_extended(); if (shoe.abort) return ; + lset(shoe.extended_addr, shoe.sz, shoe.dat); if (shoe.abort) return ; + shoe.pc += shoe.extended_len; - //printf("write(0x%x) = 0x%x\n", shoe.extended_addr, shoe.dat); return ; } case 7: { @@ -1057,27 +1025,12 @@ void ea_write() // printf("ea_write(): %u %u not implemented\n", mode, reg); return ; } - case 2: { // program counter indirect with displacement mode - printf("ea_write(): %u %u not implemented\n", mode, reg); - throw_illegal_instruction(); - return ; - } - case 3: { // (program counter ...) - printf("ea_write(): %u %u not implemented\n", mode, reg); - throw_illegal_instruction(); - return ; - } - case 4: { // immediate data - printf("ea_write(): %u %u not implemented\n", mode, reg); - throw_illegal_instruction(); - return ; - } - case 5 ... 7: { - throw_illegal_instruction(); - return ; - } } } + // fall through + default: + throw_illegal_instruction(); + return ; } } @@ -1085,35 +1038,16 @@ void ea_addr() { const uint8_t mode = (shoe.mr>>3)&7, reg = (shoe.mr&7); switch (mode) { - case 0: { // Data register direct mode - // this must be invalid. Figure out which exception this throws. - printf("ea_addr(): %u %u not implemented, pc = 0x%08x\n", mode, reg, shoe.orig_pc); - return ; - } - case 1: { // address register direct mode - printf("ea_addr(): %u %u not implemented\n", mode, reg); - // this must be invalid. Figure out which exception this throws. - return ; - } case 2: { // address register indirect mode shoe.dat = shoe.a[reg]; return ; } - case 3: { // address register indirect with postincrement mode - printf("ea_addr(): %u %u not implemented\n", mode, reg); - return ; - } - case 4: { // address register indirect with predecrement mode - printf("ea_addr(): %u %u not implemented\n", mode, reg); - return ; - } case 5: { // address register indirect with displacement mode int16_t disp = nextword(shoe.pc); shoe.dat = shoe.a[reg] + disp; return ; } case 6: { - // printf("ea_addr(): %u %u not implemented\n", mode, reg); ea_decode_extended(); if (shoe.abort) return ; shoe.dat = shoe.extended_addr; @@ -1146,16 +1080,11 @@ void ea_addr() shoe.pc += shoe.extended_len; return ; } - case 4: { // immediate data - printf("ea_addr(): %u %u not implemented, pc = 0x%08x\n", mode, reg, shoe.orig_pc); - return ; - } - case 5 ... 7: { - throw_illegal_instruction(); - return ; - } } } + default: + throw_illegal_instruction(); + return ; } } @@ -1169,7 +1098,3 @@ void ea_addr() - - - - diff --git a/gui/Shoebill/shoeAppDelegate.m b/gui/Shoebill/shoeAppDelegate.m index 59b7401..7b45c79 100644 --- a/gui/Shoebill/shoeAppDelegate.m +++ b/gui/Shoebill/shoeAppDelegate.m @@ -33,9 +33,9 @@ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; uint32_t i; - [defaults setObject:@"" forKey:@"kernelPath"]; + [defaults setObject:@"/unix" forKey:@"rootKernelPath"]; [defaults setObject:@"" forKey:@"romPath"]; - [defaults setInteger:NSOffState forKey:@"verboseState"]; + [defaults setInteger:NSOnState forKey:@"verboseState"]; [defaults setInteger:16 forKey:@"memorySize"]; [defaults setInteger:640 forKey:@"screenWidth"]; @@ -55,6 +55,10 @@ if (!isInitialized) [self createFirstTimeUserDefaults]; + + // Going from 0.0.1 to 0.0.2 leaves rootKernelPath uninitialized + if ([defaults objectForKey:@"rootKernelPath"] == nil) + [defaults setObject:@"/unix" forKey:@"rootKernelPath"]; } diff --git a/gui/Shoebill/shoeApplication.m b/gui/Shoebill/shoeApplication.m index 51f5a5d..905743a 100644 --- a/gui/Shoebill/shoeApplication.m +++ b/gui/Shoebill/shoeApplication.m @@ -219,12 +219,12 @@ uint32_t i; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSString *kernelPathStr = [defaults objectForKey:@"kernelPath"]; + NSString *rootKernelPathStr = [defaults objectForKey:@"rootKernelPath"]; NSString *romPathStr = [defaults objectForKey:@"romPath"]; NSInteger verboseState = [defaults integerForKey:@"verboseState"]; NSInteger memsize = [defaults integerForKey:@"memorySize"]; - if (kernelPathStr == Nil || [kernelPathStr length]==0) { + if (rootKernelPathStr == Nil || [rootKernelPathStr length]==0) { [self complain:@"Kernel path invalid!"]; return NO; } @@ -256,14 +256,14 @@ } - char *kernelPathCString = strdup([kernelPathStr UTF8String]); + char *rootKernelPathCString = strdup([rootKernelPathStr UTF8String]); char *romPathCString = strdup([romPathStr UTF8String]); // FIXME: I'm leaking these strings. Stop leaking stuff when the UI is more finalized control.aux_verbose = (verboseState == NSOnState); control.ram_size = (uint32_t)memsize * 1024 * 1024; - control.aux_kernel_path = kernelPathCString; + control.aux_kernel_path = rootKernelPathCString; control.rom_path = romPathCString; *width = screenWidthValue; diff --git a/gui/Shoebill/shoePreferencesWindowController.m b/gui/Shoebill/shoePreferencesWindowController.m index 14e46f3..993a789 100644 --- a/gui/Shoebill/shoePreferencesWindowController.m +++ b/gui/Shoebill/shoePreferencesWindowController.m @@ -37,7 +37,7 @@ { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSString *kernelPathStr = [defaults objectForKey:@"kernelPath"]; + NSString *rootKernelPathStr = [defaults objectForKey:@"rootKernelPath"]; NSString *romPathStr = [defaults objectForKey:@"romPath"]; NSInteger verboseState = [defaults integerForKey:@"verboseState"]; NSInteger memsize = [defaults integerForKey:@"memorySize"]; @@ -59,7 +59,7 @@ NSString *scsiPath6Str = [defaults objectForKey:@"scsiPath6"]; if (romPath) [romPath setStringValue:romPathStr]; - if (kernelPath) [kernelPath setStringValue:kernelPathStr]; + if (kernelPath) [kernelPath setStringValue:rootKernelPathStr]; [verbose setState:verboseState]; [memorySize setStringValue:[NSString stringWithFormat:@"%u", (uint32_t)memsize]]; @@ -112,9 +112,7 @@ NSString *buttonID = [sender identifier]; NSTextField *field; - if ([buttonID isEqualToString:@"kernelPathBrowse"]) - field = kernelPath; - else if ([buttonID isEqualToString:@"romPathBrowse"]) + if ([buttonID isEqualToString:@"romPathBrowse"]) field = romPath; else if ([buttonID isEqualToString:@"scsiPath0Browse"]) field = scsiPath0; @@ -139,7 +137,7 @@ - (IBAction)applyPressed:(id)sender { - NSString *kernelPathStr = [kernelPath stringValue]; + NSString *rootKernelPathStr = [kernelPath stringValue]; NSString *romPathStr = [romPath stringValue]; NSInteger verboseState = [verbose state]; NSInteger memsize = [memorySize integerValue]; @@ -157,7 +155,7 @@ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:kernelPathStr forKey:@"kernelPath"]; + [defaults setObject:rootKernelPathStr forKey:@"rootKernelPath"]; [defaults setObject:romPathStr forKey:@"romPath"]; [defaults setInteger:verboseState forKey:@"verboseState"]; [defaults setInteger:memsize forKey:@"memorySize"]; diff --git a/gui/Shoebill/shoePreferencesWindowController.xib b/gui/Shoebill/shoePreferencesWindowController.xib index 492c628..97d6b7f 100644 --- a/gui/Shoebill/shoePreferencesWindowController.xib +++ b/gui/Shoebill/shoePreferencesWindowController.xib @@ -1,13 +1,13 @@ - + - + - + @@ -19,13 +19,13 @@ - + - + @@ -40,21 +40,12 @@ - + - - - - - - - - - - + @@ -62,28 +53,8 @@ - - - - - - - - - - - + @@ -103,7 +74,7 @@ - + @@ -112,7 +83,7 @@ - + @@ -121,7 +92,7 @@ - + @@ -130,7 +101,7 @@ - + @@ -139,7 +110,7 @@ - + @@ -148,7 +119,7 @@ - + @@ -157,7 +128,7 @@ - + @@ -165,14 +136,6 @@ - @@ -387,6 +350,42 @@ + + + + + + + + + + + + + + + + + + The path to the kernel on the root image. If you don't know what this is, just use "/unix" (Note: the root image needs to be at SCSI ID 0) + + + + + + + + + +