Example #1
0
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;
}
Example #2
0
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();
}