rework address-check logic

Thu, 02 Dec 2010 20:58:12 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Thu, 02 Dec 2010 20:58:12 +0000
changeset 37
87662afa1d98
parent 36
746fb8d0653e
child 38
b948045ca964

rework address-check logic

src/main.c file | annotate | diff | revisions
src/state.h file | annotate | diff | revisions
     1.1 --- a/src/main.c	Thu Dec 02 20:42:30 2010 +0000
     1.2 +++ b/src/main.c	Thu Dec 02 20:58:12 2010 +0000
     1.3 @@ -148,29 +148,42 @@
     1.4   * 			in a non-void function, even if it's impossible to ever reach the
     1.5   * 			return-with-no-value. UGH!
     1.6   */
     1.7 -#define ACCESS_CHECK_WR() do {									\
     1.8 -		/* MEM_STATUS st; */									\
     1.9 -		switch (checkMemoryAccess(address, true)) {				\
    1.10 -			case MEM_ALLOWED:									\
    1.11 -				/* Access allowed */							\
    1.12 -				break;											\
    1.13 -			case MEM_PAGEFAULT:									\
    1.14 -				/* Page fault */								\
    1.15 -				state.genstat = 0x8FFF;							\
    1.16 -				m68k_pulse_bus_error();							\
    1.17 -				return;											\
    1.18 -			case MEM_UIE:										\
    1.19 -				/* User access to memory above 4MB */			\
    1.20 -				state.genstat = 0x9EFF;							\
    1.21 -				m68k_pulse_bus_error();							\
    1.22 -				return;											\
    1.23 -			case MEM_KERNEL:									\
    1.24 -			case MEM_PAGE_NO_WE:								\
    1.25 -				/* kernel access or page not write enabled */	\
    1.26 -				/* TODO: which regs need setting? */			\
    1.27 -				m68k_pulse_bus_error();							\
    1.28 -				return;											\
    1.29 -		}														\
    1.30 +#define ACCESS_CHECK_WR(address, bits) do {							\
    1.31 +		bool fault = false;											\
    1.32 +		/* MEM_STATUS st; */										\
    1.33 +		switch (checkMemoryAccess(address, true)) {					\
    1.34 +			case MEM_ALLOWED:										\
    1.35 +				/* Access allowed */								\
    1.36 +				break;												\
    1.37 +			case MEM_PAGEFAULT:										\
    1.38 +				/* Page fault */									\
    1.39 +				state.genstat = 0x8FFF;								\
    1.40 +				fault = true;										\
    1.41 +				break;												\
    1.42 +			case MEM_UIE:											\
    1.43 +				/* User access to memory above 4MB */				\
    1.44 +				state.genstat = 0x9EFF;								\
    1.45 +				fault = true;										\
    1.46 +				break;												\
    1.47 +			case MEM_KERNEL:										\
    1.48 +			case MEM_PAGE_NO_WE:									\
    1.49 +				/* kernel access or page not write enabled */		\
    1.50 +				/* TODO: which regs need setting? */				\
    1.51 +				fault = true;										\
    1.52 +				break;												\
    1.53 +		}															\
    1.54 +																	\
    1.55 +		if (fault) {												\
    1.56 +			if (bits >= 16)											\
    1.57 +				state.bsr0 = 0x7F00;								\
    1.58 +			else													\
    1.59 +				state.bsr0 = (address & 1) ? 0x7D00 : 0x7E00;		\
    1.60 +			state.bsr0 |= (address >> 16);							\
    1.61 +			state.bsr1 = address & 0xffff;							\
    1.62 +			printf("ERR: BusError WR\n");							\
    1.63 +			m68k_pulse_bus_error();									\
    1.64 +			return;													\
    1.65 +		}															\
    1.66  	} while (false)
    1.67  
    1.68  /**
    1.69 @@ -182,31 +195,45 @@
    1.70   * 			in a non-void function, even if it's impossible to ever reach the
    1.71   * 			return-with-no-value. UGH!
    1.72   */
    1.73 -#define ACCESS_CHECK_RD() do {									\
    1.74 -		/* MEM_STATUS st; */									\
    1.75 -		switch (checkMemoryAccess(address, false)) {			\
    1.76 -			case MEM_ALLOWED:									\
    1.77 -				/* Access allowed */							\
    1.78 -				break;											\
    1.79 -			case MEM_PAGEFAULT:									\
    1.80 -				/* Page fault */								\
    1.81 -				state.genstat = 0xCFFF;							\
    1.82 -				m68k_pulse_bus_error();							\
    1.83 -				return 0xFFFFFFFF;								\
    1.84 -			case MEM_UIE:										\
    1.85 -				/* User access to memory above 4MB */			\
    1.86 -				state.genstat = 0xDEFF;							\
    1.87 -				m68k_pulse_bus_error();							\
    1.88 -				return 0xFFFFFFFF;								\
    1.89 -			case MEM_KERNEL:									\
    1.90 -			case MEM_PAGE_NO_WE:								\
    1.91 -				/* kernel access or page not write enabled */	\
    1.92 -				/* TODO: which regs need setting? */			\
    1.93 -				m68k_pulse_bus_error();							\
    1.94 -				return 0xFFFFFFFF;								\
    1.95 -		}														\
    1.96 +#define ACCESS_CHECK_RD(address, bits) do {							\
    1.97 +		bool fault = false;											\
    1.98 +		/* MEM_STATUS st; */										\
    1.99 +		switch (checkMemoryAccess(address, false)) {				\
   1.100 +			case MEM_ALLOWED:										\
   1.101 +				/* Access allowed */								\
   1.102 +				break;												\
   1.103 +			case MEM_PAGEFAULT:										\
   1.104 +				/* Page fault */									\
   1.105 +				state.genstat = 0x8FFF;								\
   1.106 +				fault = true;										\
   1.107 +				break;												\
   1.108 +			case MEM_UIE:											\
   1.109 +				/* User access to memory above 4MB */				\
   1.110 +				state.genstat = 0x9EFF;								\
   1.111 +				fault = true;										\
   1.112 +				break;												\
   1.113 +			case MEM_KERNEL:										\
   1.114 +			case MEM_PAGE_NO_WE:									\
   1.115 +				/* kernel access or page not write enabled */		\
   1.116 +				/* TODO: which regs need setting? */				\
   1.117 +				fault = true;										\
   1.118 +				break;												\
   1.119 +		}															\
   1.120 +																	\
   1.121 +		if (fault) {												\
   1.122 +			if (bits >= 16)											\
   1.123 +				state.bsr0 = 0x7F00;								\
   1.124 +			else													\
   1.125 +				state.bsr0 = (address & 1) ? 0x7D00 : 0x7E00;		\
   1.126 +			state.bsr0 |= (address >> 16);							\
   1.127 +			state.bsr1 = address & 0xffff;							\
   1.128 +			printf("ERR: BusError RD\n");							\
   1.129 +			m68k_pulse_bus_error();									\
   1.130 +			return 0xFFFFFFFF;										\
   1.131 +		}															\
   1.132  	} while (false)
   1.133  
   1.134 +
   1.135  /**
   1.136   * @brief Read M68K memory, 32-bit
   1.137   */
   1.138 @@ -219,7 +246,7 @@
   1.139  		address |= 0x800000;
   1.140  
   1.141  	// Check access permissions
   1.142 -	ACCESS_CHECK_RD();
   1.143 +	ACCESS_CHECK_RD(address, 32);
   1.144  
   1.145  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.146  		// ROM access
   1.147 @@ -372,7 +399,7 @@
   1.148  		address |= 0x800000;
   1.149  
   1.150  	// Check access permissions
   1.151 -	ACCESS_CHECK_RD();
   1.152 +	ACCESS_CHECK_RD(address, 16);
   1.153  
   1.154  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.155  		// ROM access
   1.156 @@ -525,7 +552,7 @@
   1.157  		address |= 0x800000;
   1.158  
   1.159  	// Check access permissions
   1.160 -	ACCESS_CHECK_RD();
   1.161 +	ACCESS_CHECK_RD(address, 8);
   1.162  
   1.163  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.164  		// ROM access
   1.165 @@ -679,7 +706,7 @@
   1.166  		address |= 0x800000;
   1.167  
   1.168  	// Check access permissions
   1.169 -	ACCESS_CHECK_WR();
   1.170 +	ACCESS_CHECK_WR(address, 32);
   1.171  
   1.172  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.173  		// ROM access
   1.174 @@ -832,7 +859,7 @@
   1.175  		address |= 0x800000;
   1.176  
   1.177  	// Check access permissions
   1.178 -	ACCESS_CHECK_WR();
   1.179 +	ACCESS_CHECK_WR(address, 16);
   1.180  
   1.181  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.182  		// ROM access
   1.183 @@ -985,7 +1012,7 @@
   1.184  		address |= 0x800000;
   1.185  
   1.186  	// Check access permissions
   1.187 -	ACCESS_CHECK_WR();
   1.188 +	ACCESS_CHECK_WR(address, 8);
   1.189  
   1.190  	if ((address >= 0x800000) && (address <= 0xBFFFFF)) {
   1.191  		// ROM access
     2.1 --- a/src/state.h	Thu Dec 02 20:42:30 2010 +0000
     2.2 +++ b/src/state.h	Thu Dec 02 20:58:12 2010 +0000
     2.3 @@ -27,8 +27,10 @@
     2.4  	// Map RAM
     2.5  	uint8_t		map[0x800];			///< Map RAM
     2.6  
     2.7 -	// General Status Register
     2.8 -	uint16_t	genstat;
     2.9 +	// Registers
    2.10 +	uint16_t	genstat;			///< General Status Register
    2.11 +	uint16_t	bsr0;				///< Bus Status Register 0
    2.12 +	uint16_t	bsr1;				///< Bus Status Register 1
    2.13  
    2.14  	// GENERAL CONTROL REGISTER
    2.15  	/// GENCON.ROMLMAP -- false ORs the address with 0x800000, forcing the