view cli.py @ 30:c0c2e99b6bb0

fixed negative rel8 address bug in assembler
author james <jb302@eecs.qmul.ac.uk>
date Tue, 15 Apr 2014 12:21:22 +0100
parents 83e80c2c489c
children 4411dee34085
line wrap: on
line source
#!/usr/bin/env python
# cli.py - a command line to control the emulator using
#          the debug control class

import struct
from StringIO import StringIO
from io import BytesIO
from subprocess import Popen, PIPE, STDOUT

from asm import asm
from dbg import dbg

syms = {
        'R0_0':0,
        'R1_0':1,
        'R2_0':2,
        'R3_0':3,
        'DPH':4,
        'SPH':5,
        'PCH':6,
        'TMPH':7,
        'R0_1':8,
        'R1_1':9,
        'R2_1':10,
        'R3_1':11,
        'DPL':12,
        'SPL':13,
        'PCL':14,
        'TMPL':15,
        'BS':0,
        'IE':1,
        'OV':2,
        'S':3,
        'P':4,
        'AC':5,
        'Z':6,
        'C':7
        }

emu = dbg.controller()
emu.Emu = Popen(['bin/emu'], stdout=PIPE, stdin=PIPE, stderr=PIPE)


# assemble and execute inline asm.
# bytecode is copied to where ever the PC is and then executed
def exc():
    
    while True:
        # file like objects for source and byte code
        code = StringIO()
        bytecode = BytesIO()
        
        # get the PC
        pch = struct.unpack('>B', emu.get_reg(syms['PCH']))[0]
        pcl = struct.unpack('>B', emu.get_reg(syms['PCL']))[0]
        
        # get user input
        c = raw_input()
        if c == 'exit':
            break
        code.write(c)
        
        try:
            # assemble and determine length bytes
            a, l = asm.first_pass(code)
            if l.keys() != []:
                print 'labels not yet supported in interpreter mode'
                continue
            bytecode = asm.second_pass(bytecode, a, l)    
            bytecode.seek(0)
            byte_array = bytearray(bytecode.read())
        except:
            print 'invalid instruction'
            continue
        
        print 'PC -> ', hex(pcl | (pch << 8)), [hex(b) for b in byte_array]
        # write to emu memory and execute
        emu.set_block(pch, pcl, byte_array)
        emu.step()

cmds = {
        'step':emu.step,
        'run':emu.run,
        'gr':emu.get_reg,
        'sr':emu.set_reg,
        'gf':emu.get_flag,
        'sf':emu.set_flag,
        'gb':emu.get_block,
        'sb':emu.set_block,
        'ga':emu.get_a,
        'gfs':emu.get_flags,
        'gir':emu.get_ir,
        }

if __name__ == '__main__':
    
    while True:
    
        inp = raw_input('> ').split()
        if inp == []:
            continue
        cmd = inp[0]
        args = []
    
        try:
            # deal with inline execution independently
            if cmd == 'exc':
                exc()
                continue

            # set block has unique argument syntax
            if cmd == 'sb':
                args.append(int(inp[1], 0))
                args.append(int(inp[2], 0))
                args.append([int(x, 0) for x in inp[3:]])
                cmds[cmd](*args)
                continue
                
            # decode args
            i = 0
            for word in inp[1:]:
                if word in syms.keys():
                    args.append(syms[word])
                # only arguments after 3 will be data for set block
                # this needs to be in a list
                else:
                    args.append(int(word, 0))
                i = i + 1
            
            resp = cmds[cmd](*args)
            if resp == None:
                continue
            else:
                print [hex(struct.unpack('>B', x)[0]) for x in resp]

        except Exception, e:
            print e
            print 'invalid command or argument syntax'
            continue