// Note: Endian wrongness probably stems from the MAME origins of this emu and
// the braindead way in which MAME handles memory. :-)
//
+// JLH = James L. Hammons
+//
+// WHO WHEN WHAT
+// --- ---------- -----------------------------------------------------------
+// JLH 11/25/2009 Major rewrite of memory subsystem and handlers
+//
#include "jaguar.h"
#include <SDL.h>
#include "SDL_opengl.h"
+#include "blitter.h"
#include "cdrom.h"
+#include "dac.h"
#include "dsp.h"
+#include "eeprom.h"
#include "event.h"
#include "gpu.h"
-#include "gui.h"
+//#include "gui.h"
#include "jerry.h"
#include "joystick.h"
#include "log.h"
#include "m68k.h"
-#include "memory.h"
+//#include "memory.h"
+#include "mmu.h"
#include "settings.h"
#include "tom.h"
#include "video.h"
-#include "blitter.h"
-#include "jerry.h"
-#include "dac.h"
-#include "eeprom.h"
#define CPU_DEBUG
//Do this in makefile??? Yes! Could, but it's easier to define here...
extern int effect_start2, effect_start3, effect_start4, effect_start5, effect_start6;
#endif
-// Memory debugging identifiers
-
-const char * whoName[9] =
- { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP" };
-
uint32 jaguar_active_memory_dumps = 0;
uint32 jaguarMainROMCRC32, jaguarROMSize, jaguarRunAddress;
-uint8 jaguarMainRAM[0x400000]; // 68K CPU RAM
-uint8 jaguarMainROM[0x600000]; // 68K CPU ROM
-uint8 jaguarBootROM[0x040000]; // 68K CPU BIOS ROM--uses only half of this!
-uint8 jaguarCDBootROM[0x040000]; // 68K CPU CD BIOS ROM
bool BIOSLoaded = false;
bool CDBIOSLoaded = false;
-uint8 cdRAM[0x100];
-uint8 tomRAM[0x4000];
-uint8 jerryRAM[0x10000];
-
#ifdef CPU_DEBUG_MEMORY
uint8 writeMemMax[0x400000], writeMemMin[0x400000];
uint8 readMem[0x400000];
this crap which is currently scattered over Hell's Half Acre(tm).
Also: We need to distinguish whether or not we need .b, .w, and .dw versions of everything, or if there
-is a good way to collapse that shit.
+is a good way to collapse that shit (look below for inspiration). Current method works, but is error prone.
/*************************************
*
*/
#endif
-#define EXPERIMENTAL_MEMORY_HANDLING
+//#define EXPERIMENTAL_MEMORY_HANDLING
// Experimental memory mappage...
// Dunno if this is a good approach or not, but it seems to make better
// sense to have all this crap in one spot intstead of scattered all over
#ifdef EXPERIMENTAL_MEMORY_HANDLING
// Needed defines...
#define NEW_TIMER_SYSTEM
+
+/*
+uint8 jaguarMainRAM[0x400000]; // 68K CPU RAM
+uint8 jaguarMainROM[0x600000]; // 68K CPU ROM
+uint8 jaguarBootROM[0x040000]; // 68K CPU BIOS ROM--uses only half of this!
+uint8 jaguarCDBootROM[0x040000]; // 68K CPU CD BIOS ROM
+bool BIOSLoaded = false;
+bool CDBIOSLoaded = false;
+
+uint8 cdRAM[0x100];
+uint8 tomRAM[0x4000];
+uint8 jerryRAM[0x10000];
+static uint16 eeprom_ram[64];
+
+// NOTE: CD BIOS ROM is read from cartridge space @ $802000 (it's a cartridge, after all)
+*/
+
+enum MemType { MM_NOP = 0, MM_RAM, MM_ROM, MM_IO };
+
+// M68K Memory map/handlers
+uint32 {
+ { 0x000000, 0x3FFFFF, MM_RAM, jaguarMainRAM },
+ { 0x800000, 0xDFFEFF, MM_ROM, jaguarMainROM },
+// Note that this is really memory mapped I/O region...
+// { 0xDFFF00, 0xDFFFFF, MM_RAM, cdRAM },
+ { 0xDFFF00, 0xDFFF03, MM_IO, cdBUTCH }, // base of Butch == interrupt control register, R/W
+ { 0xDFFF04, 0xDFFF07, MM_IO, cdDSCNTRL }, // DSA control register, R/W
+ { 0xDFFF0A, 0xDFFF0B, MM_IO, cdDS_DATA }, // DSA TX/RX data, R/W
+ { 0xDFFF10, 0xDFFF13, MM_IO, cdI2CNTRL }, // i2s bus control register, R/W
+ { 0xDFFF14, 0xDFFF17, MM_IO, cdSBCNTRL }, // CD subcode control register, R/W
+ { 0xDFFF18, 0xDFFF1B, MM_IO, cdSUBDATA }, // Subcode data register A
+ { 0xDFFF1C, 0xDFFF1F, MM_IO, cdSUBDATB }, // Subcode data register B
+ { 0xDFFF20, 0xDFFF23, MM_IO, cdSB_TIME }, // Subcode time and compare enable (D24)
+ { 0xDFFF24, 0xDFFF27, MM_IO, cdFIFO_DATA }, // i2s FIFO data
+ { 0xDFFF28, 0xDFFF2B, MM_IO, cdI2SDAT2 }, // i2s FIFO data (old)
+ { 0xDFFF2C, 0xDFFF2F, MM_IO, cdUNKNOWN }, // Seems to be some sort of I2S interface
+
+ { 0xE00000, 0xE3FFFF, MM_ROM, jaguarBootROM },
+
+// { 0xF00000, 0xF0FFFF, MM_IO, TOM_REGS_RW },
+ { 0xF00050, 0xF00051, MM_IO, tomTimerPrescaler },
+ { 0xF00052, 0xF00053, MM_IO, tomTimerDivider },
+ { 0xF00400, 0xF005FF, MM_RAM, tomRAM }, // CLUT A&B: How to link these? Write to one writes to the other...
+ { 0xF00600, 0xF007FF, MM_RAM, tomRAM }, // Actually, this is a good approach--just make the reads the same as well
+ //What about LBUF writes???
+ { 0xF02100, 0xF0211F, MM_IO, GPUWriteByte }, // GPU CONTROL
+ { 0xF02200, 0xF0229F, MM_IO, BlitterWriteByte }, // BLITTER
+ { 0xF03000, 0xF03FFF, MM_RAM, GPUWriteByte }, // GPU RAM
+
+ { 0xF10000, 0xF1FFFF, MM_IO, JERRY_REGS_RW },
+
+/*
+ EEPROM:
+ { 0xF14001, 0xF14001, MM_IO_RO, eepromFOO }
+ { 0xF14801, 0xF14801, MM_IO_WO, eepromBAR }
+ { 0xF15001, 0xF15001, MM_IO_RW, eepromBAZ }
+
+ JOYSTICK:
+ { 0xF14000, 0xF14003, MM_IO, joystickFoo }
+ 0 = pad0/1 button values (4 bits each), RO(?)
+ 1 = pad0/1 index value (4 bits each), WO
+ 2 = unused, RO
+ 3 = NTSC/PAL, certain button states, RO
+
+JOYSTICK $F14000 Read/Write
+ 15.....8 7......0
+Read fedcba98 7654321q f-1 Signals J15 to J1
+ q Cartridge EEPROM output data
+Write exxxxxxm 76543210 e 1 = enable J7-J0 outputs
+ 0 = disable J7-J0 outputs
+ x don't care
+ m Audio mute
+ 0 = Audio muted (reset state)
+ 1 = Audio enabled
+ 7-4 J7-J4 outputs (port 2)
+ 3-0 J3-J0 outputs (port 1)
+JOYBUTS $F14002 Read Only
+ 15.....8 7......0
+Read xxxxxxxx rrdv3210 x don't care
+ r Reserved
+ d Reserved
+ v 1 = NTSC Video hardware
+ 0 = PAL Video hardware
+ 3-2 Button inputs B3 & B2 (port 2)
+ 1-0 Button inputs B1 & B0 (port 1)
+
+J4 J5 J6 J7 Port 2 B2 B3 J12 J13 J14 J15
+J3 J2 J1 J0 Port 1 B0 B1 J8 J9 J10 J11
+ 0 0 0 0
+ 0 0 0 1
+ 0 0 1 0
+ 0 0 1 1
+ 0 1 0 0
+ 0 1 0 1
+ 0 1 1 0
+ 0 1 1 1 Row 3 C3 Option # 9 6 3
+ 1 0 0 0
+ 1 0 0 1
+ 1 0 1 0
+ 1 0 1 1 Row 2 C2 C 0 8 5 2
+ 1 1 0 0
+ 1 1 0 1 Row 1 C1 B * 7 4 1
+ 1 1 1 0 Row 0 Pause A Up Down Left Right
+ 1 1 1 1
+
+0 bit read in any position means that button is pressed.
+C3 = C2 = 1 means std. Jag. cntrlr. or nothing attached.
+*/
+};
+
void WriteByte(uint32 address, uint8 byte, uint32 who/*=UNKNOWN*/)
{
// Not sure, but I think the system only has 24 address bits...
return vector;
}
+#define USE_NEW_MMU
+
unsigned int m68k_read_memory_8(unsigned int address)
{
#ifdef CPU_DEBUG_MEMORY
/* if (address == 0x51136 || address == 0x51138 || address == 0xFB074 || address == 0xFB076
|| address == 0x1AF05E)
WriteLog("[RM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, jaguar_mainRam[address]);//*/
+#ifndef USE_NEW_MMU
unsigned int retVal = 0;
if ((address >= 0x000000) && (address <= 0x3FFFFF))
- retVal = jaguarMainRam[address];
+ retVal = jaguarMainRAM[address];
// else if ((address >= 0x800000) && (address <= 0xDFFFFF))
else if ((address >= 0x800000) && (address <= 0xDFFEFF))
- retVal = jaguarMainRom[address - 0x800000];
+ retVal = jaguarMainROM[address - 0x800000];
else if ((address >= 0xE00000) && (address <= 0xE3FFFF))
- retVal = jaguarBootRom[address - 0xE00000];
+ retVal = jaguarBootROM[address - 0xE00000];
else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
retVal = CDROMReadByte(address);
else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
//if (address >= 0x8B5E4 && address <= 0x8B5E4 + 16)
// WriteLog("M68K: Read byte $%02X at $%08X [PC=%08X]\n", retVal, address, m68k_get_reg(NULL, M68K_REG_PC));
return retVal;
+#else
+ return MMURead8(address, M68K);
+#endif
}
void gpu_dump_disassembly(void);
/* if (address == 0x51136 || address == 0x51138 || address == 0xFB074 || address == 0xFB076
|| address == 0x1AF05E)
WriteLog("[RM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, GET16(jaguar_mainRam, address));//*/
+#ifndef USE_NEW_MMU
unsigned int retVal = 0;
if ((address >= 0x000000) && (address <= 0x3FFFFE))
// retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1];
- retVal = GET16(jaguarMainRam, address);
+ retVal = GET16(jaguarMainRAM, address);
// else if ((address >= 0x800000) && (address <= 0xDFFFFE))
else if ((address >= 0x800000) && (address <= 0xDFFEFE))
- retVal = (jaguarMainRom[address - 0x800000] << 8) | jaguarMainRom[address - 0x800000 + 1];
+ retVal = (jaguarMainROM[address - 0x800000] << 8) | jaguarMainROM[address - 0x800000 + 1];
else if ((address >= 0xE00000) && (address <= 0xE3FFFE))
- retVal = (jaguarBootRom[address - 0xE00000] << 8) | jaguarBootRom[address - 0xE00000 + 1];
+ retVal = (jaguarBootROM[address - 0xE00000] << 8) | jaguarBootROM[address - 0xE00000 + 1];
else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
retVal = CDROMReadWord(address, M68K);
else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
//if (address >= 0x8B5E4 && address <= 0x8B5E4 + 16)
// WriteLog("M68K: Read word $%04X at $%08X [PC=%08X]\n", retVal, address, m68k_get_reg(NULL, M68K_REG_PC));
return retVal;
+#else
+ return MMURead16(address, M68K);
+#endif
}
unsigned int m68k_read_memory_32(unsigned int address)
WriteLog("[RM32 PC=%08X] Addr: %08X, val: %08X\n", m68k_get_reg(NULL, M68K_REG_PC), address, (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2));//*/
//WriteLog("--> [RM32]\n");
+#ifndef USE_NEW_MMU
return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2);
+#else
+ return MMURead32(address, M68K);
+#endif
}
void m68k_write_memory_8(unsigned int address, unsigned int value)
if (address >= 0x18FA70 && address < (0x18FA70 + 8000))
WriteLog("M68K: Byte %02X written at %08X by 68K\n", value, address);//*/
+#ifndef USE_NEW_MMU
if ((address >= 0x000000) && (address <= 0x3FFFFF))
- jaguarMainRam[address] = value;
+ jaguarMainRAM[address] = value;
else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
CDROMWriteByte(address, value, M68K);
else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
JERRYWriteByte(address, value, M68K);
else
jaguar_unknown_writebyte(address, value, M68K);
+#else
+ MMUWrite8(address, value, M68K);
+#endif
}
void m68k_write_memory_16(unsigned int address, unsigned int value)
|| address == 0x1AF05E)
WriteLog("[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/
+#ifndef USE_NEW_MMU
if ((address >= 0x000000) && (address <= 0x3FFFFE))
{
/* jaguar_mainRam[address] = value >> 8;
jaguar_mainRam[address + 1] = value & 0xFF;*/
- SET16(jaguarMainRam, address, value);
+ SET16(jaguarMainRAM, address, value);
}
else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
CDROMWriteWord(address, value, M68K);
WriteLog("\tA0=%08X, A1=%08X, D0=%08X, D1=%08X\n",
m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1),
m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1));
-#endif
}
+#endif
+#else
+ MMUWrite16(address, value, M68K);
+#endif
}
void m68k_write_memory_32(unsigned int address, unsigned int value)
/* if (address == 0x51136 || address == 0xFB074)
WriteLog("[WM32 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/
+#ifndef USE_NEW_MMU
m68k_write_memory_16(address, value >> 16);
m68k_write_memory_16(address + 2, value & 0xFFFF);
+#else
+ MMUWrite32(address, value, M68K);
+#endif
}
offset &= 0xFFFFFF;
if (offset < 0x400000)
- data = jaguarMainRam[offset & 0x3FFFFF];
+ data = jaguarMainRAM[offset & 0x3FFFFF];
else if ((offset >= 0x800000) && (offset < 0xC00000))
- data = jaguarMainRom[offset - 0x800000];
+ data = jaguarMainROM[offset - 0x800000];
else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
data = CDROMReadByte(offset, who);
else if ((offset >= 0xE00000) && (offset < 0xE40000))
- data = jaguarBootRom[offset & 0x3FFFF];
+ data = jaguarBootROM[offset & 0x3FFFF];
else if ((offset >= 0xF00000) && (offset < 0xF10000))
data = TOMReadByte(offset, who);
else if ((offset >= 0xF10000) && (offset < 0xF20000))
offset &= 0xFFFFFF;
if (offset <= 0x3FFFFE)
{
- return (jaguarMainRam[(offset+0) & 0x3FFFFF] << 8) | jaguarMainRam[(offset+1) & 0x3FFFFF];
+ return (jaguarMainRAM[(offset+0) & 0x3FFFFF] << 8) | jaguarMainRAM[(offset+1) & 0x3FFFFF];
}
else if ((offset >= 0x800000) && (offset <= 0xBFFFFE))
{
offset -= 0x800000;
- return (jaguarMainRom[offset+0] << 8) | jaguarMainRom[offset+1];
+ return (jaguarMainROM[offset+0] << 8) | jaguarMainROM[offset+1];
}
// else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
return CDROMReadWord(offset, who);
else if ((offset >= 0xE00000) && (offset <= 0xE3FFFE))
- return (jaguarBootRom[(offset+0) & 0x3FFFF] << 8) | jaguarBootRom[(offset+1) & 0x3FFFF];
+ return (jaguarBootROM[(offset+0) & 0x3FFFF] << 8) | jaguarBootROM[(offset+1) & 0x3FFFF];
else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
return TOMReadWord(offset, who);
else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
offset &= 0xFFFFFF;
if (offset < 0x400000)
{
- jaguarMainRam[offset & 0x3FFFFF] = data;
+ jaguarMainRAM[offset & 0x3FFFFF] = data;
return;
}
else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
if (offset == 0x11D31A + 0x48000 || offset == 0x11D31A)
WriteLog("JWW: %s writing star %04X at %08X...\n", whoName[who], data, offset);//*/
- jaguarMainRam[(offset+0) & 0x3FFFFF] = data >> 8;
- jaguarMainRam[(offset+1) & 0x3FFFFF] = data & 0xFF;
+ jaguarMainRAM[(offset+0) & 0x3FFFFF] = data >> 8;
+ jaguarMainRAM[(offset+1) & 0x3FFFFF] = data & 0xFF;
return;
}
else if (offset >= 0xDFFF00 && offset <= 0xDFFFFE)
memset(writeMemMin, 0xFF, 0x400000);
memset(writeMemMax, 0x00, 0x400000);
#endif
- memset(jaguarMainRam, 0x00, 0x400000);
+ memset(jaguarMainRAM, 0x00, 0x400000);
// memset(jaguar_mainRom, 0xFF, 0x200000); // & set it to all Fs...
// memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s...
//NOTE: This *doesn't* fix FlipOut...
//Or does it? Hmm...
//Seems to want $01010101... Dunno why. Investigate!
- memset(jaguarMainRom, 0x01, 0x600000); // & set it to all 01s...
+ memset(jaguarMainROM, 0x01, 0x600000); // & set it to all 01s...
// memset(jaguar_mainRom, 0xFF, 0x600000); // & set it to all Fs...
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
{
//NOTE: This causes a (virtual) crash if this is set in the config but not found... !!! FIX !!!
if (vjs.useJaguarBIOS)
- memcpy(jaguarMainRam, jaguarBootRom, 8);
+ memcpy(jaguarMainRAM, jaguarBootROM, 8);
else
- SET32(jaguarMainRam, 4, jaguarRunAddress);
+ SET32(jaguarMainRAM, 4, jaguarRunAddress);
// WriteLog("jaguar_reset():\n");
TOMReset();
// uint16 vde = TOMReadWord(0xF00048);
uint16 refreshRate = (vjs.hardwareTypeNTSC ? 60 : 50);
- uint32 m68kCockRate = (vjs.hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL);
+ uint32 m68kClockRate = (vjs.hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL);
//Not sure the above is correct, since the number of lines and timings given in the JTRM
//seem to indicate the refresh rate is *half* the above...
// uint16 refreshRate = (vjs.hardwareTypeNTSC ? 30 : 25);
if (fp == NULL)
return;
- fwrite(jaguarMainRam, 1, 0x400000, fp);
+ fwrite(jaguarMainRAM, 1, 0x400000, fp);
fclose(fp);
}
uint8 * GetRamPtr(void)
{
- return jaguarMainRam;
+ return jaguarMainRAM;
}
//