📄 kitldma.c
字号:
KITLOutputDebugString("channel[x].vPFlags = 0x%x\n", channels[KITL_DMA_CHANNEL].vPFlags);
KITLOutputDebugString("vInputPB = 0x%x\n", vInputPB);
KITLOutputDebugString("vOutputPB = 0x%x\n", vOutputPB);
KITLOutputDebugString("\n");
KITLOutputDebugString("inputBuffer = 0x%x\n", inputBuffer);
KITLOutputDebugString("outputBuffer = 0x%x\n", outputBuffer);
KITLOutputDebugString("channel[x].pFlags = 0x%x\n", channels[KITL_DMA_CHANNEL].pFlags);
KITLOutputDebugString("inputPB = 0x%x\n", inputPB);
KITLOutputDebugString("outputPB = 0x%x\n", outputPB);
// Initialize the DMA Transport "hardware" (The DMA transport is a
// device invented for the Emulator. There isn't a real-world analogue,
// though it does work as if it were a real piece of hardware.)
KITLOutputDebugString ("Write DMA_KITL_HANDSHAKE (DMA_GLOBAL_REG = 0x%x)\n", KITL_DMA_GLOBAL_REG);
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_GLOBAL_REG, (ULONG)DMA_KITL_HANDSHAKE);
KITLOutputDebugString ("Write DMA_KITL_HANDSHAKE OK\n");
KITLOutputDebugString ("Read DMA_KITL_HANDSHAKE...\n");
if ( READ_REGISTER_ULONG((PULONG)KITL_DMA_GLOBAL_REG) == DMA_KITL_HANDSHAKE ) // no errors
{
KITLOutputDebugString ("Read DMA_KITL_HANDSHAKE OK\n");
// Set up flags address
KITLOutputDebugString ("Set flagsPhysical = 0x%x\n", channels[KITL_DMA_CHANNEL].pFlags);
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_FLAGS_ADDRESS_REG, (ULONG)channels[KITL_DMA_CHANNEL].pFlags);
KITLOutputDebugString ("Set flagsPhysical OK\n");
// Init interrupt request line
KITLOutputDebugString ("Init interrupt request line\n");
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_IRQ_REG, (ULONG)DMA_KITL_IRQ);
KITLOutputDebugString ("interrupt request line OK\n");
success = TRUE;
KITLOutputDebugString ("InitializeDMATransport succeeded.\n");
}
KITLOutputDebugString ("-InitializeDMATransport\n");
return success;
}
/*------------------------------------------------------------------
DMAKitlEncodePacket
Encodes a packet before sending.
------------------------------------------------------------------*/
BOOL
DMAKitlEncodePacket(
LPBYTE pbFrame,
USHORT cbData )
{
// The DMA Transport doesn't do any encoding.
return TRUE;
}
/*------------------------------------------------------------------
DMAKitlDecodePacket
Decodes a packet after receiving.
------------------------------------------------------------------*/
LPBYTE
DMAKitlDecodePacket(
LPBYTE pbFrame,
PUSHORT pcbData )
{
return pbFrame;
}
/*------------------------------------------------------------------
DMAKitlSendPacket
Sends a packet out across the transport.
Returns TRUE on success, FALSE otherwise (requires resend)
------------------------------------------------------------------*/
BOOL
DMAKitlSendPacket(
LPBYTE pbFrame,
USHORT cbFrame )
{
BOOL success = FALSE;
// Setup the param block for the DMA Transport to read.
vOutputPB->ioDataLength = cbFrame;
vOutputPB->ioDataPtr = (ULONG)outputBuffer; // Specify physical address
vOutputPB->ioStatus = 0;
// Make sure the packet is not larger than the max kitl packet
// size and not larger than the DMATransport hardware's max
// packet size.
if ( cbFrame <= KITL_MTU && cbFrame <= DMA_PACKET_SIZE )
{
// Copy the packet into our DMA buffer area.
memcpy(vOutputBuffer, pbFrame, cbFrame);
// Tell the DMA Transport hardware to grab the packet. A normal
// DMA device would operate asynchronously - but this is the
// Emulator and it will read the packet instantly when we
// write to the IO port.
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_IO_OUTPUT_REG, (ULONG)outputPB);
// Any error?
if ( vOutputPB->ioStatus == 0 )
{
success = TRUE;
}
else
{
KITLOutputDebugString("Error! DMAKitlSendPacket() FAILED.\n");
}
}
else
{
KITLOutputDebugString("Error! DMAKitlSendPacket() FAILED: Packet too large.\n");
}
return success;
}
/*------------------------------------------------------------------
DMAKitlReceivePacket
Receives a packet from the transport.
------------------------------------------------------------------*/
BOOL
DMAKitlReceivePacket(
LPBYTE pbFrame,
PUSHORT pcbData )
{
BOOL success = FALSE;
// If the data ready flag is set, there's a packet waiting for us.
if ( (*channels[ KITL_DMA_CHANNEL ].vPFlags) & DMA_KITL_FLAGS_DATA_READY )
{
// Acknowledge the interrupt.
WRITE_REGISTER_ULONG(KITL_DMA_IRQ_ACK_REG, 0);
// Setup the param block for the DMA Transport to read.
vInputPB->ioDataLength = KITL_MTU;
vInputPB->ioDataPtr = (ULONG)inputBuffer; // Specify physical address
vInputPB->ioStatus = -1;
// Grab the packet (ask the hardware to DMA into our receive buffer)
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_IO_INPUT_REG, (ULONG)inputPB);
*pcbData = (USHORT)min( *pcbData, vInputPB->ioDataLength );
// Data and no error
if ( *pcbData != 0 && vInputPB->ioStatus == 0 )
{
// Now copy that many bytes into the output buffer.
memcpy(pbFrame, vInputBuffer, *pcbData);
success = TRUE;
}
else
{
KITLOutputDebugString("Error! DMAKitlReceivePacket() FAILED.\n");
}
}
return success;
}
/*------------------------------------------------------------------
DMAKitlSetHostConfiguration
Set host configuration. Data would arrive here that was
sent from the DeviceEmulatorTransport.dll TranGetHostCfg()
function.
------------------------------------------------------------------*/
BOOL
DMAKitlSetHostConfiguration(
LPBYTE pbConfig,
USHORT cbConfig )
{
// No configuration supported
return TRUE;
}
/*------------------------------------------------------------------
DMAKitlGetDeviceConfiguration
Get device configuration. Data would be sent to the
DeviceEmulatorTransport.dll TranSetDevCfg() function.
------------------------------------------------------------------*/
BOOL
DMAKitlGetDeviceConfiguration(
LPBYTE pbConfig,
PUSHORT pcbConfig )
{
// No configuration supported.
*pcbConfig = 0;
return TRUE;
}
/*------------------------------------------------------------------
DMAKitlEnableInts
Enables interrupts on the DMA Transport hardware. The
DMA Transport will pull the IRQ line high when a packet is
available. It will pull the line low again automatically
when we read the waiting packet.
------------------------------------------------------------------*/
VOID
DMAKitlEnableInts(
BOOL fEnable )
{
ULONG global;
KITLOutputDebugString("+DMAKitlEnableInts\n");
global = READ_REGISTER_ULONG((PULONG)KITL_DMA_GLOBAL_REG);
if ( fEnable )
{
// Enable interrupts, if they're not already.
if ( !(global & DMA_KITL_INTERRUPTS_ENABLED) )
{
global |= DMA_KITL_INTERRUPTS_ENABLED;
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_GLOBAL_REG, global);
}
}
else
{
// Disable interrupts, if they're not already.
if (global & DMA_KITL_INTERRUPTS_ENABLED)
{
global &= ~DMA_KITL_INTERRUPTS_ENABLED;
WRITE_REGISTER_ULONG((PULONG)KITL_DMA_GLOBAL_REG, global);
}
}
KITLOutputDebugString("-DMAKitlEnableInts\n");
}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------
OEMKitlInit
Initialization routine called from KitlInit() to perform
platform specific hardware initialization.
Return Value:
Return TRUE if init is successful, FALSE if error.
------------------------------------------------------------------*/
BOOL
OEMKitlInit (PKITLTRANSPORT inKitlTransport)
{
return InitDMAKitl(inKitlTransport);
}
BOOL OEMKitlStartup (void)
{
BOOL rc;
BSP_ARGS* pBSPArgs;
BOOL fActiveKITL = TRUE;
KITL_RETAILMSG(ZONE_KITL_OAL, ("+OEMKitlStartup()\r\n"));
// Get pointer to expected boot args location
pBSPArgs = (BSP_ARGS*)IMAGE_SHARE_ARGS_UA_START;
/*
* Device Emulator writes directly to BSP_ARGS to pass command-line
* arguments (screen size, KITL mode, reset mode). However, it does not update
* the pBSPArgs->header to let us know this is a valid BSP_ARGS struct.
* Only the bootloader does that, and when using DMA_KITL there's no need
* for a bootloader so it normally will not have run, and BSP_ARGS will be
* invalid.
*
* However, the subset of BSP_ARGS that DE writes to will be valid.
* DE sets pBSPArgs->ScreenSignature to let us know that data is good
* (not very intuitive, but there you are).
*
if (
pBSPArgs->header.signature != OAL_ARGS_SIGNATURE ||
pBSPArgs->header.oalVersion != OAL_ARGS_VERSION ||
pBSPArgs->header.bspVersion != BSP_ARGS_VERSION
)
*/
if ( pBSPArgs->ScreenSignature != BSP_SCREEN_SIGNATURE ) {
KITL_RETAILMSG(ZONE_ERROR, ("Invalid BSP_ARGS.\r\n"));
} else {
fActiveKITL = !(pBSPArgs->kitl.flags & OAL_KITL_FLAGS_PASSIVE);
}
fActiveKITL = !(pBSPArgs->kitl.flags & OAL_KITL_FLAGS_PASSIVE);
KITL_RETAILMSG(ZONE_INIT, ("Using %s KITL\r\n", fActiveKITL ? "active" : "passive"));
rc = KitlInit ( fActiveKITL );
KITL_RETAILMSG(ZONE_KITL_OAL, ("-OEMKitlStartup(rc = %d)\r\n", rc));
return rc;
}
BOOL OEMKitlIoctl (DWORD code, VOID * pInBuffer, DWORD inSize, VOID * pOutBuffer, DWORD outSize, DWORD * pOutSize)
{
NKSetLastError (ERROR_NOT_SUPPORTED);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -