Handle memory more gracefully

Mon, 14 Jan 2013 09:48:21 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 14 Jan 2013 09:48:21 +0000
changeset 119
101fe02456ce
parent 118
feee84e0b3bf
child 120
df40e6668a46

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) {