Example #1
0
    public void ExecuteOne()
    {
        Cycle++;
        var opcodePos = Reg.ProgramCounter;
        var opcode    = (OpCode)_memory[Reg.ProgramCounter++];
        var action    = _opcodes[(int)opcode];

        if (action.Action == null)
        {
            throw new Exception($"Unknown opcode: ${(int)opcode:X} ({opcode}) at pos ${opcodePos:X} ({opcodePos})");
        }
        #region OPCODE_DEBUGGING
        CurrentExecutingOpcode           = new CurrentExecutingOpcodeStruct();
        CurrentExecutingOpcode.RegBefore = Reg;
        CurrentExecutingOpcode.PC        = (Word)opcodePos;
        CurrentExecutingOpcode.Opcode    = opcode;
        if (Reg.ProgramCounter < _memory.Length)
        {
            CurrentExecutingOpcode.B1 = _memory[Reg.ProgramCounter];
        }
        if (Reg.ProgramCounter + 1 < _memory.Length)
        {
            CurrentExecutingOpcode.B2 = _memory[Reg.ProgramCounter + 1];
        }
        #endregion

        try
        {
            action.Action.Invoke();
            DebugPrintOpcode(CurrentExecutingOpcode);
        }
        catch (Exception exception)
        {
            DebugPrintOpcode(CurrentExecutingOpcode);
            throw;
        }
    }
Example #2
0
    private void DebugPrintOpcode(CurrentExecutingOpcodeStruct ceo)
    {
        string addr;
        var    word = false;

        switch (ceo.MemoryAccessType)
        {
        case MemoryAccessType.None:
            addr = "".PadRight(10, ' ') + "; ";
            break;

        case MemoryAccessType.Immediate:
            addr = ("#" + ceo.Data.ToString("X2")).PadRight(10, ' ') + "; ";
            break;

        case MemoryAccessType.Abs:
            addr = ("$" + ceo.Address.ToString("X4")).PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            word = true;
            break;

        case MemoryAccessType.AbsX:
            addr = ("$" + ceo.Address.ToString("X4") + ",X").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            word = true;
            break;

        case MemoryAccessType.AbsY:
            addr = ("$" + ceo.Address.ToString("X4") + ",Y").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            word = true;
            break;

        case MemoryAccessType.Zpg:
            addr = ("$" + ceo.Address.ToString("X2")).PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            break;

        case MemoryAccessType.ZpgX:
            addr = ("$" + ceo.Address.ToString("X2") + ",X").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            break;

        case MemoryAccessType.ZpgY:
            addr = ("$" + ceo.Address.ToString("X2") + ",Y").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            break;

        case MemoryAccessType.Indirect:
            addr = ("($" + ceo.Address.ToString("X4") + ")").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            word = true;
            break;

        case MemoryAccessType.XIndirect:
            addr = ("($" + ceo.Address.ToString("X2") + ",X)").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            break;

        case MemoryAccessType.IndirectY:
            addr = ("($" + ceo.Address.ToString("X2") + "),Y").PadRight(10, ' ') + "; #" + ceo.Data.ToString("X2");
            break;

        default:
            addr = "[UNKNOWN]";
            break;
        }

        var str = ("$" + ceo.PC.ToString("X4")
                   + " " + (
                       ((int)ceo.Opcode).ToString("X2")
                       + (ceo.MemoryAccessType != MemoryAccessType.None ? " " + ceo.B1.ToString("X2") : "")
                       + (word ? " " + ceo.B2.ToString("X2") : "")
                       ).PadRight(9, ' ')
                   + _opcodeStr[(int)ceo.Opcode]
                   + " " + addr.PadRight(20, ' ')
                   )
                  + "A:" + Reg.A.ToString("X2") + (Reg.A != ceo.RegBefore.A ? "->" + ceo.RegBefore.A.ToString("X2") : "    ")
                  + " X:" + Reg.X.ToString("X2") + (Reg.X != ceo.RegBefore.X ? "->" + ceo.RegBefore.X.ToString("X2") : "    ")
                  + " Y:" + Reg.Y.ToString("X2") + (Reg.Y != ceo.RegBefore.Y ? "->" + ceo.RegBefore.Y.ToString("X2") : "    ")
                  + " SP:" + Reg.SP.ToString("X2") + (Reg.SP != ceo.RegBefore.SP ? "->" + ceo.RegBefore.SP.ToString("X2") : "    ")
                  + " "
                  + (Reg.Flag.N ? (Reg.Flag.N == ceo.RegBefore.Flag.N ? "N" : "n") : ".")
                  + (Reg.Flag.V ? (Reg.Flag.V == ceo.RegBefore.Flag.V ? "V" : "v") : ".")
                  + " "
                  + (Reg.Flag.B ? (Reg.Flag.B == ceo.RegBefore.Flag.B ? "B" : "b") : ".")
                  + (Reg.Flag.D ? (Reg.Flag.D == ceo.RegBefore.Flag.D ? "D" : "d") : ".")
                  + (Reg.Flag.I ? (Reg.Flag.I == ceo.RegBefore.Flag.I ? "I" : "i") : ".")
                  + (Reg.Flag.Z ? (Reg.Flag.Z == ceo.RegBefore.Flag.Z ? "Z" : "z") : ".")
                  + (Reg.Flag.C ? (Reg.Flag.C == ceo.RegBefore.Flag.C ? "C" : "c") : ".")
                  + " " + ceo.Opcode
        ;

        Trace.WriteLine(str);
    }