rework to use byte arrays to store ROM and RAM

Sun, 28 Nov 2010 22:01:45 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 28 Nov 2010 22:01:45 +0000
changeset 10
dbf4ba9563c9
parent 9
3e99497dca33
child 11
67bf6abb6e79

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); }