ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/main_amiga.cpp
(Generate patch)

Comparing BasiliskII/src/AmigaOS/main_amiga.cpp (file contents):
Revision 1.1 by cebix, 1999-10-03T14:16:25Z vs.
Revision 1.20 by jlachmann, 2001-10-16T17:27:52Z

# Line 1 | Line 1
1   /*
2   *  main_amiga.cpp - Startup code for AmigaOS
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 56 | Line 56
56   #include "debug.h"
57  
58  
59 + // Options for libnix
60 + unsigned long __stack = 0x4000;         // Stack requirement
61 + int __nocommandline = 1;                        // Disable command line parsing
62 +
63 +
64   // Constants
65   static const char ROM_FILE_NAME[] = "ROM";
66 < static const char __ver[] = "$VER: " VERSION_STRING " " __AMIGADATE__;
66 > static const char __ver[] = "$VER: " VERSION_STRING " " __DATE__;
67   static const int SCRATCH_MEM_SIZE = 65536;
68  
69  
# Line 80 | Line 85 | bool TwentyFourBitAddressing;
85  
86   // Global variables
87   extern ExecBase *SysBase;
88 + struct Library *GfxBase = NULL;
89 + struct IntuitionBase *IntuitionBase = NULL;
90   struct Library *GadToolsBase = NULL;
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
# Line 99 | Line 108 | static struct timerequest *timereq = NUL
108   static struct MsgPort *ahi_port = NULL;                 // Port for AHI
109   static struct AHIRequest *ahi_io = NULL;                // IORequest for AHI
110  
111 + static struct Process *xpram_proc = NULL;               // XPRAM watchdog
112 + static volatile bool xpram_proc_active = true;  // Flag for quitting the XPRAM watchdog
113 +
114   static struct Process *tick_proc = NULL;                // 60Hz process
115   static volatile bool tick_proc_active = true;   // Flag for quitting the 60Hz process
116  
# Line 106 | Line 118 | static bool stack_swapped = false;                             //
118   static StackSwapStruct stack_swap;
119  
120  
109 // Prototypes
110 static void jump_to_rom(void);
111 static void tick_func(void);
112
113
121   // Assembly functions
122   struct trap_regs;
123   extern "C" void AtomicAnd(uint32 *p, uint32 val);
124   extern "C" void AtomicOr(uint32 *p, uint32 val);
125   extern "C" void MoveVBR(void);
126 + extern "C" void DisableSuperBypass(void);
127   extern "C" void TrapHandlerAsm(void);
128   extern "C" void ExceptionHandlerAsm(void);
129   extern "C" void IllInstrHandler(trap_regs *regs);
130   extern "C" void PrivViolHandler(trap_regs *regs);
131 + extern "C" void quit_emulator(void);
132 + extern "C" void AsmTriggerNMI(void);
133   uint16 EmulatedSR;                                      // Emulated SR (supervisor bit and interrupt mask)
134  
135  
136 + // Prototypes
137 + static void jump_to_rom(void);
138 + static void xpram_func(void);
139 + static void tick_func(void);
140 +
141 +
142   /*
143   *  Main program
144   */
145  
146 < int main(void)
146 > int main(int argc, char **argv)
147   {
148          // Initialize variables
149          RAMBaseHost = NULL;
# Line 141 | Line 157 | int main(void)
157          printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
158          printf(" %s\n", GetString(STR_ABOUT_TEXT2));
159  
144        // Read preferences
145        PrefsInit();
146
160          // Open libraries
161 +        GfxBase = OpenLibrary((UBYTE *)"graphics.library", 39);
162 +        if (GfxBase == NULL) {
163 +                printf("Cannot open graphics.library V39.\n");
164 +                exit(1);
165 +        }
166 +        IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)"intuition.library", 39);
167 +        if (IntuitionBase == NULL) {
168 +                printf("Cannot open intuition.library V39.\n");
169 +                CloseLibrary(GfxBase);
170 +                exit(1);
171 +        }
172          DiskBase = (struct Library *)OpenResource((UBYTE *)"disk.resource");
173          if (DiskBase == NULL)
174                  QuitEmulator();
175          GadToolsBase = OpenLibrary((UBYTE *)"gadtools.library", 39);
176          if (GadToolsBase == NULL) {
177 <                ErrorAlert(GetString(STR_NO_GADTOOLS_LIB_ERR));
177 >                ErrorAlert(STR_NO_GADTOOLS_LIB_ERR);
178 >                QuitEmulator();
179 >        }
180 >        IFFParseBase = OpenLibrary((UBYTE *)"iffparse.library", 39);
181 >        if (IFFParseBase == NULL) {
182 >                ErrorAlert(STR_NO_IFFPARSE_LIB_ERR);
183                  QuitEmulator();
184          }
185          AslBase = OpenLibrary((UBYTE *)"asl.library", 36);
186          if (AslBase == NULL) {
187 <                ErrorAlert(GetString(STR_NO_ASL_LIB_ERR));
187 >                ErrorAlert(STR_NO_ASL_LIB_ERR);
188                  QuitEmulator();
189          }
190 +
191 +        if (FindTask((UBYTE *) "« Enforcer »"))
192 +                {
193 +                ErrorAlert(STR_ENFORCER_RUNNING_ERR);
194 +                QuitEmulator();
195 +                }
196 +
197 +        // These two can fail (the respective gfx support won't be available, then)
198          P96Base = OpenLibrary((UBYTE *)"Picasso96API.library", 2);
199 +        CyberGfxBase = OpenLibrary((UBYTE *)"cybergraphics.library", 2);
200 +
201 +        // Read preferences
202 +        PrefsInit(argc, argv);
203  
204          // Open AHI
205          ahi_port = CreateMsgPort();
# Line 182 | Line 223 | int main(void)
223  
224          // Check start of Chip memory (because we need access to 0x0000..0x2000)
225          if ((uint32)FindName(&SysBase->MemList, (UBYTE *)"chip memory") < 0x2000) {
226 <                ErrorAlert(GetString(STR_NO_PREPARE_EMUL_ERR));
226 >                ErrorAlert(STR_NO_PREPARE_EMUL_ERR);
227                  QuitEmulator();
228          }
229  
230          // Open timer.device
231          timereq = (struct timerequest *)AllocVec(sizeof(timerequest), MEMF_PUBLIC | MEMF_CLEAR);
232          if (timereq == NULL) {
233 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
233 >                ErrorAlert(STR_NO_MEM_ERR);
234                  QuitEmulator();
235          }
236          if (OpenDevice((UBYTE *)TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) {
237 <                ErrorAlert(GetString(STR_NO_TIMER_DEV_ERR));
237 >                ErrorAlert(STR_NO_TIMER_DEV_ERR);
238                  QuitEmulator();
239          }
240          TimerBase = (struct Library *)timereq->tr_node.io_Device;
241  
242          // Allocate scratch memory
243 <        ScratchMem = (uint32)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
243 >        ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
244          if (ScratchMem == NULL) {
245 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
245 >                ErrorAlert(STR_NO_MEM_ERR);
246                  QuitEmulator();
247          }
248          ScratchMem += SCRATCH_MEM_SIZE/2;       // ScratchMem points to middle of block
# Line 213 | Line 254 | int main(void)
254                  WarningAlert(GetString(STR_SMALL_RAM_WARN));
255                  RAMSize = 1024*1024;
256          }
257 <        RAMBaseHost = (uint8 *)AllocMem(RAMSize + 0x100000, MEMF_PUBLIC);
257 >        RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC);
258          if (RAMBaseHost == NULL) {
259 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
260 <                QuitEmulator();
259 >                uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000;
260 >                char xText[120];
261 >
262 >                sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize);
263 >
264 >                if (ChoiceAlert(xText, "Use", "Quit") != 1)
265 >                        QuitEmulator();
266 >
267 >                RAMSize = newRAMSize;
268 >                RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC);
269 >                if (RAMBaseHost == NULL) {
270 >                        ErrorAlert(STR_NO_MEM_ERR);
271 >                        QuitEmulator();
272 >                }
273          }
274          RAMBaseMac = (uint32)RAMBaseHost;
275          D(bug("Mac RAM starts at %08lx\n", RAMBaseHost));
# Line 228 | Line 281 | int main(void)
281          const char *rom_path = PrefsFindString("rom");
282  
283          // Load Mac ROM
284 <        BPTR rom_fh = Open(rom_path ? (char *)rom_path : ROM_FILE_NAME, MODE_OLDFILE);
285 <        if (rom_fh == NULL) {
286 <                ErrorAlert(GetString(STR_NO_ROM_FILE_ERR));
284 >        BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE);
285 >        if (rom_fh == 0) {
286 >                ErrorAlert(STR_NO_ROM_FILE_ERR);
287                  QuitEmulator();
288          }
289          printf(GetString(STR_READING_ROM_FILE));
290          Seek(rom_fh, 0, OFFSET_END);
291          ROMSize = Seek(rom_fh, 0, OFFSET_CURRENT);
292          if (ROMSize != 512*1024 && ROMSize != 1024*1024) {
293 <                ErrorAlert(GetString(STR_ROM_SIZE_ERR));
293 >                ErrorAlert(STR_ROM_SIZE_ERR);
294                  Close(rom_fh);
295                  QuitEmulator();
296          }
297          Seek(rom_fh, 0, OFFSET_BEGINNING);
298          if (Read(rom_fh, ROMBaseHost, ROMSize) != ROMSize) {
299 <                ErrorAlert(GetString(STR_ROM_FILE_READ_ERR));
299 >                ErrorAlert(STR_ROM_FILE_READ_ERR);
300                  Close(rom_fh);
301                  QuitEmulator();
302          }
303  
251        // Check ROM version
252        if (!CheckROM()) {
253                ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR));
254                QuitEmulator();
255        }
256
304          // Set CPU and FPU type
305          UWORD attn = SysBase->AttnFlags;
306          CPUType = attn & AFF_68040 ? 4 : (attn & AFF_68030 ? 3 : 2);
307          CPUIs68060 = attn & AFF_68060;
308          FPUType = attn & AFF_68881 ? 1 : 0;
309  
310 <        // Load XPRAM
311 <        XPRAMInit();
265 <
266 <        // Set boot volume
267 <        int16 i16 = PrefsFindInt16("bootdrive");
268 <        XPRAM[0x78] = i16 >> 8;
269 <        XPRAM[0x79] = i16 & 0xff;
270 <        i16 = PrefsFindInt16("bootdriver");
271 <        XPRAM[0x7a] = i16 >> 8;
272 <        XPRAM[0x7b] = i16 & 0xff;
273 <
274 <        // Init drivers
275 <        SonyInit();
276 <        DiskInit();
277 <        CDROMInit();
278 <        SCSIInit();
279 <
280 <        // Init network
281 <        EtherInit();
282 <
283 <        // Init serial ports
284 <        SerialInit();
285 <
286 <        // Init Time Manager
287 <        TimerInit();
288 <
289 <        // Init clipboard
290 <        ClipInit();
291 <
292 <        // Init audio
293 <        AudioInit();
294 <
295 <        // Init video
296 <        if (!VideoInit(ROMVersion == ROM_VERSION_64K || ROMVersion == ROM_VERSION_PLUS || ROMVersion == ROM_VERSION_CLASSIC))
310 >        // Initialize everything
311 >        if (!InitAll())
312                  QuitEmulator();
313  
299        // Install ROM patches
300        if (!PatchROM()) {
301                ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR));
302                QuitEmulator();
303        }
304
314          // Move VBR away from 0 if neccessary
315          MoveVBR();
316  
317 +        // On 68060, disable Super Bypass mode because of a CPU bug that is triggered by MacOS 8
318 +        if (CPUIs68060)
319 +                DisableSuperBypass();
320 +
321          // Install trap handler
322          EmulatedSR = 0x2700;
323          OldTrapHandler = MainTask->tc_TrapCode;
# Line 317 | Line 330 | int main(void)
330          MainTask->tc_ExceptCode = (APTR)ExceptionHandlerAsm;
331          SetExcept(SIGBREAKF_CTRL_C | IRQSigMask, SIGBREAKF_CTRL_C | IRQSigMask);
332  
333 +        // Start XPRAM watchdog process
334 +        xpram_proc = CreateNewProcTags(
335 +                NP_Entry, (ULONG)xpram_func,
336 +                NP_Name, (ULONG)"Basilisk II XPRAM Watchdog",
337 +                NP_Priority, 0,
338 +                TAG_END
339 +        );
340 +
341          // Start 60Hz process
342          tick_proc = CreateNewProcTags(
343 <                NP_Entry, tick_func,
344 <                NP_Name, "Basilisk II 60Hz",
343 >                NP_Entry, (ULONG)tick_func,
344 >                NP_Name, (ULONG)"Basilisk II 60Hz",
345                  NP_Priority, 5,
346                  TAG_END
347          );
# Line 328 | Line 349 | int main(void)
349          // Set task priority to -1 so we don't use all processing time
350          SetTaskPri(MainTask, -1);
351  
352 +        WriteMacInt32(0xbff, 0);        // MacsBugFlags
353 +
354          // Swap stack to Mac RAM area
355          stack_swap.stk_Lower = RAMBaseHost;
356          stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize;
# Line 354 | Line 377 | void Start680x0(void)
377   *  Quit emulator (__saveds because it might be called from an exception)
378   */
379  
380 < void __saveds QuitEmulator(void)
380 > // Assembly entry point
381 > void __saveds quit_emulator(void)
382   {
383 +        QuitEmulator();
384 + }
385 +
386 + void QuitEmulator(void)
387 + {
388 +        // Stop 60Hz process
389 +        if (tick_proc) {
390 +                SetSignal(0, SIGF_SINGLE);
391 +                tick_proc_active = false;
392 +                Wait(SIGF_SINGLE);
393 +        }
394 +
395 +        // Stop XPRAM watchdog process
396 +        if (xpram_proc) {
397 +                SetSignal(0, SIGF_SINGLE);
398 +                xpram_proc_active = false;
399 +                Wait(SIGF_SINGLE);
400 +        }
401 +
402          // Restore stack
403          if (stack_swapped) {
404                  stack_swapped = false;
# Line 369 | Line 412 | void __saveds QuitEmulator(void)
412                  FreeSignal(IRQSig);
413          }
414  
372        // Stop 60Hz thread
373        if (tick_proc) {
374                SetSignal(0, SIGF_SINGLE);
375                tick_proc_active = false;
376                Wait(SIGF_SINGLE);
377        }
378
415          // Remove trap handler
416          MainTask->tc_TrapCode = OldTrapHandler;
417  
418 <        // Save XPRAM
419 <        XPRAMExit();
384 <
385 <        // Exit video
386 <        VideoExit();
387 <
388 <        // Exit audio
389 <        AudioExit();
390 <
391 <        // Exit clipboard
392 <        ClipExit();
393 <
394 <        // Exit Time Manager
395 <        TimerExit();
396 <
397 <        // Exit serial ports
398 <        SerialExit();
399 <
400 <        // Exit network
401 <        EtherExit();
402 <
403 <        // Exit drivers
404 <        SCSIExit();
405 <        CDROMExit();
406 <        DiskExit();
407 <        SonyExit();
418 >        // Deinitialize everything
419 >        ExitAll();
420  
421          // Delete RAM/ROM area
422          if (RAMBaseHost)
423 <                FreeMem(RAMBaseHost, RAMSize + 0x100000);
423 >                FreeVec(RAMBaseHost);
424  
425          // Delete scratch memory area
426          if (ScratchMem)
# Line 435 | Line 447 | void __saveds QuitEmulator(void)
447          PrefsExit();
448  
449          // Close libraries
450 +        if (CyberGfxBase)
451 +                CloseLibrary(CyberGfxBase);
452          if (P96Base)
453                  CloseLibrary(P96Base);
454          if (AslBase)
455                  CloseLibrary(AslBase);
456 +        if (IFFParseBase)
457 +                CloseLibrary(IFFParseBase);
458          if (GadToolsBase)
459                  CloseLibrary(GadToolsBase);
460 +        if (IntuitionBase)
461 +                CloseLibrary((struct Library *)IntuitionBase);
462 +        if (GfxBase)
463 +                CloseLibrary(GfxBase);
464  
465          exit(0);
466   }
# Line 458 | Line 478 | void FlushCodeCache(void *start, uint32
478  
479  
480   /*
481 + *  Mutexes
482 + */
483 +
484 + struct B2_mutex {
485 +        int dummy;      //!!
486 + };
487 +
488 + B2_mutex *B2_create_mutex(void)
489 + {
490 +        return new B2_mutex;
491 + }
492 +
493 + void B2_lock_mutex(B2_mutex *mutex)
494 + {
495 + }
496 +
497 + void B2_unlock_mutex(B2_mutex *mutex)
498 + {
499 + }
500 +
501 + void B2_delete_mutex(B2_mutex *mutex)
502 + {
503 +        delete mutex;
504 + }
505 +
506 +
507 + /*
508   *  Interrupt flags (must be handled atomically!)
509   */
510  
# Line 478 | Line 525 | void TriggerInterrupt(void)
525          Signal(MainTask, IRQSigMask);
526   }
527  
528 + void TriggerNMI(void)
529 + {
530 +        AsmTriggerNMI();
531 + }
532 +
533  
534   /*
535 < *  60Hz thread
535 > *  60Hz thread (really 60.15Hz)
536   */
537  
538   static __saveds void tick_func(void)
# Line 520 | Line 572 | static __saveds void tick_func(void)
572                  if (++tick_counter > 60) {
573                          tick_counter = 0;
574                          WriteMacInt32(0x20c, TimerDateTime());
575 +                        SetInterruptFlag(INTFLAG_1HZ);
576 +                        TriggerInterrupt();
577                  }
578  
579                  // Trigger 60Hz interrupt
# Line 545 | Line 599 | static __saveds void tick_func(void)
599  
600  
601   /*
602 + *  XPRAM watchdog thread (saves XPRAM every minute)
603 + */
604 +
605 + static __saveds void xpram_func(void)
606 + {
607 +        uint8 last_xpram[XPRAM_SIZE];
608 +        memcpy(last_xpram, XPRAM, XPRAM_SIZE);
609 +
610 +        while (xpram_proc_active) {
611 +                for (int i=0; i<60 && xpram_proc_active; i++)
612 +                        Delay(50);              // Only wait 1 second so we quit promptly when xpram_proc_active becomes false
613 +                if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) {
614 +                        memcpy(last_xpram, XPRAM, XPRAM_SIZE);
615 +                        SaveXPRAM();
616 +                }
617 +        }
618 +
619 +        // Main task asked for termination, send signal
620 +        Forbid();
621 +        Signal(MainTask, SIGF_SINGLE);
622 + }
623 +
624 +
625 + /*
626   *  Display error alert
627   */
628  
# Line 560 | Line 638 | void ErrorAlert(const char *text)
638          req.es_Title = (UBYTE *)GetString(STR_ERROR_ALERT_TITLE);
639          req.es_TextFormat = (UBYTE *)GetString(STR_GUI_ERROR_PREFIX);
640          req.es_GadgetFormat = (UBYTE *)GetString(STR_QUIT_BUTTON);
641 <        EasyRequest(NULL, &req, NULL, text);
641 >        EasyRequest(NULL, &req, NULL, (ULONG)text);
642   }
643  
644  
# Line 580 | Line 658 | void WarningAlert(const char *text)
658          req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE);
659          req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX);
660          req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON);
661 <        EasyRequest(NULL, &req, NULL, text);
661 >        EasyRequest(NULL, &req, NULL, (ULONG)text);
662   }
663  
664  
# Line 598 | Line 676 | bool ChoiceAlert(const char *text, const
676          req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE);
677          req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX);
678          req.es_GadgetFormat = (UBYTE *)str;
679 <        return EasyRequest(NULL, &req, NULL, text);
679 >        return EasyRequest(NULL, &req, NULL, (ULONG)text);
680   }
681  
682  
# Line 633 | Line 711 | void __saveds IllInstrHandler(trap_regs
711                  EmulatedSR |= 0x0700;
712  
713                  // Call opcode routine
714 <                EmulOp(*(uint16 *)(r->pc), (M68kRegisters *)r);
714 >                EmulOp(opcode, (M68kRegisters *)r);
715                  r->pc += 2;
716  
717                  // Restore interrupts

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines