## Copyright (C) 2016 Jeremiah Orians ## This file is part of stage0. ## ## stage0 is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## stage0 is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with stage0. If not, see . import subprocess import ctypes import re import sys, getopt vm = ctypes.CDLL('./libvm.so') vm.initialize_lilith.argtype = (ctypes.c_uint, ctypes.c_uint) vm.get_memory.argtype = ctypes.c_uint vm.get_memory.restype = ctypes.c_char_p vm.step_lilith.restype = ctypes.c_uint vm.set_register.argtype = (ctypes.c_uint, ctypes.c_uint) vm.set_memory.argtype = (ctypes.c_uint, ctypes.c_ubyte) vm.get_register.argtype = ctypes.c_uint vm.get_register.restype = ctypes.c_uint POSIX_MODE = False def Reset_lilith(): global Memory_Size if 0 <= Memory_Size < 1024: unit = 'Bytes' chunks = Memory_Size elif 1024 <= Memory_Size < (1024 * 1024): unit = 'KB' chunks = Memory_Size / 1024 elif (1024 * 1024) <= Memory_Size < (1024 * 1024 * 1024): unit = 'MB' chunks = Memory_Size / (1024 * 1024) else: unit = 'GB' chunks = Memory_Size / (1024 * 1024 * 1024) print("Current Memory Size is: " + str(chunks) + unit) vm.initialize_lilith(Memory_Size, POSIX_MODE) global Current_IP Current_IP = 0 global Watchpoints Watchpoints = {0} global ROM_Name size = vm.load_lilith(ctypes.create_string_buffer(ROM_Name.encode('ascii'))) print ("Size of loaded ROM image: " + str(size) + " bytes\n") if(POSIX_MODE): Set_Register(15, size) def Step_lilith(): global Current_IP Current_IP = vm.step_lilith() global Count Count = Count + 1 return def Set_Memory(address, value): vm.set_memory(address, value) return def Set_Register(register, value): vm.set_register(register, value) return def returnPage(): return get_header() + (vm.get_memory(Current_Page)).decode('utf-8') + get_spacer1() + get_registers(0) + get_registers(9) + get_spacer2() + get_Window_shortcut() + get_disassembled() + get_footer() hexlookup = { 0 : '0', 1 : '1', 2 : '2', 3 : '3', 4 : '4', 5 : '5', 6 : '6', 7 : '7', 8 : '8', 9 : '9', 10 : 'A', 11 : 'B', 12 : 'C', 13 : 'D', 14 : 'E', 15 : 'F' } def formatByte(a): first = a >> 4 second = a % 16 return str(hexlookup[first]+hexlookup[second]) def formatAddress(a): first = a >> 24 second = (a % 16777216) >> 16 third = (a % 65536) >> 8 fourth = a % 256 myreturn = formatByte(first) + formatByte(second) + formatByte(third) + formatByte(fourth) return myreturn[:-1] + "x" def formatRegister(a): first = a >> 24 second = (a % 16777216) >> 16 third = (a % 65536) >> 8 fourth = a % 256 return formatByte(first) + formatByte(second) + formatByte(third) + formatByte(fourth) def get_header(): return """ Knight CPU Debugger
""" def get_spacer1(): return """
Index 0 1 2 3 4 5 6 7 8 8 A B C D E F
""" def get_registers(index): temp = """ """ if (0 == index): for i in range(0,9): temp = temp + """" + "\n" else: for i in range(0,7): temp = temp + """" + "\n" temp = temp + """\n" temp = temp + """\n" return temp + """
Register Value Name
R""" + str(index + i) + "" + formatRegister(vm.get_register(index + i)) + "REG" + str(index + i) +"
R""" + str(index + i) + "" + formatRegister(vm.get_register(index + i)) + "REG" + str(index + i) +"
R16""" + formatRegister(vm.get_register(16)) + " PC
R17""" + formatRegister(vm.get_register(17)) + "Counter
""" def get_spacer2(): return """
""" def get_Window_shortcut(): return """
""" def get_disassembled(): Current_IP = vm.get_register(16) f = open('z_disassembled', "r") temp = """
""" for line in f: pieces = re.split(r'\t+', line) i = int(pieces[0], 16) if (i < Current_IP): temp = temp + "" elif (i == Current_IP): temp = temp + """\n" elif i in Watchpoints: temp = temp + """\n" else: temp = temp + "\n" f.close() return temp + "
""" + pieces[0] + "" + pieces[1] + "" + pieces[2] + "
""" + pieces[0] + "" + pieces[1] + "" + pieces[2] + "
" + pieces[0] + "" + pieces[1] + "" + pieces[2] + "
" def get_footer(): return """
""" def main(argv): global Debug_Point help_string = 'Knight.py --ROM=$NAME [--DEBUG=$NUMBER] [--WINDOW=$NUMBER] [--MEMORY=$SIZE]\n' try: opts, args = getopt.getopt(argv,"R:D:W:M:P:",["ROM=","DEBUG=","WINDOW=", "MEMORY=", "POSIX-MODE"]) except getopt.GetoptError: print (help_string) sys.exit(2) for opt, arg in opts: if opt == '-h': print (help_string) sys.exit() elif opt in ("-R", "--ROM"): global ROM_Name ROM_Name = arg elif opt in ("-D", "--DEBUG"): global Debug_Point Debug_Point = int(arg) elif opt in ("-W", "--WINDOW"): global Current_Page Current_Page = int(arg, 16) elif opt in ("-M", "--MEMORY"): global Memory_Size if arg.endswith('K'): Memory_Size = (int(arg[:-1]) * 1024) elif arg.endswith('M'): Memory_Size = (int(arg[:-1]) * 1024 * 1024) elif arg.endswith('G'): Memory_Size = (int(arg[:-1]) * 1024 * 1024 * 1024) elif opt in ("-P", "--POSIX-MODE"): global POSIX_MODE POSIX_MODE = True subprocess.call("./bin/dis " + ROM_Name + " >| z_disassembled", shell=True) Reset_lilith() Current_IP = 0 Memory_Size = 16 * 1024 Current_Page = 0 Watchpoints = {0} Count=0 Debug_Point = 0 ROM_Name = "rom"