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.6 by cebix, 2000-07-06T16:04:24Z vs.
Revision 1.18 by cebix, 2001-07-03T15:59:45Z

# Line 1 | Line 1
1   /*
2   *  main_amiga.cpp - Startup code for AmigaOS
3   *
4 < *  Basilisk II (C) 1997-2000 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 97 | Line 97 | 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 108 | 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 120 | Line 123 | 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  
# Line 137 | Line 143 | static void tick_func(void);
143   *  Main program
144   */
145  
146 < int main(void)
146 > int main(int argc, char **argv)
147   {
148          // Initialize variables
149          RAMBaseHost = NULL;
# Line 168 | Line 174 | int main(void)
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(GetString(STR_NO_IFFPARSE_LIB_ERR));
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  
# Line 187 | Line 193 | int main(void)
193          CyberGfxBase = OpenLibrary((UBYTE *)"cybergraphics.library", 2);
194  
195          // Read preferences
196 <        PrefsInit();
196 >        PrefsInit(argc, argv);
197  
198          // Open AHI
199          ahi_port = CreateMsgPort();
# Line 211 | Line 217 | int main(void)
217  
218          // Check start of Chip memory (because we need access to 0x0000..0x2000)
219          if ((uint32)FindName(&SysBase->MemList, (UBYTE *)"chip memory") < 0x2000) {
220 <                ErrorAlert(GetString(STR_NO_PREPARE_EMUL_ERR));
220 >                ErrorAlert(STR_NO_PREPARE_EMUL_ERR);
221                  QuitEmulator();
222          }
223  
224          // Open timer.device
225          timereq = (struct timerequest *)AllocVec(sizeof(timerequest), MEMF_PUBLIC | MEMF_CLEAR);
226          if (timereq == NULL) {
227 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
227 >                ErrorAlert(STR_NO_MEM_ERR);
228                  QuitEmulator();
229          }
230          if (OpenDevice((UBYTE *)TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) {
231 <                ErrorAlert(GetString(STR_NO_TIMER_DEV_ERR));
231 >                ErrorAlert(STR_NO_TIMER_DEV_ERR);
232                  QuitEmulator();
233          }
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));
239 >                ErrorAlert(STR_NO_MEM_ERR);
240                  QuitEmulator();
241          }
242          ScratchMem += SCRATCH_MEM_SIZE/2;       // ScratchMem points to middle of block
# Line 242 | 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(STR_NO_MEM_ERR);
265 >                        QuitEmulator();
266 >                }
267          }
268          RAMBaseMac = (uint32)RAMBaseHost;
269          D(bug("Mac RAM starts at %08lx\n", RAMBaseHost));
# Line 258 | Line 276 | int main(void)
276  
277          // Load Mac ROM
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));
279 >        if (rom_fh == 0) {
280 >                ErrorAlert(STR_NO_ROM_FILE_ERR);
281                  QuitEmulator();
282          }
283          printf(GetString(STR_READING_ROM_FILE));
284          Seek(rom_fh, 0, OFFSET_END);
285          ROMSize = Seek(rom_fh, 0, OFFSET_CURRENT);
286          if (ROMSize != 512*1024 && ROMSize != 1024*1024) {
287 <                ErrorAlert(GetString(STR_ROM_SIZE_ERR));
287 >                ErrorAlert(STR_ROM_SIZE_ERR);
288                  Close(rom_fh);
289                  QuitEmulator();
290          }
291          Seek(rom_fh, 0, OFFSET_BEGINNING);
292          if (Read(rom_fh, ROMBaseHost, ROMSize) != ROMSize) {
293 <                ErrorAlert(GetString(STR_ROM_FILE_READ_ERR));
293 >                ErrorAlert(STR_ROM_FILE_READ_ERR);
294                  Close(rom_fh);
295                  QuitEmulator();
296          }
# Line 290 | 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 302 | 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, (ULONG)tick_func,
# Line 313 | 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 347 | Line 379 | void __saveds quit_emulator(void)
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 360 | Line 406 | void QuitEmulator(void)
406                  FreeSignal(IRQSig);
407          }
408  
363        // Stop 60Hz thread
364        if (tick_proc) {
365                SetSignal(0, SIGF_SINGLE);
366                tick_proc_active = false;
367                Wait(SIGF_SINGLE);
368        }
369
409          // Remove trap handler
410          MainTask->tc_TrapCode = OldTrapHandler;
411  
# Line 375 | Line 414 | void 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 433 | Line 472 | void FlushCodeCache(void *start, uint32
472  
473  
474   /*
475 + *  Mutexes
476 + */
477 +
478 + struct B2_mutex {
479 +        int dummy;      //!!
480 + };
481 +
482 + B2_mutex *B2_create_mutex(void)
483 + {
484 +        return new B2_mutex;
485 + }
486 +
487 + void B2_lock_mutex(B2_mutex *mutex)
488 + {
489 + }
490 +
491 + void B2_unlock_mutex(B2_mutex *mutex)
492 + {
493 + }
494 +
495 + void B2_delete_mutex(B2_mutex *mutex)
496 + {
497 +        delete mutex;
498 + }
499 +
500 +
501 + /*
502   *  Interrupt flags (must be handled atomically!)
503   */
504  
# Line 453 | Line 519 | void TriggerInterrupt(void)
519          Signal(MainTask, IRQSigMask);
520   }
521  
522 + void TriggerNMI(void)
523 + {
524 +        AsmTriggerNMI();
525 + }
526 +
527  
528   /*
529 < *  60Hz thread
529 > *  60Hz thread (really 60.15Hz)
530   */
531  
532   static __saveds void tick_func(void)
# Line 495 | Line 566 | static __saveds void tick_func(void)
566                  if (++tick_counter > 60) {
567                          tick_counter = 0;
568                          WriteMacInt32(0x20c, TimerDateTime());
569 +                        SetInterruptFlag(INTFLAG_1HZ);
570 +                        TriggerInterrupt();
571                  }
572  
573                  // Trigger 60Hz interrupt
# Line 520 | Line 593 | static __saveds void tick_func(void)
593  
594  
595   /*
596 + *  XPRAM watchdog thread (saves XPRAM every minute)
597 + */
598 +
599 + static __saveds void xpram_func(void)
600 + {
601 +        uint8 last_xpram[256];
602 +        memcpy(last_xpram, XPRAM, 256);
603 +
604 +        while (xpram_proc_active) {
605 +                for (int i=0; i<60 && xpram_proc_active; i++)
606 +                        Delay(50);              // Only wait 1 second so we quit promptly when xpram_proc_active becomes false
607 +                if (memcmp(last_xpram, XPRAM, 256)) {
608 +                        memcpy(last_xpram, XPRAM, 256);
609 +                        SaveXPRAM();
610 +                }
611 +        }
612 +
613 +        // Main task asked for termination, send signal
614 +        Forbid();
615 +        Signal(MainTask, SIGF_SINGLE);
616 + }
617 +
618 +
619 + /*
620   *  Display error alert
621   */
622  
# Line 608 | Line 705 | void __saveds IllInstrHandler(trap_regs
705                  EmulatedSR |= 0x0700;
706  
707                  // Call opcode routine
708 <                EmulOp(*(uint16 *)(r->pc), (M68kRegisters *)r);
708 >                EmulOp(opcode, (M68kRegisters *)r);
709                  r->pc += 2;
710  
711                  // Restore interrupts

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines