private static void Emit_SEX(CdpInstruction inst) { // MMM sex! EmitByteConstant(inst.Low); EmitRegisterWrite(SelectedRegister.X); // Sex X to point to a register EmitNop(); }
private static void Emit_GHI(CdpInstruction inst) { EmitGeneralRegisterRead(inst.Low); EmitHighByte(); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private static void Emit_LDN(CdpInstruction inst) { // Yeah baby!!! EmitLocal(typeof(ushort), false); EmitGeneralRegisterRead(inst.Low); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); EmitReadMemory(GetResolvedLocal(0)); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private static void Emit_STR(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // address [0] EmitLocal(typeof(ushort), false); // value [1] EmitGeneralRegisterRead(inst.Low); EmitRegisterRead(SelectedRegister.D); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(1)); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); EmitWriteMemory(GetResolvedLocal(0), GetResolvedLocal(1)); EmitNop(); }
private static void Emit_DEC(CdpInstruction inst) { EmitLocal(typeof(ushort), false); EmitGeneralRegisterRead(inst.Low); EmitByteConstant(1); s_ILGen.Emit(OpCodes.Sub); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); EmitCodeEngine(); EmitByteConstant(inst.Low); s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitGeneralRegisterWriteFunc(); }
private static void EmitSubOpcodes0(CdpInstruction inst) { if (inst.Low == 0) { Console.Write(" IDL"); EmitNop(); // Set Idle mode, we don't bother with it } else { Console.Write(" LDN (" + inst.Low.ToString("x") + ")"); Emit_LDN(inst); } }
private static void Emit_LDA(CdpInstruction inst) { EmitLocal(typeof(ushort), false); EmitGeneralRegisterRead(inst.Low); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); EmitReadMemory(GetResolvedLocal(0)); EmitRegisterWrite(SelectedRegister.D); EmitCodeEngine(); EmitByteConstant(inst.Low); EmitUshortConstant(1); EmitGeneralRegisterRead(inst.Low); s_ILGen.Emit(OpCodes.Add); EmitGeneralRegisterWriteFunc(); EmitNop(); }
private static void Emit_BNZ(CdpInstruction inst) { ushort address = Tools.Create16(inst.Hi, GetMemoryByte(s_CurrentAddress++)); Label lb = GetLabel(address); // Compare D to 0 EmitRegisterRead(SelectedRegister.D); EmitByteConstant(0); s_ILGen.Emit(OpCodes.Ceq); EmitNop(); // Branch s_ILGen.Emit(OpCodes.Brfalse, lb); EmitNop(); }
private static void Emit_PLO(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // New reg value [0] EmitGeneralRegisterRead(inst.Low); EmitUshortConstant(0xFF00); s_ILGen.Emit(OpCodes.And); EmitRegisterRead(SelectedRegister.D); s_ILGen.Emit(OpCodes.Or); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); EmitCodeEngine(); EmitByteConstant(inst.Low); s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitGeneralRegisterWriteFunc(); }
private static void Emit_ADCI(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // result [0] Label brOverflow = s_ILGen.DefineLabel(); Label brEnd = s_ILGen.DefineLabel(); // Store result of operand + D + DF EmitByteConstant(GetNextOperand()); EmitRegisterRead(SelectedRegister.DF); s_ILGen.Emit(OpCodes.Add); EmitRegisterRead(SelectedRegister.D); s_ILGen.Emit(OpCodes.Add); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); // Compare result > 255 s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitUshortConstant(0xFF); s_ILGen.Emit(OpCodes.Cgt); // Branch path s_ILGen.Emit(OpCodes.Brtrue, brOverflow); // Not Greater Than EmitNop(); EmitByteConstant(0); EmitRegisterWrite(SelectedRegister.DF); s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitRegisterWrite(SelectedRegister.D); s_ILGen.Emit(OpCodes.Br_S, brEnd); //Else Greater Than s_ILGen.MarkLabel(brOverflow); EmitNop(); EmitByteConstant(1); EmitRegisterWrite(SelectedRegister.DF); s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitUshortConstant(0xFF); s_ILGen.Emit(OpCodes.And); s_ILGen.Emit(OpCodes.Conv_U1); EmitRegisterWrite(SelectedRegister.D); // End s_ILGen.MarkLabel(brEnd); EmitNop(); }
private static void EmitSubOpcodes7(CdpInstruction inst) { try { C1802OpCodesSub7 opcode = (C1802OpCodesSub7)inst.Low; Console.Write(" " + opcode.ToString()); switch (opcode) { case C1802OpCodesSub7.ADCI: Emit_ADCI(inst); break; default: EmitNop(); Console.Write(" ...No Emit!"); break; } } catch (ArgumentException) { return; } }
private static void Emit_BR(CdpInstruction inst) { // Lets just change the address to the another section of code and keep emitting s_CurrentAddress = (ushort)((s_CurrentAddress & 0xFF00) | GetMemoryByte(s_CurrentAddress++)); }
private static void Emit_LDI(CdpInstruction inst) { EmitByteConstant(GetNextOperand()); EmitRegisterWrite(SelectedRegister.D); EmitNop(); }
private static void Emit_ADD(CdpInstruction inst) { EmitLocal(typeof(ushort), false); // result [0] EmitLocal(typeof(ushort), false); // addr [1] Label brOverflow = s_ILGen.DefineLabel(); Label brEnd = s_ILGen.DefineLabel(); // Load reference of the codeEngine EmitCodeEngine(); // Load X onto stack EmitRegisterRead(SelectedRegister.X); // Add (Memory Byte + D) EmitGeneralRegisterReadFunc(); s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(1)); EmitReadMemory(GetResolvedLocal(1)); EmitRegisterRead(SelectedRegister.D); s_ILGen.Emit(OpCodes.Add); // Store result s_ILGen.Emit(OpCodes.Stloc_S, GetResolvedLocal(0)); // load result of math result > 255 s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitUshortConstant(0xFF); s_ILGen.Emit(OpCodes.Cgt); // If (math result > 255), goto brOverflow s_ILGen.Emit(OpCodes.Brtrue_S, brOverflow); EmitNop(); // else // Store math result in D s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); s_ILGen.Emit(OpCodes.Conv_U1); // cast to byte EmitRegisterWrite(SelectedRegister.D); // Set DF carry flag to 0 s_ILGen.Emit(OpCodes.Ldc_I4_0); EmitRegisterWrite(SelectedRegister.DF); // Go to end of opcode code EmitNop(); s_ILGen.Emit(OpCodes.Br_S, brEnd); // Overflow path s_ILGen.MarkLabel(brOverflow); EmitNop(); // Set D to result & 0xFF s_ILGen.Emit(OpCodes.Ldloc_S, GetResolvedLocal(0)); EmitUshortConstant(0xFF); s_ILGen.Emit(OpCodes.And); s_ILGen.Emit(OpCodes.Conv_U1); // cast to byte EmitRegisterWrite(SelectedRegister.D); // Set DF carry flag to 1 s_ILGen.Emit(OpCodes.Ldc_I4_1); EmitRegisterWrite(SelectedRegister.DF); // End path s_ILGen.MarkLabel(brEnd); EmitNop(); }
private static void EmitOpcodes() { bool end = false; s_Labels = new Dictionary <ushort, Label>(); ushort funcAddr = s_CurrentAddress; do { s_LocalOffset = s_LocalCount; s_LastAddress = s_CurrentAddress; CdpInstruction inst = GetInstruction(s_CurrentAddress++); try { C1802OpCodes opcode = (C1802OpCodes)inst.Hi; Console.Write("1802 Opcode: " + opcode.ToString()); Label lb = s_ILGen.DefineLabel(); s_ILGen.MarkLabel(lb); s_Labels.Add(s_LastAddress, lb); switch (opcode) { case C1802OpCodes.GLO: Emit_GLO(inst); break; case C1802OpCodes.SEX: Emit_SEX(inst); break; case C1802OpCodes.STR: Emit_STR(inst); break; case C1802OpCodes.SEP: end = true; 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(); Console.Write(" ...No Emit!"); break; } Console.WriteLine(""); //if (funcAddr == 0x3f3) // EmitDumpRegsCall(); } catch (ArgumentException) { end = true; continue; } }while (!end); s_Labels.Clear(); }