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.22 by jlachmann, 2002-06-23T08:27:05Z

# 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 26 | Line 26
26   #include <intuition/intuition.h>
27   #include <devices/timer.h>
28   #include <devices/ahi.h>
29 + #define __USE_SYSBASE
30   #include <proto/exec.h>
31   #include <proto/dos.h>
32   #include <proto/intuition.h>
33 + #include <inline/exec.h>
34 + #include <inline/dos.h>
35 + #include <inline/intuition.h>
36  
37   #include "sysdeps.h"
38   #include "cpu_emulation.h"
# Line 97 | Line 101 | struct Library *AHIBase = NULL;
101   struct Library *DiskBase = NULL;
102  
103   struct Task *MainTask;                                                  // Our task
104 < uint32 ScratchMem = NULL;                                               // Scratch memory for Mac ROM writes
104 > uint8 *ScratchMem = NULL;                                               // Scratch memory for Mac ROM writes
105   APTR OldTrapHandler = NULL;                                             // Old trap handler
106   APTR OldExceptionHandler = NULL;                                // Old exception handler
107   BYTE IRQSig = -1;                                                               // "Interrupt" signal number
# Line 108 | Line 112 | static struct timerequest *timereq = NUL
112   static struct MsgPort *ahi_port = NULL;                 // Port for AHI
113   static struct AHIRequest *ahi_io = NULL;                // IORequest for AHI
114  
115 + static struct Process *xpram_proc = NULL;               // XPRAM watchdog
116 + static volatile bool xpram_proc_active = true;  // Flag for quitting the XPRAM watchdog
117 +
118   static struct Process *tick_proc = NULL;                // 60Hz process
119   static volatile bool tick_proc_active = true;   // Flag for quitting the 60Hz process
120  
# Line 120 | Line 127 | struct trap_regs;
127   extern "C" void AtomicAnd(uint32 *p, uint32 val);
128   extern "C" void AtomicOr(uint32 *p, uint32 val);
129   extern "C" void MoveVBR(void);
130 + extern "C" void DisableSuperBypass(void);
131   extern "C" void TrapHandlerAsm(void);
132   extern "C" void ExceptionHandlerAsm(void);
133   extern "C" void IllInstrHandler(trap_regs *regs);
134   extern "C" void PrivViolHandler(trap_regs *regs);
135   extern "C" void quit_emulator(void);
136 + extern "C" void AsmTriggerNMI(void);
137   uint16 EmulatedSR;                                      // Emulated SR (supervisor bit and interrupt mask)
138  
139  
140   // Prototypes
141   static void jump_to_rom(void);
142 + static void xpram_func(void);
143   static void tick_func(void);
144  
145  
# Line 137 | Line 147 | static void tick_func(void);
147   *  Main program
148   */
149  
150 < int main(void)
150 > int main(int argc, char **argv)
151   {
152          // Initialize variables
153          RAMBaseHost = NULL;
# Line 152 | Line 162 | int main(void)
162          printf(" %s\n", GetString(STR_ABOUT_TEXT2));
163  
164          // Open libraries
165 <        GfxBase = OpenLibrary((UBYTE *)"graphics.library", 39);
165 >        GfxBase = OpenLibrary((UBYTE *) "graphics.library", 39);
166          if (GfxBase == NULL) {
167                  printf("Cannot open graphics.library V39.\n");
168                  exit(1);
169          }
170 <        IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)"intuition.library", 39);
170 >        IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *) "intuition.library", 39);
171          if (IntuitionBase == NULL) {
172                  printf("Cannot open intuition.library V39.\n");
173                  CloseLibrary(GfxBase);
174                  exit(1);
175          }
176 <        DiskBase = (struct Library *)OpenResource((UBYTE *)"disk.resource");
176 >        DiskBase = (struct Library *)OpenResource((UBYTE *) "disk.resource");
177          if (DiskBase == NULL)
178                  QuitEmulator();
179 <        GadToolsBase = OpenLibrary((UBYTE *)"gadtools.library", 39);
179 >        GadToolsBase = OpenLibrary((UBYTE *) "gadtools.library", 39);
180          if (GadToolsBase == NULL) {
181 <                ErrorAlert(GetString(STR_NO_GADTOOLS_LIB_ERR));
181 >                ErrorAlert(STR_NO_GADTOOLS_LIB_ERR);
182                  QuitEmulator();
183          }
184 <        IFFParseBase = OpenLibrary((UBYTE *)"iffparse.library", 39);
184 >        IFFParseBase = OpenLibrary((UBYTE *) "iffparse.library", 39);
185          if (IFFParseBase == NULL) {
186 <                ErrorAlert(GetString(STR_NO_IFFPARSE_LIB_ERR));
186 >                ErrorAlert(STR_NO_IFFPARSE_LIB_ERR);
187                  QuitEmulator();
188          }
189 <        AslBase = OpenLibrary((UBYTE *)"asl.library", 36);
189 >        AslBase = OpenLibrary((UBYTE *) "asl.library", 36);
190          if (AslBase == NULL) {
191 <                ErrorAlert(GetString(STR_NO_ASL_LIB_ERR));
191 >                ErrorAlert(STR_NO_ASL_LIB_ERR);
192                  QuitEmulator();
193          }
194  
195 +        if (FindTask((UBYTE *) "« Enforcer »"))
196 +                {
197 +                ErrorAlert(STR_ENFORCER_RUNNING_ERR);
198 +                QuitEmulator();
199 +                }
200 +
201          // These two can fail (the respective gfx support won't be available, then)
202 <        P96Base = OpenLibrary((UBYTE *)"Picasso96API.library", 2);
203 <        CyberGfxBase = OpenLibrary((UBYTE *)"cybergraphics.library", 2);
202 >        P96Base = OpenLibrary((UBYTE *) "Picasso96API.library", 2);
203 >        CyberGfxBase = OpenLibrary((UBYTE *) "cybergraphics.library", 2);
204  
205          // Read preferences
206 <        PrefsInit();
206 >        PrefsInit(argc, argv);
207  
208          // Open AHI
209          ahi_port = CreateMsgPort();
# Line 195 | Line 211 | int main(void)
211                  ahi_io = (struct AHIRequest *)CreateIORequest(ahi_port, sizeof(struct AHIRequest));
212                  if (ahi_io) {
213                          ahi_io->ahir_Version = 2;
214 <                        if (OpenDevice((UBYTE *)AHINAME, AHI_NO_UNIT, (struct IORequest *)ahi_io, 0) == 0) {
214 >                        if (OpenDevice((UBYTE *) AHINAME, AHI_NO_UNIT, (struct IORequest *)ahi_io, 0) == 0) {
215                                  AHIBase = (struct Library *)ahi_io->ahir_Std.io_Device;
216                          }
217                  }
# Line 210 | Line 226 | int main(void)
226                          QuitEmulator();
227  
228          // Check start of Chip memory (because we need access to 0x0000..0x2000)
229 <        if ((uint32)FindName(&SysBase->MemList, (UBYTE *)"chip memory") < 0x2000) {
230 <                ErrorAlert(GetString(STR_NO_PREPARE_EMUL_ERR));
229 >        if ((uint32)FindName(&SysBase->MemList, (UBYTE *) "chip memory") < 0x2000) {
230 >                ErrorAlert(STR_NO_PREPARE_EMUL_ERR);
231                  QuitEmulator();
232          }
233  
234          // Open timer.device
235          timereq = (struct timerequest *)AllocVec(sizeof(timerequest), MEMF_PUBLIC | MEMF_CLEAR);
236          if (timereq == NULL) {
237 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
237 >                ErrorAlert(STR_NO_MEM_ERR);
238                  QuitEmulator();
239          }
240 <        if (OpenDevice((UBYTE *)TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) {
241 <                ErrorAlert(GetString(STR_NO_TIMER_DEV_ERR));
240 >        if (OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) {
241 >                ErrorAlert(STR_NO_TIMER_DEV_ERR);
242                  QuitEmulator();
243          }
244          TimerBase = (struct Library *)timereq->tr_node.io_Device;
245  
246          // Allocate scratch memory
247 <        ScratchMem = (uint32)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
247 >        ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC);
248          if (ScratchMem == NULL) {
249 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
249 >                ErrorAlert(STR_NO_MEM_ERR);
250                  QuitEmulator();
251          }
252          ScratchMem += SCRATCH_MEM_SIZE/2;       // ScratchMem points to middle of block
# Line 242 | Line 258 | int main(void)
258                  WarningAlert(GetString(STR_SMALL_RAM_WARN));
259                  RAMSize = 1024*1024;
260          }
261 <        RAMBaseHost = (uint8 *)AllocMem(RAMSize + 0x100000, MEMF_PUBLIC);
261 >        RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC);
262          if (RAMBaseHost == NULL) {
263 <                ErrorAlert(GetString(STR_NO_MEM_ERR));
264 <                QuitEmulator();
263 >                uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000;
264 >                char xText[120];
265 >
266 >                sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize);
267 >
268 >                if (ChoiceAlert(xText, "Use", "Quit") != 1)
269 >                        QuitEmulator();
270 >
271 >                RAMSize = newRAMSize;
272 >                RAMBaseHost = (uint8 *)AllocVec(RAMSize - 0x100000, MEMF_PUBLIC);
273 >                if (RAMBaseHost == NULL) {
274 >                        ErrorAlert(STR_NO_MEM_ERR);
275 >                        QuitEmulator();
276 >                }
277          }
278          RAMBaseMac = (uint32)RAMBaseHost;
279          D(bug("Mac RAM starts at %08lx\n", RAMBaseHost));
# Line 258 | Line 286 | int main(void)
286  
287          // Load Mac ROM
288          BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE);
289 <        if (rom_fh == NULL) {
290 <                ErrorAlert(GetString(STR_NO_ROM_FILE_ERR));
289 >        if (rom_fh == 0) {
290 >                ErrorAlert(STR_NO_ROM_FILE_ERR);
291                  QuitEmulator();
292          }
293          printf(GetString(STR_READING_ROM_FILE));
294          Seek(rom_fh, 0, OFFSET_END);
295          ROMSize = Seek(rom_fh, 0, OFFSET_CURRENT);
296          if (ROMSize != 512*1024 && ROMSize != 1024*1024) {
297 <                ErrorAlert(GetString(STR_ROM_SIZE_ERR));
297 >                ErrorAlert(STR_ROM_SIZE_ERR);
298                  Close(rom_fh);
299                  QuitEmulator();
300          }
301          Seek(rom_fh, 0, OFFSET_BEGINNING);
302          if (Read(rom_fh, ROMBaseHost, ROMSize) != ROMSize) {
303 <                ErrorAlert(GetString(STR_ROM_FILE_READ_ERR));
303 >                ErrorAlert(STR_ROM_FILE_READ_ERR);
304                  Close(rom_fh);
305                  QuitEmulator();
306          }
# Line 290 | Line 318 | int main(void)
318          // Move VBR away from 0 if neccessary
319          MoveVBR();
320  
321 +        // On 68060, disable Super Bypass mode because of a CPU bug that is triggered by MacOS 8
322 +        if (CPUIs68060)
323 +                DisableSuperBypass();
324 +
325 +        memset((UBYTE *) 8, 0, 0x2000-8);
326 +
327          // Install trap handler
328          EmulatedSR = 0x2700;
329          OldTrapHandler = MainTask->tc_TrapCode;
# Line 302 | Line 336 | int main(void)
336          MainTask->tc_ExceptCode = (APTR)ExceptionHandlerAsm;
337          SetExcept(SIGBREAKF_CTRL_C | IRQSigMask, SIGBREAKF_CTRL_C | IRQSigMask);
338  
339 +        // Start XPRAM watchdog process
340 +        xpram_proc = CreateNewProcTags(
341 +                NP_Entry, (ULONG)xpram_func,
342 +                NP_Name, (ULONG)"Basilisk II XPRAM Watchdog",
343 +                NP_Priority, 0,
344 +                TAG_END
345 +        );
346 +
347          // Start 60Hz process
348          tick_proc = CreateNewProcTags(
349                  NP_Entry, (ULONG)tick_func,
# Line 313 | Line 355 | int main(void)
355          // Set task priority to -1 so we don't use all processing time
356          SetTaskPri(MainTask, -1);
357  
358 +        WriteMacInt32(0xbff, 0);        // MacsBugFlags
359 +
360          // Swap stack to Mac RAM area
361          stack_swap.stk_Lower = RAMBaseHost;
362          stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize;
# Line 347 | Line 391 | void __saveds quit_emulator(void)
391  
392   void QuitEmulator(void)
393   {
394 +        // Stop 60Hz process
395 +        if (tick_proc) {
396 +                SetSignal(0, SIGF_SINGLE);
397 +                tick_proc_active = false;
398 +                Wait(SIGF_SINGLE);
399 +        }
400 +
401 +        // Stop XPRAM watchdog process
402 +        if (xpram_proc) {
403 +                SetSignal(0, SIGF_SINGLE);
404 +                xpram_proc_active = false;
405 +                Wait(SIGF_SINGLE);
406 +        }
407 +
408          // Restore stack
409          if (stack_swapped) {
410                  stack_swapped = false;
# Line 360 | Line 418 | void QuitEmulator(void)
418                  FreeSignal(IRQSig);
419          }
420  
363        // Stop 60Hz thread
364        if (tick_proc) {
365                SetSignal(0, SIGF_SINGLE);
366                tick_proc_active = false;
367                Wait(SIGF_SINGLE);
368        }
369
421          // Remove trap handler
422          MainTask->tc_TrapCode = OldTrapHandler;
423  
# Line 375 | Line 426 | void QuitEmulator(void)
426  
427          // Delete RAM/ROM area
428          if (RAMBaseHost)
429 <                FreeMem(RAMBaseHost, RAMSize + 0x100000);
429 >                FreeVec(RAMBaseHost);
430  
431          // Delete scratch memory area
432          if (ScratchMem)
# Line 433 | Line 484 | void FlushCodeCache(void *start, uint32
484  
485  
486   /*
487 + *  Mutexes
488 + */
489 +
490 + struct B2_mutex {
491 +        int dummy;      //!!
492 + };
493 +
494 + B2_mutex *B2_create_mutex(void)
495 + {
496 +        return new B2_mutex;
497 + }
498 +
499 + void B2_lock_mutex(B2_mutex *mutex)
500 + {
501 + }
502 +
503 + void B2_unlock_mutex(B2_mutex *mutex)
504 + {
505 + }
506 +
507 + void B2_delete_mutex(B2_mutex *mutex)
508 + {
509 +        delete mutex;
510 + }
511 +
512 +
513 + /*
514   *  Interrupt flags (must be handled atomically!)
515   */
516  
# Line 453 | Line 531 | void TriggerInterrupt(void)
531          Signal(MainTask, IRQSigMask);
532   }
533  
534 + void TriggerNMI(void)
535 + {
536 +        AsmTriggerNMI();
537 + }
538 +
539  
540   /*
541 < *  60Hz thread
541 > *  60Hz thread (really 60.15Hz)
542   */
543  
544   static __saveds void tick_func(void)
# Line 470 | Line 553 | static __saveds void tick_func(void)
553          if (timer_port) {
554                  timer_io = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest));
555                  if (timer_io) {
556 <                        if (!OpenDevice((UBYTE *)TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) {
556 >                        if (!OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) {
557                                  timer_mask = 1 << timer_port->mp_SigBit;
558                                  timer_io->tr_node.io_Command = TR_ADDREQUEST;
559                                  timer_io->tr_time.tv_secs = 0;
# Line 495 | Line 578 | static __saveds void tick_func(void)
578                  if (++tick_counter > 60) {
579                          tick_counter = 0;
580                          WriteMacInt32(0x20c, TimerDateTime());
581 +                        SetInterruptFlag(INTFLAG_1HZ);
582 +                        TriggerInterrupt();
583                  }
584  
585                  // Trigger 60Hz interrupt
# Line 520 | Line 605 | static __saveds void tick_func(void)
605  
606  
607   /*
608 + *  XPRAM watchdog thread (saves XPRAM every minute)
609 + */
610 +
611 + static __saveds void xpram_func(void)
612 + {
613 +        uint8 last_xpram[XPRAM_SIZE];
614 +        memcpy(last_xpram, XPRAM, XPRAM_SIZE);
615 +
616 +        while (xpram_proc_active) {
617 +                for (int i=0; i<60 && xpram_proc_active; i++)
618 +                        Delay(50);              // Only wait 1 second so we quit promptly when xpram_proc_active becomes false
619 +                if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) {
620 +                        memcpy(last_xpram, XPRAM, XPRAM_SIZE);
621 +                        SaveXPRAM();
622 +                }
623 +        }
624 +
625 +        // Main task asked for termination, send signal
626 +        Forbid();
627 +        Signal(MainTask, SIGF_SINGLE);
628 + }
629 +
630 +
631 + /*
632   *  Display error alert
633   */
634  
# Line 590 | Line 699 | struct trap_regs {     // This must match th
699  
700   void __saveds IllInstrHandler(trap_regs *r)
701   {
702 + //      D(bug("IllInstrHandler/%ld\n", __LINE__));
703 +
704          uint16 opcode = *(uint16 *)(r->pc);
705          if ((opcode & 0xff00) != 0x7100) {
706                  printf("Illegal Instruction %04x at %08lx\n", *(uint16 *)(r->pc), r->pc);
# Line 608 | Line 719 | void __saveds IllInstrHandler(trap_regs
719                  EmulatedSR |= 0x0700;
720  
721                  // Call opcode routine
722 <                EmulOp(*(uint16 *)(r->pc), (M68kRegisters *)r);
722 >                EmulOp(opcode, (M68kRegisters *)r);
723                  r->pc += 2;
724  
725                  // Restore interrupts

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines