📄 spc7110.cpp
字号:
return s7r.reg4800; //table register low case 0x4801: return s7r.reg4801; //table register middle case 0x4802: return s7r.reg4802; //table register high case 0x4803: return s7r.reg4803; //index of pointer in table (each entry is 4 bytes) case 0x4804: return s7r.reg4804; //offset register low case 0x4805: return s7r.reg4805; //offset register high case 0x4806: return s7r.reg4806; //DMA channel (not that I see this usually set, //regardless of what channel DMA is on) case 0x4807: return s7r.reg4807; //C r/w option, unknown, defval:00 is what Dark Force says //afaict, Snes9x doesn't use this at all. case 0x4808: return s7r.reg4808; //C-Length low //counts down the number of bytes left to read from the decompression buffer. //this is set by the ROM, and wraps on bounds. case 0x4809: return s7r.reg4809; //C Length high case 0x480A: return s7r.reg480A; //Offset enable. //if this is zero, 4805-6 are useless. Emulated by setting AlignBy to 0 case 0x480B: return s7r.reg480B; //decompression finished: just emulated by switching each read. case 0x480C: s7r.reg480C^=0x80; return s7r.reg480C^0x80; //Data access port //reads from the data ROM (anywhere over the first 8 mbits //behavior is complex, will document later, //possibly missing cases, because of the number of switches in play case 0x4810: if(s7r.written==0) return 0; if((s7r.written&0x07)==0x07) { uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; i%=s7r.DataRomSize; if(s7r.reg4818&0x02) { if(s7r.reg4818&0x08) { signed short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; i+=r4814; r4814++; s7r.reg4815=(uint8)(r4814>>8); s7r.reg4814=(uint8)(r4814&0x00FF); } else { unsigned short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; i+=r4814; if(r4814!=0xFFFF) r4814++; else r4814=0; s7r.reg4815=(uint8)(r4814>>8); s7r.reg4814=(uint8)(r4814&0x00FF); } } i+=s7r.DataRomOffset; uint8 tmp=ROM[i]; i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; if(s7r.reg4818&0x02) { } else if(s7r.reg4818&0x01) { if(s7r.reg4818&0x04) { signed short inc; inc=(s7r.reg4817<<8)|s7r.reg4816; if(!(s7r.reg4818&0x10)) i+=inc; else { if(s7r.reg4818&0x08) { signed short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; r4814+=inc; s7r.reg4815=(r4814&0xFF00)>>8; s7r.reg4814=r4814&0xFF; } else { unsigned short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; r4814+=inc; s7r.reg4815=(r4814&0xFF00)>>8; s7r.reg4814=r4814&0xFF; } } //is signed } else { uint16 inc; inc=(s7r.reg4817<<8)|s7r.reg4816; if(!(s7r.reg4818&0x10)) i+=inc; else { if(s7r.reg4818&0x08) { signed short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; r4814+=inc; s7r.reg4815=(r4814&0xFF00)>>8; s7r.reg4814=r4814&0xFF; } else { unsigned short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; r4814+=inc; s7r.reg4815=(r4814&0xFF00)>>8; s7r.reg4814=r4814&0xFF; } } } } else { if(!(s7r.reg4818&0x10)) i+=1; else { if(s7r.reg4818&0x08) { signed short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; r4814+=1; s7r.reg4815=(r4814&0xFF00)>>8; s7r.reg4814=r4814&0xFF; } else { unsigned short r4814; r4814=(s7r.reg4815<<8)|s7r.reg4814; r4814+=1; s7r.reg4815=(r4814&0xFF00)>>8; s7r.reg4814=r4814&0xFF; } } } #ifdef SPC7110_DEBUG printf("Returned %02X\n", tmp);#endif i%=s7r.DataRomSize; s7r.reg4811=i&0x00FF; s7r.reg4812=(i&0x00FF00)>>8; s7r.reg4813=((i&0xFF0000)>>16); return tmp; } else return 0; //direct read address low case 0x4811: return s7r.reg4811; //direct read address middle case 0x4812: return s7r.reg4812; //direct read access high case 0x4813: return s7r.reg4813; //read adjust low case 0x4814: return s7r.reg4814; //read adjust high case 0x4815: return s7r.reg4815; //read increment low case 0x4816: return s7r.reg4816; //read increment high case 0x4817: return s7r.reg4817; //Data ROM command mode //essentially, this controls the insane code of $4810 and $481A case 0x4818: return s7r.reg4818; //read after adjust port //what this does, besides more nasty stuff like 4810, //I don't know. Just assume it is a different implementation of $4810, //if it helps your sanity case 0x481A: if(s7r.written==0x1F) { uint32 i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); if(s7r.reg4818&0x08) { short adj; adj=((short)(s7r.reg4815<<8))|s7r.reg4814; i+=adj; } else { uint16 adj; adj=(s7r.reg4815<<8)|s7r.reg4814; i+=adj; } i%=s7r.DataRomSize; i+=s7r.DataRomOffset; uint8 tmp=ROM[i]; i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); if(0x60==(s7r.reg4818&0x60)) { i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); if(!(s7r.reg4818&0x10)) { if(s7r.reg4818&0x08) { short adj; adj=((short)(s7r.reg4815<<8))|s7r.reg4814; i+=adj; } else { uint16 adj; adj=(s7r.reg4815<<8)|s7r.reg4814; i+=adj; } i%=s7r.DataRomSize; s7r.reg4811=i&0x00FF; s7r.reg4812=(i&0x00FF00)>>8; s7r.reg4813=((i&0xFF0000)>>16); } else { if(s7r.reg4818&0x08) { short adj; adj=((short)(s7r.reg4815<<8))|s7r.reg4814; adj+=adj; s7r.reg4815=(adj&0xFF00)>>8; s7r.reg4814=adj&0xFF; } else { uint16 adj; adj=(s7r.reg4815<<8)|s7r.reg4814; adj+=adj; s7r.reg4815=(adj&0xFF00)>>8; s7r.reg4814=adj&0xFF; } } }#ifdef SPC7110_DEBUG printf("Returned %02X\n", tmp);#endif return tmp; } else return 0; //multiplicand low or dividend lowest case 0x4820: return s7r.reg4820; //multiplicand high or divdend lower case 0x4821: return s7r.reg4821; //dividend higher case 0x4822: return s7r.reg4822; //dividend highest case 0x4823: return s7r.reg4823; //multiplier low case 0x4824: return s7r.reg4824; //multiplier high case 0x4825: return s7r.reg4825; //divisor low case 0x4826: return s7r.reg4826; //divisor high case 0x4827: return s7r.reg4827; //result lowest case 0x4828: return s7r.reg4828; //result lower case 0x4829: return s7r.reg4829; //result higher case 0x482A: return s7r.reg482A; //result highest case 0x482B: return s7r.reg482B; //remainder (division) low case 0x482C: return s7r.reg482C; //remainder (division) high case 0x482D: return s7r.reg482D; //signed/unsigned case 0x482E: return s7r.reg482E; //finished flag, emulated as an on-read toggle. case 0x482F: if(s7r.reg482F) { s7r.reg482F=0; return 0x80; } return 0; break; //SRAM toggle case 0x4830: return s7r.reg4830; //DX bank mapping case 0x4831: return s7r.reg4831; //EX bank mapping case 0x4832: return s7r.reg4832; //FX bank mapping case 0x4833: return s7r.reg4833; //SRAM mapping? We have no clue! case 0x4834: return s7r.reg4834;//RTC enable case 0x4840: if(!Settings.SPC7110RTC) return Address>>8; return s7r.reg4840;//command/index/value of RTC (essentially, zero unless we're in read mode case 0x4841: if(!Settings.SPC7110RTC) return Address>>8; if(rtc_f9.init) { S9xUpdateRTC(); uint8 tmp=rtc_f9.reg[rtc_f9.index]; rtc_f9.index++; rtc_f9.index%=0x10;#ifdef SPC7110_DEBUG printf("$4841 returned %02X\n", tmp);#endif return tmp; } else return 0;//RTC done flag case 0x4842: if(!Settings.SPC7110RTC) return Address>>8; s7r.reg4842^=0x80; return s7r.reg4842^0x80; default:#ifdef SPC7110_DEBUG printf("Access to Reg %04X\n", Address);#endif return 0x00; }}}void S9xSetSPC7110 (uint8 data, uint16 Address){#ifdef SPC7110_DEBUG printf("%04X written to, value %02X\n", Address, data);#endif switch(Address) {//Writes to $4800 are undefined. //table low, middle, and high. case 0x4801: s7r.reg4801=data; break; case 0x4802: s7r.reg4802=data; break; case 0x4803: s7r.reg4803=data; break; //table index (4 byte entries, bigendian with a multiplier byte) case 0x4804: s7r.reg4804=data; break; //offset low case 0x4805: s7r.reg4805=data; break; //offset high, starts decompression case 0x4806: s7r.reg4806=data; (*Copy7110)(); s7r.bank50Internal=0; s7r.reg480C&=0x7F; break; //DMA channel register (Is it used??) case 0x4807: s7r.reg4807=data; break; //C r/w? I have no idea. If you get weird values written here before a bug, //The Dumper should probably be contacted about running a test. case 0x4808: s7r.reg4808=data; break; //C-Length low case 0x4809: s7r.reg4809=data; break; //C-Length high case 0x480A: s7r.reg480A=data; break; //Offset enable case 0x480B: { s7r.reg480B=data; int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; int j= 4*s7r.reg4804; j+=s7r.DataRomOffset; j+=table; if(s7r.reg480B==0) s7r.AlignBy=0; else { switch(ROM[j]) { case 0x03: s7r.AlignBy=8; break; case 0x01: s7r.AlignBy=2; break; case 0x02: s7r.AlignBy=4; break; case 0x00: default: s7r.AlignBy=1; break; } }// s7r.decomp_set=true; } break;//$4810 is probably read only. //Data port address low case 0x4811: s7r.reg4811=data; s7r.written|=0x01; break; //data port address middle case 0x4812: s7r.reg4812=data; s7r.written|=0x02; break; //data port address high case 0x4813: s7r.reg4813=data; s7r.written|=0x04; break; //data port adjust low (has a funky immediate increment mode) case 0x4814: s7r.reg4814=data; if(s7r.reg4818&0x02) { if((s7r.reg4818&0x20)&&!(s7r.reg4818&0x40)) { s7r.offset_add|=0x01; if(s7r.offset_add==3) { if(s7r.reg4818&0x10) { } else { uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; if(s7r.reg4818&0x08) { i+=(signed char)s7r.reg4814; } else { i+=s7r.reg4814; } i%=s7r.DataRomSize; s7r.reg4811=i&0x00FF; s7r.reg4812=(i&0x00FF00)>>8; s7r.reg4813=((i&0xFF0000)>>16); } } } else if((s7r.reg4818&0x40)&&!(s7r.reg4818&0x20)) { s7r.offset_add|=0x01; if(s7r.offset_add==3) { if(s7r.reg4818&0x10) { } else { uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; if(s7r.reg4818&0x08) { short adj; adj=((short)(s7r.reg4815<<8))|s7r.reg4814; i+=adj; } else { uint16 adj; adj=(s7r.reg4815<<8)|s7r.reg4814; i+=adj; } i%=s7r.DataRomSize; s7r.reg4811=i&0x00FF; s7r.reg4812=(i&0x00FF00)>>8; s7r.reg4813=((i&0xFF0000)>>16); } } } } s7r.written|=0x08; break; //data port adjust high (has a funky immediate increment mode) case 0x4815: s7r.reg4815=data; if(s7r.reg4818&0x02) { if(s7r.reg4818&0x20&&!(s7r.reg4818&0x40)) { s7r.offset_add|=0x02; if(s7r.offset_add==3) { if(s7r.reg4818&0x10) { } else { uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; if(s7r.reg4818&0x08) { i+=(signed char)s7r.reg4814; } else { i+=s7r.reg4814; } i%=s7r.DataRomSize; s7r.reg4811=i&0x00FF; s7r.reg4812=(i&0x00FF00)>>8; s7r.reg4813=((i&0xFF0000)>>16); } } } else if(s7r.reg4818&0x40&&!(s7r.reg4818&0x20)) { s7r.offset_add|=0x02; if(s7r.offset_add==3) { if(s7r.reg4818&0x10) { } else { uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; if(s7r.reg4818&0x08)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -