Thu, 02 Dec 2010 20:58:12 +0000
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