📄 sa1.cpp
字号:
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 + -