/// <summary> /// The start of each decode process resets all of the member variables /// to default values /// </summary> protected virtual void Reset() { m_opcodeType = ZMachine.Common.OpcodeType.UNKNOWN; m_operandCount = 0; m_operands = new short[8]; m_rawoperands = new short[8]; m_operandTypes = new ZMachine.Common.OperandType[8]; m_length = 0; m_vartype = -1; m_branch = 0; m_offset = 0; }
protected virtual void DecodeVARVAR(byte instruct) { // VAR VAR m_opcodeType = ZMachine.Common.OpcodeType.OP_VAR; if (instruct == 0xec || instruct == 0xfa) { m_vartype = m_memory.GetWord(PC); PC += 2; } else { // Make the single byte into a full word so that coding // is easier. The LSB of the word needs to be 0xFF m_vartype = (m_memory.GetByte(PC++) << 8) | 0xff; } // Mask the opcode to strip off operand type bits // Plus, opcode C1 is actually a OP2, not a OPVAR if (instruct == 0xC1) { m_opcodeType = ZMachine.Common.OpcodeType.OP_2; m_opcode = 1; } else { m_opcode = (byte)(instruct & 0x1F); } // Decode each bitpair of the vartype word to determine the // operand types. If a 11b is encountered, then there are // no more operands. for (int t = 0; t < 8; t++) { bool EOF = false; switch ((m_vartype >> ((7 - t) * 2)) & 0x03) { case 0x00: // Long constant FetchLongConstantOperand(); break; case 0x01: // Small constant FetchSmallConstantOperand(); break; case 0x02: // Variable FetchVariableOperand(); break; case 0x03: // End of variables; EOF = true; break; } if (EOF) break; m_operandCount++; } }
protected virtual void DecodeVAR2OP(byte instruct) { // VAR 2OP m_opcodeType = ZMachine.Common.OpcodeType.OP_2; m_vartype = m_memory.GetByte(PC++); if ((m_vartype & 0xC0) == 0x00) { // Operand 1 is a long constant FetchLongConstantOperand(); } else if ((m_vartype & 0xC0) == 0x40) { // Operand 1 is a small constant FetchSmallConstantOperand(); } else if ((m_vartype & 0xC0) == 0x80) { // Operand 1 is a variable FetchVariableOperand(); } m_operandCount++; if ((m_vartype & 0x30) == 0x00) { // Operand 2 is a long constant FetchLongConstantOperand(); } else if ((m_vartype & 0x30) == 0x10) { // Operand 2 is a small constant FetchSmallConstantOperand(); } else if ((m_vartype & 0x30) == 0x20) { // Operand 2 is a variable FetchVariableOperand(); } m_operandCount++; // Mask the opcode to strip off operand type bits m_opcode = (byte)(instruct & 0x1F); }
protected virtual void Decode2OP(byte instruct) { // This is a 2OP m_opcodeType = ZMachine.Common.OpcodeType.OP_2; if ((instruct & 0x40) == 0x40) { // Operand 1 is a variable FetchVariableOperand(); } else { // Operand 1 is a constant FetchSmallConstantOperand(); } m_operandCount++; if ((instruct & 0x20) == 0x20) { // Operand 2 is a variable FetchVariableOperand(); } else { // Operand 2 is a constant FetchSmallConstantOperand(); } m_operandCount++; // Mask the opcode to strip off operand type bits m_opcode = (byte)(instruct & 0x1F); }
protected virtual void Decode1OP(byte instruct) { // 1OP m_opcodeType = ZMachine.Common.OpcodeType.OP_1; if ((instruct & 0x30) == 0x00) { // Operand 1 is a long constant FetchLongConstantOperand(); } else if ((instruct & 0x30) == 0x10) { // Operand 1 is a small constant FetchSmallConstantOperand(); } else if ((instruct & 0x30) == 0x20) { // Operand 1 is a variable FetchVariableOperand(); } m_operandCount++; // Mask the opcode to strip off operand type bits m_opcode = (byte)(instruct & 0x0F); }
protected virtual void Decode0OP(byte instruct) { // 0OP (no operands) m_opcodeType = ZMachine.Common.OpcodeType.OP_0; // Mask the opcode to strip off operand type bits m_opcode = (byte)(instruct & 0x0F); }