Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
3.2 KiB

  1. // $Header: G:/SwDev/WDM/Video/bt848/rcs/Command.cpp 1.4 1998/04/29 22:43:30 tomz Exp $
  2. #include "command.h"
  3. #ifndef __PHYSADDR_H
  4. #include "physaddr.h"
  5. #endif
  6. BYTE Command::InstrSize_ [] =
  7. {
  8. 2, 1, 1, 2, 2, 5, 2, 3, 0xFF
  9. };
  10. BYTE Command::InstrNumber_ [] =
  11. {
  12. 8, 0, 1, 8, 8, 2, 8, 3, 4, 5, 6, 7
  13. };
  14. /* Method: Command::CreateCommand
  15. * Purpose: Compiles an instruction based on the input
  16. * Input: lpDst: PVOID - pointer to the instruction
  17. * Instr: Instruction - opcode
  18. * awByteCnt: WORD [] - array of byte counts for various instructions
  19. * adwAddress: DWORD [] - array of addresses for various instructions
  20. * SOL: bool - value of the SOL bit
  21. * EOL: bool - value of the EOL bit
  22. * Intr: bool - value of the interrupt bit
  23. */
  24. LPVOID Command::Create(
  25. LPVOID lpDst, Instruction Instr, WORD awByteCnt [], DWORD adwAddress [],
  26. bool, bool SOL, bool EOL, bool Intr )
  27. {
  28. // this is to be retrieved later to set EOL bit when instructions are split
  29. // due to the non-contiguous physical memory
  30. pdwInstrAddr_ = (PDWORD)lpDst;
  31. ThisInstr_ = Instr;
  32. DWORD dwAssembly [5]; // maximum instruction size
  33. // get pointer to the first dword of a command
  34. LPFIRSTDWORD lpFD = (LPFIRSTDWORD)dwAssembly;
  35. lpFD->Initer = 0; // virgin out the command
  36. // bingo - started new command
  37. lpFD->Gen.OpCode = Instr;
  38. // set all the flags
  39. lpFD->Gen.SOL = SOL;
  40. lpFD->Gen.EOL = EOL;
  41. lpFD->Gen.IRQ = Intr;
  42. switch ( Instr ) {
  43. case WRIT: // this command needs target address and byte count
  44. dwAssembly [1] = adwAddress [0]; // next DWORD is an address
  45. lpFD->Gen.ByteCount = awByteCnt [0];
  46. break;
  47. case SKIP: // these pair is interested in byte count only
  48. case WRITEC:
  49. lpFD->Gen.ByteCount = awByteCnt [0];
  50. break;
  51. case JUMP: // this command cares about target address only
  52. dwAssembly [1] = adwAddress [0];
  53. break;
  54. case SYNC:
  55. break;
  56. case WRITE123: // need everything here...
  57. lpFD->Gen.ByteCount = awByteCnt [0];
  58. LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCb = awByteCnt [1];
  59. LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCr = awByteCnt [2];
  60. dwAssembly [2] = adwAddress [0]; // third DWORD is an Y address
  61. dwAssembly [3] = adwAddress [1]; // third DWORD is an Cb address
  62. dwAssembly [4] = adwAddress [2]; // third DWORD is an Cr address
  63. break;
  64. case SKIP123:
  65. lpFD->Gen.ByteCount = awByteCnt [0];
  66. LPFIRSTDWORD( &dwAssembly [1] )->Gen.ByteCount = awByteCnt [1]; // second byte count is in DWORD #2
  67. break;
  68. case WRITE1S23: // this command needs Y byte count and dest. address
  69. lpFD->Gen.ByteCount = awByteCnt [0];
  70. LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCb = awByteCnt [1];
  71. LPFIRSTDWORD( &dwAssembly [1] )->CRByteCounts.ByteCountCr = awByteCnt [2];
  72. dwAssembly [2] = adwAddress [0]; // third DWORD is an address
  73. break;
  74. default:
  75. return (LPVOID)-1;
  76. }
  77. RtlCopyMemory( lpDst, dwAssembly, GetInstrSize() * sizeof( DWORD ) );
  78. PDWORD pdwRet = (PDWORD)lpDst + GetInstrSize();
  79. *pdwRet = PROGRAM_TERMINATOR;
  80. return pdwRet;
  81. }