From a34be0c722746101ef35a8f860d6d618deca213b Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Thu, 26 Nov 2009 06:11:48 +0000 Subject: [PATCH] We can now compile, but still doesn't work at this point... Lots of cleanup --- src/eeprom.cpp | 2 +- src/file.cpp | 50 ++++---- src/gui/gui.cpp | 16 +-- src/jaguar.cpp | 90 ++++++++----- src/jaguar.h | 8 +- src/jerry.cpp | 326 +++++++++++++++++++++++++----------------------- src/mmu.cpp | 245 ++++++++++++++++++++++++++++++++++++ src/tom.cpp | 42 +++---- src/vj.cpp | 6 +- 9 files changed, 535 insertions(+), 250 deletions(-) diff --git a/src/eeprom.cpp b/src/eeprom.cpp index 35e0d4d..fe3b1d0 100644 --- a/src/eeprom.cpp +++ b/src/eeprom.cpp @@ -48,7 +48,7 @@ static bool foundEEPROM = false; void EepromInit(void) { - sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainRomCRC32); + sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32); FILE * fp = fopen(eeprom_filename, "rb"); if (fp) diff --git a/src/file.cpp b/src/file.cpp index 58d22e7..4fc852c 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -96,7 +96,7 @@ else bool JaguarLoadFile(char * path) { // jaguarRomSize = JaguarLoadROM(mem, path); - jaguarRomSize = JaguarLoadROM(jaguarMainRom, path); + jaguarROMSize = JaguarLoadROM(jaguarMainROM, path); /*//This is not *nix friendly for some reason... // if (!UserSelectFile(path, newPath)) @@ -107,7 +107,7 @@ bool JaguarLoadFile(char * path) exit(0); }*/ - if (jaguarRomSize == 0) + if (jaguarROMSize == 0) { // WriteLog("VJ: Could not load ROM from file \"%s\"...\nAborting!\n", newPath); WriteLog("GUI: Could not load ROM from file \"%s\"...\nAborting load!\n", path); @@ -117,8 +117,8 @@ bool JaguarLoadFile(char * path) return false; // This is a start... } - jaguarMainRomCRC32 = crc32_calcCheckSum(jaguarMainRom, jaguarRomSize); - WriteLog("CRC: %08X\n", (unsigned int)jaguarMainRomCRC32); + jaguarMainROMCRC32 = crc32_calcCheckSum(jaguarMainROM, jaguarROMSize); + WriteLog("CRC: %08X\n", (unsigned int)jaguarMainROMCRC32); EepromInit(); jaguarRunAddress = 0x802000; @@ -129,12 +129,12 @@ bool JaguarLoadFile(char * path) if (strcasecmp(ext, ".rom") == 0) { // File extension ".ROM": Alpine image that loads/runs at $802000 - WriteLog("GUI: Setting up homebrew (ROM)... Run address: 00802000, length: %08X\n", jaguarRomSize); + WriteLog("GUI: Setting up homebrew (ROM)... Run address: 00802000, length: %08X\n", jaguarROMSize); - for(int i=jaguarRomSize-1; i>=0; i--) - jaguarMainRom[0x2000 + i] = jaguarMainRom[i]; + for(int i=jaguarROMSize-1; i>=0; i--) + jaguarMainROM[0x2000 + i] = jaguarMainROM[i]; - memset(jaguarMainRom, 0xFF, 0x2000); + memset(jaguarMainROM, 0xFF, 0x2000); /* memcpy(jaguar_mainRam, jaguar_mainRom, jaguarRomSize); memset(jaguar_mainRom, 0xFF, 0x600000); memcpy(jaguar_mainRom + 0x2000, jaguar_mainRam, jaguarRomSize); @@ -184,8 +184,8 @@ Let's try setting up the illegal instruction vector for a stubulated jaguar... // Try setting the vector to say, $1000 and putting an instruction there that loops forever: // This kludge works! Yeah! - SET32(jaguarMainRam, 0x10, 0x00001000); - SET16(jaguarMainRam, 0x1000, 0x60FE); // Here: bra Here + SET32(jaguarMainRAM, 0x10, 0x00001000); + SET16(jaguarMainRAM, 0x1000, 0x60FE); // Here: bra Here } else if (strcasecmp(ext, ".abs") == 0) { @@ -237,18 +237,18 @@ Starting Address for executable = 0x00802000 Start of Text Segment = 0x00802000 Start of Data Segment = 0x00803dd0 */ - if (jaguarMainRom[0] == 0x60 && jaguarMainRom[1] == 0x1B) + if (jaguarMainROM[0] == 0x60 && jaguarMainROM[1] == 0x1B) { - uint32 loadAddress = GET32(jaguarMainRom, 0x16), //runAddress = GET32(jaguar_mainRom, 0x2A), - codeSize = GET32(jaguarMainRom, 0x02) + GET32(jaguarMainRom, 0x06); + uint32 loadAddress = GET32(jaguarMainROM, 0x16), //runAddress = GET32(jaguar_mainRom, 0x2A), + codeSize = GET32(jaguarMainROM, 0x02) + GET32(jaguarMainROM, 0x06); WriteLog("GUI: Setting up homebrew (ABS-1)... Run address: %08X, length: %08X\n", loadAddress, codeSize); if (loadAddress < 0x800000) - memcpy(jaguarMainRam + loadAddress, jaguarMainRom + 0x24, codeSize); + memcpy(jaguarMainRAM + loadAddress, jaguarMainROM + 0x24, codeSize); else { for(int i=codeSize-1; i>=0; i--) - jaguarMainRom[(loadAddress - 0x800000) + i] = jaguarMainRom[i + 0x24]; + jaguarMainROM[(loadAddress - 0x800000) + i] = jaguarMainROM[i + 0x24]; /* memcpy(jaguar_mainRam, jaguar_mainRom + 0x24, codeSize); memset(jaguar_mainRom, 0xFF, 0x600000); memcpy(jaguar_mainRom + (loadAddress - 0x800000), jaguar_mainRam, codeSize); @@ -257,18 +257,18 @@ Start of Data Segment = 0x00803dd0 jaguarRunAddress = loadAddress; } - else if (jaguarMainRom[0] == 0x01 && jaguarMainRom[1] == 0x50) + else if (jaguarMainROM[0] == 0x01 && jaguarMainROM[1] == 0x50) { - uint32 loadAddress = GET32(jaguarMainRom, 0x28), runAddress = GET32(jaguarMainRom, 0x24), - codeSize = GET32(jaguarMainRom, 0x18) + GET32(jaguarMainRom, 0x1C); + uint32 loadAddress = GET32(jaguarMainROM, 0x28), runAddress = GET32(jaguarMainROM, 0x24), + codeSize = GET32(jaguarMainROM, 0x18) + GET32(jaguarMainROM, 0x1C); WriteLog("GUI: Setting up homebrew (ABS-2)... Run address: %08X, length: %08X\n", runAddress, codeSize); if (loadAddress < 0x800000) - memcpy(jaguarMainRam + loadAddress, jaguarMainRom + 0xA8, codeSize); + memcpy(jaguarMainRAM + loadAddress, jaguarMainROM + 0xA8, codeSize); else { for(int i=codeSize-1; i>=0; i--) - jaguarMainRom[(loadAddress - 0x800000) + i] = jaguarMainRom[i + 0xA8]; + jaguarMainROM[(loadAddress - 0x800000) + i] = jaguarMainROM[i + 0xA8]; /* memcpy(jaguar_mainRam, jaguar_mainRom + 0xA8, codeSize); memset(jaguar_mainRom, 0xFF, 0x600000); memcpy(jaguar_mainRom + (loadAddress - 0x800000), jaguar_mainRam, codeSize); @@ -279,7 +279,7 @@ Start of Data Segment = 0x00803dd0 } else { - WriteLog("GUI: Couldn't find correct ABS format: %02X %02X\n", jaguarMainRom[0], jaguarMainRom[1]); + WriteLog("GUI: Couldn't find correct ABS format: %02X %02X\n", jaguarMainROM[0], jaguarMainROM[1]); return false; } } @@ -288,9 +288,9 @@ Start of Data Segment = 0x00803dd0 // File extension ".JAG": Atari server file with header //NOTE: The bytes 'JAGR' should also be at position $1C... // Also, there's *always* a $601A header at position $00... - if (jaguarMainRom[0] == 0x60 && jaguarMainRom[1] == 0x1A) + if (jaguarMainROM[0] == 0x60 && jaguarMainROM[1] == 0x1A) { - uint32 loadAddress = GET32(jaguarMainRom, 0x22), runAddress = GET32(jaguarMainRom, 0x2A); + uint32 loadAddress = GET32(jaguarMainROM, 0x22), runAddress = GET32(jaguarMainROM, 0x2A); //This is not always right! Especially when converted via bin2jag1!!! //We should have access to the length of the furshlumiger file that was loaded anyway! //Now, we do! ;-) @@ -299,8 +299,8 @@ Start of Data Segment = 0x00803dd0 //jaguarRunAddress // WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength); // memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, progLength); - WriteLog("GUI: Setting up homebrew (JAG)... Run address: %08X, length: %08X\n", runAddress, jaguarRomSize - 0x2E); - memcpy(jaguarMainRam + loadAddress, jaguarMainRom + 0x2E, jaguarRomSize - 0x2E); + WriteLog("GUI: Setting up homebrew (JAG)... Run address: %08X, length: %08X\n", runAddress, jaguarROMSize - 0x2E); + memcpy(jaguarMainRAM + loadAddress, jaguarMainROM + 0x2E, jaguarROMSize - 0x2E); // SET32(jaguar_mainRam, 4, runAddress); jaguarRunAddress = runAddress; } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 95e0192..2cdd58d 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -347,14 +347,14 @@ Window * ResetJaguar(void) Window * ResetJaguarCD(void) { - memcpy(jaguarMainRom, jaguarCDBootROM, 0x40000); + memcpy(jaguarMainROM, jaguarCDBootROM, 0x40000); jaguarRunAddress = 0x802000; - jaguarMainRomCRC32 = crc32_calcCheckSum(jaguarMainRom, 0x40000); + jaguarMainROMCRC32 = crc32_calcCheckSum(jaguarMainROM, 0x40000); JaguarReset(); //This is a quick kludge to get the CDBIOS to boot properly... //Wild speculation: It could be that this memory location is wired into the CD unit //somehow, which lets it know whether or not a cart is present in the unit... - jaguarMainRom[0x0040B] = 0x03; + jaguarMainROM[0x0040B] = 0x03; return RunEmu(); } @@ -508,13 +508,13 @@ Window * RunEmu(void) debounceRunKey = true; uint32 cartType = 4; - if (jaguarRomSize == 0x200000) + if (jaguarROMSize == 0x200000) cartType = 0; - else if (jaguarRomSize == 0x400000) + else if (jaguarROMSize == 0x400000) cartType = 1; - else if (jaguarMainRomCRC32 == 0x687068D5) + else if (jaguarMainROMCRC32 == 0x687068D5) cartType = 2; - else if (jaguarMainRomCRC32 == 0x55A0669C) + else if (jaguarMainROMCRC32 == 0x55A0669C) cartType = 3; const char * cartTypeName[5] = { "2M Cartridge", "4M Cartridge", "CD BIOS", "CD Dev BIOS", "Homebrew" }; @@ -555,7 +555,7 @@ else { DrawString2(overlayPixels, 8, 24*FONT_HEIGHT, 0x007F63FF, transparency, "Running..."); DrawString2(overlayPixels, 8, 26*FONT_HEIGHT, 0x001FFF3F, transparency, "%s, run address: %06X", cartTypeName[cartType], jaguarRunAddress); - DrawString2(overlayPixels, 8, 27*FONT_HEIGHT, 0x001FFF3F, transparency, "CRC: %08X", jaguarMainRomCRC32); + DrawString2(overlayPixels, 8, 27*FONT_HEIGHT, 0x001FFF3F, transparency, "CRC: %08X", jaguarMainROMCRC32); if (showMsgFrames == 0) { diff --git a/src/jaguar.cpp b/src/jaguar.cpp index 582ec85..facaa12 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -7,13 +7,22 @@ // 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 #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" @@ -22,13 +31,10 @@ #include "log.h" #include "m68k.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... @@ -436,7 +442,7 @@ ADDRESS_MAP_END */ #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 @@ -799,6 +805,8 @@ int irq_ack_handler(int level) return vector; } +#define USE_NEW_MMU + unsigned int m68k_read_memory_8(unsigned int address) { #ifdef CPU_DEBUG_MEMORY @@ -813,15 +821,16 @@ unsigned int m68k_read_memory_8(unsigned int address) /* 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)) @@ -836,6 +845,9 @@ unsigned int m68k_read_memory_8(unsigned int address) //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); @@ -903,16 +915,17 @@ unsigned int m68k_read_memory_16(unsigned int address) /* 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)) @@ -931,6 +944,9 @@ unsigned int m68k_read_memory_16(unsigned int address) //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) @@ -940,7 +956,11 @@ 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) @@ -964,8 +984,9 @@ 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)) @@ -974,6 +995,9 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) 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) @@ -1021,11 +1045,12 @@ if (address == 0xF02110) || 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); @@ -1040,8 +1065,11 @@ if (address == 0xF02110) 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) @@ -1059,8 +1087,12 @@ if (address == 0xF03214 && value == 0x88E30047) /* 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 } @@ -1232,13 +1264,13 @@ uint8 JaguarReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) 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)) @@ -1254,18 +1286,18 @@ uint16 JaguarReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) 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)) @@ -1284,7 +1316,7 @@ void JaguarWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) offset &= 0xFFFFFF; if (offset < 0x400000) { - jaguarMainRam[offset & 0x3FFFFF] = data; + jaguarMainRAM[offset & 0x3FFFFF] = data; return; } else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF)) @@ -1412,8 +1444,8 @@ if (who == GPU && (gpu_pc == 0xF03604 || gpu_pc == 0xF03638)) 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) @@ -1470,13 +1502,13 @@ void JaguarInit(void) 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); @@ -1495,9 +1527,9 @@ void JaguarReset(void) { //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(); @@ -1696,13 +1728,13 @@ void DumpMainMemory(void) if (fp == NULL) return; - fwrite(jaguarMainRam, 1, 0x400000, fp); + fwrite(jaguarMainRAM, 1, 0x400000, fp); fclose(fp); } uint8 * GetRamPtr(void) { - return jaguarMainRam; + return jaguarMainRAM; } // diff --git a/src/jaguar.h b/src/jaguar.h index d4bb738..96d7b4c 100644 --- a/src/jaguar.h +++ b/src/jaguar.h @@ -23,14 +23,14 @@ void JaguarExecuteNew(void); // Exports from JAGUAR.CPP -extern uint8 jaguarMainRam[]; -extern uint8 jaguarMainRom[]; -extern uint8 jaguarBootRom[]; +extern uint8 jaguarMainRAM[]; +extern uint8 jaguarMainROM[]; +extern uint8 jaguarBootROM[]; extern uint8 jaguarCDBootROM[]; extern bool BIOSLoaded; extern bool CDBIOSLoaded; extern int32 jaguarCPUInExec; -extern uint32 jaguarMainRomCRC32, jaguarRomSize, jaguarRunAddress; +extern uint32 jaguarMainROMCRC32, jaguarROMSize, jaguarRunAddress; extern char * jaguarEepromsPath; extern const char * whoName[9]; diff --git a/src/jerry.cpp b/src/jerry.cpp index e7aee58..8603b90 100644 --- a/src/jerry.cpp +++ b/src/jerry.cpp @@ -5,144 +5,151 @@ // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Carwin Jones (BeOS) // Cleanups/rewrites/fixes by James L. Hammons // -// ------------------------------------------------------------ -// JERRY REGISTERS (Mapped by Aaron Giles) -// ------------------------------------------------------------ -// F10000-F13FFF R/W xxxxxxxx xxxxxxxx Jerry -// F10000 W xxxxxxxx xxxxxxxx JPIT1 - timer 1 pre-scaler -// F10002 W xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider -// F10004 W xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler -// F10008 W xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider -// F10010 W ------xx xxxxxxxx CLK1 - processor clock divider -// F10012 W ------xx xxxxxxxx CLK2 - video clock divider -// F10014 W -------- --xxxxxx CLK3 - chroma clock divider -// F10020 R/W ---xxxxx ---xxxxx JINTCTRL - interrupt control register -// W ---x---- -------- (J_SYNCLR - clear synchronous serial intf ints) -// W ----x--- -------- (J_ASYNCLR - clear asynchronous serial intf ints) -// W -----x-- -------- (J_TIM2CLR - clear timer 2 [tempo] interrupts) -// W ------x- -------- (J_TIM1CLR - clear timer 1 [sample] interrupts) -// W -------x -------- (J_EXTCLR - clear external interrupts) -// R/W -------- ---x---- (J_SYNENA - enable synchronous serial intf ints) -// R/W -------- ----x--- (J_ASYNENA - enable asynchronous serial intf ints) -// R/W -------- -----x-- (J_TIM2ENA - enable timer 2 [tempo] interrupts) -// R/W -------- ------x- (J_TIM1ENA - enable timer 1 [sample] interrupts) -// R/W -------- -------x (J_EXTENA - enable external interrupts) -// F10030 R/W -------- xxxxxxxx ASIDATA - asynchronous serial data -// F10032 W -x------ -xxxxxxx ASICTRL - asynchronous serial control -// W -x------ -------- (TXBRK - transmit break) -// W -------- -x------ (CLRERR - clear error) -// W -------- --x----- (RINTEN - enable receiver interrupts) -// W -------- ---x---- (TINTEN - enable transmitter interrupts) -// W -------- ----x--- (RXIPOL - receiver input polarity) -// W -------- -----x-- (TXOPOL - transmitter output polarity) -// W -------- ------x- (PAREN - parity enable) -// W -------- -------x (ODD - odd parity select) -// F10032 R xxx-xxxx x-xxxxxx ASISTAT - asynchronous serial status -// R x------- -------- (ERROR - OR of PE,FE,OE) -// R -x------ -------- (TXBRK - transmit break) -// R --x----- -------- (SERIN - serial input) -// R ----x--- -------- (OE - overrun error) -// R -----x-- -------- (FE - framing error) -// R ------x- -------- (PE - parity error) -// R -------x -------- (TBE - transmit buffer empty) -// R -------- x------- (RBF - receive buffer full) -// R -------- ---x---- (TINTEN - enable transmitter interrupts) -// R -------- ----x--- (RXIPOL - receiver input polarity) -// R -------- -----x-- (TXOPOL - transmitter output polarity) -// R -------- ------x- (PAREN - parity enable) -// R -------- -------x (ODD - odd parity) -// F10034 R/W xxxxxxxx xxxxxxxx ASICLK - asynchronous serial interface clock -// F10036 R xxxxxxxx xxxxxxxx JPIT1 - timer 1 pre-scaler -// F10038 R xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider -// F1003A R xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler -// F1003C R xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider -// ------------------------------------------------------------ -// F14000-F17FFF R/W xxxxxxxx xxxxxxxx Joysticks and GPIO0-5 -// F14000 R xxxxxxxx xxxxxxxx JOYSTICK - read joystick state -// F14000 W x------- xxxxxxxx JOYSTICK - latch joystick output -// W x------- -------- (enable joystick outputs) -// W -------- xxxxxxxx (joystick output data) -// F14002 R xxxxxxxx xxxxxxxx JOYBUTS - button register -// F14800-F14FFF R/W xxxxxxxx xxxxxxxx GPI00 - reserved (CD-ROM? no.) -// F15000-F15FFF R/W xxxxxxxx xxxxxxxx GPI01 - reserved -// F16000-F16FFF R/W xxxxxxxx xxxxxxxx GPI02 - reserved -// F17000-F177FF R/W xxxxxxxx xxxxxxxx GPI03 - reserved -// F17800-F17BFF R/W xxxxxxxx xxxxxxxx GPI04 - reserved -// F17C00-F17FFF R/W xxxxxxxx xxxxxxxx GPI05 - reserved -// ------------------------------------------------------------ -// F18000-F1FFFF R/W xxxxxxxx xxxxxxxx Jerry DSP -// F1A100 R/W xxxxxxxx xxxxxxxx D_FLAGS - DSP flags register -// R/W x------- -------- (DMAEN - DMA enable) -// R/W -x------ -------- (REGPAGE - register page) -// W --x----- -------- (D_EXT0CLR - clear external interrupt 0) -// W ---x---- -------- (D_TIM2CLR - clear timer 2 interrupt) -// W ----x--- -------- (D_TIM1CLR - clear timer 1 interrupt) -// W -----x-- -------- (D_I2SCLR - clear I2S interrupt) -// W ------x- -------- (D_CPUCLR - clear CPU interrupt) -// R/W -------x -------- (D_EXT0ENA - enable external interrupt 0) -// R/W -------- x------- (D_TIM2ENA - enable timer 2 interrupt) -// R/W -------- -x------ (D_TIM1ENA - enable timer 1 interrupt) -// R/W -------- --x----- (D_I2SENA - enable I2S interrupt) -// R/W -------- ---x---- (D_CPUENA - enable CPU interrupt) -// R/W -------- ----x--- (IMASK - interrupt mask) -// R/W -------- -----x-- (NEGA_FLAG - ALU negative) -// R/W -------- ------x- (CARRY_FLAG - ALU carry) -// R/W -------- -------x (ZERO_FLAG - ALU zero) -// F1A102 R/W -------- ------xx D_FLAGS - upper DSP flags -// R/W -------- ------x- (D_EXT1ENA - enable external interrupt 1) -// R/W -------- -------x (D_EXT1CLR - clear external interrupt 1) -// F1A104 W -------- ----xxxx D_MTXC - matrix control register -// W -------- ----x--- (MATCOL - column/row major) -// W -------- -----xxx (MATRIX3-15 - matrix width) -// F1A108 W ----xxxx xxxxxx-- D_MTXA - matrix address register -// F1A10C W -------- -----x-x D_END - data organization register -// W -------- -----x-- (BIG_INST - big endian instruction fetch) -// W -------- -------x (BIG_IO - big endian I/O) -// F1A110 R/W xxxxxxxx xxxxxxxx D_PC - DSP program counter -// F1A114 R/W xxxxxxxx xx-xxxxx D_CTRL - DSP control/status register -// R xxxx---- -------- (VERSION - DSP version code) -// R/W ----x--- -------- (BUS_HOG - hog the bus!) -// R/W -----x-- -------- (D_EXT0LAT - external interrupt 0 latch) -// R/W ------x- -------- (D_TIM2LAT - timer 2 interrupt latch) -// R/W -------x -------- (D_TIM1LAT - timer 1 interrupt latch) -// R/W -------- x------- (D_I2SLAT - I2S interrupt latch) -// R/W -------- -x------ (D_CPULAT - CPU interrupt latch) -// R/W -------- ---x---- (SINGLE_GO - single step one instruction) -// R/W -------- ----x--- (SINGLE_STEP - single step mode) -// R/W -------- -----x-- (FORCEINT0 - cause interrupt 0 on GPU) -// R/W -------- ------x- (CPUINT - send GPU interrupt to CPU) -// R/W -------- -------x (DSPGO - enable DSP execution) -// F1A116 R/W -------- -------x D_CTRL - upper DSP control/status register -// R/W -------- -------x (D_EXT1LAT - external interrupt 1 latch) -// F1A118-F1A11B W xxxxxxxx xxxxxxxx D_MOD - modulo instruction mask -// F1A11C-F1A11F R xxxxxxxx xxxxxxxx D_REMAIN - divide unit remainder -// F1A11C W -------- -------x D_DIVCTRL - divide unit control -// W -------- -------x (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide) -// F1A120-F1A123 R xxxxxxxx xxxxxxxx D_MACHI - multiply & accumulate high bits -// F1A148 W xxxxxxxx xxxxxxxx R_DAC - right transmit data -// F1A14C W xxxxxxxx xxxxxxxx L_DAC - left transmit data -// F1A150 W -------- xxxxxxxx SCLK - serial clock frequency -// F1A150 R -------- ------xx SSTAT -// R -------- ------x- (left - no description) -// R -------- -------x (WS - word strobe status) -// F1A154 W -------- --xxxx-x SMODE - serial mode -// W -------- --x----- (EVERYWORD - interrupt on MSB of every word) -// W -------- ---x---- (FALLING - interrupt on falling edge) -// W -------- ----x--- (RISING - interrupt of rising edge) -// W -------- -----x-- (WSEN - enable word strobes) -// W -------- -------x (INTERNAL - enables serial clock) -// ------------------------------------------------------------ -// F1B000-F1CFFF R/W xxxxxxxx xxxxxxxx Local DSP RAM -// ------------------------------------------------------------ -// F1D000 R xxxxxxxx xxxxxxxx ROM_TRI - triangle wave -// F1D200 R xxxxxxxx xxxxxxxx ROM_SINE - full sine wave -// F1D400 R xxxxxxxx xxxxxxxx ROM_AMSINE - amplitude modulated sine wave -// F1D600 R xxxxxxxx xxxxxxxx ROM_12W - sine wave and second order harmonic -// F1D800 R xxxxxxxx xxxxxxxx ROM_CHIRP16 - chirp -// F1DA00 R xxxxxxxx xxxxxxxx ROM_NTRI - traingle wave with noise -// F1DC00 R xxxxxxxx xxxxxxxx ROM_DELTA - spike -// F1DE00 R xxxxxxxx xxxxxxxx ROM_NOISE - white noise -// ------------------------------------------------------------ +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ----------------------------------------------------------- +// JLH 11/25/2009 Major rewrite of memory subsystem and handlers +// + +// ------------------------------------------------------------ +// JERRY REGISTERS (Mapped by Aaron Giles) +// ------------------------------------------------------------ +// F10000-F13FFF R/W xxxxxxxx xxxxxxxx Jerry +// F10000 W xxxxxxxx xxxxxxxx JPIT1 - timer 1 pre-scaler +// F10002 W xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider +// F10004 W xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler +// F10008 W xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider +// F10010 W ------xx xxxxxxxx CLK1 - processor clock divider +// F10012 W ------xx xxxxxxxx CLK2 - video clock divider +// F10014 W -------- --xxxxxx CLK3 - chroma clock divider +// F10020 R/W ---xxxxx ---xxxxx JINTCTRL - interrupt control register +// W ---x---- -------- (J_SYNCLR - clear synchronous serial intf ints) +// W ----x--- -------- (J_ASYNCLR - clear asynchronous serial intf ints) +// W -----x-- -------- (J_TIM2CLR - clear timer 2 [tempo] interrupts) +// W ------x- -------- (J_TIM1CLR - clear timer 1 [sample] interrupts) +// W -------x -------- (J_EXTCLR - clear external interrupts) +// R/W -------- ---x---- (J_SYNENA - enable synchronous serial intf ints) +// R/W -------- ----x--- (J_ASYNENA - enable asynchronous serial intf ints) +// R/W -------- -----x-- (J_TIM2ENA - enable timer 2 [tempo] interrupts) +// R/W -------- ------x- (J_TIM1ENA - enable timer 1 [sample] interrupts) +// R/W -------- -------x (J_EXTENA - enable external interrupts) +// F10030 R/W -------- xxxxxxxx ASIDATA - asynchronous serial data +// F10032 W -x------ -xxxxxxx ASICTRL - asynchronous serial control +// W -x------ -------- (TXBRK - transmit break) +// W -------- -x------ (CLRERR - clear error) +// W -------- --x----- (RINTEN - enable receiver interrupts) +// W -------- ---x---- (TINTEN - enable transmitter interrupts) +// W -------- ----x--- (RXIPOL - receiver input polarity) +// W -------- -----x-- (TXOPOL - transmitter output polarity) +// W -------- ------x- (PAREN - parity enable) +// W -------- -------x (ODD - odd parity select) +// F10032 R xxx-xxxx x-xxxxxx ASISTAT - asynchronous serial status +// R x------- -------- (ERROR - OR of PE,FE,OE) +// R -x------ -------- (TXBRK - transmit break) +// R --x----- -------- (SERIN - serial input) +// R ----x--- -------- (OE - overrun error) +// R -----x-- -------- (FE - framing error) +// R ------x- -------- (PE - parity error) +// R -------x -------- (TBE - transmit buffer empty) +// R -------- x------- (RBF - receive buffer full) +// R -------- ---x---- (TINTEN - enable transmitter interrupts) +// R -------- ----x--- (RXIPOL - receiver input polarity) +// R -------- -----x-- (TXOPOL - transmitter output polarity) +// R -------- ------x- (PAREN - parity enable) +// R -------- -------x (ODD - odd parity) +// F10034 R/W xxxxxxxx xxxxxxxx ASICLK - asynchronous serial interface clock +// F10036 R xxxxxxxx xxxxxxxx JPIT1 - timer 1 pre-scaler +// F10038 R xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider +// F1003A R xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler +// F1003C R xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider +// ------------------------------------------------------------ +// F14000-F17FFF R/W xxxxxxxx xxxxxxxx Joysticks and GPIO0-5 +// F14000 R xxxxxxxx xxxxxxxx JOYSTICK - read joystick state +// F14000 W x------- xxxxxxxx JOYSTICK - latch joystick output +// W x------- -------- (enable joystick outputs) +// W -------- xxxxxxxx (joystick output data) +// F14002 R xxxxxxxx xxxxxxxx JOYBUTS - button register +// F14800-F14FFF R/W xxxxxxxx xxxxxxxx GPI00 - reserved (CD-ROM? no.) +// F15000-F15FFF R/W xxxxxxxx xxxxxxxx GPI01 - reserved +// F16000-F16FFF R/W xxxxxxxx xxxxxxxx GPI02 - reserved +// F17000-F177FF R/W xxxxxxxx xxxxxxxx GPI03 - reserved +// F17800-F17BFF R/W xxxxxxxx xxxxxxxx GPI04 - reserved +// F17C00-F17FFF R/W xxxxxxxx xxxxxxxx GPI05 - reserved +// ------------------------------------------------------------ +// F18000-F1FFFF R/W xxxxxxxx xxxxxxxx Jerry DSP +// F1A100 R/W xxxxxxxx xxxxxxxx D_FLAGS - DSP flags register +// R/W x------- -------- (DMAEN - DMA enable) +// R/W -x------ -------- (REGPAGE - register page) +// W --x----- -------- (D_EXT0CLR - clear external interrupt 0) +// W ---x---- -------- (D_TIM2CLR - clear timer 2 interrupt) +// W ----x--- -------- (D_TIM1CLR - clear timer 1 interrupt) +// W -----x-- -------- (D_I2SCLR - clear I2S interrupt) +// W ------x- -------- (D_CPUCLR - clear CPU interrupt) +// R/W -------x -------- (D_EXT0ENA - enable external interrupt 0) +// R/W -------- x------- (D_TIM2ENA - enable timer 2 interrupt) +// R/W -------- -x------ (D_TIM1ENA - enable timer 1 interrupt) +// R/W -------- --x----- (D_I2SENA - enable I2S interrupt) +// R/W -------- ---x---- (D_CPUENA - enable CPU interrupt) +// R/W -------- ----x--- (IMASK - interrupt mask) +// R/W -------- -----x-- (NEGA_FLAG - ALU negative) +// R/W -------- ------x- (CARRY_FLAG - ALU carry) +// R/W -------- -------x (ZERO_FLAG - ALU zero) +// F1A102 R/W -------- ------xx D_FLAGS - upper DSP flags +// R/W -------- ------x- (D_EXT1ENA - enable external interrupt 1) +// R/W -------- -------x (D_EXT1CLR - clear external interrupt 1) +// F1A104 W -------- ----xxxx D_MTXC - matrix control register +// W -------- ----x--- (MATCOL - column/row major) +// W -------- -----xxx (MATRIX3-15 - matrix width) +// F1A108 W ----xxxx xxxxxx-- D_MTXA - matrix address register +// F1A10C W -------- -----x-x D_END - data organization register +// W -------- -----x-- (BIG_INST - big endian instruction fetch) +// W -------- -------x (BIG_IO - big endian I/O) +// F1A110 R/W xxxxxxxx xxxxxxxx D_PC - DSP program counter +// F1A114 R/W xxxxxxxx xx-xxxxx D_CTRL - DSP control/status register +// R xxxx---- -------- (VERSION - DSP version code) +// R/W ----x--- -------- (BUS_HOG - hog the bus!) +// R/W -----x-- -------- (D_EXT0LAT - external interrupt 0 latch) +// R/W ------x- -------- (D_TIM2LAT - timer 2 interrupt latch) +// R/W -------x -------- (D_TIM1LAT - timer 1 interrupt latch) +// R/W -------- x------- (D_I2SLAT - I2S interrupt latch) +// R/W -------- -x------ (D_CPULAT - CPU interrupt latch) +// R/W -------- ---x---- (SINGLE_GO - single step one instruction) +// R/W -------- ----x--- (SINGLE_STEP - single step mode) +// R/W -------- -----x-- (FORCEINT0 - cause interrupt 0 on GPU) +// R/W -------- ------x- (CPUINT - send GPU interrupt to CPU) +// R/W -------- -------x (DSPGO - enable DSP execution) +// F1A116 R/W -------- -------x D_CTRL - upper DSP control/status register +// R/W -------- -------x (D_EXT1LAT - external interrupt 1 latch) +// F1A118-F1A11B W xxxxxxxx xxxxxxxx D_MOD - modulo instruction mask +// F1A11C-F1A11F R xxxxxxxx xxxxxxxx D_REMAIN - divide unit remainder +// F1A11C W -------- -------x D_DIVCTRL - divide unit control +// W -------- -------x (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide) +// F1A120-F1A123 R xxxxxxxx xxxxxxxx D_MACHI - multiply & accumulate high bits +// F1A148 W xxxxxxxx xxxxxxxx R_DAC - right transmit data +// F1A14C W xxxxxxxx xxxxxxxx L_DAC - left transmit data +// F1A150 W -------- xxxxxxxx SCLK - serial clock frequency +// F1A150 R -------- ------xx SSTAT +// R -------- ------x- (left - no description) +// R -------- -------x (WS - word strobe status) +// F1A154 W -------- --xxxx-x SMODE - serial mode +// W -------- --x----- (EVERYWORD - interrupt on MSB of every word) +// W -------- ---x---- (FALLING - interrupt on falling edge) +// W -------- ----x--- (RISING - interrupt of rising edge) +// W -------- -----x-- (WSEN - enable word strobes) +// W -------- -------x (INTERNAL - enables serial clock) +// ------------------------------------------------------------ +// F1B000-F1CFFF R/W xxxxxxxx xxxxxxxx Local DSP RAM +// ------------------------------------------------------------ +// F1D000 R xxxxxxxx xxxxxxxx ROM_TRI - triangle wave +// F1D200 R xxxxxxxx xxxxxxxx ROM_SINE - full sine wave +// F1D400 R xxxxxxxx xxxxxxxx ROM_AMSINE - amplitude modulated sine wave +// F1D600 R xxxxxxxx xxxxxxxx ROM_12W - sine wave and second order harmonic +// F1D800 R xxxxxxxx xxxxxxxx ROM_CHIRP16 - chirp +// F1DA00 R xxxxxxxx xxxxxxxx ROM_NTRI - traingle wave with noise +// F1DC00 R xxxxxxxx xxxxxxxx ROM_DELTA - spike +// F1DE00 R xxxxxxxx xxxxxxxx ROM_NOISE - white noise +// ------------------------------------------------------------ #include "jerry.h" @@ -199,15 +206,16 @@ void JERRYI2SCallback(void); void JERRYI2SExec(uint32 cycles) { #ifndef NEW_TIMER_SYSTEM +#warning "externed var in source--should be in header file. !!! FIX !!!" extern uint16 serialMode; // From DAC.CPP if (serialMode & 0x01) // INTERNAL flag (JERRY is master) { // Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP??? //Yes, it should. !!! FIX !!! - jerry_i2s_interrupt_divide &= 0xFF; + JERRYI2SInterruptDivide &= 0xFF; - if (jerry_i2s_interrupt_timer == -1) + if (JERRYI2SInterruptTimer == -1) { // We don't have to divide the RISC clock rate by this--the reason is a bit // convoluted. Will put explanation here later... @@ -215,18 +223,18 @@ void JERRYI2SExec(uint32 cycles) // in one second. For example, if the sample rate is 44100, we divide the clock rate by // this: 26590906 / 44100 = 602 cycles. // Which means, every 602 cycles that go by we have to generate an interrupt. - jerryI2SCycles = 32 * (2 * (jerry_i2s_interrupt_divide + 1)); + jerryI2SCycles = 32 * (2 * (JERRYI2SInterruptDivide + 1)); } - jerry_i2s_interrupt_timer -= cycles; - if (jerry_i2s_interrupt_timer <= 0) + JERYI2SInterruptTimer -= cycles; + if (JERRYI2SInterruptTimer <= 0) { //This is probably wrong as well (i.e., need to check enable lines)... !!! FIX !!! DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); - jerry_i2s_interrupt_timer += jerryI2SCycles; + JERRYI2SInterruptTimer += jerryI2SCycles; #ifdef JERRY_DEBUG - if (jerry_i2s_interrupt_timer < 0) - WriteLog("JERRY: Missed generating an interrupt (missed %u)!\n", (-jerry_i2s_interrupt_timer / jerryI2SCycles) + 1); + if (JERRYI2SInterruptTimer < 0) + WriteLog("JERRY: Missed generating an interrupt (missed %u)!\n", (-JERRYI2SInterruptTimer / jerryI2SCycles) + 1); #endif } } @@ -237,8 +245,8 @@ void JERRYI2SExec(uint32 cycles) // The whole interrupt system is pretty much borked and is need of an overhaul. // What we need is a way of handling these interrupts when they happen instead of // scanline boundaries the way it is now. - jerry_i2s_interrupt_timer -= cycles; - if (jerry_i2s_interrupt_timer <= 0) + JERRYI2SInterruptTimer -= cycles; + if (JERRYI2SInterruptTimer <= 0) { //This is probably wrong as well (i.e., need to check enable lines)... !!! FIX !!! [DONE] if (ButchIsReadyToSend())//Not sure this is right spot to check... @@ -247,7 +255,7 @@ void JERRYI2SExec(uint32 cycles) SetSSIWordsXmittedFromButch(); DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); } - jerry_i2s_interrupt_timer += 602; + JERRYI2SInterruptTimer += 602; } } #else @@ -288,8 +296,8 @@ void JERRYResetI2S(void) { //WriteLog("i2s: reseting\n"); //This is really SCLK... !!! FIX !!! - jerry_i2s_interrupt_divide = 8; - jerry_i2s_interrupt_timer = -1; + JERRYI2SInterruptDivide = 8; + JERRYI2SInterruptTimer = -1; } void JERRYResetPIT1(void) @@ -356,15 +364,15 @@ void JERRYI2SCallback(void) { // Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP??? //Yes, it should. !!! FIX !!! -#warning "Yes, it should. !!! FIX !!!" - jerry_i2s_interrupt_divide &= 0xFF; +#warning "Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP??? Yes, it should. !!! FIX !!!" + JERRYI2SInterruptDivide &= 0xFF; // We don't have to divide the RISC clock rate by this--the reason is a bit // convoluted. Will put explanation here later... // What's needed here is to find the ratio of the frequency to the number of clock cycles // in one second. For example, if the sample rate is 44100, we divide the clock rate by // this: 26590906 / 44100 = 602 cycles. // Which means, every 602 cycles that go by we have to generate an interrupt. - jerryI2SCycles = 32 * (2 * (jerry_i2s_interrupt_divide + 1)); + jerryI2SCycles = 32 * (2 * (JERRYI2SInterruptDivide + 1)); //This should be in this file with an extern reference in the header file so that //DAC.CPP can see it... !!! FIX !!! @@ -644,11 +652,11 @@ void JERRYWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) { // WriteLog("JERRY: Writing %02X to SCLK...\n", data); if ((offset & 0x03) == 2) - jerry_i2s_interrupt_divide = (jerry_i2s_interrupt_divide & 0x00FF) | ((uint32)data << 8); + JERRYI2SInterruptDivide = (JERRYI2SInterruptDivide & 0x00FF) | ((uint32)data << 8); else - jerry_i2s_interrupt_divide = (jerry_i2s_interrupt_divide & 0xFF00) | (uint32)data; + JERRYI2SInterruptDivide = (JERRYI2SInterruptDivide & 0xFF00) | (uint32)data; - jerry_i2s_interrupt_timer = -1; + JERRYI2SInterruptTimer = -1; #ifndef NEW_TIMER_SYSTEM jerry_i2s_exec(0); #else @@ -763,8 +771,8 @@ void JERRYWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/) { WriteLog("JERRY: Writing %04X to SCLK (by %s)...\n", data, whoName[who]); //This should *only* be enabled when SMODE has its INTERNAL bit set! !!! FIX !!! - jerry_i2s_interrupt_divide = (uint8)data; - jerry_i2s_interrupt_timer = -1; + JERRYI2SInterruptDivide = (uint8)data; + JERRYI2SInterruptTimer = -1; #ifndef NEW_TIMER_SYSTEM jerry_i2s_exec(0); #else diff --git a/src/mmu.cpp b/src/mmu.cpp index 3e746d2..669a79e 100644 --- a/src/mmu.cpp +++ b/src/mmu.cpp @@ -14,6 +14,247 @@ #include "mmu.h" +/* +Addresses to be handled: + +SYSTEM SETUP REGISTERS + +*MEMCON1 Memory Control Register 1 F00000 RW +*MEMCON2 Memory Control Register 2 F00002 RW +HC Horizontal Count F00004 RW +VC Vertical Count F00006 RW +LPH Light Pen Horizontal F00008 RO +LPV Light Pen Vertical F0000A RO +OB[0-3] Object Data Field F00010-16 RO +OLP Object List Pointer F00020-23 WO +OBF Object Flag F00026 WO +VMODE Video Mode F00028 WO +BORD1 Border Colour (Red & Green) F0002A WO +BORD2 Border Colour (Blue) F0002C WO +*HP Horizontal Period F0002E WO +*HBB Horizontal Blank Begin F00030 WO +*HBE Horizontal Blank End F00032 WO +*HS Horizontal Sync F00034 WO +*HVS Horizontal Vertical Sync F00036 WO +HDB1 Horizontal Display Begin 1 F00038 WO +HDB2 Horizontal Display Begin 2 F0003A WO +HDE Horizontal Display End F0003C WO +*VP Vertical Period F0003E WO +*VBB Vertical Blank Begin F00040 WO +*VBE Vertical Blank End F00042 WO +*VS Vertical Sync F00044 WO +VDB Vertical Display Begin F00046 WO +VDE Vertical Display End F00048 WO +*VEB Vertical Equalization Begin F0004A WO +*VEE Vertical Equalization End F0004C WO +VI Vertical Interrupt F0004E WO +PIT[0-1] Programmable Interrupt Timer F00050-52 WO +*HEQ Horizontal Equalization End F00054 WO +BG Background Colour F00058 WO +INT1 CPU Interrupt Control Register F000E0 RW +INT2 CPU Interrupt Resume Register F000E2 WO +CLUT Colour Look-Up Table F00400-7FE RW +LBUF Line Buffer F00800-1D9E RW + +GPU REGISTERS + +G_FLAGS GPU Flags Register F02100 RW +G_MTXC Matrix Control Register F02104 WO +G_MTXA Matrix Address Register F02108 WO +G_END Data Organization Register F0210C WO +G_PC GPU Program Counter F02110 RW +G_CTRL GPU Control/Status Register F02114 RW +G_HIDATA High Data Register F02118 RW +G_REMAIN Divide Unit Remainder F0211C RO +G_DIVCTRL Divide Unit Control F0211C WO + +BLITTER REGISTERS + +A1_BASE A1 Base Register F02200 WO +A1_FLAGS Flags Register F02204 WO +A1_CLIP A1 Clipping Size F02208 WO +A1_PIXEL A1 Pixel Pointer F0220C WO + F02204 RO +A1_STEP A1 Step Value F02210 WO +A1_FSTEP A1 Step Fraction Value F02214 WO +A1_FPIXEL A1 Pixel Pointer Fraction F02218 RW +A1_INC A1 Increment F0221C WO +A1_FINC A1 Increment Fraction F02220 WO +A2_BASE A2 Base Register F02224 WO +A2_FLAGS A2 Flags Register F02228 WO +A2_MASK A2 Window Mask F0222C WO +A2_PIXEL A2 Pixel Pointer F02230 WO + F0222C RO +A2_STEP A2 Step Value F02234 WO +B_CMD Command/Status Register F02238 RW +B_COUNT Counters Register F0223C WO +B_SRCD Source Data Register F02240 WO +B_DSTD Destination Data Register F02248 WO +B_DSTZ Destination Z Register F02250 WO +B_SRCZ1 Source Z Register 1 F02258 WO +B_SRCZ2 Source Z Register 2 F02260 WO +B_PATD Pattern Data Register F02268 WO +B_IINC Intensity Increment F02270 WO +B_ZINC Z Increment F02274 WO +B_STOP Collision Control F02278 WO +B_I3 Intensity 3 F0227C WO +B_I2 Intensity 2 F02280 WO +B_I1 Intensity 1 F02284 WO +B_I0 Intensity 0 F02288 WO +B_Z3 Z 3 F0228C WO +B_Z2 Z 2 F02290 WO +B_Z1 Z 1 F02294 WO +B_Z0 Z 0 F02298 WO + +JERRY REGISTERS + +*CLK1 Processor Clock Divider F10010 WO +*CLK2 Video Clock Divider F10012 WO +*CLK3 Chroma Clock Divider F10014 WO +JPIT1 Timer 1 Pre-scaler F10000 WO +JPIT3 Timer 2 Pre-scaler F10004 WO +JPIT2 Timer 1 Divider F10002 WO +JPIT4 Timer 2 Divider F10006 WO +J_INT Interrup Control Register F10020 RW +SCLK Serial Clock Frequency F1A150 WO +SMODE Serial Mode F1A154 WO +LTXD Left Transmit Data F1A148 WO +RTXD Right Transmit Data F1A14C WO +LRXD Left Receive Data F1A148 RO +RRXD Right Receive Data F1A14C RO +L_I2S Left I2S Serial Interface F1A148 RW +R_I2S Right I2S Serial Interface F1A14C RW +SSTAT Serial Status F1A150 RO +ASICLK Asynchronous Serial Interface Clock F10034 RW +ASICTRL Asynchronous Serial Control F10032 WO +ASISTAT Asynchronous Serial Status F10032 RO +ASIDATA Asynchronous Serial Data F10030 RW + +JOYSTICK REGISTERS + +JOYSTICK Joystick Register F14000 RW +JOYBUTS Button Register F14002 RW + +DSP REGISTERS + +D_FLAGS DSP Flags Register F1A100 RW +D_MTXC DSP Matrix Control Register F1A104 WO +D_MTXA DSP Matrix Address Register F1A108 WO +D_END DSP Data Organization Register F1A10C WO +D_PC DSP Program Counter F1A110 RW +D_CTRL DSP Control/Status Register F1A114 RW +D_MOD Modulo Instruction Mask F1A118 WO +D_REMAIN Divide Unit Remainder F1A11C RO +D_DIVCTRL Divide Unit Control F1A11C WO +D_MACHI MAC High Result Bits F1A120 RO +*/ + +/* +The approach here is to have a list of addresses and who handles them. Could be +a one-to-one memory location up to a range for each function. Will look +something like this: + + { 0xF14000, 0xF14001, MM_IO, JoystickReadHanlder, JoystickWriteHandler }, + +Would be nice to have a way of either calling a handler function or reading/writing +directly to/from a variable or array... +*/ + +enum MemType { MM_NOP = 0, MM_RAM, MM_ROM, MM_IO }; + +#if 0 +// Jaguar Memory map/handlers +uint32 memoryMap[] = { + { 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. +*/ +}; +#endif + void MMUWrite8(uint32 address, uint8 data, uint32 who/*= UNKNOWN*/) { } @@ -32,17 +273,21 @@ void MMUWrite64(uint32 address, uint64 data, uint32 who/*= UNKNOWN*/) uint8 MMURead8(uint32 address, uint32 who/*= UNKNOWN*/) { + return 0; } uint16 MMURead16(uint32 address, uint32 who/*= UNKNOWN*/) { + return 0; } uint32 MMURead32(uint32 address, uint32 who/*= UNKNOWN*/) { + return 0; } uint64 MMURead64(uint32 address, uint32 who/*= UNKNOWN*/) { + return 0; } diff --git a/src/tom.cpp b/src/tom.cpp index e33201c..f1a7ed8 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -937,7 +937,7 @@ void TOMExecScanline(uint16 scanline, bool render) if (inActiveDisplayArea) { //NOTE: The following doesn't put BORDER color on the sides... !!! FIX !!! -#warning The following doesn't put BORDER color on the sides... !!! FIX !!! +#warning "The following doesn't put BORDER color on the sides... !!! FIX !!!" if (vjs.renderType == RT_NORMAL) scanline_render[TOMGetVideoMode()](TOMBackbuffer); else//TV type render @@ -1195,9 +1195,9 @@ void TOMReset(void) tom_gpu_int_pending = 0; tom_video_int_pending = 0; - tom_timer_prescaler = 0; // TOM PIT is disabled - tom_timer_divider = 0; - tom_timer_counter = 0; + tomTimerPrescaler = 0; // TOM PIT is disabled + tomTimerDivider = 0; + tomTimerCounter = 0; memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render)); } @@ -1225,13 +1225,13 @@ uint8 TOMReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) else if ((offset >= 0xF02200) && (offset < 0xF022A0)) return BlitterReadByte(offset, who); else if (offset == 0xF00050) - return tom_timer_prescaler >> 8; + return tomTimerPrescaler >> 8; else if (offset == 0xF00051) - return tom_timer_prescaler & 0xFF; + return tomTimerPrescaler & 0xFF; else if (offset == 0xF00052) - return tom_timer_divider >> 8; + return tomTimerDivider >> 8; else if (offset == 0xF00053) - return tom_timer_divider & 0xFF; + return tomTimerDivider & 0xFF; return tomRam8[offset & 0x3FFF]; } @@ -1284,9 +1284,9 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) else if ((offset >= 0xF02200) && (offset < 0xF022A0)) return BlitterReadWord(offset, who); else if (offset == 0xF00050) - return tom_timer_prescaler; + return tomTimerPrescaler; else if (offset == 0xF00052) - return tom_timer_divider; + return tomTimerDivider; offset &= 0x3FFF; return (TOMReadByte(offset, who) << 8) | TOMReadByte(offset + 1, who); @@ -1327,25 +1327,25 @@ void TOMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) } else if (offset == 0xF00050) { - tom_timer_prescaler = (tom_timer_prescaler & 0x00FF) | (data << 8); + tomTimerPrescaler = (tomTimerPrescaler & 0x00FF) | (data << 8); TOMResetPIT(); return; } else if (offset == 0xF00051) { - tom_timer_prescaler = (tom_timer_prescaler & 0xFF00) | data; + tomTimerPrescaler = (tomTimerPrescaler & 0xFF00) | data; TOMResetPIT(); return; } else if (offset == 0xF00052) { - tom_timer_divider = (tom_timer_divider & 0x00FF) | (data << 8); + tomTimerDivider = (tomTimerDivider & 0x00FF) | (data << 8); TOMResetPIT(); return; } else if (offset == 0xF00053) { - tom_timer_divider = (tom_timer_divider & 0xFF00) | data; + tomTimerDivider = (tomTimerDivider & 0xFF00) | data; TOMResetPIT(); return; } @@ -1400,13 +1400,13 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) }*/ else if (offset == 0xF00050) { - tom_timer_prescaler = data; + tomTimerPrescaler = data; TOMResetPIT(); return; } else if (offset == 0xF00052) { - tom_timer_divider = data; + tomTimerDivider = data; TOMResetPIT(); return; } @@ -1536,9 +1536,9 @@ void TOMResetPIT(void) // Need to remove previous timer from the queue, if it exists... RemoveCallback(TOMPITCallback); - if (tom_timer_prescaler) + if (tomTimerPrescaler) { - double usecs = (float)(tom_timer_prescaler + 1) * (float)(tom_timer_divider + 1) * RISC_CYCLE_IN_USEC; + double usecs = (float)(tomTimerPrescaler + 1) * (float)(tomTimerDivider + 1) * RISC_CYCLE_IN_USEC; SetCallbackTime(TOMPITCallback, usecs); } #endif @@ -1552,11 +1552,11 @@ void TOMResetPIT(void) // once the timer system is stable. void TOMExecPIT(uint32 cycles) { - if (tom_timer_prescaler) + if (tomTimerPrescaler) { - tom_timer_counter -= cycles; + tomTimerCounter -= cycles; - if (tom_timer_counter <= 0) + if (tomTimerCounter <= 0) { TOMSetPendingTimerInt(); GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE); // GPUSetIRQLine does the 'IRQ enabled' checking diff --git a/src/vj.cpp b/src/vj.cpp index 763d440..123a0f5 100644 --- a/src/vj.cpp +++ b/src/vj.cpp @@ -170,20 +170,20 @@ int main(int argc, char * argv[]) // Get the BIOS ROM #ifdef USE_BUILT_IN_BIOS WriteLog("VJ: Using built in BIOS/CD BIOS...\n"); - memcpy(jaguarBootRom, jagBootROM, 0x20000); + memcpy(jaguarBootROM, jagBootROM, 0x20000); memcpy(jaguarCDBootROM, jagCDROM, 0x40000); BIOSLoaded = CDBIOSLoaded = true; #else // What would be nice here would be a way to check if the BIOS was loaded so that we // could disable the pushbutton on the Misc Options menu... !!! FIX !!! [DONE here, but needs to be fixed in GUI as well!] WriteLog("About to attempt to load BIOSes...\n"); - BIOSLoaded = (JaguarLoadROM(jaguarBootRom, vjs.jagBootPath) == 0x20000 ? true : false); + BIOSLoaded = (JaguarLoadROM(jaguarBootROM, vjs.jagBootPath) == 0x20000 ? true : false); WriteLog("VJ: BIOS is %savailable...\n", (BIOSLoaded ? "" : "not ")); CDBIOSLoaded = (JaguarLoadROM(jaguarCDBootROM, vjs.CDBootPath) == 0x40000 ? true : false); WriteLog("VJ: CD BIOS is %savailable...\n", (CDBIOSLoaded ? "" : "not ")); #endif - SET32(jaguarMainRam, 0, 0x00200000); // Set top of stack... + SET32(jaguarMainRAM, 0, 0x00200000); // Set top of stack... WriteLog("Initializing video subsystem...\n"); VideoInit(); -- 2.37.2