Mon, 14 Jan 2013 09:48:21 +0000
Handle memory more gracefully
Fixed in this cset:
* Return an 'empty space' value if the memory wraps around
* Allow the 'empty bus' value to be changed via an ifdef
* Properly handle situations where expansion memory is turned off
src/memory.c | file | annotate | diff | revisions |
1.1 diff -r feee84e0b3bf -r 101fe02456ce src/memory.c 1.2 --- a/src/memory.c Mon Jan 14 09:22:12 2013 +0000 1.3 +++ b/src/memory.c Mon Jan 14 09:48:21 2013 +0000 1.4 @@ -8,6 +8,11 @@ 1.5 #include "utils.h" 1.6 #include "memory.h" 1.7 1.8 +// The value which will be returned if the CPU attempts to read from empty memory 1.9 +// TODO (FIXME?) - need to figure out if R/W ops wrap around. This seems to appease the UNIX kernel and P4TEST. 1.10 +#define EMPTY 0xFFFFFFFFUL 1.11 +// #define EMPTY 0x55555555UL 1.12 + 1.13 /****************** 1.14 * Memory mapping 1.15 ******************/ 1.16 @@ -211,9 +216,9 @@ 1.17 LOG("Bus Error while reading, addr %08X, statcode %d", address, st); \ 1.18 if (state.ee) m68k_pulse_bus_error(); \ 1.19 if (bits == 32) \ 1.20 - return 0xFFFFFFFF; \ 1.21 + return EMPTY & 0xFFFFFFFF; \ 1.22 else \ 1.23 - return (1UL << bits)-1; \ 1.24 + return EMPTY & ((1UL << bits)-1); \ 1.25 } \ 1.26 } while (0) 1.27 /*}}}*/ 1.28 @@ -544,7 +549,7 @@ 1.29 uint32_t IoRead(uint32_t address, int bits)/*{{{*/ 1.30 { 1.31 bool handled = false; 1.32 - uint32_t data = 0xFFFFFFFF; 1.33 + uint32_t data = EMPTY & 0xFFFFFFFF; 1.34 1.35 if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.36 // I/O register space, zone A 1.37 @@ -717,7 +722,7 @@ 1.38 */ 1.39 uint32_t m68k_read_memory_32(uint32_t address)/*{{{*/ 1.40 { 1.41 - uint32_t data = 0xFFFFFFFF; 1.42 + uint32_t data = EMPTY & 0xFFFFFFFF; 1.43 1.44 // If ROMLMAP is set, force system to access ROM 1.45 if (!state.romlmap) 1.46 @@ -733,12 +738,15 @@ 1.47 // RAM access 1.48 uint32_t newAddr = mapAddr(address, false); 1.49 if (newAddr <= 0x1fffff) { 1.50 - return RD32(state.base_ram, newAddr, state.base_ram_size - 1); 1.51 + if (newAddr >= state.base_ram_size) 1.52 + return EMPTY & 0xffffffff; 1.53 + else 1.54 + return RD32(state.base_ram, newAddr, state.base_ram_size - 1); 1.55 } else { 1.56 - if (newAddr <= (state.exp_ram_size + 0x200000 - 1)) 1.57 + if ((newAddr <= (state.exp_ram_size + 0x200000 - 1)) && (newAddr >= 0x200000)) 1.58 return RD32(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1); 1.59 else 1.60 - return 0xffffffff; 1.61 + return EMPTY & 0xffffffff; 1.62 } 1.63 } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.64 // I/O register space, zone A 1.65 @@ -766,7 +774,7 @@ 1.66 */ 1.67 uint32_t m68k_read_memory_16(uint32_t address)/*{{{*/ 1.68 { 1.69 - uint16_t data = 0xFFFF; 1.70 + uint16_t data = EMPTY & 0xFFFF; 1.71 1.72 // If ROMLMAP is set, force system to access ROM 1.73 if (!state.romlmap) 1.74 @@ -782,12 +790,15 @@ 1.75 // RAM access 1.76 uint32_t newAddr = mapAddr(address, false); 1.77 if (newAddr <= 0x1fffff) { 1.78 - return RD16(state.base_ram, newAddr, state.base_ram_size - 1); 1.79 + if (newAddr >= state.base_ram_size) 1.80 + return EMPTY & 0xffff; 1.81 + else 1.82 + return RD16(state.base_ram, newAddr, state.base_ram_size - 1); 1.83 } else { 1.84 - if (newAddr <= (state.exp_ram_size + 0x200000 - 1)) 1.85 + if ((newAddr <= (state.exp_ram_size + 0x200000 - 1)) && (newAddr >= 0x200000)) 1.86 return RD16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1); 1.87 else 1.88 - return 0xffff; 1.89 + return EMPTY & 0xffff; 1.90 } 1.91 } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.92 // I/O register space, zone A 1.93 @@ -815,7 +826,7 @@ 1.94 */ 1.95 uint32_t m68k_read_memory_8(uint32_t address)/*{{{*/ 1.96 { 1.97 - uint8_t data = 0xFF; 1.98 + uint8_t data = EMPTY & 0xFF; 1.99 1.100 // If ROMLMAP is set, force system to access ROM 1.101 if (!state.romlmap) 1.102 @@ -831,12 +842,15 @@ 1.103 // RAM access 1.104 uint32_t newAddr = mapAddr(address, false); 1.105 if (newAddr <= 0x1fffff) { 1.106 - return RD8(state.base_ram, newAddr, state.base_ram_size - 1); 1.107 + if (newAddr >= state.base_ram_size) 1.108 + return EMPTY & 0xff; 1.109 + else 1.110 + return RD8(state.base_ram, newAddr, state.base_ram_size - 1); 1.111 } else { 1.112 - if (newAddr <= (state.exp_ram_size + 0x200000 - 1)) 1.113 + if ((newAddr <= (state.exp_ram_size + 0x200000 - 1)) && (newAddr >= 0x200000)) 1.114 return RD8(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1); 1.115 else 1.116 - return 0xff; 1.117 + return EMPTY & 0xff; 1.118 } 1.119 } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.120 // I/O register space, zone A 1.121 @@ -876,10 +890,15 @@ 1.122 } else if (address <= 0x3FFFFF) { 1.123 // RAM access 1.124 uint32_t newAddr = mapAddr(address, true); 1.125 - if (newAddr <= 0x1fffff) 1.126 - WR32(state.base_ram, newAddr, state.base_ram_size - 1, value); 1.127 - else 1.128 - WR32(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, value); 1.129 + if (newAddr <= 0x1fffff) { 1.130 + if (newAddr < state.base_ram_size) { 1.131 + WR32(state.base_ram, newAddr, state.base_ram_size - 1, value); 1.132 + } 1.133 + } else { 1.134 + if ((newAddr - 0x200000) < state.exp_ram_size) { 1.135 + WR32(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, value); 1.136 + } 1.137 + } 1.138 } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.139 // I/O register space, zone A 1.140 switch (address & 0x0F0000) { 1.141 @@ -917,10 +936,15 @@ 1.142 // RAM access 1.143 uint32_t newAddr = mapAddr(address, true); 1.144 1.145 - if (newAddr <= 0x1fffff) 1.146 - WR16(state.base_ram, newAddr, state.base_ram_size - 1, value); 1.147 - else 1.148 - WR16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, value); 1.149 + if (newAddr <= 0x1fffff) { 1.150 + if (newAddr < state.base_ram_size) { 1.151 + WR16(state.base_ram, newAddr, state.base_ram_size - 1, value); 1.152 + } 1.153 + } else { 1.154 + if ((newAddr - 0x200000) < state.exp_ram_size) { 1.155 + WR16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, value); 1.156 + } 1.157 + } 1.158 } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.159 // I/O register space, zone A 1.160 switch (address & 0x0F0000) { 1.161 @@ -957,10 +981,15 @@ 1.162 } else if (address <= 0x3FFFFF) { 1.163 // RAM access 1.164 uint32_t newAddr = mapAddr(address, true); 1.165 - if (newAddr <= 0x1fffff) 1.166 - WR8(state.base_ram, newAddr, state.base_ram_size - 1, value); 1.167 - else 1.168 - WR8(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, value); 1.169 + if (newAddr <= 0x1fffff) { 1.170 + if (newAddr < state.base_ram_size) { 1.171 + WR8(state.base_ram, newAddr, state.base_ram_size - 1, value); 1.172 + } 1.173 + } else { 1.174 + if ((newAddr - 0x200000) < state.exp_ram_size) { 1.175 + WR8(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, value); 1.176 + } 1.177 + } 1.178 } else if ((address >= 0x400000) && (address <= 0x7FFFFF)) { 1.179 // I/O register space, zone A 1.180 switch (address & 0x0F0000) {