91 |
|
struct Library *IFFParseBase = NULL; |
92 |
|
struct Library *AslBase = NULL; |
93 |
|
struct Library *P96Base = NULL; |
94 |
+ |
struct Library *CyberGfxBase = NULL; |
95 |
|
struct Library *TimerBase = NULL; |
96 |
|
struct Library *AHIBase = NULL; |
97 |
|
struct Library *DiskBase = NULL; |
98 |
|
|
99 |
|
struct Task *MainTask; // Our task |
100 |
< |
uint32 ScratchMem = NULL; // Scratch memory for Mac ROM writes |
100 |
> |
uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes |
101 |
|
APTR OldTrapHandler = NULL; // Old trap handler |
102 |
|
APTR OldExceptionHandler = NULL; // Old exception handler |
103 |
|
BYTE IRQSig = -1; // "Interrupt" signal number |
125 |
|
extern "C" void IllInstrHandler(trap_regs *regs); |
126 |
|
extern "C" void PrivViolHandler(trap_regs *regs); |
127 |
|
extern "C" void quit_emulator(void); |
128 |
+ |
extern "C" void AsmTriggerNMI(void); |
129 |
|
uint16 EmulatedSR; // Emulated SR (supervisor bit and interrupt mask) |
130 |
|
|
131 |
|
|
182 |
|
ErrorAlert(GetString(STR_NO_ASL_LIB_ERR)); |
183 |
|
QuitEmulator(); |
184 |
|
} |
185 |
+ |
|
186 |
+ |
// These two can fail (the respective gfx support won't be available, then) |
187 |
|
P96Base = OpenLibrary((UBYTE *)"Picasso96API.library", 2); |
188 |
+ |
CyberGfxBase = OpenLibrary((UBYTE *)"cybergraphics.library", 2); |
189 |
|
|
190 |
|
// Read preferences |
191 |
|
PrefsInit(); |
229 |
|
TimerBase = (struct Library *)timereq->tr_node.io_Device; |
230 |
|
|
231 |
|
// Allocate scratch memory |
232 |
< |
ScratchMem = (uint32)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC); |
232 |
> |
ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC); |
233 |
|
if (ScratchMem == NULL) { |
234 |
|
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
235 |
|
QuitEmulator(); |
243 |
|
WarningAlert(GetString(STR_SMALL_RAM_WARN)); |
244 |
|
RAMSize = 1024*1024; |
245 |
|
} |
246 |
< |
RAMBaseHost = (uint8 *)AllocMem(RAMSize + 0x100000, MEMF_PUBLIC); |
246 |
> |
RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC); |
247 |
|
if (RAMBaseHost == NULL) { |
248 |
< |
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
249 |
< |
QuitEmulator(); |
248 |
> |
uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000; |
249 |
> |
char xText[120]; |
250 |
> |
|
251 |
> |
sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize); |
252 |
> |
|
253 |
> |
if (ChoiceAlert(xText, "Use", "Quit") != 1) |
254 |
> |
QuitEmulator(); |
255 |
> |
|
256 |
> |
RAMSize = newRAMSize; |
257 |
> |
RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC); |
258 |
> |
if (RAMBaseHost == NULL) { |
259 |
> |
ErrorAlert(GetString(STR_NO_MEM_ERR)); |
260 |
> |
QuitEmulator(); |
261 |
> |
} |
262 |
|
} |
263 |
|
RAMBaseMac = (uint32)RAMBaseHost; |
264 |
|
D(bug("Mac RAM starts at %08lx\n", RAMBaseHost)); |
326 |
|
// Set task priority to -1 so we don't use all processing time |
327 |
|
SetTaskPri(MainTask, -1); |
328 |
|
|
329 |
+ |
WriteMacInt32(0xbff, 0); // MacsBugFlags |
330 |
+ |
|
331 |
|
// Swap stack to Mac RAM area |
332 |
|
stack_swap.stk_Lower = RAMBaseHost; |
333 |
|
stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize; |
362 |
|
|
363 |
|
void QuitEmulator(void) |
364 |
|
{ |
365 |
+ |
// Stop 60Hz thread |
366 |
+ |
if (tick_proc) { |
367 |
+ |
SetSignal(0, SIGF_SINGLE); |
368 |
+ |
tick_proc_active = false; |
369 |
+ |
Wait(SIGF_SINGLE); |
370 |
+ |
} |
371 |
+ |
|
372 |
|
// Restore stack |
373 |
|
if (stack_swapped) { |
374 |
|
stack_swapped = false; |
382 |
|
FreeSignal(IRQSig); |
383 |
|
} |
384 |
|
|
359 |
– |
// Stop 60Hz thread |
360 |
– |
if (tick_proc) { |
361 |
– |
SetSignal(0, SIGF_SINGLE); |
362 |
– |
tick_proc_active = false; |
363 |
– |
Wait(SIGF_SINGLE); |
364 |
– |
} |
365 |
– |
|
385 |
|
// Remove trap handler |
386 |
|
MainTask->tc_TrapCode = OldTrapHandler; |
387 |
|
|
390 |
|
|
391 |
|
// Delete RAM/ROM area |
392 |
|
if (RAMBaseHost) |
393 |
< |
FreeMem(RAMBaseHost, RAMSize + 0x100000); |
393 |
> |
FreeVec(RAMBaseHost); |
394 |
|
|
395 |
|
// Delete scratch memory area |
396 |
|
if (ScratchMem) |
417 |
|
PrefsExit(); |
418 |
|
|
419 |
|
// Close libraries |
420 |
+ |
if (CyberGfxBase) |
421 |
+ |
CloseLibrary(CyberGfxBase); |
422 |
|
if (P96Base) |
423 |
|
CloseLibrary(P96Base); |
424 |
|
if (AslBase) |
468 |
|
Signal(MainTask, IRQSigMask); |
469 |
|
} |
470 |
|
|
471 |
+ |
void TriggerNMI(void) |
472 |
+ |
{ |
473 |
+ |
AsmTriggerNMI(); |
474 |
+ |
} |
475 |
+ |
|
476 |
|
|
477 |
|
/* |
478 |
|
* 60Hz thread |
515 |
|
if (++tick_counter > 60) { |
516 |
|
tick_counter = 0; |
517 |
|
WriteMacInt32(0x20c, TimerDateTime()); |
518 |
+ |
SetInterruptFlag(INTFLAG_1HZ); |
519 |
+ |
TriggerInterrupt(); |
520 |
|
} |
521 |
|
|
522 |
|
// Trigger 60Hz interrupt |
630 |
|
EmulatedSR |= 0x0700; |
631 |
|
|
632 |
|
// Call opcode routine |
633 |
< |
EmulOp(*(uint16 *)(r->pc), (M68kRegisters *)r); |
633 |
> |
EmulOp(opcode, (M68kRegisters *)r); |
634 |
|
r->pc += 2; |
635 |
|
|
636 |
|
// Restore interrupts |