|
|
// $Header: G:/SwDev/WDM/Video/bt848/rcs/Command.cpp 1.4 1998/04/29 22:43:30 tomz Exp $
#include "command.h"
#ifndef __PHYSADDR_H
#include "physaddr.h"
#endif
BYTE Command::InstrSize_ [] = { 2, 1, 1, 2, 2, 5, 2, 3, 0xFF };
BYTE Command::InstrNumber_ [] = { 8, 0, 1, 8, 8, 2, 8, 3, 4, 5, 6, 7 };
/* Method: Command::CreateCommand
* Purpose: Compiles an instruction based on the input * Input: lpDst: PVOID - pointer to the instruction * Instr: Instruction - opcode * awByteCnt: WORD [] - array of byte counts for various instructions * adwAddress: DWORD [] - array of addresses for various instructions * SOL: bool - value of the SOL bit * EOL: bool - value of the EOL bit * Intr: bool - value of the interrupt bit */ LPVOID Command::Create( LPVOID lpDst, Instruction Instr, WORD awByteCnt [], DWORD adwAddress [], bool, bool SOL, bool EOL, bool Intr ) { // this is to be retrieved later to set EOL bit when instructions are split
// due to the non-contiguous physical memory
pdwInstrAddr_ = (PDWORD)lpDst;
ThisInstr_ = Instr;
DWORD dwAssembly [5]; // maximum instruction size
// get pointer to the first dword of a command
LPFIRSTDWORD lpFD = (LPFIRSTDWORD)dwAssembly;
lpFD->Initer = 0; // virgin out the command
// bingo - started new command
lpFD->Gen.OpCode = Instr;
// set all the flags
lpFD->Gen.SOL = SOL; lpFD->Gen.EOL = EOL; lpFD->Gen.IRQ = Intr;
switch ( Instr ) { case WRIT: // this command needs target address and byte count
dwAssembly [1] = adwAddress [0]; // next DWORD is an address
lpFD->Gen.ByteCount = awByteCnt [0]; break; case SKIP: // these pair is interested in byte count only
case WRITEC: lpFD->Gen.ByteCount = awByteCnt [0]; break; case JUMP: // this command cares about target address only
dwAssembly [1] = adwAddress [0]; break; case SYNC: break; case WRITE123: // need everything here...
lpFD->Gen.ByteCount = awByteCnt [0]; LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCb = awByteCnt [1]; LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCr = awByteCnt [2]; dwAssembly [2] = adwAddress [0]; // third DWORD is an Y address
dwAssembly [3] = adwAddress [1]; // third DWORD is an Cb address
dwAssembly [4] = adwAddress [2]; // third DWORD is an Cr address
break; case SKIP123: lpFD->Gen.ByteCount = awByteCnt [0]; LPFIRSTDWORD( &dwAssembly [1] )->Gen.ByteCount = awByteCnt [1]; // second byte count is in DWORD #2
break; case WRITE1S23: // this command needs Y byte count and dest. address
lpFD->Gen.ByteCount = awByteCnt [0]; LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCb = awByteCnt [1]; LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCr = awByteCnt [2]; dwAssembly [2] = adwAddress [0]; // third DWORD is an address
break; default: return (LPVOID)-1; } RtlCopyMemory( lpDst, dwAssembly, GetInstrSize() * sizeof( DWORD ) ); PDWORD pdwRet = (PDWORD)lpDst + GetInstrSize(); *pdwRet = PROGRAM_TERMINATOR; return pdwRet; }
|