private void Emit_GHI(CdpInstruction inst) { EmitGeneralRegisterRead(inst.Low); EmitHighByte(); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private void Emit_SEX(CdpInstruction inst) { // MMM sex! EmitByteConstant(inst.Low); EmitRegisterWrite(SelectedRegister.X); // Sex X to point to a register EmitNop(); }
private void Emit_LDI(CdpInstruction inst) { byte val = GetNextOperand(); WriteDebug(" " + val.ToString("X1") + " "); EmitByteConstant(val); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private void Emit_LDN(CdpInstruction inst) { // Yeah baby!!! EmitLocal(typeof(ushort), false); EmitGeneralRegisterRead(inst.Low); EmitLocalStore(0); EmitReadMemory(GetResolvedLocal(0)); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private void Emit_LDX(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // Address [0] EmitCoreStateObject(); EmitRegisterRead(SelectedRegister.X); EmitGeneralRegisterReadFunc(); EmitLocalStore(0); EmitReadMemory(GetResolvedLocal(0)); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private void Emit_STR(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // address [0] EmitLocal(typeof(ushort), false); // value [1] EmitGeneralRegisterRead(inst.Low); EmitRegisterRead(SelectedRegister.D); EmitLocalStore(1); EmitLocalStore(0); EmitWriteMemory(GetResolvedLocal(0), GetResolvedLocal(1)); EmitNop(); }
private void Emit_DEC(CdpInstruction inst) { EmitLocal(typeof(ushort), false); EmitGeneralRegisterRead(inst.Low); EmitByteConstant(1); ILGenerator.Emit(OpCodes.Sub); EmitLocalStore(0); EmitCoreStateObject(); EmitByteConstant(inst.Low); EmitLocalLoad(0); EmitGeneralRegisterWriteFunc(); }
private void EmitSubOpcodes0(CdpInstruction inst) { if (inst.Low == 0) { WriteDebug(" IDL"); EmitNop(); // Set Idle mode, we don't bother with it } else { WriteDebug(" LDN (" + inst.Low.ToString("x") + ")"); Emit_LDN(inst); } }
private void Emit_LDA(CdpInstruction inst) { EmitLocal(typeof(ushort), false); EmitGeneralRegisterRead(inst.Low); EmitLocalStore(0); EmitReadMemory(GetResolvedLocal(0)); EmitRegisterWrite(SelectedRegister.D); EmitCoreStateObject(); EmitByteConstant(inst.Low); EmitUshortConstant(1); EmitGeneralRegisterRead(inst.Low); ILGenerator.Emit(OpCodes.Add); EmitGeneralRegisterWriteFunc(); EmitNop(); }
private void Emit_BNZ(CdpInstruction inst) { ushort address = (ushort)((CurrentAddress & 0xF00) | GetMemoryByte((ushort)(CurrentAddress++))); Label lb = GetLabel(address); // Compare D to 0 EmitRegisterRead(SelectedRegister.D); EmitByteConstant(0); ILGenerator.Emit(OpCodes.Ceq); EmitNop(); // Branch ILGenerator.Emit(OpCodes.Brfalse, lb); EmitNop(); }
private void Emit_ADCI(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // result [0] Label brOverflow = ILGenerator.DefineLabel(); Label brEnd = ILGenerator.DefineLabel(); // Store result of operand + D + DF EmitByteConstant(GetNextOperand()); EmitRegisterRead(SelectedRegister.DF); ILGenerator.Emit(OpCodes.Add); EmitRegisterRead(SelectedRegister.D); ILGenerator.Emit(OpCodes.Add); EmitLocalStore(0); // Compare result > 255 EmitLocalLoad(0); EmitUshortConstant(0xFF); ILGenerator.Emit(OpCodes.Cgt); // Branch path ILGenerator.Emit(OpCodes.Brtrue, brOverflow); // Not Greater Than EmitNop(); EmitByteConstant(0); EmitRegisterWrite(SelectedRegister.DF); EmitLocalLoad(0); EmitRegisterWrite(SelectedRegister.D); ILGenerator.Emit(OpCodes.Br_S, brEnd); //Else Greater Than ILGenerator.MarkLabel(brOverflow); EmitNop(); EmitByteConstant(1); EmitRegisterWrite(SelectedRegister.DF); EmitLocalLoad(0); EmitUshortConstant(0xFF); ILGenerator.Emit(OpCodes.And); ILGenerator.Emit(OpCodes.Conv_U1); EmitRegisterWrite(SelectedRegister.D); // End ILGenerator.MarkLabel(brEnd); EmitNop(); }
private void Emit_PLO(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // New reg value [0] EmitGeneralRegisterRead(inst.Low); EmitUshortConstant(0xFF00); ILGenerator.Emit(OpCodes.And); EmitRegisterRead(SelectedRegister.D); ILGenerator.Emit(OpCodes.Or); EmitLocalStore(0); EmitCoreStateObject(); EmitByteConstant(inst.Low); WriteDebug(" (write) R" + inst.Low.ToString("X1")); EmitLocalLoad(0); EmitGeneralRegisterWriteFunc(); }
private void EmitSubOpcodes7(CdpInstruction inst) { try { C1802OpCodesSub7 opcode = (C1802OpCodesSub7)inst.Low; WriteDebug(" " + opcode.ToString()); switch (opcode) { case C1802OpCodesSub7.ADCI: Emit_ADCI(inst); break; default: EmitNop(); WriteDebug(" ...No Emit!"); break; } } catch (ArgumentException) { return; } }
private void Emit_PHI(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // New reg value [0] EmitUshortConstant(0xFF); EmitGeneralRegisterRead(inst.Low); ILGenerator.Emit(OpCodes.And); EmitRegisterRead(SelectedRegister.D); ILGenerator.Emit(OpCodes.Conv_U2); ILGenerator.Emit(OpCodes.Ldc_I4_S, 8); ILGenerator.Emit(OpCodes.Shl); ILGenerator.Emit(OpCodes.Or); EmitLocalStore(0); EmitCoreStateObject(); EmitByteConstant(inst.Low); EmitLocalLoad(0); EmitGeneralRegisterWriteFunc(); }
private void EmitOpcodes() { bool end = false; ushort funcAddr = (ushort)CurrentAddress; if (funcAddr == m_DebugAddress && m_DebugDMA) { EimtMemoryDebug(true); } do { UpdateLocalOffsetBase(); SaveCurrentAddress(); CdpInstruction inst = GetInstruction((ushort)(CurrentAddress++)); try { C1802OpCodes opcode = (C1802OpCodes)inst.Hi; WriteDebug("\n1802 Opcode: " + opcode.ToString() + "(" + inst.Data.ToString("X2") + ")"); MarkLabel(); switch (opcode) { // All called routines must end with SEP pointing to R4! case C1802OpCodes.SEP: { if (inst.Low == 4) { end = true; break; } else { WriteDebug(" : Warning: code doesn't point to r4, value: " + inst.Low.ToString("X1") + "\n"); break; } } case C1802OpCodes.GLO: Emit_GLO(inst); break; case C1802OpCodes.SEX: Emit_SEX(inst); break; case C1802OpCodes.STR: Emit_STR(inst); break; case C1802OpCodes.LDA: Emit_LDA(inst); break; case C1802OpCodes.Sub15: EmitSubOpcodes15(inst); break; case C1802OpCodes.Sub0: EmitSubOpcodes0(inst); break; case C1802OpCodes.Sub7: EmitSubOpcodes7(inst); break; case C1802OpCodes.Sub3: EmitSubOpcodes3(inst); break; case C1802OpCodes.PLO: Emit_PLO(inst); break; case C1802OpCodes.INC: Emit_INC(inst); break; case C1802OpCodes.GHI: Emit_GHI(inst); break; case C1802OpCodes.PHI: Emit_PHI(inst); break; case C1802OpCodes.DEC: Emit_DEC(inst); break; default: EmitNop(); WriteDebug(" ...No Emit!"); break; } if (funcAddr == m_DebugAddress && m_DebugRegs) { EmitDumpRegsCall(); } } catch (ArgumentException) { end = true; continue; } }while (!end); if (funcAddr == m_DebugAddress && m_DebugDMA) { EimtMemoryDebug(false); } }
private void Emit_ADD(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // result [0] EmitLocal(typeof(ushort), false); // addr [1] Label brOverflow = ILGenerator.DefineLabel(); Label brEnd = ILGenerator.DefineLabel(); // Load reference of the codeEngine EmitCoreStateObject(); // Load X onto stack EmitRegisterRead(SelectedRegister.X); // Add (Memory Byte + D) EmitGeneralRegisterReadFunc(); EmitLocalStore(1); EmitReadMemory(GetResolvedLocal(1)); EmitRegisterRead(SelectedRegister.D); ILGenerator.Emit(OpCodes.Add); // Store result EmitLocalStore(0); // load result of math result > 255 EmitLocalLoad(0); EmitUshortConstant(0xFF); ILGenerator.Emit(OpCodes.Cgt); // If (math result > 255), goto brOverflow ILGenerator.Emit(OpCodes.Brtrue_S, brOverflow); EmitNop(); // else // Store math result in D EmitLocalLoad(0); ILGenerator.Emit(OpCodes.Conv_U1); // cast to byte EmitRegisterWrite(SelectedRegister.D); // Set DF carry flag to 0 ILGenerator.Emit(OpCodes.Ldc_I4_0); EmitRegisterWrite(SelectedRegister.DF); // Go to end of opcode code EmitNop(); ILGenerator.Emit(OpCodes.Br_S, brEnd); // Overflow path ILGenerator.MarkLabel(brOverflow); EmitNop(); // Set D to result & 0xFF EmitLocalLoad(0); EmitUshortConstant(0xFF); ILGenerator.Emit(OpCodes.And); ILGenerator.Emit(OpCodes.Conv_U1); // cast to byte EmitRegisterWrite(SelectedRegister.D); // Set DF carry flag to 1 ILGenerator.Emit(OpCodes.Ldc_I4_1); EmitRegisterWrite(SelectedRegister.DF); // End path ILGenerator.MarkLabel(brEnd); EmitNop(); }
private void Emit_BR(CdpInstruction inst) { // Lets just change the address to the another section of code and keep emitting CurrentAddress = (ushort)((CurrentAddress & 0xFF00) | GetMemoryByte((ushort)(CurrentAddress++))); }