294 lines
6.4 KiB
C++
294 lines
6.4 KiB
C++
#include "common.h"
|
|
#include "regs.h"
|
|
#include "dack.h"
|
|
|
|
extern DWORD GetCurrentTime_ms( void );
|
|
|
|
void Dack::init( const PDEVICE_INIT_INFO pDevInit )
|
|
{
|
|
ioBase = pDevInit->ioBase;
|
|
}
|
|
|
|
NTSTATUS Dack::PCIF_RESET( void )
|
|
{
|
|
DWORD st, et;
|
|
UCHAR val;
|
|
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, 0x80 );
|
|
DigitalOutMode = 0x00;
|
|
|
|
st = GetCurrentTime_ms();
|
|
for( ; ; ) {
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
if( ( val & 0x80 ) != 0x80 )
|
|
break;
|
|
|
|
et = GetCurrentTime_ms();
|
|
if( st + 10000 < et ) {
|
|
TRAP;
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
void Dack::PCIF_AMUTE_ON( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val |= 0x40;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_AMUTE_OFF( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xbf;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_AMUTE2_ON( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val |= 0x20;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_AMUTE2_OFF( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xdf;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_VSYNC_ON( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val |= 0x10;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_VSYNC_OFF( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xef;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_PACK_START_ON( void )
|
|
{
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_PSCNT, 0x04 );
|
|
}
|
|
|
|
void Dack::PCIF_PACK_START_OFF( void )
|
|
{
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_PSCNT, 0x00 );
|
|
}
|
|
|
|
void Dack::PCIF_SET_DIGITAL_OUT( UCHAR mode )
|
|
{
|
|
DigitalOutMode = mode;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_VMODE, mode );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_HSCNT, 0x70 );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_VSCNT, 0x0b );
|
|
if ( mode == 0x04 ) // S3 LPB
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_HSVS, 0x00 );
|
|
else
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_HSVS, 0x00 );
|
|
}
|
|
|
|
void Dack::PCIF_SET_DMA0_SIZE( ULONG dmaSize )
|
|
{
|
|
UCHAR val;
|
|
|
|
if ( dmaSize == 0 )
|
|
return;
|
|
|
|
dmaSize--;
|
|
|
|
// select MTC-0
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xf8;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
|
|
// write DMA size
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCLL, (UCHAR)( dmaSize & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCLH, (UCHAR)( ( dmaSize >> 8 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCHL, (UCHAR)( ( dmaSize >> 16 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCHH, (UCHAR)( ( dmaSize >> 24 ) & 0xff ) );
|
|
}
|
|
|
|
void Dack::PCIF_SET_DMA1_SIZE( ULONG dmaSize )
|
|
{
|
|
UCHAR val;
|
|
|
|
if ( dmaSize == 0 )
|
|
return;
|
|
|
|
dmaSize--;
|
|
|
|
// select MTC-1
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xf8;
|
|
val |= 0x04;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
|
|
// write DMA size
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCLL, (UCHAR)( dmaSize & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCLH, (UCHAR)( ( dmaSize >> 8 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCHL, (UCHAR)( ( dmaSize >> 16 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MTCHH, (UCHAR)( ( dmaSize >> 24 ) & 0xff ) );
|
|
}
|
|
|
|
void Dack::PCIF_SET_DMA0_ADDR( ULONG dmaAddr )
|
|
{
|
|
UCHAR val;
|
|
|
|
// select MTC-0
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xf8;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
|
|
// write DMA0 address
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRLL, (UCHAR)( dmaAddr & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRLH, (UCHAR)( ( dmaAddr >> 8 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRHL, (UCHAR)( ( dmaAddr >> 16 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRHH, (UCHAR)( ( dmaAddr >> 24 ) & 0xff ) );
|
|
}
|
|
|
|
void Dack::PCIF_SET_DMA1_ADDR( ULONG dmaAddr )
|
|
{
|
|
UCHAR val;
|
|
|
|
// select MTC-1
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xf8;
|
|
val |= 0x04;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
|
|
// write DMA1 address
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRLL, (UCHAR)( dmaAddr & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRLH, (UCHAR)( ( dmaAddr >> 8 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRHL, (UCHAR)( ( dmaAddr >> 16 ) & 0xff ) );
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_MADRHH, (UCHAR)( ( dmaAddr >> 24 ) & 0xff ) );
|
|
}
|
|
|
|
void Dack::PCIF_DMA0_START( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xfc;
|
|
val |= 0x01;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_DMA1_START( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_CNTL );
|
|
val &= 0xfc;
|
|
val |= 0x02;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CNTL, val );
|
|
}
|
|
|
|
void Dack::PCIF_SET_PALETTE( UCHAR select, PUCHAR pPalette )
|
|
{
|
|
int i;
|
|
UCHAR val;
|
|
|
|
val = (READ_PORT_UCHAR( ioBase + PCIF_CPCNT ) & 0xFC) | select | 0x04;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CPCNT, val ); // clear color palette pointer
|
|
|
|
for ( i = 0; i < 256; i++ ) {
|
|
// DACK bug recovery. Use value from 0x07 to 0xFD in AMC mode and setting Palette Y.
|
|
if( DigitalOutMode == 0x07 ) {
|
|
if( select == PALETTE_Y ) {
|
|
// convert 0x00 to 0xFF --> 0x07 to 0xFD
|
|
// round up numbers of five and above and drop anything under five
|
|
val = (UCHAR)(((LONG)pPalette[i] * 246 * 2 + 255) / (255 * 2) + 7);
|
|
}
|
|
}
|
|
else if( pPalette[i] > 253 )
|
|
val = 253;
|
|
else
|
|
val = pPalette[i];
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CPLT, val );
|
|
}
|
|
}
|
|
|
|
void Dack::PCIF_GET_PALETTE( UCHAR select, PUCHAR pPalette )
|
|
{
|
|
int i;
|
|
UCHAR val;
|
|
|
|
val = (READ_PORT_UCHAR( ioBase + PCIF_CPCNT ) & 0xFC) | select | 0x04;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_CPCNT, val ); // clear color palette pointer
|
|
for ( i = 0; i < 256; i++ )
|
|
pPalette[i] = READ_PORT_UCHAR( ioBase + PCIF_CPLT );
|
|
}
|
|
|
|
void Dack::PCIF_CHECK_SERIAL( void )
|
|
{
|
|
DWORD st, et;
|
|
UCHAR val;
|
|
|
|
st = GetCurrentTime_ms();
|
|
for( ; ; ) {
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_SCNT );
|
|
if( ( val & 0x80 ) != 0x80 )
|
|
break;
|
|
|
|
et = GetCurrentTime_ms();
|
|
if( st + 10000 < et ) {
|
|
TRAP;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Dack::PCIF_DMA_ABORT( void )
|
|
{
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_INTF, 0x04 );
|
|
}
|
|
|
|
void Dack::PCIF_ALL_IFLAG_CLEAR( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_INTF );
|
|
val |= 0x23;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_INTF, val );
|
|
}
|
|
|
|
void Dack::PCIF_ASPECT_0403( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_TEST );
|
|
val |= 0x10;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_TEST, val );
|
|
}
|
|
|
|
void Dack::PCIF_ASPECT_1609( void )
|
|
{
|
|
UCHAR val;
|
|
|
|
val = READ_PORT_UCHAR( ioBase + PCIF_TEST );
|
|
val &= 0xef;
|
|
WRITE_PORT_UCHAR( ioBase + PCIF_TEST, val );
|
|
}
|