windows-nt/Source/XPSP1/NT/drivers/wdm/capture/mini/bt848/command.cpp
2020-09-26 16:20:57 +08:00

95 lines
3.1 KiB
C++

// $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;
}