diff jaguar.c @ 1090:a68274a25e2f

Initial stab at implementing the Jaguar object processor
author Michael Pavone <pavone@retrodev.com>
date Sun, 16 Oct 2016 18:25:18 -0700
parents 87597a048d38
children f338c950fcef
line wrap: on
line diff
--- a/jaguar.c	Wed Oct 12 09:39:52 2016 -0700
+++ b/jaguar.c	Sun Oct 16 18:25:18 2016 -0700
@@ -89,6 +89,21 @@
 						mem_pointers[rom + 2] = system->cart + ((0x400000 & (system->cart_size-1)) >> 1);
 						system->memcon_written = 1;
 						printf("MEMCON1 write - ROMHI: %d\n", value & 1);
+						switch (system->memcon1 >> 3 & 3)
+						{
+						case 0:
+							system->rom_cycles = 10;
+							break;
+						case 1:
+							system->rom_cycles = 8;
+							break;
+						case 2:
+							system->rom_cycles = 6;
+							break;
+						case 3:
+							system->rom_cycles = 5;
+							break;
+						}
 						//TODO: invalidate code cache
 					}
 					system->memcon1 = value;
@@ -239,6 +254,112 @@
 	return 0xFFFF;
 }
 
+uint64_t rom0_read_64(uint32_t address, jaguar_context *system)
+{
+	address &= 0x1FFFFF;
+	uint64_t high = rom0_read_16(address, system);
+	uint64_t highmid = rom0_read_16(address+2, system);
+	uint64_t lowmid = rom0_read_16(address+4, system);
+	uint64_t low = rom0_read_16(address+6, system);
+	return high << 48 | highmid << 32 | lowmid << 16 | low;
+}
+
+void rom0_write_64(uint32_t address, jaguar_context *system, uint64_t val)
+{
+	address &= 0x1FFFFF;
+	rom0_write_16(address, system, val >> 48);
+	rom0_write_16(address+2, system, val >> 32);
+	rom0_write_16(address+4, system, val >> 16);
+	rom0_write_16(address+6, system, val);
+}
+
+uint64_t jag_read_phrase(jaguar_context *system, uint32_t address, uint32_t *cycles)
+{
+	if (!system->memcon_written) {
+		//unsure of timing, but presumably at least 2 32-bit reads 
+		//which presumably take a minimum of 1 cycle
+		//reality probably depends on the exact area read
+		//docs seem to imply some areas only 16-bits wide whereas others are 32-bit
+		*cycles += 2;
+		return rom0_read_64(address, system);
+	}
+	uint16_t *src;
+	if (system->memcon1 & 1) {
+		if (address < 0x800000) {
+			src = system->dram + (address >> 1 & (DRAM_WORDS - 1));
+			//DRAM is 64-bits wide, but sounds like an access is still at least two cycles
+			*cycles += 2;
+		} else if (address < 0xE00000) {
+			//cart is slow and only 32-bits wide
+			*cycles += 2 * (system->rom_cycles);
+			src = system->cart + (address >> 1 & (system->cart_size - 1));
+		} else {
+			*cycles += 2;
+			return rom0_read_64(address, system);
+		}
+	} else if (address > 0x800000) {
+		src = system->dram + (address >> 1 & (DRAM_WORDS - 1));
+		//DRAM is 64-bits wide, but sounds like an access is still at least two cycles
+		*cycles += 2;
+	} else if (address > 0x200000) {
+		//cart is slow and only 32-bits wide
+		*cycles += 2 * (system->rom_cycles);
+		src = system->cart + (address >> 1 & (system->cart_size - 1));
+	} else {
+		*cycles += 2;
+		return rom0_read_64(address, system);
+	}
+	uint64_t high = src[0];
+	uint64_t highmid = src[1];
+	uint64_t lowmid = src[2];
+	uint64_t low = src[3];
+	return high << 48 | highmid << 32 | lowmid << 16 | low;
+}
+
+uint32_t jag_write_phrase(jaguar_context *system, uint32_t address, uint64_t val)
+{
+	if (!system->memcon_written) {
+		//unsure of timing, but presumably at least 2 32-bit reads 
+		//which presumably take a minimum of 1 cycle
+		//reality probably depends on the exact area read
+		//docs seem to imply some areas only 16-bits wide whereas others are 32-bit
+		rom0_write_64(address, system, val);
+		return 2;
+	}
+	uint16_t *dst;
+	uint32_t cycles;
+	if (system->memcon1 & 1) {
+		if (address < 0x800000) {
+			dst = system->dram + (address >> 1 & (DRAM_WORDS - 1));
+			//DRAM is 64-bits wide, but sounds like an access is still at least two cycles
+			cycles = 2;
+		} else if (address < 0xE00000) {
+			dst = system->cart + (address >> 1 & (system->cart_size - 1));
+			//cart is slow and only 32-bits wide
+			cycles = 2 * (system->rom_cycles);
+		} else {
+			rom0_write_64(address, system, val);
+			return 2;
+		}
+	} else if (address > 0x800000) {
+		dst = system->dram + (address >> 1 & (DRAM_WORDS - 1));
+		//DRAM is 64-bits wide, but sounds like an access is still at least two cycles
+		cycles = 2;
+	} else if (address > 0x200000) {
+		dst = system->cart + (address >> 1 & (system->cart_size - 1));
+		//cart is slow and only 32-bits wide
+		cycles = 2 * (system->rom_cycles);
+	} else {
+		rom0_write_64(address, system, val);
+		return 2;
+	}
+	dst[0] = val >> 48;
+	dst[1] = val >> 32;
+	dst[2] = val >> 16;
+	dst[3] = val;
+	return cycles;
+}
+
 m68k_context * sync_components(m68k_context * context, uint32_t address)
 {
 	jaguar_context *system = context->system;
@@ -318,6 +439,7 @@
 	system->m68k = init_68k_context(opts, handle_m68k_reset);
 	system->m68k->system = system;
 	system->video = jag_video_init();
+	system->video->system = system;
 	return system;
 }