Sun, 12 Dec 2010 23:47:35 +0000
improve error and DMA handling
doc/3B1 Memory Map.ods | file | annotate | diff | revisions | |
src/main.c | file | annotate | diff | revisions | |
src/memory.c | file | annotate | diff | revisions | |
src/state.c | file | annotate | diff | revisions | |
src/state.h | file | annotate | diff | revisions |
1.1 Binary file doc/3B1 Memory Map.ods has changed
2.1 --- a/src/main.c Mon Dec 06 01:43:04 2010 +0000 2.2 +++ b/src/main.c Sun Dec 12 23:47:35 2010 +0000 2.3 @@ -164,7 +164,11 @@ 2.4 2.5 // set up system state 2.6 // 512K of RAM 2.7 - state_init(512*1024); 2.8 + int i; 2.9 + if ((i = state_init(512*1024)) != STATE_E_OK) { 2.10 + fprintf(stderr, "ERROR: Emulator initialisation failed. Error code %d.\n", i); 2.11 + return i; 2.12 + } 2.13 2.14 // set up musashi and reset the CPU 2.15 m68k_set_cpu_type(M68K_CPU_TYPE_68010); 2.16 @@ -190,6 +194,10 @@ 2.17 2.18 // Load a disc image 2.19 FILE *disc = fopen("discim", "rb"); 2.20 + if (!disc) { 2.21 + fprintf(stderr, "ERROR loading disc image 'discim'.\n"); 2.22 + return -4; 2.23 + } 2.24 wd2797_load(&state.fdc_ctx, disc, 512, 10, 2); 2.25 2.26 /*** 2.27 @@ -212,11 +220,6 @@ 2.28 // 2.29 if (state.dmaen) { //((state.dma_count < 0x3fff) && state.dmaen) { 2.30 printf("DMA: copy addr=%08X count=%08X idmarw=%d dmarw=%d\n", state.dma_address, state.dma_count, state.idmarw, state.dma_reading); 2.31 - if (state.dmaenb) { 2.32 - state.dmaenb = false; 2.33 -// state.dma_address++; 2.34 - state.dma_count++; 2.35 - } 2.36 // DMA ready to go -- so do it. 2.37 size_t num = 0; 2.38 while (state.dma_count < 0x4000) {
3.1 --- a/src/memory.c Mon Dec 06 01:43:04 2010 +0000 3.2 +++ b/src/memory.c Sun Dec 12 23:47:35 2010 +0000 3.3 @@ -238,8 +238,9 @@ 3.4 case 0x050000: // Phone status 3.5 break; 3.6 case 0x060000: // DMA Count 3.7 - // U/OERR- is always inactive (bit set) 3.8 - data = (state.dma_count & 0x3fff) | 0x8000; 3.9 + // TODO: U/OERR- is always inactive (bit set)... or should it be = DMAEN+? 3.10 + // Bit 14 is always unused, so leave it set 3.11 + data = (state.dma_count & 0x3fff) | 0xC000; 3.12 handled = true; 3.13 break; 3.14 case 0x070000: // Line Printer Status Register 3.15 @@ -408,8 +409,9 @@ 3.16 case 0x050000: // Phone status 3.17 break; 3.18 case 0x060000: // DMA Count 3.19 - // U/OERR- is always inactive (bit set) 3.20 - data = (state.dma_count & 0x3fff) | 0x8000; 3.21 + // TODO: U/OERR- is always inactive (bit set)... or should it be = DMAEN+? 3.22 + // Bit 14 is always unused, so leave it set 3.23 + data = (state.dma_count & 0x3fff) | 0xC000; 3.24 handled = true; 3.25 break; 3.26 case 0x070000: // Line Printer Status Register 3.27 @@ -758,8 +760,12 @@ 3.28 state.dma_count = (value & 0x3FFF); 3.29 state.idmarw = ((value & 0x4000) == 0x4000); 3.30 state.dmaen = ((value & 0x8000) == 0x8000); 3.31 - state.dmaenb = state.dmaen; 3.32 printf("\tcount %04X, idmarw %d, dmaen %d\n", state.dma_count, state.idmarw, state.dmaen); 3.33 + // This handles the "dummy DMA transfer" mentioned in the docs 3.34 + // TODO: access check, peripheral access 3.35 + if (!state.idmarw) 3.36 + WR32(state.ram, mapAddr(address, false), state.ram_size - 1, 0xDEAD); 3.37 + state.dma_count++; 3.38 handled = true; 3.39 break; 3.40 case 0x070000: // Line Printer Status Register 3.41 @@ -961,8 +967,12 @@ 3.42 state.dma_count = (value & 0x3FFF); 3.43 state.idmarw = ((value & 0x4000) == 0x4000); 3.44 state.dmaen = ((value & 0x8000) == 0x8000); 3.45 - state.dmaenb = state.dmaen; 3.46 printf("\tcount %04X, idmarw %d, dmaen %d\n", state.dma_count, state.idmarw, state.dmaen); 3.47 + // This handles the "dummy DMA transfer" mentioned in the docs 3.48 + // TODO: access check, peripheral access 3.49 + if (!state.idmarw) 3.50 + WR32(state.ram, mapAddr(address, false), state.ram_size - 1, 0xDEAD); 3.51 + state.dma_count++; 3.52 handled = true; 3.53 break; 3.54 case 0x070000: // Line Printer Status Register
4.1 --- a/src/state.c Mon Dec 06 01:43:04 2010 +0000 4.2 +++ b/src/state.c Sun Dec 12 23:47:35 2010 +0000 4.3 @@ -26,9 +26,15 @@ 4.4 // Load ROMs 4.5 FILE *r14c, *r15c; 4.6 r14c = fopen("roms/14c.bin", "rb"); 4.7 -// if (r14c == NULL) FAIL("unable to open roms/14c.bin"); 4.8 + if (r14c == NULL) { 4.9 + fprintf(stderr, "[state] Error loading roms/14c.bin.\n"); 4.10 + return -3; 4.11 + } 4.12 r15c = fopen("roms/15c.bin", "rb"); 4.13 -// if (r15c == NULL) FAIL("unable to open roms/15c.bin"); 4.14 + if (r15c == NULL) { 4.15 + fprintf(stderr, "[state] Error loading roms/15c.bin.\n"); 4.16 + return -3; 4.17 + } 4.18 4.19 // get ROM file size 4.20 fseek(r14c, 0, SEEK_END); 4.21 @@ -37,8 +43,14 @@ 4.22 fseek(r15c, 0, SEEK_END); 4.23 size_t romlen2 = ftell(r15c); 4.24 fseek(r15c, 0, SEEK_SET); 4.25 -// if (romlen2 != romlen) FAIL("ROMs are not the same size!"); 4.26 -// if ((romlen + romlen2) > ROM_SIZE) FAIL("ROMs are too large to fit in memory!"); 4.27 + if (romlen2 != romlen) { 4.28 + fprintf(stderr, "[state] ROMs are not the same size!\n"); 4.29 + return -3; 4.30 + } 4.31 + if ((romlen + romlen2) > ROM_SIZE) { 4.32 + fprintf(stderr, "[state] ROM files are too large!\n"); 4.33 + return -3; 4.34 + } 4.35 4.36 // sanity checks completed; load the ROMs! 4.37 uint8_t *romdat1, *romdat2;
5.1 --- a/src/state.h Mon Dec 06 01:43:04 2010 +0000 5.2 +++ b/src/state.h Sun Dec 12 23:47:35 2010 +0000 5.3 @@ -10,6 +10,16 @@ 5.4 #define ROM_SIZE 32768 5.5 5.6 /** 5.7 + * State error codes 5.8 + */ 5.9 +typedef enum { 5.10 + STATE_E_OK = 0, ///< Operation succeeded 5.11 + STATE_E_BAD_RAMSIZE = -1, ///< Bad RAM size specified (not a multiple of 512K, or less than 512K) 5.12 + STATE_E_NO_MEMORY = -2, ///< Out of memory while allocating state variables 5.13 + STATE_E_ROM_LOAD_FAIL = -3 ///< Error loading ROMs 5.14 +} STATE_ERR; 5.15 + 5.16 +/** 5.17 * @brief Emulator state storage 5.18 * 5.19 * This structure stores the internal state of the emulator.