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