95 lines
3.1 KiB
C++
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;
|
||
|
}
|
||
|
|