[memory] Emulate main memory read wrap-around

Fri, 18 Jan 2013 17:18:50 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 18 Jan 2013 17:18:50 +0000
changeset 129
8b24770dea79
parent 127
4c03f6433d0d
child 130
1fc7d607dbb4

[memory] Emulate main memory read wrap-around

3B1s with 512K or 1MB of base memory have a decoding quirk which causes reads
to 'wrap around'. That is to say, on a 512K machine, reading from addresses 0,
512K, 1024K or 1536K will address the same RAM byte. On a 1MB machine,
addresses 0 and 1024K address the same RAM byte.

Emulating this incorrectly causes P4TEST to report an incorrect amount of
available base RAM.

src/memory.c file | annotate | diff | revisions
     1.1 diff -r 4c03f6433d0d -r 8b24770dea79 src/memory.c
     1.2 --- a/src/memory.c	Wed Jan 16 00:41:51 2013 +0000
     1.3 +++ b/src/memory.c	Fri Jan 18 17:18:50 2013 +0000
     1.4 @@ -11,7 +11,8 @@
     1.5  // The value which will be returned if the CPU attempts to read from empty memory
     1.6  // TODO (FIXME?) - need to figure out if R/W ops wrap around. This seems to appease the UNIX kernel and P4TEST.
     1.7  #define EMPTY 0xFFFFFFFFUL
     1.8 -// #define EMPTY 0x55555555UL
     1.9 +//#define EMPTY 0x55555555UL
    1.10 +//#define EMPTY 0x00000000UL
    1.11  
    1.12  /******************
    1.13   * Memory mapping
    1.14 @@ -737,10 +738,8 @@
    1.15  		// RAM access
    1.16  		uint32_t newAddr = mapAddr(address, false);
    1.17  		if (newAddr <= 0x1fffff) {
    1.18 -			if (newAddr >= state.base_ram_size)
    1.19 -				return EMPTY & 0xffffffff;
    1.20 -			else
    1.21 -				return RD32(state.base_ram, newAddr, state.base_ram_size - 1);
    1.22 +			// Base memory wraps around
    1.23 +			return RD32(state.base_ram, newAddr, state.base_ram_size - 1);
    1.24  		} else {
    1.25  			if ((newAddr <= (state.exp_ram_size + 0x200000 - 1)) && (newAddr >= 0x200000))
    1.26  				return RD32(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1);
    1.27 @@ -789,10 +788,8 @@
    1.28  		// RAM access
    1.29  		uint32_t newAddr = mapAddr(address, false);
    1.30  		if (newAddr <= 0x1fffff) {
    1.31 -			if (newAddr >= state.base_ram_size)
    1.32 -				return EMPTY & 0xffff;
    1.33 -			else
    1.34 -				return RD16(state.base_ram, newAddr, state.base_ram_size - 1);
    1.35 +			// Base memory wraps around
    1.36 +			return RD16(state.base_ram, newAddr, state.base_ram_size - 1);
    1.37  		} else {
    1.38  			if ((newAddr <= (state.exp_ram_size + 0x200000 - 1)) && (newAddr >= 0x200000))
    1.39  				return RD16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1);
    1.40 @@ -841,10 +838,8 @@
    1.41  		// RAM access
    1.42  		uint32_t newAddr = mapAddr(address, false);
    1.43  		if (newAddr <= 0x1fffff) {
    1.44 -			if (newAddr >= state.base_ram_size)
    1.45 -				return EMPTY & 0xff;
    1.46 -			else
    1.47 -				return RD8(state.base_ram, newAddr, state.base_ram_size - 1);
    1.48 +			// Base memory wraps around
    1.49 +			return RD8(state.base_ram, newAddr, state.base_ram_size - 1);
    1.50  		} else {
    1.51  			if ((newAddr <= (state.exp_ram_size + 0x200000 - 1)) && (newAddr >= 0x200000))
    1.52  				return RD8(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1);