⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sa1.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	break;    case 0x2203://	printf ("SA1 reset vector: %04x\n", byte | (Memory.FillRAM [0x2204] << 8));	break;    case 0x2204://	printf ("SA1 reset vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2203]);	break;    case 0x2205://	printf ("SA1 NMI vector: %04x\n", byte | (Memory.FillRAM [0x2206] << 8));	break;    case 0x2206://	printf ("SA1 NMI vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2205]);	break;    case 0x2207://	printf ("SA1 IRQ vector: %04x\n", byte | (Memory.FillRAM [0x2208] << 8));	break;    case 0x2208://	printf ("SA1 IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2207]);	break;    case 0x2209:	Memory.FillRAM [0x2209] = byte;	if (byte & 0x80)	    Memory.FillRAM [0x2300] |= 0x80;	if (byte & Memory.FillRAM [0x2201] & 0x80)	{	    S9xSetIRQ (SA1_IRQ_SOURCE);	}	break;    case 0x220a:	if (((byte ^ Memory.FillRAM [0x220a]) & 0x80) &&	    (Memory.FillRAM [0x2301] & byte & 0x80))	{	    SA1.Flags |= IRQ_PENDING_FLAG;	    SA1.IRQActive |= SNES_IRQ_SOURCE;//	    SA1.Executing = !SA1.Waiting;	}	if (((byte ^ Memory.FillRAM [0x220a]) & 0x40) &&	    (Memory.FillRAM [0x2301] & byte & 0x40))	{	    SA1.Flags |= IRQ_PENDING_FLAG;	    SA1.IRQActive |= TIMER_IRQ_SOURCE;//	    SA1.Executing = !SA1.Waiting;	}	if (((byte ^ Memory.FillRAM [0x220a]) & 0x20) &&	    (Memory.FillRAM [0x2301] & byte & 0x20))	{	    SA1.Flags |= IRQ_PENDING_FLAG;	    SA1.IRQActive |= DMA_IRQ_SOURCE;//	    SA1.Executing = !SA1.Waiting;	}	if (((byte ^ Memory.FillRAM [0x220a]) & 0x10) &&	    (Memory.FillRAM [0x2301] & byte & 0x10))	{#ifdef DEBUGGER	    printf ("###SA1 NMI\n");#endif	}	break;    case 0x220b:	if (byte & 0x80)	{	    SA1.IRQActive &= ~SNES_IRQ_SOURCE;	    Memory.FillRAM [0x2301] &= ~0x80;	}	if (byte & 0x40)	{	    SA1.IRQActive &= ~TIMER_IRQ_SOURCE;	    Memory.FillRAM [0x2301] &= ~0x40;	}	if (byte & 0x20)	{	    SA1.IRQActive &= ~DMA_IRQ_SOURCE;	    Memory.FillRAM [0x2301] &= ~0x20;	}	if (byte & 0x10)	{	    // Clear NMI	    Memory.FillRAM [0x2301] &= ~0x10;	}	if (!SA1.IRQActive)	    SA1.Flags &= ~IRQ_PENDING_FLAG;	break;    case 0x220c://	printf ("SNES NMI vector: %04x\n", byte | (Memory.FillRAM [0x220d] << 8));	break;    case 0x220d://	printf ("SNES NMI vector: %04x\n", (byte << 8) | Memory.FillRAM [0x220c]);	break;    case 0x220e://	printf ("SNES IRQ vector: %04x\n", byte | (Memory.FillRAM [0x220f] << 8));	break;    case 0x220f://	printf ("SNES IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM [0x220e]);	break;    case 0x2210:#if 0	printf ("Timer %s\n", (byte & 0x80) ? "linear" : "HV");	printf ("Timer H-IRQ %s\n", (byte & 1) ? "enabled" : "disabled");	printf ("Timer V-IRQ %s\n", (byte & 2) ? "enabled" : "disabled");#endif	break;    case 0x2211://	printf ("Timer reset\n");	break;    case 0x2212://	printf ("H-Timer %04x\n", byte | (Memory.FillRAM [0x2213] << 8));	break;    case 0x2213://	printf ("H-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2212]);	break;    case 0x2214://	printf ("V-Timer %04x\n", byte | (Memory.FillRAM [0x2215] << 8));	break;    case 0x2215://	printf ("V-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2214]);	break;    case 0x2220:    case 0x2221:    case 0x2222:    case 0x2223:	S9xSetSA1MemMap (address - 0x2220, byte);//	printf ("MMC: %02x\n", byte);	break;    case 0x2224://	printf ("BWRAM image SNES %02x -> 0x6000\n", byte);	Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000;	break;    case 0x2225://	printf ("BWRAM image SA1 %02x -> 0x6000 (%02x)\n", byte, Memory.FillRAM [address]);	if (byte != Memory.FillRAM [address])	    S9xSA1SetBWRAMMemMap (byte);	break;    case 0x2226://	printf ("BW-RAM SNES write %s\n", (byte & 0x80) ? "enabled" : "disabled");	break;    case 0x2227://	printf ("BW-RAM SA1 write %s\n", (byte & 0x80) ? "enabled" : "disabled");	break;    case 0x2228://	printf ("BW-RAM write protect area %02x\n", byte);	break;    case 0x2229://	printf ("I-RAM SNES write protect area %02x\n", byte);	break;    case 0x222a://	printf ("I-RAM SA1 write protect area %02x\n", byte);	break;    case 0x2230:#if 0	printf ("SA1 DMA %s\n", (byte & 0x80) ? "enabled" : "disabled");	printf ("DMA priority %s\n", (byte & 0x40) ? "DMA" : "SA1");	printf ("DMA %s\n", (byte & 0x20) ? "char conv" : "normal");	printf ("DMA type %s\n", (byte & 0x10) ? "BW-RAM -> I-RAM" : "SA1 -> I-RAM");	printf ("DMA distination %s\n", (byte & 4) ? "BW-RAM" : "I-RAM");	printf ("DMA source %s\n", DMAsource [byte & 3]);#endif	break;    case 0x2231:	if (byte & 0x80)	    SA1.in_char_dma = FALSE;#if 0	printf ("CHDEND %s\n", (byte & 0x80) ? "complete" : "incomplete");	printf ("DMA colour mode %d\n", byte & 3);	printf ("virtual VRAM width %d\n", (byte >> 2) & 7);#endif	break;    case 0x2232:    case 0x2233:    case 0x2234:	Memory.FillRAM [address] = byte;#if 0	printf ("DMA source start %06x\n", 		Memory.FillRAM [0x2232] | (Memory.FillRAM [0x2233] << 8) |		(Memory.FillRAM [0x2234] << 16));#endif	break;    case 0x2235:	Memory.FillRAM [address] = byte;	break;    case 0x2236:	Memory.FillRAM [address] = byte;	if ((Memory.FillRAM [0x2230] & 0xa4) == 0x80)	{	    // Normal DMA to I-RAM	    S9xSA1DMA ();	}	else	if ((Memory.FillRAM [0x2230] & 0xb0) == 0xb0)	{	    Memory.FillRAM [0x2300] |= 0x20;	    if (Memory.FillRAM [0x2201] & 0x20)		S9xSetIRQ (SA1_DMA_IRQ_SOURCE);	    SA1.in_char_dma = TRUE;	}	break;    case 0x2237:	Memory.FillRAM [address] = byte;	if ((Memory.FillRAM [0x2230] & 0xa4) == 0x84)	{	    // Normal DMA to BW-RAM	    S9xSA1DMA ();	}#if 0	printf ("DMA dest address %06x\n", 		Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8) |		(Memory.FillRAM [0x2237] << 16));#endif	break;    case 0x2238:    case 0x2239:	Memory.FillRAM [address] = byte;#if 0	printf ("DMA length %04x\n", 		Memory.FillRAM [0x2238] | (Memory.FillRAM [0x2239] << 8));#endif	break;    case 0x223f:	SA1.VirtualBitmapFormat = (byte & 0x80) ? 2 : 4;	//printf ("virtual VRAM depth %d\n", (byte & 0x80) ? 2 : 4);	break;    case 0x2240:    case 0x2241:    case 0x2242:    case 0x2243:    case 0x2244:    case 0x2245:    case 0x2246:    case 0x2247:    case 0x2248:    case 0x2249:    case 0x224a:    case 0x224b:    case 0x224c:    case 0x224d:    case 0x224e:#if 0	if (!(SA1.Flags & TRACE_FLAG))	{	    TraceSA1 ();	    Trace ();	}#endif	Memory.FillRAM [address] = byte;	break;    case 0x224f:	Memory.FillRAM [address] = byte;	if ((Memory.FillRAM [0x2230] & 0xb0) == 0xa0)	{	    // Char conversion 2 DMA enabled	    memmove (&Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000] + SA1.in_char_dma * 16,		     &Memory.FillRAM [0x2240], 16);	    SA1.in_char_dma = (SA1.in_char_dma + 1) & 7;	    if ((SA1.in_char_dma & 3) == 0)	    {		S9xSA1CharConv2 ();	    }	}	break;    case 0x2250:	if (byte & 2)	    SA1.sum = 0;	SA1.arithmetic_op = byte & 3;	break;        case 0x2251:	SA1.op1 = (SA1.op1 & 0xff00) | byte;	break;    case 0x2252:	SA1.op1 = (SA1.op1 & 0xff) | (byte << 8);	break;    case 0x2253:	SA1.op2 = (SA1.op2 & 0xff00) | byte;	break;    case 0x2254:	SA1.op2 = (SA1.op2 & 0xff) | (byte << 8);	switch (SA1.arithmetic_op)	{        case 0:	// multiply	    SA1.sum = SA1.op1 * SA1.op2;	    break;	case 1: // divide	    if (SA1.op2 == 0)		SA1.sum = SA1.op1 << 16;	    else	    {		SA1.sum = (SA1.op1 / (int) ((uint16) SA1.op2)) |			  ((SA1.op1 % (int) ((uint16) SA1.op2)) << 16);	    }	    break;	case 2:	default: // cumulative sum	    SA1.sum += SA1.op1 * SA1.op2;	    if (SA1.sum & ((int64) 0xffffff << 32))		SA1.overflow = TRUE;	    break;	}	break;    case 0x2258:    // Variable bit-field length/auto inc/start.	Memory.FillRAM [0x2258] = byte;	S9xSA1ReadVariableLengthData (TRUE, FALSE);	return;    case 0x2259:    case 0x225a:    case 0x225b:    // Variable bit-field start address	Memory.FillRAM [address] = byte;	// XXX: ???	SA1.variable_bit_pos = 0;	S9xSA1ReadVariableLengthData (FALSE, TRUE);	return;    default://	printf ("W: %02x->%04x\n", byte, address);	break;    }    if (address >= 0x2200 && address <= 0x22ff)	Memory.FillRAM [address] = byte;}static void S9xSA1CharConv2 (){    uint32 dest = Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8);    uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1;    int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 :		(Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2;    int bytes_per_char = 8 * depth;    uint8 *p = &Memory.FillRAM [0x3000] + dest + offset * bytes_per_char;    uint8 *q = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000] + offset * 64;    switch (depth)    {    case 2:	break;    case 4:	break;    case 8:	for (int l = 0; l < 8; l++, q += 8)	{	    for (int b = 0; b < 8; b++)	    {		uint8 r = *(q + b);		*(p +  0) = (*(p +  0) << 1) | ((r >> 0) & 1);		*(p +  1) = (*(p +  1) << 1) | ((r >> 1) & 1);		*(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1);		*(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1);		*(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1);		*(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1);		*(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1);		*(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1);	    }	    p += 2;	}	break;    }}static void S9xSA1DMA (){    uint32 src =  Memory.FillRAM [0x2232] |	         (Memory.FillRAM [0x2233] << 8) |		 (Memory.FillRAM [0x2234] << 16);    uint32 dst =  Memory.FillRAM [0x2235] |	         (Memory.FillRAM [0x2236] << 8) |		 (Memory.FillRAM [0x2237] << 16);    uint32 len =  Memory.FillRAM [0x2238] |		 (Memory.FillRAM [0x2239] << 8);    uint8 *s;    uint8 *d;    switch (Memory.FillRAM [0x2230] & 3)    {    case 0: // ROM	s = SA1.Map [(src >> MEMMAP_SHIFT) & MEMMAP_MASK];	if (s >= (uint8 *) CMemory::MAP_LAST)	    s += (src & 0xffff);	else	    s = Memory.ROM + (src & 0xffff);	break;    case 1: // BW-RAM	src &= Memory.SRAMMask;	len &= Memory.SRAMMask;	s = Memory.SRAM + src;	break;    default:    case 2:	src &= 0x3ff;	len &= 0x3ff;	s = &Memory.FillRAM [0x3000] + src;	break;    }    if (Memory.FillRAM [0x2230] & 4)    {	dst &= Memory.SRAMMask;	len &= Memory.SRAMMask;	d = Memory.SRAM + dst;    }    else    {	dst &= 0x3ff;	len &= 0x3ff;	d = &Memory.FillRAM [0x3000] + dst;    }    memmove (d, s, len);    Memory.FillRAM [0x2301] |= 0x20;        if (Memory.FillRAM [0x220a] & 0x20)    {	SA1.Flags |= IRQ_PENDING_FLAG;	SA1.IRQActive |= DMA_IRQ_SOURCE;//	SA1.Executing = !SA1.Waiting;    }}void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift){    uint32 addr =  Memory.FillRAM [0x2259] |		  (Memory.FillRAM [0x225a] << 8) |		  (Memory.FillRAM [0x225b] << 16);    uint8 shift = Memory.FillRAM [0x2258] & 15;    if (no_shift)	shift = 0;    else    if (shift == 0)	shift = 16;    uint8 s = shift + SA1.variable_bit_pos;    if (s >= 16)    {	addr += (s >> 4) << 1;	s &= 15;    }    uint32 data = S9xSA1GetWord (addr) |		  (S9xSA1GetWord (addr + 2) << 16);    data >>= s;    Memory.FillRAM [0x230c] = (uint8) data;    Memory.FillRAM [0x230d] = (uint8) (data >> 8);    if (inc)    {	SA1.variable_bit_pos = (SA1.variable_bit_pos + shift) & 15;	Memory.FillRAM [0x2259] = (uint8) addr;	Memory.FillRAM [0x225a] = (uint8) (addr >> 8);	Memory.FillRAM [0x225b] = (uint8) (addr >> 16);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -