import sys

import MOS6502
from disasm import disasm

def cpuInfo(cpu):
    lines = ''
    lines +=  "A: " + hex(cpu.GetRegister('A')) + "\t"
    lines +=  "X: " + hex(cpu.GetRegister('X')) + "\t"
    lines +=  "Y: " + hex(cpu.GetRegister('Y')) + "\n"
    lines +=  "S: " + hex(cpu.GetRegister('S')) + "\t"
    lines +=  "PC: " + hex(cpu.GetRegister('PC')) + "\t"
    if cpu.GetFlag('C') != 0: 
        lines += "C "
    if cpu.GetFlag('Z') != 0: 
        lines += "Z "
    if cpu.GetFlag('I') != 0: 
        lines += "I "
    if cpu.GetFlag('V') != 0: 
        lines += "V "
    if cpu.GetFlag('N') != 0: 
        lines += "N"

    return lines

def stepCPU(cpu):
    nextAddr = cpu.step()
    mem = cpu.GetMemory(nextAddr, 3)
    print hex(nextAddr) + " " + disasm(mem, 1)[0]

def getArg(cpu, argString):
    # if a register, get the value
    registers = {   
            'A': cpu.GetRegister('A'),
            'X': cpu.GetRegister('X'),
            'Y': cpu.GetRegister('Y'),
            'PC': cpu.GetRegister('PC'),
            'S': cpu.GetRegister('S') }
    for key in registers:
        if key in argString:
            return register[key]

    # if a length arg, remove the L and cast to hex int
    if argString[0] == 'L':
        return int(argString[1:-1], 16)

    # if a number, its always hex
    return int(argString, 16)


def handleCmd(cpu, cmdString):
    cmdList = cmdString.split()
    cmd = cmdList[0]

    if cmd == 'step' or cmd == 's':
        stepCPU(cpu)

    if cmd == 'i':
        print cpuInfo(cpu)

    if cmd == 'run' or cmd == 'r':
        cpu.runToBreak()

def debugLoop(cpu):
    cmd = ''
    while (1):
        sys.stdout.write("> ")
        lastCmd = cmd
        cmd = sys.stdin.readline().strip()
        if cmd == '':
            cmd = lastCmd
        if cmd == 'quit':
            return
        handleCmd(cpu, cmd)

cpu = MOS6502.CPU()
cpu.LoadRom("smb1.nes")
debugLoop(cpu)


@@ -3,16 +3,30 @@
 port sys
+%0Aimport struct
 %0A%0Aimport
@@ -1276,10 +1276,8 @@
 g%5B1:
--1
 %5D, 1
@@ -1345,16 +1345,1026 @@
 g, 16)%0A%0A
+def printMemLine(lineAddr, dataLine):%0A    sys.stdout.write(hex(lineAddr & 0xFFFF) + %22: %22)%0A    for byte in dataLine:%0A        sys.stdout.write(format(byte & 0xFF, '02x') + %22 %22)%0A    sys.stdout.write(%22%5Cn%22)%0A'''    %0A    sys.stdout.write(%22%5Ct %7C%22)%0A    for byte in dataLine:%0A        print byte%0A        sys.stdout.write(format(byte, 'c'))%0A    print %22%7C%22%0A'''%0A%0Adef displayMemory(cpu, cmdList):%0A    if len(cmdList) %3C 2:%0A        print %22display memory: d %3Caddress%3E %5Bopt: 'L'ength%5D%22%0A        return%0A%0A    lineLen = 0x10%0A    length = 0x40 # default length to show%0A    address = getArg(cpu, cmdList%5B1%5D)%0A    if len(cmdList) %3E 2:%0A        length = getArg(cpu, cmdList%5B2%5D)%0A%0A    index = 0%0A    while index %3C length:%0A        dataLine = %5B%5D%0A        lineAddr = address + index%0A        for i in range(0, lineLen):%0A            dataLine.append(cpu.ReadMemory(address + index))%0A            index += 1%0A            if index == length:%0A                printMemLine(lineAddr, dataLine)%0A                return%0A        printMemLine(lineAddr, dataLine)%0A
 %0Adef han
@@ -2561,19 +2561,18 @@
 cmd == '
-run
+go
 ' or cmd
@@ -2576,17 +2576,17 @@
 cmd == '
-r
+g
 ':%0A     
@@ -2606,16 +2606,94 @@
 reak()%0A%0A
+    if cmd == 'display' or cmd == 'd':%0A        displayMemory(cpu, cmdList)%0A%0A%0A%0A
 def debu

add display memory command