void fastPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; /* BatteryTimeRec batteryTimeInfo; */ SMStatus soundStatus; ThreadID threadID; ThreadState threadState; EventRecord eventRecord; Point point; WindowPtr windowPtr; PScrapStuff scrapInfo; UnsignedWide usSinceStartup; BYTE dataBuffer[ 2 + 8 ]; /* short driverRefNum; */ UInt32 dateTime; /* int count, dummy; */ NumVersion version; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get the status of the last alert, how much battery time is remaining and the voltage from all batteries, the internal battery status, the current date and time and time since system startup in ticks, the application heap limit and current and heap zone, free memory in the current and system heap, microseconds since system startup, whether QuickDraw has finished drawing, modem status, SCSI status information, maximum block allocatable without compacting, available stack space, the last QuickDraw error code */ /* addRandomValue( randomState, GetAlertStage() ); count = BatteryCount(); while( count-- > 0 ) { addRandomValue( randomState, GetBatteryVoltage( count ) ); GetBatteryTimes( count, &batteryTimeInfo ); addRandomData( randomState, &batteryTimeInfo, sizeof( BatteryTimeRec ) ); } if( !BatteryStatus( buffer, dataBuffer + 1 ) ) addRandomValue( randomState, dataBuffer ); */ GetDateTime( &dateTime ); addRandomValue( randomState, dateTime ); addRandomValue( randomState, TickCount() ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON addRandomValue( randomState, GetApplLimit() ); addRandomValue( randomState, GetZone() ); addRandomValue( randomState, SystemZone() ); addRandomValue( randomState, FreeMem() ); addRandomValue( randomState, FreeMemSys() ); #endif /* MicroSeconds( &usSinceStartup ); addRandomData( randomState, &usSinceStartup, sizeof( UnsignedWide ) ); */ addRandomValue( randomState, QDDone( NULL ) ); /* ModemStatus( dataBuffer ); addRandomValue( randomState, dataBuffer[ 0 ] ); */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON addRandomValue( randomState, SCSIStat() ); #endif addRandomValue( randomState, MaxBlock() ); addRandomValue( randomState, StackSpace() ); addRandomValue( randomState, QDError() ); /* Get the event code and message, time, and mouse location for the next event in the event queue and the OS event queue */ if( EventAvail( everyEvent, &eventRecord ) ) addRandomData( randomState, &eventRecord, sizeof( EventRecord ) ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( OSEventAvail( everyEvent, &eventRecord ) ) addRandomData( randomState, &eventRecord, sizeof( EventRecord ) ); #endif /* Get all sorts of information such as device-specific info, grafport information, visible and clipping region, pattern, pen, text, and colour information, and other details, on the topmost window. Also get the window variant. If there's a colour table record, add the colour table as well */ if( ( windowPtr = FrontWindow() ) != NULL ) { /* CTabHandle colourHandle; */ #if !defined OPAQUE_TOOLBOX_STRUCTS || !OPAQUE_TOOLBOX_STRUCTS addRandomData( randomState, windowPtr, sizeof( GrafPort ) ); #endif addRandomValue( randomState, GetWVariant( windowPtr ) ); /* if( GetAuxWin( windowPtr, colourHandle ) ) { CTabPtr colourPtr; HLock( colourHandle ); colourPtr = *colourHandle; addRandomData( randomState, colourPtr, sizeof( ColorTable ) ); HUnlock( colourHandle ); } */ } /* Get mouse-related such as the mouse button status and mouse position, information on the window underneath the mouse */ addRandomValue( randomState, Button() ); GetMouse( &point ); addRandomData( randomState, &point, sizeof( Point ) ); FindWindow( point, &windowPtr ); #if !defined OPAQUE_TOOLBOX_STRUCTS || !OPAQUE_TOOLBOX_STRUCTS if( windowPtr != NULL ) addRandomData( randomState, windowPtr, sizeof( GrafPort ) ); #endif /* Get the size, handle, and location of the desk scrap/clipboard */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON scrapInfo = InfoScrap(); addRandomData( randomState, scrapInfo, sizeof( ScrapStuff ) ); #endif /* Get information on the current thread */ threadID = kCurrentThreadID; /*GetThreadID( &threadID ); */ GetThreadState( threadID, &threadState ); addRandomData( randomState, &threadState, sizeof( ThreadState ) ); /* Get the sound mananger status. This gets the number of allocated sound channels and the current CPU load from these channels */ SndManagerStatus( sizeof( SMStatus ), &soundStatus ); addRandomData( randomState, &soundStatus, sizeof( SMStatus ) ); /* Get the speech manager version and status */ /* version = SpeechManagerVersion(); addRandomData( randomState, &version, sizeof( NumVersion ) ); addRandomValue( randomState, SpeechBusy() ); */ /* Get the status of the serial port. This gets information on recent errors, read and write pending status, and flow control values */ /* if( !OpenDriver( "\p.AIn", &driverRefNum ) ) { SerStaRec serialStatus; SetStatus( driverRefNum, &serialStatus ); addRandomData( randomState, &serialStatus, sizeof( SerStaRec ) ); } if( !OpenDriver( "\p.AOut", &driverRefNum ) ) { SerStaRec serialStatus; SetStatus( driverRefNum, &serialStatus ); addRandomData( randomState, &serialStatus, sizeof( SerStaRec ) ); } */ /* Flush any remaining data through */ endRandomData( randomState, 10 ); }
void EmulOp(M68kRegisters *r, uint32 pc, int selector) { D(bug("EmulOp %04x at %08x\n", selector, pc)); switch (selector) { case OP_BREAK: // Breakpoint printf("*** Breakpoint\n"); Dump68kRegs(r); break; case OP_XPRAM1: { // Read/write from/to XPRam uint32 len = r->d[3]; uint8 *adr = Mac2HostAddr(r->a[3]); D(bug("XPRAMReadWrite d3: %08lx, a3: %p\n", len, adr)); int ofs = len & 0xffff; len >>= 16; if (len & 0x8000) { len &= 0x7fff; for (uint32 i=0; i<len; i++) XPRAM[((ofs + i) & 0xff) + 0x1300] = *adr++; } else { for (uint32 i=0; i<len; i++) *adr++ = XPRAM[((ofs + i) & 0xff) + 0x1300]; } break; } case OP_XPRAM2: // Read from XPRam r->d[1] = XPRAM[(r->d[1] & 0xff) + 0x1300]; break; case OP_XPRAM3: // Write to XPRam XPRAM[(r->d[1] & 0xff) + 0x1300] = r->d[2]; break; case OP_NVRAM1: { // Read from NVRAM int ofs = r->d[0]; r->d[0] = XPRAM[ofs & 0x1fff]; bool localtalk = !(XPRAM[0x13e0] || XPRAM[0x13e1]); // LocalTalk enabled? switch (ofs) { case 0x13e0: // Disable LocalTalk (use EtherTalk instead) if (localtalk) r->d[0] = 0x00; break; case 0x13e1: if (localtalk) r->d[0] = 0x01; break; case 0x13e2: if (localtalk) r->d[0] = 0x00; break; case 0x13e3: if (localtalk) r->d[0] = 0x0a; break; } break; } case OP_NVRAM2: // Write to NVRAM XPRAM[r->d[0] & 0x1fff] = r->d[1]; break; case OP_NVRAM3: // Read/write from/to NVRAM if (r->d[3]) { r->d[0] = XPRAM[(r->d[4] + 0x1300) & 0x1fff]; } else { XPRAM[(r->d[4] + 0x1300) & 0x1fff] = r->d[5]; r->d[0] = 0; } break; case OP_FIX_MEMTOP: // Fixes MemTop in BootGlobs during startup D(bug("Fix MemTop\n")); WriteMacInt32(BootGlobsAddr - 20, RAMBase + RAMSize); // MemTop r->a[6] = RAMBase + RAMSize; break; case OP_FIX_MEMSIZE: { // Fixes physical/logical RAM size during startup D(bug("Fix MemSize\n")); uint32 diff = ReadMacInt32(0x1ef8) - ReadMacInt32(0x1ef4); WriteMacInt32(0x1ef8, RAMSize); // Physical RAM size WriteMacInt32(0x1ef4, RAMSize - diff); // Logical RAM size break; } case OP_FIX_BOOTSTACK: // Fixes boot stack pointer in boot 3 resource D(bug("Fix BootStack\n")); r->a[1] = r->a[7] = RAMBase + RAMSize * 3 / 4; break; case OP_SONY_OPEN: // Floppy driver functions r->d[0] = SonyOpen(r->a[0], r->a[1]); break; case OP_SONY_PRIME: r->d[0] = SonyPrime(r->a[0], r->a[1]); break; case OP_SONY_CONTROL: r->d[0] = SonyControl(r->a[0], r->a[1]); break; case OP_SONY_STATUS: r->d[0] = SonyStatus(r->a[0], r->a[1]); break; case OP_DISK_OPEN: // Disk driver functions r->d[0] = DiskOpen(r->a[0], r->a[1]); break; case OP_DISK_PRIME: r->d[0] = DiskPrime(r->a[0], r->a[1]); break; case OP_DISK_CONTROL: r->d[0] = DiskControl(r->a[0], r->a[1]); break; case OP_DISK_STATUS: r->d[0] = DiskStatus(r->a[0], r->a[1]); break; case OP_CDROM_OPEN: // CD-ROM driver functions r->d[0] = CDROMOpen(r->a[0], r->a[1]); break; case OP_CDROM_PRIME: r->d[0] = CDROMPrime(r->a[0], r->a[1]); break; case OP_CDROM_CONTROL: r->d[0] = CDROMControl(r->a[0], r->a[1]); break; case OP_CDROM_STATUS: r->d[0] = CDROMStatus(r->a[0], r->a[1]); break; case OP_AUDIO_DISPATCH: // Audio component functions r->d[0] = gMacAudio->Dispatch(r->a[3], r->a[4]); break; case OP_SOUNDIN_OPEN: // Sound input driver functions r->d[0] = gMacAudio->InOpen(r->a[0], r->a[1]); break; case OP_SOUNDIN_PRIME: r->d[0] = gMacAudio->InPrime(r->a[0], r->a[1]); break; case OP_SOUNDIN_CONTROL: r->d[0] = gMacAudio->InControl(r->a[0], r->a[1]); break; case OP_SOUNDIN_STATUS: r->d[0] = gMacAudio->InStatus(r->a[0], r->a[1]); break; case OP_SOUNDIN_CLOSE: r->d[0] = gMacAudio->InClose(r->a[0], r->a[1]); break; case OP_ADBOP: // ADBOp() replacement gADBInput->Op(r->d[0], Mac2HostAddr(ReadMacInt32(r->a[0]))); break; case OP_INSTIME: // InsTime() replacement r->d[0] = InsTime(r->a[0], r->d[1]); break; case OP_RMVTIME: // RmvTime() replacement r->d[0] = RmvTime(r->a[0]); break; case OP_PRIMETIME: // PrimeTime() replacement r->d[0] = PrimeTime(r->a[0], r->d[0]); break; case OP_MICROSECONDS: // Microseconds() replacement Microseconds(r->a[0], r->d[0]); break; case OP_PUT_SCRAP: // PutScrap() patch PutScrap(ReadMacInt32(r->a[7] + 8), Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 12)); break; case OP_GET_SCRAP: // GetScrap() patch GetScrap((void **)Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 8), ReadMacInt32(r->a[7] + 12)); break; case OP_DEBUG_STR: // DebugStr() shows warning message if (PrefsFindBool("nogui")) { uint8 *pstr = Mac2HostAddr(ReadMacInt32(r->a[7] + 4)); char str[256]; int i; for (i=0; i<pstr[0]; i++) str[i] = pstr[i+1]; str[i] = 0; WarningAlert(str); } break; case OP_INSTALL_DRIVERS: { // Patch to install our own drivers during startup // Install drivers InstallDrivers(); // Patch MakeExecutable() MakeExecutableTvec = FindLibSymbol("\023PrivateInterfaceLib", "\016MakeExecutable"); D(bug("MakeExecutable TVECT at %08x\n", MakeExecutableTvec)); WriteMacInt32(MakeExecutableTvec, NativeFunction(NATIVE_MAKE_EXECUTABLE)); #if defined(__powerpc__) /* Native PowerPC */ WriteMacInt32(MakeExecutableTvec + 4, (uint32)TOC); #endif // Patch DebugStr() static const uint8 proc_template[] = { M68K_EMUL_OP_DEBUG_STR >> 8, M68K_EMUL_OP_DEBUG_STR & 0xFF, 0x4e, 0x74, // rtd #4 0x00, 0x04 }; BUILD_SHEEPSHAVER_PROCEDURE(proc); WriteMacInt32(0x1dfc, proc); break; } case OP_NAME_REGISTRY: // Patch Name Registry and initialize CallUniversalProc r->d[0] = (uint32)-1; PatchNameRegistry(); InitCallUniversalProc(); break; case OP_RESET: // Early in MacOS reset D(bug("*** RESET ***\n")); TimerReset(); MacOSUtilReset(); gMacAudio->Reset(); // Enable DR emulator (disabled for now) if (PrefsFindBool("jit68k") && 0) { D(bug("DR activated\n")); WriteMacInt32(KernelDataAddr + 0x17a0, 3); // Prepare for DR emulator activation WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE); WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE); WriteMacInt32(KernelDataAddr + 0x1b04, DR_CACHE_BASE); WriteMacInt32(KernelDataAddr + 0x1b00, DR_EMULATOR_BASE); memcpy((void *)DR_EMULATOR_BASE, (void *)(ROMBase + 0x370000), DR_EMULATOR_SIZE); MakeExecutable(0, DR_EMULATOR_BASE, DR_EMULATOR_SIZE); } break; case OP_IRQ: // Level 1 interrupt WriteMacInt16(ReadMacInt32(KernelDataAddr + 0x67c), 0); // Clear interrupt r->d[0] = 0; if (HasMacStarted()) { if (InterruptFlags & INTFLAG_VIA) { ClearInterruptFlag(INTFLAG_VIA); #if !PRECISE_TIMING TimerInterrupt(); #endif ExecuteNative(NATIVE_VIDEO_VBL); static int tick_counter = 0; if (++tick_counter >= 60) { tick_counter = 0; SonyInterrupt(); DiskInterrupt(); CDROMInterrupt(); } r->d[0] = 1; // Flag: 68k interrupt routine executes VBLTasks etc. } if (InterruptFlags & INTFLAG_SERIAL) { ClearInterruptFlag(INTFLAG_SERIAL); SerialInterrupt(); } if (InterruptFlags & INTFLAG_ETHER) { ClearInterruptFlag(INTFLAG_ETHER); ExecuteNative(NATIVE_ETHER_IRQ); } if (InterruptFlags & INTFLAG_TIMER) { ClearInterruptFlag(INTFLAG_TIMER); TimerInterrupt(); } if (InterruptFlags & INTFLAG_AUDIO) { ClearInterruptFlag(INTFLAG_AUDIO); gMacAudio->Interrupt(); } if (InterruptFlags & INTFLAG_ADB) { ClearInterruptFlag(INTFLAG_ADB); gADBInput->Interrupt(); } } else r->d[0] = 1; break; case OP_SCSI_DISPATCH: { // SCSIDispatch() replacement uint32 ret = ReadMacInt32(r->a[7]); uint16 sel = ReadMacInt16(r->a[7] + 4); r->a[7] += 6; // D(bug("SCSIDispatch(%d)\n", sel)); int stack; switch (sel) { case 0: // SCSIReset WriteMacInt16(r->a[7], SCSIReset()); stack = 0; break; case 1: // SCSIGet WriteMacInt16(r->a[7], SCSIGet()); stack = 0; break; case 2: // SCSISelect case 11: // SCSISelAtn WriteMacInt16(r->a[7] + 2, SCSISelect(ReadMacInt8(r->a[7] + 1))); stack = 2; break; case 3: // SCSICmd WriteMacInt16(r->a[7] + 6, SCSICmd(ReadMacInt16(r->a[7]), Mac2HostAddr(ReadMacInt32(r->a[7] + 2)))); stack = 6; break; case 4: // SCSIComplete WriteMacInt16(r->a[7] + 12, SCSIComplete(ReadMacInt32(r->a[7]), ReadMacInt32(r->a[7] + 4), ReadMacInt32(r->a[7] + 8))); stack = 12; break; case 5: // SCSIRead case 8: // SCSIRBlind WriteMacInt16(r->a[7] + 4, SCSIRead(ReadMacInt32(r->a[7]))); stack = 4; break; case 6: // SCSIWrite case 9: // SCSIWBlind WriteMacInt16(r->a[7] + 4, SCSIWrite(ReadMacInt32(r->a[7]))); stack = 4; break; case 10: // SCSIStat WriteMacInt16(r->a[7], SCSIStat()); stack = 0; break; case 12: // SCSIMsgIn WriteMacInt16(r->a[7] + 4, 0); stack = 4; break; case 13: // SCSIMsgOut WriteMacInt16(r->a[7] + 2, 0); stack = 2; break; case 14: // SCSIMgrBusy WriteMacInt16(r->a[7], SCSIMgrBusy()); stack = 0; break; default: printf("FATAL: SCSIDispatch: illegal selector\n"); stack = 0; //!! SysError(12) } r->a[0] = ret; r->a[7] += stack; break; } case OP_SCSI_ATOMIC: // SCSIAtomic() replacement D(bug("SCSIAtomic\n")); r->d[0] = (uint32)-7887; break; case OP_CHECK_SYSV: { // Check we are not using MacOS < 8.1 with a NewWorld ROM r->a[1] = r->d[1]; r->a[0] = ReadMacInt32(r->d[1]); uint32 sysv = ReadMacInt16(r->a[0]); D(bug("Detected MacOS version %d.%d.%d\n", (sysv >> 8) & 0xf, (sysv >> 4) & 0xf, sysv & 0xf)); if (ROMType == ROMTYPE_NEWWORLD && sysv < 0x0801) r->d[1] = 0; break; } case OP_NTRB_17_PATCH: r->a[2] = ReadMacInt32(r->a[7]); r->a[7] += 4; if (ReadMacInt16(r->a[2] + 6) == 17) PatchNativeResourceManager(); break; case OP_NTRB_17_PATCH2: r->a[7] += 8; PatchNativeResourceManager(); break; case OP_NTRB_17_PATCH3: r->a[2] = ReadMacInt32(r->a[7]); r->a[7] += 4; D(bug("%d %d\n", ReadMacInt16(r->a[2]), ReadMacInt16(r->a[2] + 6))); if (ReadMacInt16(r->a[2]) == 11 && ReadMacInt16(r->a[2] + 6) == 17) PatchNativeResourceManager(); break; case OP_NTRB_17_PATCH4: r->d[0] = ReadMacInt16(r->a[7]); r->a[7] += 2; D(bug("%d %d\n", ReadMacInt16(r->a[2]), ReadMacInt16(r->a[2] + 6))); if (ReadMacInt16(r->a[2]) == 11 && ReadMacInt16(r->a[2] + 6) == 17) PatchNativeResourceManager(); break; case OP_CHECKLOAD: { // vCheckLoad() patch uint32 type = ReadMacInt32(r->a[7]); r->a[7] += 4; int16 id = ReadMacInt16(r->a[2]); if (r->a[0] == 0) break; uint32 adr = ReadMacInt32(r->a[0]); if (adr == 0) break; uint16 *p = (uint16 *)Mac2HostAddr(adr); uint32 size = ReadMacInt32(adr - 8) & 0xffffff; CheckLoad(type, id, p, size); break; } case OP_EXTFS_COMM: // External file system routines WriteMacInt16(r->a[7] + 14, ExtFSComm(ReadMacInt16(r->a[7] + 12), ReadMacInt32(r->a[7] + 8), ReadMacInt32(r->a[7] + 4))); break; case OP_EXTFS_HFS: WriteMacInt16(r->a[7] + 20, ExtFSHFS(ReadMacInt32(r->a[7] + 16), ReadMacInt16(r->a[7] + 14), ReadMacInt32(r->a[7] + 10), ReadMacInt32(r->a[7] + 6), ReadMacInt16(r->a[7] + 4))); break; case OP_IDLE_TIME: // Sleep if no events pending if (ReadMacInt32(0x14c) == 0) idle_wait(); r->a[0] = ReadMacInt32(0x2b6); break; case OP_IDLE_TIME_2: // Sleep if no events pending if (ReadMacInt32(0x14c) == 0) idle_wait(); r->d[0] = (uint32)-2; break; default: printf("FATAL: EMUL_OP called with bogus selector %08x\n", selector); QuitEmulator(); break; } }