static const Mapper172::FDC_CMD_DESC FdcCmdTableJ[32] = { /* 0x00 */ { 1, 1, Mapper172::FdcNop }, /* 0x01 */ { 1, 1, Mapper172::FdcNop }, /* 0x02 */ { 9, 7, Mapper172::FdcReadTrack }, /* 0x03 */ { 3, 0, Mapper172::FdcSpecify }, /* 0x04 */ { 2, 1, Mapper172::FdcSenseDriveStatus }, /* 0x05 */ { 9, 7, Mapper172::FdcWriteData }, /* 0x06 */ { 9, 7, Mapper172::FdcReadData }, /* 0x07 */ { 2, 0, Mapper172::FdcRecalibrate }, /* 0x08 */ { 1, 2, Mapper172::FdcSenseIntStatus }, /* 0x09 */ { 9, 7, Mapper172::FdcWriteDeletedData }, /* 0x0A */ { 2, 7, Mapper172::FdcReadID }, /* 0x0B */ { 1, 1, Mapper172::FdcNop }, /* 0x0C */ { 9, 7, Mapper172::FdcReadDeletedData }, /* 0x0D */ { 6, 7, Mapper172::FdcFormatTrack }, /* 0x0E */ { 1, 1, Mapper172::FdcNop }, /* 0x0F */ { 3, 0, Mapper172::FdcSeek }, /* 0x10 */ { 1, 1, Mapper172::FdcNop }, /* 0x11 */ { 9, 7, Mapper172::FdcScanEqual }, /* 0x12 */ { 1, 1, Mapper172::FdcNop }, /* 0x13 */ { 1, 1, Mapper172::FdcNop }, /* 0x14 */ { 1, 1, Mapper172::FdcNop }, /* 0x15 */ { 1, 1, Mapper172::FdcNop }, /* 0x16 */ { 1, 1, Mapper172::FdcNop }, /* 0x17 */ { 1, 1, Mapper172::FdcNop }, /* 0x18 */ { 1, 1, Mapper172::FdcNop }, /* 0x19 */ { 9, 7, Mapper172::FdcScanLowOrEqual }, /* 0x1A */ { 1, 1, Mapper172::FdcNop }, /* 0x1B */ { 1, 1, Mapper172::FdcNop }, /* 0x1C */ { 1, 1, Mapper172::FdcNop }, /* 0x1D */ { 9, 7, Mapper172::FdcScanHighOrEqual }, /* 0x1E */ { 1, 1, Mapper172::FdcNop }, /* 0x1F */ { 1, 1, Mapper172::FdcNop }, }; void Mapper172::Reset() { memcpy( YSRAM, PROM, 0x8000); ZEROMEMORY( JDRAM, sizeof(JDRAM) ); ZEROMEMORY( JSRAM, sizeof(JSRAM) ); ZEROMEMORY( JCRAM, sizeof(JCRAM) ); SetPROM_32K_Bank( 0 ); irq_enable = 0; irq_counter = 0; WE_SRAM = 0; WE_DRAM = 0; RE_DRAM = 1; reg[0] = 0; reg[1] = 0; reg[2] = 0; reg[3] = 0; read_mode = 0; read_mode1 = 0; write_mode = 0; write_mode1 = 0; //for FDC code by fanoble lpDisk = NULL; DISK = NULL; if(Load_DiskIMG() != NULL) DISK = Load_DiskIMG(); pFdcDataPtr = DISK; bFdcIrq = FALSE; bFdcHwReset = FALSE; bFdcSoftReset = FALSE; bFdcDmaInt = FALSE; nFdcDrvSel = 0; nFdcMotor = 0; nFdcMainStatus = FDC_MS_RQM; nFDCStatus[0] = 0; nFDCStatus[1] = 0; nFDCStatus[2] = 0; nFDCStatus[3] = 0; bFdcCycle = 0; bFdcPhase = FDC_PH_IDLE; nFdcCylinder = 0; nFdcHeadAddres = 0; nFdcRecord = 0; nFdcNumber = 0; } BYTE Mapper172::ReadLow( WORD addr ) { // if((addr<0x6000)&&(addr!=0x418E)) DEBUGOUT( "ReadLow - addr= %04x ; dat= %03x\n", addr, Mapper::ReadLow( addr ) ); switch (addr) { case 0x4188://FDC主状态寄存器(STATUS) // DEBUGOUT( "Read 0x4188 = %04X\n", nFdcMainStatus ); return nFdcMainStatus; break; case 0x4189: if(read_mode){ read_mode1++; if(read_mode1==512) read_mode=0; reg[2] = *(pFdcDataPtr++); return reg[2]; } // DEBUGOUT( "Read 0x4189 = %04X\n", bFdcResults[bFdcCycle] ); read_mode1 = 0; write_mode = 0; reg[2] = bFdcResults[bFdcCycle]; bFdcCycle++; if (bFdcCycle == pFdcCmd->bRLength) { bFdcCycle = 0; bFdcPhase = FDC_PH_IDLE; nFdcMainStatus &= ~FDC_MS_DATA_IN; nFdcMainStatus |= FDC_MS_RQM; } return reg[2]; break; case 0x418E: if (bFdcIrq) return 0xC0; else return 0x00; break; case 0x41AC: // break; } if((addr>=0x6000)&&(WE_SRAM==1)){ return JSRAM[addr-0x6000]; } if((addr>=0x6000)&&(RE_DRAM==1)){ // if((addr>=0x6000)){ return JDRAM[addr-0x6000+(reg[0]*0x8000)]; } if(addr>=0x6000) return CPU_MEM_BANK[addr>>13][addr&0x1FFF]; return Mapper::ReadLow( addr ); } void Mapper172::WriteLow( WORD addr, BYTE data ) { if((addr>=0x6000)&&(WE_SRAM==1)){ JSRAM[addr-0x6000] = data; } if((addr>=0x6000)&&(WE_DRAM==1)){ // if((addr>=0x6000)){ JDRAM[addr-0x6000+(reg[1]*0x8000)] = data; } if(addr>=0x6000) CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; // if((addr<0x6000)&&(addr!=0x418E)) DEBUGOUT( "WriteLow - addr= %04x ; dat= %03x\n", addr, data ); switch (addr) { case 0x4180: DEBUGOUT( "Write 0x4180 = %04X\n", data ); //s????xxx: BIOS ROM bankswitch register. //Load page xxx (4K) of the BIOS ROM to the page frame at $e000. //Also, s might be an enable for SRAM at $6000-$7fff. // WE_SRAM = data & 0x80; SetPROM_4K_Bank(0xE000, data&7); // SetPROM_8K_Bank(7, data&7); break; case 0x4181: //P?mmppcc: Game Mode Control. //P=1 enables MMC2 CHR-ROM switch //values of mm select game mode (00=old game, 01=new game, 10=MMC1, 11=MMC3) //values of pp select PRG page size (00=8k, 01=16k, 10=32k, 11=invalid) //values of cc select CHR page size (1 << cc KBytes). (same as Bung's doc) // DEBUGOUT( "Write 0x4181 = %04X\n", data ); break; case 0x4182: //Rfffvvii: New game mode PPU Config. (same as Bung's doc) // DEBUGOUT( "Write 0x4181 = %04X\n", data ); break; case 0x4183: //PPPPCCCC: PRG and CHR high address line masks (same as Bung's doc) // DEBUGOUT( "Write 0x4181 = %04X\n", data ); break; case 0x4185: // break; case 0x4186: //Send Parallel data. break; case 0x4189: // DEBUGOUT( "Write 0x4189 = %04X\n", data ); if(write_mode){ write_mode1++; if(write_mode1==512) write_mode=0; *pFdcDataPtr = data; pFdcDataPtr++; } write_mode1 = 0; read_mode = 0; switch (bFdcPhase) { case FDC_PH_EXECUTION: case FDC_PH_RESULT: // ERROR break; case FDC_PH_IDLE: default: bFdcCycle = 0; bFdcPhase = FDC_PH_COMMAND; pFdcCmd = &FdcCmdTableJ[data & FDC_CC_MASK]; // fall through case FDC_PH_COMMAND: bFdcCommands[bFdcCycle] = data; bFdcCycle++; if (bFdcCycle == pFdcCmd->bWLength) { bFdcPhase = FDC_PH_EXECUTION; pFdcCmd->pFun(this); if (pFdcCmd->bRLength) { nFdcMainStatus |= FDC_MS_DATA_IN; nFdcMainStatus |= FDC_MS_RQM; bFdcPhase = FDC_PH_RESULT; if((bFdcCommands[0]&0x0F)==0x06) read_mode = 1; if((bFdcCommands[0]&0x0F)==0x05) write_mode = 1; } else { bFdcPhase = FDC_PH_IDLE; } bFdcCycle = 0; } break; } break; case 0x418A://DCR // DEBUGOUT( "Write 0x418A = %04X\n", data ); data = data; break; case 0x418B://FDC数字输出寄存器(DOR)(数字控制寄存器) // DEBUGOUT( "Write 0x418B = %04X\n", data ); bFdcDmaInt = (data & 8) ? TRUE : FALSE; nFdcDrvSel = data & 3; nFdcMotor = data >> 4; if (data & 4) { if (bFdcSoftReset) { FdcSoftReset(); bFdcSoftReset = FALSE; // irq after soft reset if (0 == nFdcDrvSel) bFdcIrq = TRUE; // Drv A Only else bFdcIrq = FALSE; } } else { if (!bFdcSoftReset) { bFdcSoftReset = TRUE; bFdcIrq = FALSE; } } break; case 0x418C: // break; case 0x418D: data = data&0x03; if(data==0) SetVRAM_Mirror( VRAM_VMIRROR ); else if(data==1) SetVRAM_Mirror( VRAM_HMIRROR ); else if(data==2) SetVRAM_Mirror( VRAM_MIRROR4L ); else SetVRAM_Mirror( VRAM_MIRROR4H ); break; case 0x418E: // break; case 0x418F: reg[3] = data; break; case 0x4190: //????xxxx: Map 32k DRAM bank (of a possible 512k) to $6000-$DFFF for reading. //Reading and writing function independently of each other. WE_DRAM = 0; RE_DRAM = 1; reg[0] = data & 0x0F; SetJDRAM_32K_Bank( reg[0] ); break; case 0x4191: //????xxxx: Map 32k DRAM bank to $6000-$DFFF for writing. WE_DRAM = 1; RE_DRAM = 0; reg[1] = data & 0x0F; SetJDRAM_32K_Bank( reg[1] ); break; case 0x4194: // break; case 0x4198: //??xxxxxx: Map 8k DRAM bank to PPU 0x0000. SetJCRAM_8K_Bank( data & 0x3F ); break; case 0x42FF: // break; } } BOOL Mapper172::ReadHigh(WORD addr, LPBYTE pdata) { if( addr>=0xE000 ) return FALSE; if( RE_DRAM == 0 ) return FALSE; *pdata = JDRAM[addr-0x6000+(reg[0]*0x8000)]; return TRUE; } void Mapper172::Write( WORD addr, BYTE data ) { // if(addr>=0xE000) DEBUGOUT( "Write - addr= %04x ; dat= %03x\n", addr, data ); if( (addr<0xE000)&&(WE_DRAM==1) ) { // if( (addr<0xE000) ) { JDRAM[addr-0x6000+(reg[1]*0x8000)] = data; }else{ CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data; } } void Mapper172::Clock( INT cycles ) { /* if( irq_enable ) { if( (irq_counter+=cycles) >= 0x7FFF ) { // irq_counter = 0x7FFF; // nes->cpu->IRQ_NotPending(); irq_enable = 0; // irq_counter &= 0x7FFF; irq_counter = 0x7FFF; nes->cpu->SetIRQ( IRQ_MAPPER ); } }*/ } void Mapper172::PPU_Latch( WORD addr ) { if(DirectInput.m_Sw[DIK_PAUSE]){ // nes->Dump_JDRAM(); // nes->Dump_CPULMEM(); // nes->Dump_CPUHMEM(); // nes->Dump_YWRAM(); } } LPBYTE Mapper172::Load_DiskIMG() { FILE *fp = NULL; if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) { throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY ); } if( !(fp = ::fopen( "DrPCJr.img", "rb" )) ) { LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN ); ::wsprintf( szErrorString, szErrStr, "DrPCJr.img" ); throw szErrorString; } ::fread(lpDisk, 0x168000, 1, fp); FCLOSE(fp); return lpDisk; } //for FDC code by fanoble void Mapper172::FdcHardReset(void) { DEBUGOUT( "FdcHardReset!!!\n" ); bFdcDmaInt = FALSE; FdcSoftReset(); } void Mapper172::FdcSoftReset(void) { DEBUGOUT( "FdcSoftReset!!!\n" ); nFdcDrvSel = 0; nFdcMotor = 0; nFdcMainStatus = FDC_MS_RQM; nFDCStatus[0] = 0; nFDCStatus[1] = 0; nFDCStatus[2] = 0; nFDCStatus[3] = 0; bFdcCycle = 0; bFdcPhase = FDC_PH_IDLE; } //读数据命令(READ DATA) void Mapper172::FdcReadData(Mapper172* thiz) { DEBUGOUT( "FdcReadData!!!\n" ); BYTE C = thiz->bFdcCommands[2]; //磁道号 BYTE H = thiz->bFdcCommands[3]; //磁头号 BYTE R = thiz->bFdcCommands[4]; //扇区号 BYTE N = thiz->bFdcCommands[5]; INT LBA = H * 18 + C * 36 + (R - 1); DEBUGOUT( "C = %04X\n", C ); DEBUGOUT( "H = %04X\n", H ); DEBUGOUT( "R = %04X\n", R ); DEBUGOUT( "N = %04X\n", N ); thiz->pFdcDataPtr = thiz->DISK + LBA * 512; R++; if (19 == R) { R = 1; H++; if (2 == H) { C++; if (80 == C) C = 0; } } thiz->nFDCStatus[0] = 0; thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 thiz->bFdcResults[3] = C; thiz->bFdcResults[4] = H; thiz->bFdcResults[5] = R; thiz->bFdcResults[6] = N; thiz->nFdcCylinder = C; thiz->nFdcHeadAddres = H; thiz->nFdcRecord = R; thiz->nFdcNumber = N; } //写数据命令(WRITE DATA) void Mapper172::FdcWriteData(Mapper172* thiz) { DEBUGOUT( "FdcWriteData!!!\n" ); BYTE C = thiz->bFdcCommands[2]; //磁道号 BYTE H = thiz->bFdcCommands[3]; //磁头号 BYTE R = thiz->bFdcCommands[4]; //扇区号 BYTE N = thiz->bFdcCommands[5]; INT LBA = H * 18 + C * 36 + (R - 1); DEBUGOUT( "C = %04X\n", C ); DEBUGOUT( "H = %04X\n", H ); DEBUGOUT( "R = %04X\n", R ); DEBUGOUT( "N = %04X\n", N ); thiz->pFdcDataPtr = thiz->DISK + LBA * 512; R++; if (19 == R) { R = 1; H++; if (2 == H) { C++; if (80 == C) C = 0; } } thiz->nFDCStatus[0] = 0; thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 thiz->bFdcResults[3] = C; thiz->bFdcResults[4] = H; thiz->bFdcResults[5] = R; thiz->bFdcResults[6] = N; thiz->nFdcCylinder = C; thiz->nFdcHeadAddres = H; thiz->nFdcRecord = R; thiz->nFdcNumber = N; } void Mapper172::FdcNop(Mapper172* thiz) { DEBUGOUT( "FdcNop!!!\n" ); thiz->nFDCStatus[0] = FDC_S0_IC1; thiz->bFdcResults[0] = thiz->nFDCStatus[0]; } void Mapper172::FdcReadTrack(Mapper172* thiz) { DEBUGOUT( "FdcReadTrack!!!\n" ); thiz = thiz; } void Mapper172::FdcSpecify(Mapper172* thiz) { DEBUGOUT( "FdcSpecify!!!\n" ); thiz = thiz; } void Mapper172::FdcSenseDriveStatus(Mapper172* thiz) { DEBUGOUT( "FdcSenseDriveStatus!!!\n" ); thiz->bFdcResults[0] = thiz->nFDCStatus[3]; } void Mapper172::FdcRecalibrate(Mapper172* thiz) { DEBUGOUT( "FdcRecalibrate!!!\n" ); thiz->nFdcCylinder = 0; //磁头回到0磁道 thiz->nFDCStatus[0] |= FDC_S0_SE; } void Mapper172::FdcSenseIntStatus(Mapper172* thiz) { DEBUGOUT( "FdcSenseIntStatus!!!\n" ); thiz->bFdcResults[0] = thiz->nFDCStatus[0]; thiz->bFdcResults[1] = thiz->nFdcCylinder; } void Mapper172::FdcWriteDeletedData(Mapper172* thiz) { DEBUGOUT( "FdcWriteDeletedData!!!\n" ); thiz = thiz; } void Mapper172::FdcReadID(Mapper172* thiz) { DEBUGOUT( "FdcReadID!!!\n" ); thiz->nFDCStatus[0] = 0; thiz->bFdcResults[0] = thiz->nFDCStatus[0]; thiz->bFdcResults[1] = thiz->nFDCStatus[1]; thiz->bFdcResults[2] = thiz->nFDCStatus[2]; thiz->bFdcResults[3] = thiz->nFdcCylinder; thiz->bFdcResults[4] = thiz->nFdcHeadAddres; thiz->bFdcResults[5] = thiz->nFdcRecord; thiz->bFdcResults[6] = thiz->nFdcNumber; } void Mapper172::FdcReadDeletedData(Mapper172* thiz) { DEBUGOUT( "FdcReadDeletedData!!!\n" ); thiz = thiz; } void Mapper172::FdcFormatTrack(Mapper172* thiz) { DEBUGOUT( "FdcFormatTrack!!!\n" ); BYTE C = thiz->bFdcCommands[2]; //磁道号 BYTE H = thiz->bFdcCommands[3]; //磁头号 BYTE R = thiz->bFdcCommands[4]; //扇区号 BYTE N = thiz->bFdcCommands[5]; R++; if (19 == R) { R = 1; H++; if (2 == H) { C++; if (80 == C) C = 0; } } thiz->nFDCStatus[0] = 0; thiz->bFdcResults[0] = thiz->nFDCStatus[0]; // ST0 thiz->bFdcResults[1] = thiz->nFDCStatus[1]; // ST1 thiz->bFdcResults[2] = thiz->nFDCStatus[2]; // ST2 thiz->bFdcResults[3] = C; thiz->bFdcResults[4] = H; thiz->bFdcResults[5] = R; thiz->bFdcResults[6] = N; thiz->nFdcCylinder = C; thiz->nFdcHeadAddres = H; thiz->nFdcRecord = R; thiz->nFdcNumber = N; } void Mapper172::FdcSeek(Mapper172* thiz) { DEBUGOUT( "FdcSeek!!!\n" ); BYTE US; US = thiz->bFdcCommands[1] & 3; thiz->nFdcHeadAddres = ( thiz->bFdcCommands[1] & 7 ) >> 2; thiz->nFdcCylinder = thiz->bFdcCommands[2]; thiz->nFDCStatus[0] = FDC_S0_SE; } void Mapper172::FdcScanEqual(Mapper172* thiz) { DEBUGOUT( "FdcScanEqual!!!\n" ); thiz = thiz; } void Mapper172::FdcScanLowOrEqual(Mapper172* thiz) { DEBUGOUT( "FdcScanLowOrEqual!!!\n" ); thiz = thiz; } void Mapper172::FdcScanHighOrEqual(Mapper172* thiz) { DEBUGOUT( "FdcScanHighOrEqual!!!\n" ); thiz = thiz; }