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