Skip to content

Commit 0a50424

Browse files
committed
file jaguarLoadedRAMStart addition
Signed-off-by: Joseph Mattiello <[email protected]>
1 parent 8faa924 commit 0a50424

3 files changed

Lines changed: 43 additions & 5 deletions

File tree

src/file.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ bool JaguarLoadFile(uint8_t *buffer, size_t bufsize)
6666
{
6767
int fileType;
6868
jaguarROMSize = bufsize;
69+
jaguarLoadedRAMStart = 0;
70+
jaguarLoadedRAMEnd = 0;
6971

7072
if (jaguarROMSize == 0)
7173
return false;
@@ -104,6 +106,8 @@ bool JaguarLoadFile(uint8_t *buffer, size_t bufsize)
104106
codeSize = GET32(buffer, 0x02) + GET32(buffer, 0x06);
105107
memcpy(jagMemSpace + loadAddress, buffer + 0x24, codeSize);
106108
jaguarRunAddress = loadAddress;
109+
jaguarLoadedRAMStart = loadAddress;
110+
jaguarLoadedRAMEnd = loadAddress + codeSize;
107111
return true;
108112
}
109113
else if (fileType == JST_ABS_TYPE2)
@@ -112,6 +116,8 @@ bool JaguarLoadFile(uint8_t *buffer, size_t bufsize)
112116
codeSize = GET32(buffer, 0x18) + GET32(buffer, 0x1C);
113117
memcpy(jagMemSpace + loadAddress, buffer + 0xA8, codeSize);
114118
jaguarRunAddress = runAddress;
119+
jaguarLoadedRAMStart = loadAddress;
120+
jaguarLoadedRAMEnd = loadAddress + codeSize;
115121
return true;
116122
}
117123
// NB: This is *wrong*
@@ -124,8 +130,11 @@ bool JaguarLoadFile(uint8_t *buffer, size_t bufsize)
124130
// Still need to do some checking here for type 2 vs. type 3. This assumes 3
125131
// Also, JAGR vs. JAGL (word command size vs. long command size)
126132
uint32_t loadAddress = GET32(buffer, 0x22), runAddress = GET32(buffer, 0x2A);
127-
memcpy(jagMemSpace + loadAddress, buffer + 0x2E, jaguarROMSize - 0x2E);
133+
uint32_t codeSize = jaguarROMSize - 0x2E;
134+
memcpy(jagMemSpace + loadAddress, buffer + 0x2E, codeSize);
128135
jaguarRunAddress = runAddress;
136+
jaguarLoadedRAMStart = loadAddress;
137+
jaguarLoadedRAMEnd = loadAddress + codeSize;
129138

130139
// Hmm. Is this kludge necessary?
131140
SET32(jaguarMainRAM, 0x10, 0x00001000); // Set Exception #4 (Illegal Instruction)
@@ -136,8 +145,11 @@ bool JaguarLoadFile(uint8_t *buffer, size_t bufsize)
136145
else if (fileType == JST_WTFOMGBBQ)
137146
{
138147
uint32_t loadAddress = (buffer[0x1F] << 24) | (buffer[0x1E] << 16) | (buffer[0x1D] << 8) | buffer[0x1C];
139-
memcpy(jagMemSpace + loadAddress, buffer + 0x20, jaguarROMSize - 0x20);
148+
uint32_t codeSize = jaguarROMSize - 0x20;
149+
memcpy(jagMemSpace + loadAddress, buffer + 0x20, codeSize);
140150
jaguarRunAddress = loadAddress;
151+
jaguarLoadedRAMStart = loadAddress;
152+
jaguarLoadedRAMEnd = loadAddress + codeSize;
141153
return true;
142154
}
143155

src/jaguar.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ extern uint8_t jagMemSpace[];
114114
// Internal variables
115115

116116
uint32_t jaguarMainROMCRC32, jaguarROMSize, jaguarRunAddress;
117+
uint32_t jaguarLoadedRAMStart, jaguarLoadedRAMEnd;
117118

118119
bool jaguarCartInserted = false;
119120
bool lowerField = false;
@@ -1431,11 +1432,17 @@ void JaguarReset(void)
14311432
{
14321433
unsigned i;
14331434

1434-
// Only problem with this approach: It wipes out RAM loaded files...!
1435-
// Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
1435+
// Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents.
1436+
// Skip the region occupied by a RAM-loaded executable (ABS/COFF) so it survives reset.
14361437
JaguarSeedPRNG(12345);
14371438
for(i=8; i<0x200000; i+=4)
1438-
*((uint32_t *)(&jaguarMainRAM[i])) = JaguarRand();
1439+
{
1440+
uint32_t r = JaguarRand();
1441+
if (jaguarLoadedRAMEnd > jaguarLoadedRAMStart
1442+
&& i >= jaguarLoadedRAMStart && i < jaguarLoadedRAMEnd)
1443+
continue;
1444+
*((uint32_t *)(&jaguarMainRAM[i])) = r;
1445+
}
14391446

14401447
// New timer base code stuffola...
14411448
InitializeEventList();
@@ -1445,15 +1452,32 @@ void JaguarReset(void)
14451452
// Only use the system BIOS if it's available...! (it's always available now!)
14461453
// AND only if a jaguar cartridge has been inserted.
14471454
if (vjs.useJaguarBIOS && jaguarCartInserted && !vjs.hardwareTypeAlpine)
1455+
{
14481456
memcpy(jaguarMainRAM, jagMemSpace + 0xE00000, 8);
1457+
}
14491458
else
1459+
{
14501460
SET32(jaguarMainRAM, 4, jaguarRunAddress);
14511461

1462+
/* For RAM-loaded files (ABS/COFF), the exception vector table
1463+
* ($8–$3FF) may be outside the loaded region. Install an RTE
1464+
* trampoline so interrupts that fire before the program sets up
1465+
* its own handlers return safely instead of crashing. */
1466+
if (jaguarLoadedRAMEnd > jaguarLoadedRAMStart
1467+
&& jaguarLoadedRAMStart > 0x400)
1468+
{
1469+
SET16(jaguarMainRAM, 0x400, 0x4E73); /* RTE */
1470+
for (i = 2; i < 256; i++)
1471+
SET32(jaguarMainRAM, i * 4, 0x400);
1472+
}
1473+
}
1474+
14521475
TOMReset();
14531476
JERRYReset();
14541477
GPUReset();
14551478
DSPReset();
14561479
CDROMReset();
1480+
14571481
m68k_pulse_reset(); // Reset the 68000
14581482

14591483
lowerField = false; // Reset the lower field flag
@@ -1487,6 +1511,7 @@ void JaguarExecuteNew(void)
14871511
double timeToNextEvent = GetTimeToNextEvent(EVENT_MAIN);
14881512
m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
14891513
GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
1514+
DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
14901515
BUTCHExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
14911516
HandleNextEvent(EVENT_MAIN);
14921517
} while(!frameDone);

src/jaguar.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ extern uint32_t bpmAddress1;
4242
extern "C" {
4343
#endif
4444
extern uint32_t jaguarMainROMCRC32, jaguarROMSize, jaguarRunAddress;
45+
extern uint32_t jaguarLoadedRAMStart, jaguarLoadedRAMEnd;
4546
#ifdef __cplusplus
4647
}
4748
#endif

0 commit comments

Comments
 (0)