/*******************************************************************************
 * NES Mapper for BBK
 *
 *  Author:  <fanoble@yeah.net>
 *
 *  Create:   2014-06-24, by fanoble
 *******************************************************************************
 */

static const Mapper171::FDC_CMD_DESC FdcCmdTableB[32] =
{
	/* 0x00 */ { 1, 1, Mapper171::FdcNop },
	/* 0x01 */ { 1, 1, Mapper171::FdcNop },
	/* 0x02 */ { 9, 7, Mapper171::FdcReadTrack },
	/* 0x03 */ { 3, 0, Mapper171::FdcSpecify },
	/* 0x04 */ { 2, 1, Mapper171::FdcSenseDriveStatus },
	/* 0x05 */ { 9, 7, Mapper171::FdcWriteData },
	/* 0x06 */ { 9, 7, Mapper171::FdcReadData },
	/* 0x07 */ { 2, 0, Mapper171::FdcRecalibrate },
	/* 0x08 */ { 1, 2, Mapper171::FdcSenseIntStatus },
	/* 0x09 */ { 9, 7, Mapper171::FdcWriteDeletedData },
	/* 0x0A */ { 2, 7, Mapper171::FdcReadID },
	/* 0x0B */ { 1, 1, Mapper171::FdcNop },
	/* 0x0C */ { 9, 7, Mapper171::FdcReadDeletedData },
	/* 0x0D */ { 6, 7, Mapper171::FdcFormatTrack },
	/* 0x0E */ { 1, 1, Mapper171::FdcNop },
	/* 0x0F */ { 3, 0, Mapper171::FdcSeek },
	/* 0x10 */ { 1, 1, Mapper171::FdcNop },
	/* 0x11 */ { 9, 7, Mapper171::FdcScanEqual },
	/* 0x12 */ { 1, 1, Mapper171::FdcNop },
	/* 0x13 */ { 1, 1, Mapper171::FdcNop },
	/* 0x14 */ { 1, 1, Mapper171::FdcNop },
	/* 0x15 */ { 1, 1, Mapper171::FdcNop },
	/* 0x16 */ { 1, 1, Mapper171::FdcNop },
	/* 0x17 */ { 1, 1, Mapper171::FdcNop },
	/* 0x18 */ { 1, 1, Mapper171::FdcNop },
	/* 0x19 */ { 9, 7, Mapper171::FdcScanLowOrEqual },
	/* 0x1A */ { 1, 1, Mapper171::FdcNop },
	/* 0x1B */ { 1, 1, Mapper171::FdcNop },
	/* 0x1C */ { 1, 1, Mapper171::FdcNop },
	/* 0x1D */ { 9, 7, Mapper171::FdcScanHighOrEqual },
	/* 0x1E */ { 1, 1, Mapper171::FdcNop },
	/* 0x1F */ { 1, 1, Mapper171::FdcNop },
};

void Mapper171::Reset()
{
	DISK = Load_DiskIMG();

	pFdcDataPtr = DISK;

	// BIOS fixed to Page FE
	BIOS = BDRAM + 0x78000;

	memset(BDRAM, 0, sizeof(BDRAM));

	// 4xxx - 7xxx
	SetPROM_Bank(2, BIOS + 0x0000, BANKTYPE_RAM);
	SetPROM_Bank(3, BIOS + 0x2000, BANKTYPE_RAM);

	// 8xxx - Bxxx
	SetPROM_Bank(4, BDRAM + 0x0000, BANKTYPE_RAM);
	SetPROM_Bank(5, BDRAM + 0x2000, BANKTYPE_RAM);

	// Cxxx - Fxxx
	SetPROM_16K_Bank(6, 7);

//	SetPROM_32K_Bank(0);

	SetYCRAM_8K_Bank(0);

	nPageCD = 0;
	nPageEF = 0;

	// FDC
	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;

	p_mode = 0;
	NT_data = 0;
	nes->ppu->SetExtLatchMode( TRUE );

	irq_enable = 0;
	irq_counter = 0;

	reg[0]=0;
	reg[1]=0;
	reg[2]=0;
	reg[3]=0;

}

// 8000 - FFFF
BOOL Mapper171::ReadHigh(WORD addr, LPBYTE pdata)
{
	if (addr < 0xFF00 ||
		addr > 0xFFEF)
		return FALSE;

	switch (addr)
	{
		case 0xFF18:	// 真人语音系统相关;
	DEBUGOUT( "ReadH  A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, bFdcResults[bFdcCycle]&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
			*pdata = 0x8F;
			return TRUE;

		case 0xFF80:	// FDCDMADackIO
			*pdata = *pFdcDataPtr++;
			return TRUE;
		case 0xFF88:	// FDCDMATcIO
			*pdata = *pFdcDataPtr++;
			return TRUE;
		case 0xFF90:	// FDCDRQPortI/FDCCtrlPortO
			// I: D6 : FDC DRQ
			*pdata = 0x40;
			return TRUE;
		case 0xFF98:	// FDCIRQPortI/FDCDMADackIO
			// I: D6 : IRQ
			if (bFdcIrq)
				*pdata = 0x40;
			else
				*pdata = 0;
			return TRUE;

		case 0xFFA0:	// FDCResetPortO/FDCStatPortI
			// I: D7 : FDC ready
			// I: D6 : FDC dir
			// I: D5 : FDC busy
			*pdata = nFdcMainStatus;
//	DEBUGOUT( "ReadH  A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, nFdcMainStatus&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
			return TRUE;
		case 0xFFA8:	// FDCDataPortIO
			*pdata = bFdcResults[bFdcCycle];
			bFdcCycle++;
			if (bFdcCycle == pFdcCmd->bRLength)
			{
				// prepare for next command
				bFdcCycle = 0;
				bFdcPhase = FDC_PH_IDLE;

				nFdcMainStatus &= ~FDC_MS_DATA_IN;
				nFdcMainStatus |= FDC_MS_RQM;
			}
			return TRUE;
		case 0xFFB8:	// FDCChangePortI/FDCSpeedPortO
			// I: D7 : Disk changed
			*pdata = 0;
			return TRUE;

		default:
			DEBUGOUT("Read %02X\n", addr);
			break;
	}

	return FALSE;
}

void Mapper171::Write(WORD addr, BYTE data)
{

	if (addr < 0xFF00)
	{
		CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
//		Write_PRAM( addr, data );
		return;
	}

	DEBUGOUT( "WriteH A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
	switch (addr&0xFF)	//0xFF00-0xFFFF
	{
		case 0x00:
			reg[1] = data;
			break;
		case 0x01:	// VideoCtrlPort
			// D3 : C000-FFFF map to DRAM/-ROM
			// D2 : INT count/-load
			// D[1:0] : 6116's AV10 connection
			//          00: AV10
			//          01: AV11
			//          10: AV0
			//          11: AV1

			p_mode = data&0x40;
			reg[2] = data&0x08;

			reg[0] = data&0x03;
			if(reg[0]==0)		SetVRAM_Mirror( VRAM_VMIRROR );
			else if(reg[0]==1)	SetVRAM_Mirror( VRAM_HMIRROR );
			else if(reg[0]==2)	SetVRAM_Mirror( VRAM_MIRROR4L );
			else				SetVRAM_Mirror( VRAM_MIRROR4H );

			if(data&0x4){
				irq_enable = 1;
				nes->cpu->ClrIRQ( IRQ_MAPPER );
			}else{
//				irq_enable = 0;
				nes->cpu->ClrIRQ( IRQ_MAPPER );
			}

			if(data&8){
				// map C000-FFF to DRAM
//				int nOffset;
//				nOffset = nPageCD * 0x2000;
//				nOffset &= 0x7FFFF;	// truncate to 512K
//				SetPROM_Bank(6, BDRAM + nOffset, BANKTYPE_RAM);
//				nOffset = nPageEF * 0x2000;
//				nOffset &= 0x7FFFF;	// truncate to 512K
//				SetPROM_Bank(7, BDRAM + nOffset, BANKTYPE_RAM);

				SetBDRAM_8K_Bank(6 , nPageCD&0x3F);
				SetBDRAM_8K_Bank(7 , nPageEF&0x3F);
			}
			else{
				// map C000-FFF to ROM
				SetPROM_16K_Bank(6, 7);
			}
			break;

//		case 0x02:	// IntCountPortL
			// D[4:0] : counter
//			break;

		case 0x03:	// VideoDataPort0
			data &= 0x0F;
			SetYCRAM_2K_Bank( 0, data);
			break;

		case 0x04:	// DRAMPagePort
//			data &= 0x1F;	//  512K
//			SetPROM_Bank(4, BDRAM + data * 0x4000 + 0x0000, BANKTYPE_RAM);
//			SetPROM_Bank(5, BDRAM + data * 0x4000 + 0x2000, BANKTYPE_RAM);

			SetBDRAM_16K_Bank(4 , data&0x1F);
			if(((reg[1]==4)||p_mode)&&(data<0xE0)) SetPROM_16K_Bank(4, data&7);
			break;
/*
		case 0x0A:
			break;
		case 0x1A:
			reg[3] = data;
			break;
		case 0x12:
//			reg12 = data;
			break;
		case 0x22:
//			reg22 = data;
			break;
*/
		case 0x0B:	// VideoDataPort1
			data &= 0x0F;	// 32K
			SetYCRAM_2K_Bank( 2, data);
			break;

//		case 0x10:	// SoundPort0/SpeakInitPort
			//
//			break;

		case 0x13:	// VideoDataPort2
			data &= 0x0F;	// 32K
			SetYCRAM_2K_Bank( 4, data);
			break;

		case 0x14:
			data &= 0x3F;
			SetBDRAM_8K_Bank(4 , data);
			break;

//		case 0x18:	// 真人语音系统相关;
//			data = data;
//			break;

		case 0x1B:	// VideoDataPort3
			data &= 0x0F;	// 32K
			SetYCRAM_2K_Bank( 6, data);
			break;

		case 0x1C:
			data &= 0x3F;
			SetBDRAM_8K_Bank(5 , data);
			break;

		case 0x24:	// DRAMPagePortCD
			nPageCD = data;
			if(reg[2]) SetBDRAM_8K_Bank(6 , data&0x3F);
			break;
		case 0x2C:	// DRAMPagePortEF
			nPageEF = data;
			if(reg[2]) SetBDRAM_8K_Bank(7 , data&0x3F);
			break;

//		case 0x40:	// PCDaCtPortO/PCCDataPort
			// D4 : Signal to PC's ERROR
			// D[3:0] : Output PC data
//			break;
//		case 0x48:	// PCCtrlPortI/PCCStatsPortI/PCDataPortIH
			// D[7:4] : PC input data
			// D3 : Signal of PC's pin STB
//			break;
//		case 0x50:	// PCDataPortIL/PCCCtrlPoutO
			// D[3:0] : PC input data
//			break;

//		case 0x80:	// FDCDMADackIO
//			data = data;
//			break;
//		case 0x88:	// FDCDMATcIO
//			data = data;
//			break;

		case 0x90:	// FDCDRQPortI/FDCCtrlPortO
			// O: D5 : Drv B motor
			// O: D4 : Drv A motor
			// O: D3 : Enable INT and DMA
			// O: D2 : not FDC Reset
			// O: D[1:0] : Drv sel

			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 0x98:	// FDCIRQPortI/FDCDMADackIO
			// I: D6 : IRQ
//			data = data;
//			break;
		case 0xA0:	// FDCResetPortO/FDCStatPortI
			// O: D6 : FDC pin reset
			if (data & 0x40)
			{
				if (!bFdcHwReset)
				{
					bFdcHwReset = TRUE;
					bFdcIrq = FALSE;
				}
			}
			else
			{
				if (bFdcHwReset)
				{
					FdcHardReset();
					bFdcHwReset = FALSE;
				}
			}
			break;
		case 0xA8:	// FDCDataPortIO
			switch (bFdcPhase)
			{
				case FDC_PH_EXECUTION:
				case FDC_PH_RESULT:
					// ERROR
					break;
				case FDC_PH_IDLE:
				default:
					bFdcCycle = 0;
					bFdcPhase = FDC_PH_COMMAND;
					pFdcCmd = &FdcCmdTableB[data & FDC_CC_MASK];
					// fall through
				case FDC_PH_COMMAND:
					bFdcCommands[bFdcCycle] = data;
					bFdcCycle++;
					if (bFdcCycle == pFdcCmd->bWLength)
					{
						bFdcPhase = FDC_PH_EXECUTION;
//						nFdcMainStatus &= ~FDC_MS_RQM;
						pFdcCmd->pFun(this);
						if (pFdcCmd->bRLength)	// prepare for reading
						{
							nFdcMainStatus |= FDC_MS_DATA_IN;
							bFdcPhase = FDC_PH_RESULT;
						}
						else
						{
							bFdcPhase = FDC_PH_IDLE;
						}
						bFdcCycle = 0;
					}
					break;
			}
			break;
//		case 0xB8:	// FDCChangePortI/FDCSpeedPortO
			// I: D7 : Disk changed
			// O: D[1:0] : 00 500kbps(1.2M, 1.44M)
			//             01 300kbps(360K) 
			//             10 250kbps(720K)
//			data = data;
//			break;

//		case 0x09:
//		case 0x17:
//			data = data;
//			break;

		// code patch
//		case 0x2B:
//			CPU_MEM_BANK[7][addr & 0x1FFF] = data;
//			break;

		default:
			DEBUGOUT("Write %02X -> [%04X]\n", data, addr);
			break;
	}
}

// 4100 - 7FFF
BYTE Mapper171::ReadLow(WORD addr)
{
	BYTE data = 0;

	if (addr < 0x4400)
	{
		// 4100 - 43FF, IO for system
		data = BIOS[addr - 0x4000];
	}
	else if (addr < 0x5800)
	{
		// 4400 - 57FF, IO for ROM/RAM
		data = BIOS[addr - 0x4000];
	}
	else if (addr < 0x6000)
	{
		// 5800 - 5FFF, 2K RAM
		data = BIOS[addr - 0x4000];
	}
	else if (addr < 0x6100)
	{
		// 6000 - 60FF, reserved
		data = BIOS[addr - 0x4000];
	}
	else
	{
		// 6100 - 7FFF, RAM
		data = BIOS[addr - 0x4000];
	}

	return data;
}

// 4100 - 7FFF
void Mapper171::WriteLow(WORD addr, BYTE data)
{
	if (addr < 0x4400)
	{
		// 4100 - 43FF, IO for system
		BIOS[addr - 0x4000] = data;
	}
	else if (addr < 0x5800)
	{
		// 4400 - 57FF, IO for ROM/RAM
		BIOS[addr - 0x4000] = data;
	}
	else if (addr < 0x6000)
	{
		// 5800 - 5FFF, 2K RAM
		BIOS[addr - 0x4000] = data;
	}
	else if (addr < 0x6100)
	{
		// 6000 - 60FF, reserved
		BIOS[addr - 0x4000] = data;
	}
	else
	{
		// 6100 - 7FFF, RAM
		BIOS[addr - 0x4000] = data;
	}
}

void	Mapper171::Write_PRAM( WORD addr, BYTE data )
{
	if(addr<0xC000){
//		BDRAM[(addr-0x8000)+(bank*0x4000)] = data;
		CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
	}else{
		BDRAM[addr+0x70000] = data;
	}
}
/*
void	Mapper171::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	Mapper171::HSync( INT scanline )
{
	if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) {
//		SetYCRAM_2K_Bank( 0, (scanline&0xF0)>>4);
		if( irq_enable ) {

			irq_enable  = 0;
			nes->cpu->SetIRQ( IRQ_MAPPER );
		}
	}
}
*/

void	Mapper171::PPU_Latch( WORD addr )
{
	if((addr&0xF000)==0x2000){
		NT_data=(addr>>6)&0x0F;
		if(p_mode){
//			SetYCRAM_2K_Bank( 0, NT_data);
//			SetYCRAM_2K_Bank( 2, NT_data);
//			SetYCRAM_2K_Bank( 4, NT_data);
//			SetYCRAM_2K_Bank( 6, NT_data);
		}
	}

	if((DirectInput.m_Sw[DIK_PGUP])&&(DirectInput.m_Sw[DIK_PGDN])){
		DISK = Change_DiskIMG();
		pFdcDataPtr = DISK;
	}

	if(DirectInput.m_Sw[DIK_PAUSE]){
		nes->Dump_BDRAM();
		nes->Dump_YCRAM();
		nes->Dump_VRAM();
		nes->Dump_CPULMEM();
		nes->Dump_CPUHMEM();
	}
}
void	Mapper171::PPU_ExtLatchX( INT x )
{
	a3 = (x&1)<<3;
}
void	Mapper171::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr )
{
	INT loopy_v = nes->ppu->GetPPUADDR();
	INT loopy_y = nes->ppu->GetTILEY();
	INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8;
	INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4);
	INT attrsft = (ntbladr&0x0040)>>4;
	LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10];
	INT ntbl_x  = ntbladr&0x001F;
	INT tileadr, ntb;

	ntb = (ntbladr>>6)&0x0F;

		if(p_mode){
//			SetYCRAM_2K_Bank( 0, ntb);
//			SetYCRAM_2K_Bank( 2, NT_data);
//			SetYCRAM_2K_Bank( 4, NT_data);
//			SetYCRAM_2K_Bank( 6, NT_data);
		}

//	DEBUGOUT("ntb=%04X tileofs=%02X\n", ntb, tileofs );

	attradr &= 0x3FF;
	attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2;
	tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y;

	chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF   ];
	chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
}

LPBYTE	Mapper171::Load_DiskIMG()
{
	FILE *fp = NULL;
	if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) {
		throw	CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
	}
	if( !(fp = ::fopen( img_fname, "rb" )) ) {
		LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
		::wsprintf( szErrorString, szErrStr, img_fname );
		throw	szErrorString;
	}
	::fread(lpDisk, 0x168000, 1, fp);
	FCLOSE(fp);
	return lpDisk;
}
LPBYTE	Mapper171::Change_DiskIMG()
{
	FILE *fp = NULL;
	if( !(lpDisk = (LPBYTE)malloc( 0x168000 )) ) {
		throw	CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
	}
	if( !(fp = ::fopen( "BBK.IMG", "rb" )) ) {
		LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
		::wsprintf( szErrorString, szErrStr, "BBK.img" );
		throw	szErrorString;
	}
	::fread(lpDisk, 0x168000, 1, fp);
	FCLOSE(fp);
	return lpDisk;
}

// for FDC
void Mapper171::FdcHardReset(void)
{
	DEBUGOUT( "FdcHardReset!!!\n" );
	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;
}
void Mapper171::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;
}
void Mapper171::FdcNop(Mapper171* thiz)
{
	DEBUGOUT( "FdcNop!!!\n" );
	thiz->nFDCStatus[0] = FDC_S0_IC1;
	thiz->bFdcResults[0] = thiz->nFDCStatus[0];
}
void Mapper171::FdcReadTrack(Mapper171* thiz)
{
	DEBUGOUT( "FdcReadTrack!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcSpecify(Mapper171* thiz)
{
	DEBUGOUT( "FdcSpecify!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcSenseDriveStatus(Mapper171* thiz)
{
	DEBUGOUT( "FdcSenseDriveStatus!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcWriteData(Mapper171* thiz)
{
	DEBUGOUT( "FdcWriteData!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcReadData(Mapper171* 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;
	LBA = H * 18 + C * 36 + (R - 1);
	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;
}
void Mapper171::FdcRecalibrate(Mapper171* thiz)
{
	DEBUGOUT( "FdcRecalibrate!!!\n" );
	BYTE US;
	US = thiz->bFdcCommands[1] & 3;
	if (0 == US)
		thiz->nFDCStatus[0] = FDC_S0_SE;
	else
		thiz->nFDCStatus[0] = FDC_S0_SE | FDC_S0_IC0;
}
void Mapper171::FdcSenseIntStatus(Mapper171* thiz)
{
	DEBUGOUT( "FdcSenseIntStatus!!!\n" );
	if (0 == thiz->nFdcDrvSel)	// Drv A Only
		thiz->nFDCStatus[0] = FDC_S0_IC0 | FDC_S0_IC1;
	else
		thiz->nFDCStatus[0] = FDC_S0_SE | FDC_S0_IC0;
	thiz->bFdcResults[0] = thiz->nFDCStatus[0];
	thiz->bFdcResults[1] = thiz->nFdcCylinder;	// PCN
}
void Mapper171::FdcWriteDeletedData(Mapper171* thiz)
{
	DEBUGOUT( "FdcWriteDeletedData!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcReadID(Mapper171* thiz)
{
	DEBUGOUT( "FdcReadID!!!\n" );
	thiz->nFDCStatus[0] = 0;
	thiz->bFdcResults[0] = thiz->nFDCStatus[0];
}
void Mapper171::FdcReadDeletedData(Mapper171* thiz)
{
	DEBUGOUT( "FdcReadDeletedData!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcFormatTrack(Mapper171* thiz)
{
	DEBUGOUT( "FdcFormatTrack!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcSeek(Mapper171* thiz)
{
	DEBUGOUT( "FdcSeek!!!\n" );
	// new cylinder number
	BYTE NCN;
	BYTE US;
	US = thiz->bFdcCommands[1] & 3;
	NCN = thiz->bFdcCommands[2];
	thiz->nFdcCylinder = NCN;
	thiz->nFDCStatus[0] = FDC_S0_SE;
}
void Mapper171::FdcScanEqual(Mapper171* thiz)
{
	DEBUGOUT( "FdcScanEqual!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcScanLowOrEqual(Mapper171* thiz)
{
	DEBUGOUT( "FdcScanLowOrEqual!!!\n" );
	thiz = thiz;
}
void Mapper171::FdcScanHighOrEqual(Mapper171* thiz)
{
	DEBUGOUT( "FdcScanHighOrEqual!!!\n" );
	thiz = thiz;
}

/*******************************************************************************
                           E N D  O F  F I L E
*******************************************************************************/
