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