AxibugEmuOnline/References/VirtuaNESex_src_191105/NES/Mapper/Mapper172.cpp

592 lines
14 KiB
C++
Raw Normal View History

2024-08-05 17:58:53 +08:00
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<44><43>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>(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<44><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>(DOR)(<28><><EFBFBD>ֿ<EFBFBD><D6BF>ƼĴ<C6BC><C4B4><EFBFBD>)
// 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;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(READ DATA)
void Mapper172::FdcReadData(Mapper172* thiz)
{
DEBUGOUT( "FdcReadData!!!\n" );
BYTE C = thiz->bFdcCommands[2]; //<2F>ŵ<EFBFBD><C5B5><EFBFBD>
BYTE H = thiz->bFdcCommands[3]; //<2F><>ͷ<EFBFBD><CDB7>
BYTE R = thiz->bFdcCommands[4]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}
//д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(WRITE DATA)
void Mapper172::FdcWriteData(Mapper172* thiz)
{
DEBUGOUT( "FdcWriteData!!!\n" );
BYTE C = thiz->bFdcCommands[2]; //<2F>ŵ<EFBFBD><C5B5><EFBFBD>
BYTE H = thiz->bFdcCommands[3]; //<2F><>ͷ<EFBFBD><CDB7>
BYTE R = thiz->bFdcCommands[4]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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; //<2F><>ͷ<EFBFBD>ص<EFBFBD>0<EFBFBD>ŵ<EFBFBD>
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]; //<2F>ŵ<EFBFBD><C5B5><EFBFBD>
BYTE H = thiz->bFdcCommands[3]; //<2F><>ͷ<EFBFBD><CDB7>
BYTE R = thiz->bFdcCommands[4]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}