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.2 by cebix, 1999-10-19T17:41:21Z vs.
Revision 1.15 by cebix, 2001-02-02T20:52:57Z

# 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();
# Line 153 | Line 177 | int main(void)
177                  ErrorAlert(GetString(STR_NO_GADTOOLS_LIB_ERR));
178                  QuitEmulator();
179          }
180 +        IFFParseBase = OpenLibrary((UBYTE *)"iffparse.library", 39);
181 +        if (IFFParseBase == NULL) {
182 +                ErrorAlert(GetString(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));
188                  QuitEmulator();
189          }
190 +
191 +        // These two can fail (the respective gfx support won't be available, then)
192          P96Base = OpenLibrary((UBYTE *)"Picasso96API.library", 2);
193 +        CyberGfxBase = OpenLibrary((UBYTE *)"cybergraphics.library", 2);
194 +
195 +        // Read preferences
196 +        PrefsInit(argc, argv);
197  
198          // Open AHI
199          ahi_port = CreateMsgPort();
# Line 199 | Line 234 | int main(void)
234          TimerBase = (struct Library *)timereq->tr_node.io_Device;
235  
236          // Allocate scratch memory
237 <        ScratchMem = (uint32)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
237 >        ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
238          if (ScratchMem == NULL) {
239                  ErrorAlert(GetString(STR_NO_MEM_ERR));
240                  QuitEmulator();
# Line 213 | Line 248 | int main(void)
248                  WarningAlert(GetString(STR_SMALL_RAM_WARN));
249                  RAMSize = 1024*1024;
250          }
251 <        RAMBaseHost = (uint8 *)AllocMem(RAMSize + 0x100000, MEMF_PUBLIC);
251 >        RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC);
252          if (RAMBaseHost == NULL) {
253 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
254 <                QuitEmulator();
253 >                uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000;
254 >                char xText[120];
255 >
256 >                sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize);
257 >
258 >                if (ChoiceAlert(xText, "Use", "Quit") != 1)
259 >                        QuitEmulator();
260 >
261 >                RAMSize = newRAMSize;
262 >                RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC);
263 >                if (RAMBaseHost == NULL) {
264 >                        ErrorAlert(GetString(STR_NO_MEM_ERR));
265 >                        QuitEmulator();
266 >                }
267          }
268          RAMBaseMac = (uint32)RAMBaseHost;
269          D(bug("Mac RAM starts at %08lx\n", RAMBaseHost));
# Line 228 | Line 275 | int main(void)
275          const char *rom_path = PrefsFindString("rom");
276  
277          // Load Mac ROM
278 <        BPTR rom_fh = Open(rom_path ? (char *)rom_path : ROM_FILE_NAME, MODE_OLDFILE);
278 >        BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE);
279          if (rom_fh == NULL) {
280                  ErrorAlert(GetString(STR_NO_ROM_FILE_ERR));
281                  QuitEmulator();
# Line 261 | Line 308 | int main(void)
308          // Move VBR away from 0 if neccessary
309          MoveVBR();
310  
311 +        // On 68060, disable Super Bypass mode because of a CPU bug that is triggered by MacOS 8
312 +        if (CPUIs68060)
313 +                DisableSuperBypass();
314 +
315          // Install trap handler
316          EmulatedSR = 0x2700;
317          OldTrapHandler = MainTask->tc_TrapCode;
# Line 273 | Line 324 | int main(void)
324          MainTask->tc_ExceptCode = (APTR)ExceptionHandlerAsm;
325          SetExcept(SIGBREAKF_CTRL_C | IRQSigMask, SIGBREAKF_CTRL_C | IRQSigMask);
326  
327 +        // Start XPRAM watchdog process
328 +        xpram_proc = CreateNewProcTags(
329 +                NP_Entry, (ULONG)xpram_func,
330 +                NP_Name, (ULONG)"Basilisk II XPRAM Watchdog",
331 +                NP_Priority, 0,
332 +                TAG_END
333 +        );
334 +
335          // Start 60Hz process
336          tick_proc = CreateNewProcTags(
337 <                NP_Entry, tick_func,
338 <                NP_Name, "Basilisk II 60Hz",
337 >                NP_Entry, (ULONG)tick_func,
338 >                NP_Name, (ULONG)"Basilisk II 60Hz",
339                  NP_Priority, 5,
340                  TAG_END
341          );
# Line 284 | Line 343 | int main(void)
343          // Set task priority to -1 so we don't use all processing time
344          SetTaskPri(MainTask, -1);
345  
346 +        WriteMacInt32(0xbff, 0);        // MacsBugFlags
347 +
348          // Swap stack to Mac RAM area
349          stack_swap.stk_Lower = RAMBaseHost;
350          stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize;
# Line 310 | Line 371 | void Start680x0(void)
371   *  Quit emulator (__saveds because it might be called from an exception)
372   */
373  
374 < void __saveds QuitEmulator(void)
374 > // Assembly entry point
375 > void __saveds quit_emulator(void)
376   {
377 +        QuitEmulator();
378 + }
379 +
380 + void QuitEmulator(void)
381 + {
382 +        // Stop 60Hz process
383 +        if (tick_proc) {
384 +                SetSignal(0, SIGF_SINGLE);
385 +                tick_proc_active = false;
386 +                Wait(SIGF_SINGLE);
387 +        }
388 +
389 +        // Stop XPRAM watchdog process
390 +        if (xpram_proc) {
391 +                SetSignal(0, SIGF_SINGLE);
392 +                xpram_proc_active = false;
393 +                Wait(SIGF_SINGLE);
394 +        }
395 +
396          // Restore stack
397          if (stack_swapped) {
398                  stack_swapped = false;
# Line 325 | Line 406 | void __saveds QuitEmulator(void)
406                  FreeSignal(IRQSig);
407          }
408  
328        // Stop 60Hz thread
329        if (tick_proc) {
330                SetSignal(0, SIGF_SINGLE);
331                tick_proc_active = false;
332                Wait(SIGF_SINGLE);
333        }
334
409          // Remove trap handler
410          MainTask->tc_TrapCode = OldTrapHandler;
411  
# Line 340 | Line 414 | void __saveds QuitEmulator(void)
414  
415          // Delete RAM/ROM area
416          if (RAMBaseHost)
417 <                FreeMem(RAMBaseHost, RAMSize + 0x100000);
417 >                FreeVec(RAMBaseHost);
418  
419          // Delete scratch memory area
420          if (ScratchMem)
# Line 367 | Line 441 | void __saveds QuitEmulator(void)
441          PrefsExit();
442  
443          // Close libraries
444 +        if (CyberGfxBase)
445 +                CloseLibrary(CyberGfxBase);
446          if (P96Base)
447                  CloseLibrary(P96Base);
448          if (AslBase)
449                  CloseLibrary(AslBase);
450 +        if (IFFParseBase)
451 +                CloseLibrary(IFFParseBase);
452          if (GadToolsBase)
453                  CloseLibrary(GadToolsBase);
454 +        if (IntuitionBase)
455 +                CloseLibrary((struct Library *)IntuitionBase);
456 +        if (GfxBase)
457 +                CloseLibrary(GfxBase);
458  
459          exit(0);
460   }
# Line 410 | Line 492 | void TriggerInterrupt(void)
492          Signal(MainTask, IRQSigMask);
493   }
494  
495 + void TriggerNMI(void)
496 + {
497 +        AsmTriggerNMI();
498 + }
499 +
500  
501   /*
502 < *  60Hz thread
502 > *  60Hz thread (really 60.15Hz)
503   */
504  
505   static __saveds void tick_func(void)
# Line 452 | Line 539 | static __saveds void tick_func(void)
539                  if (++tick_counter > 60) {
540                          tick_counter = 0;
541                          WriteMacInt32(0x20c, TimerDateTime());
542 +                        SetInterruptFlag(INTFLAG_1HZ);
543 +                        TriggerInterrupt();
544                  }
545  
546                  // Trigger 60Hz interrupt
# Line 477 | Line 566 | static __saveds void tick_func(void)
566  
567  
568   /*
569 + *  XPRAM watchdog thread (saves XPRAM every minute)
570 + */
571 +
572 + static __saveds void xpram_func(void)
573 + {
574 +        uint8 last_xpram[256];
575 +        memcpy(last_xpram, XPRAM, 256);
576 +
577 +        while (xpram_proc_active) {
578 +                for (int i=0; i<60 && xpram_proc_active; i++)
579 +                        Delay(50);              // Only wait 1 second so we quit promptly when xpram_proc_active becomes false
580 +                if (memcmp(last_xpram, XPRAM, 256)) {
581 +                        memcpy(last_xpram, XPRAM, 256);
582 +                        SaveXPRAM();
583 +                }
584 +        }
585 +
586 +        // Main task asked for termination, send signal
587 +        Forbid();
588 +        Signal(MainTask, SIGF_SINGLE);
589 + }
590 +
591 +
592 + /*
593   *  Display error alert
594   */
595  
# Line 492 | Line 605 | void ErrorAlert(const char *text)
605          req.es_Title = (UBYTE *)GetString(STR_ERROR_ALERT_TITLE);
606          req.es_TextFormat = (UBYTE *)GetString(STR_GUI_ERROR_PREFIX);
607          req.es_GadgetFormat = (UBYTE *)GetString(STR_QUIT_BUTTON);
608 <        EasyRequest(NULL, &req, NULL, text);
608 >        EasyRequest(NULL, &req, NULL, (ULONG)text);
609   }
610  
611  
# Line 512 | Line 625 | void WarningAlert(const char *text)
625          req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE);
626          req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX);
627          req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON);
628 <        EasyRequest(NULL, &req, NULL, text);
628 >        EasyRequest(NULL, &req, NULL, (ULONG)text);
629   }
630  
631  
# Line 530 | Line 643 | bool ChoiceAlert(const char *text, const
643          req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE);
644          req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX);
645          req.es_GadgetFormat = (UBYTE *)str;
646 <        return EasyRequest(NULL, &req, NULL, text);
646 >        return EasyRequest(NULL, &req, NULL, (ULONG)text);
647   }
648  
649  
# Line 565 | Line 678 | void __saveds IllInstrHandler(trap_regs
678                  EmulatedSR |= 0x0700;
679  
680                  // Call opcode routine
681 <                EmulOp(*(uint16 *)(r->pc), (M68kRegisters *)r);
681 >                EmulOp(opcode, (M68kRegisters *)r);
682                  r->pc += 2;
683  
684                  // Restore interrupts

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines