From: Shamus Hammons Date: Tue, 14 Jun 2016 03:36:06 +0000 (-0500) Subject: Added Memory Track support. One small step towards full CD-ROM support. X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=virtualjaguar;a=commitdiff_plain;h=a0fe543d62fa18a83c2c7d99d483ab5ea0f321b4 Added Memory Track support. One small step towards full CD-ROM support. --- diff --git a/jaguarcore.mak b/jaguarcore.mak index 9d44b41..a90bb18 100644 --- a/jaguarcore.mak +++ b/jaguarcore.mak @@ -71,6 +71,7 @@ OBJS := \ obj/joystick.o \ obj/log.o \ obj/memory.o \ + obj/memtrack.o \ obj/mmu.o \ obj/op.o \ obj/settings.o \ diff --git a/src/cdintf.cpp b/src/cdintf.cpp index 45b6be2..1cf2ee2 100644 --- a/src/cdintf.cpp +++ b/src/cdintf.cpp @@ -7,7 +7,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/16/2010 Created this log ;-) // @@ -59,6 +59,7 @@ static void TestCDIO(void) static CdIo_t * cdioPtr = NULL; #endif + bool CDIntfInit(void) { #ifdef HAVE_LIB_CDIO @@ -78,6 +79,7 @@ bool CDIntfInit(void) #endif } + void CDIntfDone(void) { WriteLog("CDINTF: Shutting down CD-ROM subsystem.\n"); @@ -88,6 +90,7 @@ void CDIntfDone(void) #endif } + bool CDIntfReadBlock(uint32_t sector, uint8_t * buffer) { #warning "!!! FIX !!! CDIntfReadBlock not implemented!" @@ -96,6 +99,7 @@ bool CDIntfReadBlock(uint32_t sector, uint8_t * buffer) return false; } + uint32_t CDIntfGetNumSessions(void) { #warning "!!! FIX !!! CDIntfGetNumSessions not implemented!" @@ -104,6 +108,7 @@ uint32_t CDIntfGetNumSessions(void) return 2; } + void CDIntfSelectDrive(uint32_t driveNum) { #warning "!!! FIX !!! CDIntfSelectDrive not implemented!" @@ -111,6 +116,7 @@ void CDIntfSelectDrive(uint32_t driveNum) WriteLog("CDINTF: SelectDrive unimplemented!\n"); } + uint32_t CDIntfGetCurrentDrive(void) { #warning "!!! FIX !!! CDIntfGetCurrentDrive not implemented!" @@ -119,6 +125,7 @@ uint32_t CDIntfGetCurrentDrive(void) return 0; } + const uint8_t * CDIntfGetDriveName(uint32_t driveNum) { #warning "!!! FIX !!! CDIntfGetDriveName driveNum is currently ignored!" @@ -134,6 +141,7 @@ const uint8_t * CDIntfGetDriveName(uint32_t driveNum) #endif } + uint8_t CDIntfGetSessionInfo(uint32_t session, uint32_t offset) { #warning "!!! FIX !!! CDIntfGetSessionInfo not implemented!" @@ -142,6 +150,7 @@ uint8_t CDIntfGetSessionInfo(uint32_t session, uint32_t offset) return 0xFF; } + uint8_t CDIntfGetTrackInfo(uint32_t track, uint32_t offset) { #warning "!!! FIX !!! CDIntfTrackInfo not implemented!" @@ -149,3 +158,4 @@ uint8_t CDIntfGetTrackInfo(uint32_t track, uint32_t offset) WriteLog("CDINTF: GetTrackInfo unimplemented!\n"); return 0xFF; } + diff --git a/src/cdintf.h b/src/cdintf.h index 530f3a8..83c021b 100644 --- a/src/cdintf.h +++ b/src/cdintf.h @@ -1,7 +1,7 @@ // // CDINTF.H: OS agnostic CDROM access funcions // -// by James L. Hammons +// by James Hammons // #ifndef __CDINTF_H__ diff --git a/src/cdrom.cpp b/src/cdrom.cpp index a984c20..40d6daf 100644 --- a/src/cdrom.cpp +++ b/src/cdrom.cpp @@ -9,7 +9,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/16/2010 Created this log ;-) // @@ -172,8 +172,9 @@ static uint16_t CDROMBusRead(void); #define I2SDAT2 BUTCH + 0x28 // i2s FIFO data (old) #define UNKNOWN BUTCH + 0x2C // Seems to be some sort of I2S interface -const char * BReg[12] = { "BUTCH", "DSCNTRL", "DS_DATA", "???", "I2CNTRL", "SBCNTRL", "SUBDATA", "SUBDATB", - "SB_TIME", "FIFO_DATA", "I2SDAT2", "UNKNOWN" }; +const char * BReg[12] = { "BUTCH", "DSCNTRL", "DS_DATA", "???", "I2CNTRL", + "SBCNTRL", "SUBDATA", "SUBDATB", "SB_TIME", "FIFO_DATA", "I2SDAT2", + "UNKNOWN" }; //extern const char * whoName[9]; diff --git a/src/eeprom.cpp b/src/eeprom.cpp index 2fb896e..66c4a4c 100644 --- a/src/eeprom.cpp +++ b/src/eeprom.cpp @@ -9,7 +9,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/16/2010 Created this log ;-) // @@ -63,6 +63,13 @@ static bool haveCDROMEEPROM = false; void EepromInit(void) { + // No need for EEPROM for the Memory Track device :-P + if (jaguarMainROMCRC32 == 0xFDF37F47) + { + WriteLog("EEPROM: Memory Track device detected...\n"); + return; + } + // Handle regular cartridge EEPROM sprintf(eeprom_filename, "%s%08X.eeprom", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32); sprintf(cdromEEPROMFilename, "%scdrom.eeprom", vjs.EEPROMPath); @@ -141,7 +148,7 @@ static void EEPROMSave(void) void ReadEEPROMFromFile(FILE * file, uint16_t * ram) { uint8_t buffer[128]; - fread(buffer, 1, 128, file); + size_t ignored = fread(buffer, 1, 128, file); for(int i=0; i<64; i++) ram[i] = (buffer[(i * 2) + 0] << 8) | buffer[(i * 2) + 1]; diff --git a/src/file.cpp b/src/file.cpp index 4586245..4262297 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -48,7 +48,7 @@ uint32_t JaguarLoadROM(uint8_t * &rom, char * path) #warning "!!! FIX !!! Should have sanity checking for ROM size to prevent buffer overflow!" uint32_t romSize = 0; - WriteLog("JaguarLoadROM: Attempting to load file '%s'...", path); + WriteLog("FILE: JaguarLoadROM attempting to load file '%s'...", path); char * ext = strrchr(path, '.'); // No filename extension == YUO FAIL IT (it is loading the file). @@ -60,8 +60,8 @@ uint32_t JaguarLoadROM(uint8_t * &rom, char * path) return 0; } - WriteLog("Succeeded in finding extension (%s)!\n", ext); - WriteLog("VJ: Loading \"%s\"...", path); + WriteLog("\nFILE: Succeeded in finding extension (%s)!\n", ext); + WriteLog("FILE: Loading \"%s\"...", path); if (strcasecmp(ext, ".zip") == 0) { @@ -277,7 +277,7 @@ bool AlpineLoadFile(char * path) } jaguarMainROMCRC32 = crc32_calcCheckSum(buffer, jaguarROMSize); - WriteLog("CRC: %08X\n", (unsigned int)jaguarMainROMCRC32); + WriteLog("FILE: CRC is %08X\n", (unsigned int)jaguarMainROMCRC32); EepromInit(); jaguarRunAddress = 0x802000; diff --git a/src/jaguar.cpp b/src/jaguar.cpp index 4d96dca..f829892 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -32,6 +32,7 @@ #include "log.h" #include "m68000/m68kinterface.h" //#include "memory.h" +#include "memtrack.h" #include "mmu.h" #include "settings.h" #include "tom.h" @@ -1163,7 +1164,16 @@ unsigned int m68k_read_memory_16(unsigned int 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]; + { + // Memory Track reading... + if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47)) + { + retVal = MTReadWord(address); + } + else + 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 = (jaguarDevBootROM1[address - 0xE00000] << 8) | jaguarDevBootROM1[address - 0xE00000 + 1]; @@ -1208,7 +1218,20 @@ unsigned int m68k_read_memory_32(unsigned int address) //WriteLog("--> [RM32]\n"); #ifndef USE_NEW_MMU - return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2); + uint32_t retVal = 0; + + if ((address >= 0x800000) && (address <= 0xDFFEFE)) + { + // Memory Track reading... + if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47)) + retVal = MTReadLong(address); + else + retVal = GET32(jaguarMainROM, address - 0x800000); + + return retVal; + } + + return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2); #else return MMURead32(address, M68K); #endif @@ -1346,6 +1369,12 @@ if (address == 0xF02110) jaguar_mainRam[address + 1] = value & 0xFF;*/ SET16(jaguarMainRAM, address, value); } + // Memory Track device writes.... + else if ((address >= 0x800000) && (address <= 0x87FFFE)) + { + if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47)) + MTWriteWord(address, value); + } else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE)) CDROMWriteWord(address, value, M68K); else if ((address >= 0xF00000) && (address <= 0xF0FFFE)) diff --git a/src/jerry.cpp b/src/jerry.cpp index 32f8c92..1e2478f 100644 --- a/src/jerry.cpp +++ b/src/jerry.cpp @@ -164,6 +164,7 @@ #include "joystick.h" #include "log.h" #include "m68000/m68kinterface.h" +#include "memtrack.h" #include "settings.h" #include "tom.h" //#include "memory.h" @@ -358,6 +359,7 @@ void JERRYI2SCallback(void) void JERRYInit(void) { JoystickInit(); + MTInit(); memcpy(&jerry_ram_8[0xD000], waveTableROM, 0x1000); JERRYPIT1Prescaler = 0xFFFF; @@ -375,6 +377,7 @@ void JERRYReset(void) { JoystickReset(); EepromReset(); + MTReset(); JERRYResetI2S(); memset(jerry_ram_8, 0x00, 0xD000); // Don't clear out the Wavetable ROM...! @@ -398,6 +401,7 @@ void JERRYDone(void) JoystickDone(); DACDone(); EepromDone(); + MTDone(); } diff --git a/src/memtrack.cpp b/src/memtrack.cpp new file mode 100644 index 0000000..cc9daab --- /dev/null +++ b/src/memtrack.cpp @@ -0,0 +1,225 @@ +// +// Memory Track cartridge emulation +// +// by James Hammons +// (C) 2016 Underground Software +// +// The Memory Track is just a large(-ish) EEPROM, holding 128K. We emulate the +// Atmel part, since it seems to be easier to deal with than the AMD part. The +// way it works is the 68K checks in its R/W functions to see if the MT is +// inserted, and, if so, call the R/W functions here. It also checks to see if +// the ROM width was changed to 32-bit; if not, then it reads the normal ROM in +// the ROM space like usual. +// +// The Atmel part reads/writes a single byte into a long space. So we have to +// adjust for that when reading from/writing to the NVRAM. +// +// JLH = James Hammons +// +// Who When What +// --- ---------- ----------------------------------------------------------- +// JLH 06/12/2016 Created this file ;-) +// + +#include "memtrack.h" + +#include +#include +#include +#include + + +#define MEMTRACK_FILENAME "memtrack.eeprom" +//#define DEBUG_MEMTRACK + +enum { MT_NONE, MT_PROD_ID, MT_RESET, MT_WRITE_ENABLE }; +enum { MT_IDLE, MT_PHASE1, MT_PHASE2 }; + +uint8_t mtMem[0x20000]; +uint8_t mtCommand = MT_NONE; +uint8_t mtState = MT_IDLE; +bool haveMT = false; +char mtFilename[MAX_PATH]; + +// Private function prototypes +void MTWriteFile(void); +void MTStateMachine(uint8_t reg, uint16_t data); + + +void MTInit(void) +{ + sprintf(mtFilename, "%s%s", vjs.EEPROMPath, MEMTRACK_FILENAME); + FILE * fp = fopen(mtFilename, "rb"); + + if (fp) + { + size_t ignored = fread(mtMem, 1, 0x20000, fp); + fclose(fp); + WriteLog("MT: Loaded NVRAM from %s\n", mtFilename); + haveMT = true; + } + else + WriteLog("MT: Could not open file \"%s\"!\n", mtFilename); +} + + +void MTReset(void) +{ + if (!haveMT) + memset(mtMem, 0xFF, 0x20000); +} + + +void MTDone(void) +{ + MTWriteFile(); + WriteLog("MT: Done.\n"); +} + + +void MTWriteFile(void) +{ + if (!haveMT) + return; + + FILE * fp = fopen(mtFilename, "wb"); + + if (fp) + { + fwrite(mtMem, 1, 0x20000, fp); + fclose(fp); + } + else + WriteLog("MT: Could not create file \"%s\"!", mtFilename); +} + + +// +// This is crappy, there doesn't seem to be a word interface to the NVRAM. But +// we'll keep this as a placeholder for now. +// +uint16_t MTReadWord(uint32_t addr) +{ + uint32_t value = MTReadLong(addr); + + if ((addr & 0x03) == 0) + value >>= 16; + else if ((addr & 0x03) == 2) + value &= 0xFFFF; + +#ifdef DEBUG_MEMTRACK +WriteLog("MT: Reading word @ $%06X: $%04X\n", addr, value); +#endif + + return (uint16_t)value; +} + + +uint32_t MTReadLong(uint32_t addr) +{ + uint32_t value = 0; + + if (mtCommand == MT_PROD_ID) + { + if (addr == 0x800000) + value = 0x1F; + else if (addr == 0x800004) + value = 0xD5; + } + else + { + value = (uint32_t)mtMem[(addr & 0x7FFFC) >> 2]; + } + + // We do this because we're not sure how the real thing behaves; but it + // seems reasonable on its face to do it this way. :-P So we turn off write + // mode when reading the NVRAM. + if (mtCommand == MT_WRITE_ENABLE) + mtCommand = MT_NONE; + +#ifdef DEBUG_MEMTRACK +WriteLog("MT: Reading long @ $%06X: $%08X\n", addr, value << 16); +#endif + return value << 16; +} + + +void MTWriteWord(uint32_t addr, uint16_t data) +{ + // We don't care about writes to long offsets + 2 + if ((addr & 0x3) == 2) + return; + +#ifdef DEBUG_MEMTRACK +WriteLog("MT: Writing word @ $%06X: $%04X (Writing is %sabled)\n", addr, data, (mtCommand == MT_WRITE_ENABLE ? "en" : "dis")); +#endif + + // Write to the NVRAM if it's enabled... + if (mtCommand == MT_WRITE_ENABLE) + { + mtMem[(addr & 0x7FFFC) >> 2] = (uint8_t)(data & 0xFF); + return; + } + + switch (addr) + { + case (0x800000 + (4 * 0x5555)): // $815554 + MTStateMachine(0, data); + break; + case (0x800000 + (4 * 0x2AAA)): // $80AAA8 + MTStateMachine(1, data); + break; + } +} + + +void MTWriteLong(uint32_t addr, uint32_t data) +{ + // Strip off lower 3 bits of the passed in address + addr &= 0xFFFFFC; + + MTWriteWord(addr + 0, data & 0xFFFF); + MTWriteWord(addr + 2, data >> 16); +} + + +void MTStateMachine(uint8_t reg, uint16_t data) +{ +#ifdef DEBUG_MEMTRACK +WriteLog("MTStateMachine: reg = %u, data = $%02X, current state = %u\n", reg, data, mtState); +#endif + switch (mtState) + { + case MT_IDLE: + if ((reg == 0) && (data == 0xAA)) + mtState = MT_PHASE1; + + break; + case MT_PHASE1: + if ((reg == 1) && (data == 0x55)) + mtState = MT_PHASE2; + else + mtState = MT_IDLE; + + break; + case MT_PHASE2: + if (reg == 0) + { + if (data == 0x90) // Product ID + mtCommand = MT_PROD_ID; + else if (data == 0xF0) // Reset + mtCommand = MT_NONE; + else if (data == 0xA0) // Write enagle + mtCommand = MT_WRITE_ENABLE; + else + mtCommand = MT_NONE; + } + + mtState = MT_IDLE; + break; + } +#ifdef DEBUG_MEMTRACK +WriteLog(" state = %u, cmd = %u\n", mtState, mtCommand); +#endif +} + diff --git a/src/memtrack.h b/src/memtrack.h new file mode 100644 index 0000000..d6eb036 --- /dev/null +++ b/src/memtrack.h @@ -0,0 +1,15 @@ +// +// memtrack.h: Header file +// + +#include + +void MTInit(void); +void MTReset(void); +void MTDone(void); + +uint16_t MTReadWord(uint32_t addr); +uint32_t MTReadLong(uint32_t addr); +void MTWriteWord(uint32_t addr, uint16_t data); +void MTWriteLong(uint32_t addr, uint32_t data); + diff --git a/src/tom.cpp b/src/tom.cpp index 3d6243b..6de6116 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -652,6 +652,12 @@ uint16_t TOMGetVP(void) } +uint16_t TOMGetMEMCON1(void) +{ + return GET16(tomRam8, MEMCON1); +} + + #define LEFT_BG_FIX // // 16 BPP CRY/RGB mixed mode rendering diff --git a/src/tom.h b/src/tom.h index 8c5640a..4ac5736 100644 --- a/src/tom.h +++ b/src/tom.h @@ -43,6 +43,7 @@ uint16_t TOMGetHDB(void); uint16_t TOMGetVDB(void); uint16_t TOMGetHC(void); uint16_t TOMGetVP(void); +uint16_t TOMGetMEMCON1(void); void TOMDumpIORegistersToLog(void);