--- BasiliskII/src/AmigaOS/main_amiga.cpp 1999/10/03 14:16:25 1.1 +++ BasiliskII/src/AmigaOS/main_amiga.cpp 2000/10/16 17:37:57 1.12 @@ -1,7 +1,7 @@ /* * main_amiga.cpp - Startup code for AmigaOS * - * Basilisk II (C) 1997-1999 Christian Bauer + * Basilisk II (C) 1997-2000 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,9 +56,14 @@ #include "debug.h" +// Options for libnix +unsigned long __stack = 0x4000; // Stack requirement +int __nocommandline = 1; // Disable command line parsing + + // Constants static const char ROM_FILE_NAME[] = "ROM"; -static const char __ver[] = "$VER: " VERSION_STRING " " __AMIGADATE__; +static const char __ver[] = "$VER: " VERSION_STRING " " __DATE__; static const int SCRATCH_MEM_SIZE = 65536; @@ -80,15 +85,19 @@ bool TwentyFourBitAddressing; // Global variables extern ExecBase *SysBase; +struct Library *GfxBase = NULL; +struct IntuitionBase *IntuitionBase = NULL; struct Library *GadToolsBase = NULL; +struct Library *IFFParseBase = NULL; struct Library *AslBase = NULL; struct Library *P96Base = NULL; +struct Library *CyberGfxBase = NULL; struct Library *TimerBase = NULL; struct Library *AHIBase = NULL; struct Library *DiskBase = NULL; struct Task *MainTask; // Our task -uint32 ScratchMem = NULL; // Scratch memory for Mac ROM writes +uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes APTR OldTrapHandler = NULL; // Old trap handler APTR OldExceptionHandler = NULL; // Old exception handler BYTE IRQSig = -1; // "Interrupt" signal number @@ -106,11 +115,6 @@ static bool stack_swapped = false; // static StackSwapStruct stack_swap; -// Prototypes -static void jump_to_rom(void); -static void tick_func(void); - - // Assembly functions struct trap_regs; extern "C" void AtomicAnd(uint32 *p, uint32 val); @@ -120,9 +124,16 @@ extern "C" void TrapHandlerAsm(void); extern "C" void ExceptionHandlerAsm(void); extern "C" void IllInstrHandler(trap_regs *regs); extern "C" void PrivViolHandler(trap_regs *regs); +extern "C" void quit_emulator(void); +extern "C" void AsmTriggerNMI(void); uint16 EmulatedSR; // Emulated SR (supervisor bit and interrupt mask) +// Prototypes +static void jump_to_rom(void); +static void tick_func(void); + + /* * Main program */ @@ -141,10 +152,18 @@ int main(void) printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - // Read preferences - PrefsInit(); - // Open libraries + GfxBase = OpenLibrary((UBYTE *)"graphics.library", 39); + if (GfxBase == NULL) { + printf("Cannot open graphics.library V39.\n"); + exit(1); + } + IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)"intuition.library", 39); + if (IntuitionBase == NULL) { + printf("Cannot open intuition.library V39.\n"); + CloseLibrary(GfxBase); + exit(1); + } DiskBase = (struct Library *)OpenResource((UBYTE *)"disk.resource"); if (DiskBase == NULL) QuitEmulator(); @@ -153,12 +172,23 @@ int main(void) ErrorAlert(GetString(STR_NO_GADTOOLS_LIB_ERR)); QuitEmulator(); } + IFFParseBase = OpenLibrary((UBYTE *)"iffparse.library", 39); + if (IFFParseBase == NULL) { + ErrorAlert(GetString(STR_NO_IFFPARSE_LIB_ERR)); + QuitEmulator(); + } AslBase = OpenLibrary((UBYTE *)"asl.library", 36); if (AslBase == NULL) { ErrorAlert(GetString(STR_NO_ASL_LIB_ERR)); QuitEmulator(); } + + // These two can fail (the respective gfx support won't be available, then) P96Base = OpenLibrary((UBYTE *)"Picasso96API.library", 2); + CyberGfxBase = OpenLibrary((UBYTE *)"cybergraphics.library", 2); + + // Read preferences + PrefsInit(); // Open AHI ahi_port = CreateMsgPort(); @@ -199,7 +229,7 @@ int main(void) TimerBase = (struct Library *)timereq->tr_node.io_Device; // Allocate scratch memory - ScratchMem = (uint32)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC); + ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC); if (ScratchMem == NULL) { ErrorAlert(GetString(STR_NO_MEM_ERR)); QuitEmulator(); @@ -213,10 +243,22 @@ int main(void) WarningAlert(GetString(STR_SMALL_RAM_WARN)); RAMSize = 1024*1024; } - RAMBaseHost = (uint8 *)AllocMem(RAMSize + 0x100000, MEMF_PUBLIC); + RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC); if (RAMBaseHost == NULL) { - ErrorAlert(GetString(STR_NO_MEM_ERR)); - QuitEmulator(); + uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000; + char xText[120]; + + sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize); + + if (ChoiceAlert(xText, "Use", "Quit") != 1) + QuitEmulator(); + + RAMSize = newRAMSize; + RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC); + if (RAMBaseHost == NULL) { + ErrorAlert(GetString(STR_NO_MEM_ERR)); + QuitEmulator(); + } } RAMBaseMac = (uint32)RAMBaseHost; D(bug("Mac RAM starts at %08lx\n", RAMBaseHost)); @@ -228,7 +270,7 @@ int main(void) const char *rom_path = PrefsFindString("rom"); // Load Mac ROM - BPTR rom_fh = Open(rom_path ? (char *)rom_path : ROM_FILE_NAME, MODE_OLDFILE); + BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE); if (rom_fh == NULL) { ErrorAlert(GetString(STR_NO_ROM_FILE_ERR)); QuitEmulator(); @@ -248,60 +290,16 @@ int main(void) QuitEmulator(); } - // Check ROM version - if (!CheckROM()) { - ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR)); - QuitEmulator(); - } - // Set CPU and FPU type UWORD attn = SysBase->AttnFlags; CPUType = attn & AFF_68040 ? 4 : (attn & AFF_68030 ? 3 : 2); CPUIs68060 = attn & AFF_68060; FPUType = attn & AFF_68881 ? 1 : 0; - // Load XPRAM - XPRAMInit(); - - // Set boot volume - int16 i16 = PrefsFindInt16("bootdrive"); - XPRAM[0x78] = i16 >> 8; - XPRAM[0x79] = i16 & 0xff; - i16 = PrefsFindInt16("bootdriver"); - XPRAM[0x7a] = i16 >> 8; - XPRAM[0x7b] = i16 & 0xff; - - // Init drivers - SonyInit(); - DiskInit(); - CDROMInit(); - SCSIInit(); - - // Init network - EtherInit(); - - // Init serial ports - SerialInit(); - - // Init Time Manager - TimerInit(); - - // Init clipboard - ClipInit(); - - // Init audio - AudioInit(); - - // Init video - if (!VideoInit(ROMVersion == ROM_VERSION_64K || ROMVersion == ROM_VERSION_PLUS || ROMVersion == ROM_VERSION_CLASSIC)) + // Initialize everything + if (!InitAll()) QuitEmulator(); - // Install ROM patches - if (!PatchROM()) { - ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR)); - QuitEmulator(); - } - // Move VBR away from 0 if neccessary MoveVBR(); @@ -319,8 +317,8 @@ int main(void) // Start 60Hz process tick_proc = CreateNewProcTags( - NP_Entry, tick_func, - NP_Name, "Basilisk II 60Hz", + NP_Entry, (ULONG)tick_func, + NP_Name, (ULONG)"Basilisk II 60Hz", NP_Priority, 5, TAG_END ); @@ -328,6 +326,8 @@ int main(void) // Set task priority to -1 so we don't use all processing time SetTaskPri(MainTask, -1); + WriteMacInt32(0xbff, 0); // MacsBugFlags + // Swap stack to Mac RAM area stack_swap.stk_Lower = RAMBaseHost; stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize; @@ -354,8 +354,21 @@ void Start680x0(void) * Quit emulator (__saveds because it might be called from an exception) */ -void __saveds QuitEmulator(void) +// Assembly entry point +void __saveds quit_emulator(void) +{ + QuitEmulator(); +} + +void QuitEmulator(void) { + // Stop 60Hz thread + if (tick_proc) { + SetSignal(0, SIGF_SINGLE); + tick_proc_active = false; + Wait(SIGF_SINGLE); + } + // Restore stack if (stack_swapped) { stack_swapped = false; @@ -369,46 +382,15 @@ void __saveds QuitEmulator(void) FreeSignal(IRQSig); } - // Stop 60Hz thread - if (tick_proc) { - SetSignal(0, SIGF_SINGLE); - tick_proc_active = false; - Wait(SIGF_SINGLE); - } - // Remove trap handler MainTask->tc_TrapCode = OldTrapHandler; - // Save XPRAM - XPRAMExit(); - - // Exit video - VideoExit(); - - // Exit audio - AudioExit(); - - // Exit clipboard - ClipExit(); - - // Exit Time Manager - TimerExit(); - - // Exit serial ports - SerialExit(); - - // Exit network - EtherExit(); - - // Exit drivers - SCSIExit(); - CDROMExit(); - DiskExit(); - SonyExit(); + // Deinitialize everything + ExitAll(); // Delete RAM/ROM area if (RAMBaseHost) - FreeMem(RAMBaseHost, RAMSize + 0x100000); + FreeVec(RAMBaseHost); // Delete scratch memory area if (ScratchMem) @@ -435,12 +417,20 @@ void __saveds QuitEmulator(void) PrefsExit(); // Close libraries + if (CyberGfxBase) + CloseLibrary(CyberGfxBase); if (P96Base) CloseLibrary(P96Base); if (AslBase) CloseLibrary(AslBase); + if (IFFParseBase) + CloseLibrary(IFFParseBase); if (GadToolsBase) CloseLibrary(GadToolsBase); + if (IntuitionBase) + CloseLibrary((struct Library *)IntuitionBase); + if (GfxBase) + CloseLibrary(GfxBase); exit(0); } @@ -478,6 +468,11 @@ void TriggerInterrupt(void) Signal(MainTask, IRQSigMask); } +void TriggerNMI(void) +{ + AsmTriggerNMI(); +} + /* * 60Hz thread @@ -520,6 +515,8 @@ static __saveds void tick_func(void) if (++tick_counter > 60) { tick_counter = 0; WriteMacInt32(0x20c, TimerDateTime()); + SetInterruptFlag(INTFLAG_1HZ); + TriggerInterrupt(); } // Trigger 60Hz interrupt @@ -560,7 +557,7 @@ void ErrorAlert(const char *text) req.es_Title = (UBYTE *)GetString(STR_ERROR_ALERT_TITLE); req.es_TextFormat = (UBYTE *)GetString(STR_GUI_ERROR_PREFIX); req.es_GadgetFormat = (UBYTE *)GetString(STR_QUIT_BUTTON); - EasyRequest(NULL, &req, NULL, text); + EasyRequest(NULL, &req, NULL, (ULONG)text); } @@ -580,7 +577,7 @@ void WarningAlert(const char *text) req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE); req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX); req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON); - EasyRequest(NULL, &req, NULL, text); + EasyRequest(NULL, &req, NULL, (ULONG)text); } @@ -598,7 +595,7 @@ bool ChoiceAlert(const char *text, const req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE); req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX); req.es_GadgetFormat = (UBYTE *)str; - return EasyRequest(NULL, &req, NULL, text); + return EasyRequest(NULL, &req, NULL, (ULONG)text); } @@ -633,7 +630,7 @@ void __saveds IllInstrHandler(trap_regs EmulatedSR |= 0x0700; // Call opcode routine - EmulOp(*(uint16 *)(r->pc), (M68kRegisters *)r); + EmulOp(opcode, (M68kRegisters *)r); r->pc += 2; // Restore interrupts