public override void Prepare(SpanLocation memory) { Size = 1; OpCode = Bits.BottomFour(memory.Bytes[0]); Operation = OpCode switch { 0x00 => new Operation(nameof(RetTrue), RetTrue), 0x01 => new Operation(nameof(RetFalse), RetFalse), 0x02 => new Operation(nameof(Print), Print, hasText: true), 0x08 => new Operation(nameof(RetPopped), RetPopped), 0x0B => new Operation(nameof(NewLine), NewLine), _ => throw new InvalidOperationException($"Unknown OP0 opcode {OpCode:X}") }; if (Operation.HasText) { var decoded = textResolver.Decode(memory.Forward(1)); Size += decoded.BytesConsumed; Text = decoded.Text; } if (Operation.HasStore) { StoreResult = memory.Bytes[Size]; Size += 1; } if (Operation.HasBranch) { var branchData = machine.Memory.SpanAt(memory.Address + Size); Branch = branchResolver.ResolveBranch(branchData); Size += Branch.Size; } DumpToLog(memory, Size); }
public override void Prepare(SpanLocation memory) { operandResolver.AddOperands(Operands, memory.Bytes); Size = 1 + Operands.Size; OpCode = Bits.BottomFour(memory.Bytes[0]); Operation = OpCode switch { 0x00 => new Operation(nameof(JZ), JZ, hasBranch: true), 0x01 => new Operation(nameof(GetSibling), GetSibling, hasBranch: true, hasStore: true), 0x02 => new Operation(nameof(GetChild), GetChild, hasStore: true, hasBranch: true), 0x03 => new Operation(nameof(GetParent), GetParent, hasStore: true), 0x05 => new Operation(nameof(Inc), Inc), 0x06 => new Operation(nameof(Dec), Dec), 0x0A => new Operation(nameof(PrintObj), PrintObj), 0x0B => new Operation(nameof(Ret), Ret), 0x0C => new Operation(nameof(Jump), Jump), 0x0d => new Operation(nameof(PrintPaddr), PrintPaddr), _ => throw new InvalidOperationException($"Unknown OP1 opcode {OpCode:X}") }; if (Operation.HasStore) { StoreResult = memory.Bytes[Size]; Size += 1; } if (Operation.HasBranch) { var branchData = machine.Memory.SpanAt(memory.Address + Size); Branch = branchResolver.ResolveBranch(branchData); Size += Branch.Size; } DumpToLog(memory, Size); }
public override void Prepare(SpanLocation memory) { OpCode = Bits.BottomFive(memory.Bytes[0]); Operation = OpCode switch { 0x01 => new Operation(nameof(JE), JE, hasBranch: true), 0x02 => new Operation(nameof(JL), JL, hasBranch: true), 0x03 => new Operation(nameof(JG), JG, hasBranch: true), 0x04 => new Operation(nameof(DecChk), DecChk, hasBranch: true), 0x05 => new Operation(nameof(IncChk), IncChk, hasBranch: true), 0x06 => new Operation(nameof(Jin), Jin, hasBranch: true), 0x09 => new Operation(nameof(And), And, hasStore: true), 0x0A => new Operation(nameof(TestAttr), TestAttr, hasBranch: true), 0x0B => new Operation(nameof(SetAttr), SetAttr), 0x0D => new Operation(nameof(StoreB), StoreB), 0x0E => new Operation(nameof(InsertObj), InsertObj), 0x0F => new Operation(nameof(LoadW), LoadW, hasStore: true), 0x10 => new Operation(nameof(LoadB), LoadB, hasStore: true), 0x11 => new Operation(nameof(GetProp), GetProp, hasStore: true), 0x14 => new Operation(nameof(Add), Add, hasStore: true), 0x15 => new Operation(nameof(Sub), Sub, hasStore: true), _ => throw new InvalidOperationException($"Unknown OP2 opcode {OpCode:X}") }; if (OpCode == 0x05) { // 😒 seven Z-machine opcodes access variables but by their numbers ... // inc, dec, inc_chk, dec_chk, store, pull, load. 😒 indirectOperandResolver.AddOperands(Operands, memory.Bytes.Slice(1)); Size = 1 + Operands.Size; } else if (Bits.SevenSixSet(memory.Bytes[0]) == true && Bits.FiveSet(memory.Bytes[0]) == false) { // 😒 2OPS, but VAR operands 😒 varOperandResolver.AddOperands(Operands, memory.Bytes.Slice(1)); Size = 2 + Operands.Size; } else { op2OperandResolver.AddOperands(Operands, memory.Bytes); Size = 1 + Operands.Size; } if (Operation.HasStore) { StoreResult = memory.Bytes[Size]; Size += 1; } if (Operation.HasBranch) { var branchData = machine.Memory.SpanAt(memory.Address + Size); Branch = branchResolver.ResolveBranch(branchData); Size += Branch.Size; } DumpToLog(memory, Size); }