Ejemplo n.º 1
0
void S9xDoDMA (uint8 Channel)
{
    uint8 Work;

    if (Channel > 7 || CPU.InDMA)
	return;

    CPU.InDMA = TRUE;
    bool8 in_sa1_dma = FALSE;
    uint8 *in_sdd1_dma = NULL;
    SDMA *d = &DMA[Channel];

    int count = d->TransferBytes;

    if (count == 0)
	count = 0x10000;

    int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1);

    switch (d->BAddress)
    {
    case 0x18:
    case 0x19:
	if (IPPU.RenderThisFrame)
	    FLUSH_REDRAW ();
	break;
    }

    if (Settings.SDD1)
    {
	if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0)
	{
	    // Hacky support for pre-decompressed S-DD1 data
	    inc = !d->AAddressDecrement ? 1 : -1;
	    uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4;

	    address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)];
		if(Settings.SDD1Pack)
		{
			uint8* in_ptr=GetBasePointer(((d->ABank << 16) | d->AAddress));
			in_ptr+=d->AAddress;

			SDD1_decompress(buffer,in_ptr,d->TransferBytes);
			in_sdd1_dma=buffer;
		}
		else
		{

			void *ptr = bsearch (&address, Memory.SDD1Index, 
					 Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries);
			if (ptr)
			in_sdd1_dma = *(uint32 *) ((uint8 *) ptr + 4) + Memory.SDD1Data;

/*
	    if (!in_sdd1_dma)
	    {
		// No matching decompressed data found. Must be some new 
		// graphics not encountered before. Log it if it hasn't been
		// already.
		uint8 *p = Memory.SDD1LoggedData;
		bool8 found = FALSE;
		uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0;

		for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8)
		{
		    if (*p == d->ABank ||
			*(p + 1) == (d->AAddress >> 8) &&
			*(p + 2) == (d->AAddress & 0xff) &&
			*(p + 3) == (count >> 8) &&
			*(p + 4) == (count & 0xff) &&
			*(p + 7) == SDD1Bank)
		    {
			found = TRUE;
			break;
		    }
		}
		if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES)
		{
		    *p = d->ABank;
		    *(p + 1) = d->AAddress >> 8;
		    *(p + 2) = d->AAddress & 0xff;
		    *(p + 3) = count >> 8;
		    *(p + 4) = count & 0xff;
		    *(p + 7) = SDD1Bank;
		    Memory.SDD1LoggedDataCount += 1;
		}
*/	    }
	}
	Memory.FillRAM [0x4801] = 0;
    }
Ejemplo n.º 2
0
void S9xMainLoop (void)
{
	for (;;)
	{
		APU_EXECUTE();
		
		if (CPU.Flags)
		{
			if (CPU.Flags & NMI_FLAG)
			{
				if (Timings.NMITriggerPos <= CPU.Cycles)
				{
					CPU.Flags &= ~NMI_FLAG;
					Timings.NMITriggerPos = 0xffff;
					if (CPU.WaitingForInterrupt)
					{
						CPU.WaitingForInterrupt = FALSE;
						Registers.PCw++;
					}
				
					S9xOpcode_NMI();
				}
			}
		
#ifdef DEBUGGER
			if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
			{
				for (int Break = 0; Break != 6; Break++)
				{
					if (S9xBreakpoint[Break].Enabled &&
						S9xBreakpoint[Break].Bank == Registers.PB &&
						S9xBreakpoint[Break].Address == Registers.PCw)
					{
						if (S9xBreakpoint[Break].Enabled == 2)
							S9xBreakpoint[Break].Enabled = TRUE;
						else
							CPU.Flags |= DEBUG_MODE_FLAG;
					}
				}
			}
#endif
			
			CHECK_SOUND();

			if (CPU.Flags & IRQ_PENDING_FLAG)
			{
				if (CPU.WaitingForInterrupt)
				{
					CPU.WaitingForInterrupt = FALSE;
					Registers.PCw++;
				}

				if (CPU.IRQActive && !Settings.DisableIRQ)
				{
					if (!CheckFlag(IRQ))
						S9xOpcode_IRQ();
				}
				else
					CPU.Flags &= ~IRQ_PENDING_FLAG;
			}
			
			if (CPU.Flags & SCAN_KEYS_FLAG)
				break;

#ifdef DEBUGGER
			if (CPU.Flags & DEBUG_MODE_FLAG)
				break;

			if (CPU.Flags & TRACE_FLAG)
				S9xTrace();

			if (CPU.Flags & SINGLE_STEP_FLAG)
			{
				CPU.Flags &= ~SINGLE_STEP_FLAG;
				CPU.Flags |= DEBUG_MODE_FLAG;
			}
#endif
		}
		
#ifdef CPU_SHUTDOWN
		CPU.PBPCAtOpcodeStart = Registers.PBPC;
#endif

		register uint8				Op;
		register struct	SOpcodes	*Opcodes;
		
		if (CPU.PCBase)
		{
			Op = CPU.PCBase[Registers.PCw];
			CPU.Cycles += CPU.MemSpeed;
			Opcodes = ICPU.S9xOpcodes;
		}
		else
		{
			Op = S9xGetByte(Registers.PBPC);
			OpenBus = Op;
			Opcodes = S9xOpcodesSlow;
		}
		
		if ((Registers.PCw&MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
		{
			uint8	*oldPCBase = CPU.PCBase;

			CPU.PCBase = GetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4)));
			if (oldPCBase!=CPU.PCBase || (Registers.PCw&~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
				Opcodes = S9xOpcodesSlow;
		}
		
		Registers.PCw++;
		(*Opcodes[Op].S9xOpcode)();
				
		S9xUpdateAPUTimer();
		
		if (SA1.Executing)
			S9xSA1MainLoop();
		
		if (CPU.Cycles >= CPU.NextEvent)
			S9xDoHEventProcessing();
    }
	
    S9xPackStatus();
    APURegisters.PC = IAPU.PC - IAPU.RAM;
    S9xAPUPackStatus();
	
    if (CPU.Flags & SCAN_KEYS_FLAG)
    {
#ifdef DEBUGGER
		if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
#endif
		S9xSyncSpeed();
		CPU.Flags &= ~SCAN_KEYS_FLAG;
    }
}
Ejemplo n.º 3
0
void S9xMainLoop (void)
{
	if(ICPU.SavedAtOp)
	{
		ICPU.SavedAtOp = FALSE;
		Registers.PCw = CPU.PBPCAtOpcodeStart;
		if(CPU.PCBase)
			CPU.Cycles -= CPU.MemSpeed;
		goto doOp;
	}

	for (;;)
	{
		if (CPU.Flags)
		{
			if (CPU.Flags & NMI_FLAG)
			{
				if (Timings.NMITriggerPos <= CPU.Cycles)
				{
					CPU.Flags &= ~NMI_FLAG;
					Timings.NMITriggerPos = 0xffff;
					if (CPU.WaitingForInterrupt)
					{
						CPU.WaitingForInterrupt = FALSE;
						Registers.PCw++;
					}

					S9xOpcode_NMI();
				}
			}

#ifdef DEBUGGER
			if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
			{
				for (int Break = 0; Break != 6; Break++)
				{
					if (S9xBreakpoint[Break].Enabled &&
						S9xBreakpoint[Break].Bank == Registers.PB &&
						S9xBreakpoint[Break].Address == Registers.PCw)
					{
						if (S9xBreakpoint[Break].Enabled == 2)
							S9xBreakpoint[Break].Enabled = TRUE;
						else
							CPU.Flags |= DEBUG_MODE_FLAG;
					}
				}
			}
#endif

			CHECK_SOUND();

			if (CPU.Flags & IRQ_FLAG)
			{
				if (CPU.IRQPending)
					// FIXME: In case of IRQ during WRAM refresh
					CPU.IRQPending = 0;
				else
				{
					if (CPU.WaitingForInterrupt)
					{
						CPU.WaitingForInterrupt = FALSE;
						Registers.PCw++;
					}

					if (CPU.IRQActive && !Settings.DisableIRQ)
					{
						if (!CheckFlag(IRQ))
						// in IRQ handler $4211 is supposed to be read, so IRQ_FLAG should be cleared.
							S9xOpcode_IRQ();
					}
					else
						CPU.Flags &= ~IRQ_FLAG;
				}
			}

			if (CPU.Flags & SCAN_KEYS_FLAG)
				break;

#ifdef DEBUGGER
			if (CPU.Flags & DEBUG_MODE_FLAG)
				break;

			if (CPU.Flags & TRACE_FLAG)
				S9xTrace();

			if (CPU.Flags & SINGLE_STEP_FLAG)
			{
				CPU.Flags &= ~SINGLE_STEP_FLAG;
				CPU.Flags |= DEBUG_MODE_FLAG;
			}
#endif
		}

#ifdef CPU_SHUTDOWN
		CPU.PBPCAtOpcodeStart = Registers.PBPC;
#endif
	doOp:
		register uint8				Op;
		register struct	SOpcodes	*Opcodes;

		CPU.PrevCycles = CPU.Cycles;

		if (CPU.PCBase)
		{
			Op = CPU.PCBase[Registers.PCw];
			CPU.Cycles += CPU.MemSpeed;
			Opcodes = ICPU.S9xOpcodes;
		}
		else
		{
			Op = S9xGetByte(Registers.PBPC);
			OpenBus = Op;
			Opcodes = S9xOpcodesSlow;
		}

		if ((Registers.PCw&MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
		{
			uint8	*oldPCBase = CPU.PCBase;

			CPU.PCBase = GetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4)));
			if (oldPCBase!=CPU.PCBase || (Registers.PCw&~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
				Opcodes = S9xOpcodesSlow;
		}

		Registers.PCw++;
		(*Opcodes[Op].S9xOpcode)();

		if(ICPU.SavedAtOp)
		{
			ICPU.SavedAtOp = false;
			continue;
		}

		S9xAPUExecute();

		if (SA1.Executing)
			S9xSA1MainLoop();

		while (CPU.Cycles >= CPU.NextEvent)
			S9xDoHEventProcessing();
    }

    S9xPackStatus();
    APURegisters.PC = IAPU.PC - IAPU.RAM;
    S9xAPUPackStatus();

    if (CPU.Flags & SCAN_KEYS_FLAG)
    {
#ifdef DEBUGGER
		if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
#endif
		S9xSyncSpeed();
		CPU.Flags &= ~SCAN_KEYS_FLAG;
    }
}