unsigned long processInterrupt(unsigned long intMask, unsigned short npc, unsigned long startTime, signed long cycleLimit) { // known limitation: if the code uses ROM routines (e.g. register restore/return sequence) then we will // be missing those cpu cycles in our calculation.. unsigned long originalDigiCount= sDigiCount; if (isPsidDummyIrqVector()) { // no point in trying to keep the stack consistent for a PSID cpuReset(); } // provide dummy return address - which we use to return from the emulation: // in case of RTI (e.g. progs implementing $fffe/f vector directly) this will be used "as is". // if some program was to return with "RTS" (e.g. legacy PSID) the address would be returned as $0001. push(0); // addr high push(0); // addr low push(p); // processor status (processor would do this in case of interrupt...) // only set pc and keep current stackpointer and registers in case player directly passes // them between calls (see Look_sharp.sid) pc= npc; sProgramMode= intMask; initCycleCount( (intMask == NMI_OFFSET_MASK) ? 7 : 0, startTime); while (pc > 1 && ((cycleLimit <0) || (sCycles <cycleLimit))) cpuParse(); sProgramMode= MAIN_OFFSET_MASK; if (intMask == IRQ_OFFSET_MASK) { sCurrentVolume= getmem(0xd418); } markSampleOrigin(intMask, startTime, originalDigiCount); return sCycles; }
static uint32_t processInterrupt(uint32_t intMask, uint16_t npc, uint32_t startTime, int32_t cycleLimit) { // known limitation: if the code uses ROM routines calculation is flawed (see mock-up ROM routines). uint16_t originalDigiCount= digiGetCount(); uint16_t originalDigiOverflowCount= digiGetOverflowCount(); sidResetVolumeChangeCount(); if (isPsidDummyIrqVector()) { // no point in trying to keep the stack consistent for a PSID cpuRegReset(); } cpuResetToIrq(npc); cpuSetProgramMode(intMask); initCycleCount(intMask, startTime); if (intMask == IRQ_OFFSET_MASK) { vicSyncRasterIRQ(); // FIXME the cpu interrupt flag should also be set before starting the interrupt handler! // but since no one seems to have missed it yet.. } while (cpuPcIsValid() && ((cycleLimit <0) || (cpuCycles() <cycleLimit))) { vicSimRasterline(); cpuParse(); } cpuSetProgramMode(MAIN_OFFSET_MASK); digiTagOrigin(intMask, startTime, originalDigiCount, originalDigiOverflowCount); if (intMask == IRQ_OFFSET_MASK) _volUpdates+= sidGetNumberOfVolumeChanges(); // number of updates to the volume return cpuCycles(); }