Sun, 28 Nov 2010 22:01:45 +0000
rework to use byte arrays to store ROM and RAM
src/main.c | file | annotate | diff | revisions |
1.1 diff -r 3e99497dca33 -r dbf4ba9563c9 src/main.c 1.2 --- a/src/main.c Sun Nov 28 20:52:53 2010 +0000 1.3 +++ b/src/main.c Sun Nov 28 22:01:45 2010 +0000 1.4 @@ -7,8 +7,6 @@ 1.5 #include "musashi/m68k.h" 1.6 #include "version.h" 1.7 1.8 -#define ROM_SIZE (32768/2) 1.9 - 1.10 void state_done(void); 1.11 1.12 void FAIL(char *err) 1.13 @@ -18,15 +16,16 @@ 1.14 exit(EXIT_FAILURE); 1.15 } 1.16 1.17 +// Maximum size of the Boot PROMs. Must be a binary power of two. 1.18 +#define ROM_SIZE 32768 1.19 1.20 struct { 1.21 // Boot PROM can be up to 32Kbytes total size 1.22 - uint16_t rom[ROM_SIZE]; 1.23 + uint8_t rom[ROM_SIZE]; 1.24 1.25 // Main system RAM 1.26 - uint16_t *ram; 1.27 + uint8_t *ram; 1.28 size_t ram_size; // number of RAM bytes allocated 1.29 - uint32_t ram_addr_mask; // address mask 1.30 1.31 // GENERAL CONTROL REGISTER 1.32 bool romlmap; 1.33 @@ -42,11 +41,10 @@ 1.34 state.romlmap = false; 1.35 1.36 // Allocate RAM 1.37 - // TODO: make sure ram size selection is valid! 1.38 + // TODO: make sure ram size selection is valid (512K, 1MB, 1.5MB, 2MB, 2.5MB, 3MB or 4MB)! 1.39 state.ram = malloc(state.ram_size); 1.40 if (state.ram == NULL) 1.41 return -1; 1.42 - state.ram_addr_mask = state.ram_size - 1; 1.43 1.44 // Load ROMs 1.45 FILE *r14c, *r15c; 1.46 @@ -63,8 +61,7 @@ 1.47 size_t romlen2 = ftell(r15c); 1.48 fseek(r15c, 0, SEEK_SET); 1.49 if (romlen2 != romlen) FAIL("ROMs are not the same size!"); 1.50 - if ((romlen / 4) > (ROM_SIZE / 2)) FAIL("ROM 14C is too big!"); 1.51 - if ((romlen2 / 4) > (ROM_SIZE / 2)) FAIL("ROM 15C is too big!"); 1.52 + if ((romlen + romlen2) > ROM_SIZE) FAIL("ROMs are too large to fit in memory!"); 1.53 1.54 // sanity checks completed; load the ROMs! 1.55 uint8_t *romdat1, *romdat2; 1.56 @@ -74,10 +71,16 @@ 1.57 fread(romdat2, 1, romlen2, r14c); 1.58 1.59 // convert the ROM data 1.60 - for (size_t i=0; i<romlen; i++) { 1.61 - state.rom[i] = ((romdat1[i] << 8) | (romdat2[i])); 1.62 + for (size_t i=0; i<(romlen + romlen2); i+=2) { 1.63 + state.rom[i+0] = romdat1[i/2]; 1.64 + state.rom[i+1] = romdat2[i/2]; 1.65 } 1.66 1.67 + for (size_t i=0; i<16; i++) printf("%02X ", state.rom[i]); 1.68 + printf("\n"); 1.69 + 1.70 + // TODO: if ROM buffer not filled, repeat the ROM data we read until it is. 1.71 + 1.72 // free the data arrays and close the files 1.73 free(romdat1); 1.74 free(romdat2); 1.75 @@ -94,8 +97,6 @@ 1.76 } 1.77 1.78 // read m68k memory 1.79 -// TODO: refactor musashi to use stdint, and properly sized integers! 1.80 -// TODO: find a way to make musashi use function pointers instead of hard coded callbacks, maybe use a context struct too 1.81 uint32_t m68k_read_memory_32(uint32_t address) 1.82 { 1.83 uint32_t data = 0xFFFFFFFF; 1.84 @@ -108,13 +109,19 @@ 1.85 1.86 if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.87 // ROM access 1.88 - data = ((state.rom[(address & (ROM_SIZE-1)) / 2] << 16) | (state.rom[((address & (ROM_SIZE-1)) / 2)+1])); 1.89 - } else if (address <= 0x3FFFFF) { 1.90 + data = (((uint32_t)state.rom[(address + 0) & (ROM_SIZE - 1)] << 24) | 1.91 + ((uint32_t)state.rom[(address + 1) & (ROM_SIZE - 1)] << 16) | 1.92 + ((uint32_t)state.rom[(address + 2) & (ROM_SIZE - 1)] << 8) | 1.93 + ((uint32_t)state.rom[(address + 3) & (ROM_SIZE - 1)])); 1.94 + } else if (address < state.ram_size - 1) { 1.95 // RAM 1.96 - data = state.ram[(address & state.ram_addr_mask) / 2]; 1.97 + data = (((uint32_t)state.ram[address + 0] << 24) | 1.98 + ((uint32_t)state.ram[address + 1] << 16) | 1.99 + ((uint32_t)state.ram[address + 2] << 8) | 1.100 + ((uint32_t)state.ram[address + 3])); 1.101 } 1.102 1.103 - printf(" ==> %04X\n", data); 1.104 + printf(" ==> %08X\n", data); 1.105 return data; 1.106 } 1.107 1.108 @@ -128,7 +135,15 @@ 1.109 if (!state.romlmap) 1.110 address |= 0x800000; 1.111 1.112 - data = (m68k_read_memory_32(address) >> 16) & 0xFFFF; 1.113 + if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.114 + // ROM access 1.115 + data = ((state.rom[(address + 0) & (ROM_SIZE - 1)] << 8) | 1.116 + (state.rom[(address + 1) & (ROM_SIZE - 1)])); 1.117 + } else if (address < state.ram_size - 1) { 1.118 + // RAM 1.119 + data = ((state.ram[address + 0] << 8) | 1.120 + (state.ram[address + 1])); 1.121 + } 1.122 1.123 printf(" ==> %04X\n", data); 1.124 return data; 1.125 @@ -144,7 +159,13 @@ 1.126 if (!state.romlmap) 1.127 address |= 0x800000; 1.128 1.129 - data = m68k_read_memory_32(address) & 0xFF; 1.130 + if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.131 + // ROM access 1.132 + data = state.rom[(address + 0) & (ROM_SIZE - 1)]; 1.133 + } else if (address < state.ram_size) { 1.134 + // RAM access 1.135 + data = state.ram[address + 0]; 1.136 + } 1.137 1.138 printf("==> %02X\n", data); 1.139 return data; 1.140 @@ -162,10 +183,12 @@ 1.141 if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.142 // ROM access 1.143 // TODO: bus error here? can't write to rom! 1.144 - } else if (address <= 0x3FFFFF) { 1.145 - // RAM 1.146 - state.ram[(address & state.ram_addr_mask) / 2] = (value >> 16); 1.147 - state.ram[((address & state.ram_addr_mask) / 2)+1] = value & 0xffff; 1.148 + } else if (address < state.ram_size) { 1.149 + // RAM access 1.150 + state.ram[address + 0] = (value >> 24) & 0xff; 1.151 + state.ram[address + 1] = (value >> 16) & 0xff; 1.152 + state.ram[address + 2] = (value >> 8) & 0xff; 1.153 + state.ram[address + 3] = value & 0xff; 1.154 } else { 1.155 switch (address) { 1.156 case 0xE43000: state.romlmap = ((value & 0x8000) == 0x8000); 1.157 @@ -184,9 +207,10 @@ 1.158 if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.159 // ROM access 1.160 // TODO: bus error here? can't write to rom! 1.161 - } else if (address <= 0x3FFFFF) { 1.162 - // RAM 1.163 - state.ram[(address & state.ram_addr_mask) / 2] = value & 0xFFFF; 1.164 + } else if (address < state.ram_size) { 1.165 + // RAM access 1.166 + state.ram[address + 0] = (value >> 8) & 0xff; 1.167 + state.ram[address + 1] = value & 0xff; 1.168 } else { 1.169 switch (address) { 1.170 case 0xE43000: state.romlmap = ((value & 0x8000) == 0x8000); 1.171 @@ -205,15 +229,8 @@ 1.172 if ((address >= 0x800000) && (address <= 0xBFFFFF)) { 1.173 // ROM access 1.174 // TODO: bus error here? can't write to rom! 1.175 - } else if (address <= 0x3FFFFF) { 1.176 - // RAM 1.177 - switch (address & 3) { 1.178 - // FIXME 1.179 - case 3: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0xFFFFFF00) | (value & 0xFF); 1.180 - case 2: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0xFFFF00FF) | ((value & 0xFF) << 8); 1.181 - case 1: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0xFF00FFFF) | ((value & 0xFF) << 16); 1.182 - case 0: state.ram[(address & state.ram_addr_mask) / 4] = (state.ram[(address & state.ram_addr_mask) / 4] & 0x00FFFFFF) | ((value & 0xFF) << 24); 1.183 - } 1.184 + } else if (address < state.ram_size) { 1.185 + state.ram[address] = value & 0xff; 1.186 } else { 1.187 switch (address) { 1.188 case 0xE43000: state.romlmap = ((value & 0x80) == 0x80); 1.189 @@ -221,6 +238,7 @@ 1.190 } 1.191 } 1.192 1.193 +// for the disassembler 1.194 uint32_t m68k_read_disassembler_32(uint32_t addr) { return m68k_read_memory_32(addr); } 1.195 uint32_t m68k_read_disassembler_16(uint32_t addr) { return m68k_read_memory_16(addr); } 1.196 uint32_t m68k_read_disassembler_8 (uint32_t addr) { return m68k_read_memory_8 (addr); }