User_Interface.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. ## Copyright (C) 2016 Jeremiah Orians
  2. ## This file is part of stage0.
  3. ##
  4. ## stage0 is free software: you can redistribute it and/or modify
  5. ## it under the terms of the GNU General Public License as published by
  6. ## the Free Software Foundation, either version 3 of the License, or
  7. ## (at your option) any later version.
  8. ##
  9. ## stage0 is distributed in the hope that it will be useful,
  10. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ## GNU General Public License for more details.
  13. ##
  14. ## You should have received a copy of the GNU General Public License
  15. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
  16. import subprocess
  17. import ctypes
  18. import re
  19. import sys, getopt
  20. vm = ctypes.CDLL('./libvm.so')
  21. vm.initialize_lilith.argtype = (ctypes.c_uint, ctypes.c_uint)
  22. vm.get_memory.argtype = ctypes.c_uint
  23. vm.get_memory.restype = ctypes.c_char_p
  24. vm.step_lilith.restype = ctypes.c_uint
  25. vm.set_register.argtype = (ctypes.c_uint, ctypes.c_uint)
  26. vm.set_memory.argtype = (ctypes.c_uint, ctypes.c_ubyte)
  27. vm.get_register.argtype = ctypes.c_uint
  28. vm.get_register.restype = ctypes.c_uint
  29. POSIX_MODE = False
  30. def Reset_lilith():
  31. global Memory_Size
  32. if 0 <= Memory_Size < 1024:
  33. unit = 'Bytes'
  34. chunks = Memory_Size
  35. elif 1024 <= Memory_Size < (1024 * 1024):
  36. unit = 'KB'
  37. chunks = Memory_Size / 1024
  38. elif (1024 * 1024) <= Memory_Size < (1024 * 1024 * 1024):
  39. unit = 'MB'
  40. chunks = Memory_Size / (1024 * 1024)
  41. else:
  42. unit = 'GB'
  43. chunks = Memory_Size / (1024 * 1024 * 1024)
  44. print("Current Memory Size is: " + str(chunks) + unit)
  45. vm.initialize_lilith(Memory_Size, POSIX_MODE)
  46. global Current_IP
  47. Current_IP = 0
  48. global Watchpoints
  49. Watchpoints = {0}
  50. global ROM_Name
  51. size = vm.load_lilith(ctypes.create_string_buffer(ROM_Name.encode('ascii')))
  52. print ("Size of loaded ROM image: " + str(size) + " bytes\n")
  53. if(POSIX_MODE):
  54. Set_Register(15, size)
  55. def Step_lilith():
  56. global Current_IP
  57. Current_IP = vm.step_lilith()
  58. global Count
  59. Count = Count + 1
  60. return
  61. def Set_Memory(address, value):
  62. vm.set_memory(address, value)
  63. return
  64. def Set_Register(register, value):
  65. vm.set_register(register, value)
  66. return
  67. def returnPage():
  68. 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()
  69. 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' }
  70. def formatByte(a):
  71. first = a >> 4
  72. second = a % 16
  73. return str(hexlookup[first]+hexlookup[second])
  74. def formatAddress(a):
  75. first = a >> 24
  76. second = (a % 16777216) >> 16
  77. third = (a % 65536) >> 8
  78. fourth = a % 256
  79. myreturn = formatByte(first) + formatByte(second) + formatByte(third) + formatByte(fourth)
  80. return myreturn[:-1] + "x"
  81. def formatRegister(a):
  82. first = a >> 24
  83. second = (a % 16777216) >> 16
  84. third = (a % 65536) >> 8
  85. fourth = a % 256
  86. return formatByte(first) + formatByte(second) + formatByte(third) + formatByte(fourth)
  87. def get_header():
  88. return """
  89. <!DOCTYPE html>
  90. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  91. <head>
  92. <meta charset="utf-8" />
  93. <title>Knight CPU Debugger</title>
  94. <link rel="stylesheet" type="text/css" href="static/style.css" />
  95. <script type="text/javascript" src="static/jquery-1.8.3.js"> </script>
  96. <script type="text/javascript" src="static/script.js"></script>
  97. </head>
  98. <body>
  99. <div>
  100. <a href="RUN"><button type="button">RUN</button></a>
  101. <a href="STOP"><button type="button">STOP</button></a>
  102. <a href="PAGEDOWN"><button type="button">PAGE DOWN</button></a>
  103. <a href="PAGEUP"><button type="button">PAGE UP</button></a>
  104. <a href="STEP"><button type="button">STEP</button></a>
  105. <a href="RESET"><button type="button">RESET</button></a>
  106. <a href="SPEEDBREAKPOINT"><button type="button">Run Until Breakpoint</button></a>
  107. </div>
  108. <div>
  109. <div style="height:230px; width:60%; float:left; overflow-y: scroll;">
  110. <table class="Memory">
  111. <thead>
  112. <tr>
  113. <th>Index</th>
  114. <th>0</th>
  115. <th>1</th>
  116. <th>2</th>
  117. <th>3</th>
  118. <th>4</th>
  119. <th>5</th>
  120. <th>6</th>
  121. <th>7</th>
  122. <th>8</th>
  123. <th>8</th>
  124. <th>A</th>
  125. <th>B</th>
  126. <th>C</th>
  127. <th>D</th>
  128. <th>E</th>
  129. <th>F</th>
  130. </tr>
  131. </thead>
  132. <tbody>"""
  133. def get_spacer1():
  134. return """ </tbody>
  135. </table>
  136. </div>
  137. <div>
  138. """
  139. def get_registers(index):
  140. temp = """ <table class="Registers">
  141. <thead>
  142. <tr>
  143. <th>Register</th>
  144. <th>Value</th>
  145. <th>Name</th>
  146. </tr>
  147. </thead>
  148. <tbody>"""
  149. if (0 == index):
  150. for i in range(0,9):
  151. temp = temp + """<tr><td>R""" + str(index + i) + "</td><td>" + formatRegister(vm.get_register(index + i)) + "</td>" + "<td>REG" + str(index + i) +"</tr>\n"
  152. else:
  153. for i in range(0,7):
  154. temp = temp + """<tr><td>R""" + str(index + i) + "</td><td>" + formatRegister(vm.get_register(index + i)) + "</td>" + "<td>REG" + str(index + i) +"</tr>\n"
  155. temp = temp + """<tr><td>R16</td><td>""" + formatRegister(vm.get_register(16)) + "</td><td> PC </td></tr>\n"
  156. temp = temp + """<tr><td>R17</td><td>""" + formatRegister(vm.get_register(17)) + "</td><td>Counter</td></tr>\n"
  157. return temp + """ </tbody>
  158. </table> """
  159. def get_spacer2():
  160. return """
  161. </div>
  162. </div>
  163. """
  164. def get_Window_shortcut():
  165. return """
  166. <form action="WINDOW" style="position:absolute; left:10px; top:260px;">
  167. <input type="submit" value="Window Fast Move"> <input type="text" name="Window">
  168. </form>
  169. """
  170. def get_disassembled():
  171. Current_IP = vm.get_register(16)
  172. f = open('z_disassembled', "r")
  173. temp = """ <div style="position:absolute; left:10px; top:280px; overflow-y: scroll; height:200px; width:60%;">
  174. <table class="Debug"><tbody>"""
  175. for line in f:
  176. pieces = re.split(r'\t+', line)
  177. i = int(pieces[0], 16)
  178. if (i < Current_IP):
  179. temp = temp + ""
  180. elif (i == Current_IP):
  181. temp = temp + """<tr class="current"><td>""" + pieces[0] + "</td><td>" + pieces[1] + "</td><td>" + pieces[2] + "</td></tr>\n"
  182. elif i in Watchpoints:
  183. temp = temp + """<tr class="breakpoint"><td>""" + pieces[0] + "</td><td>" + pieces[1] + "</td><td>" + pieces[2] + "</td></tr>\n"
  184. else:
  185. temp = temp + "<tr><td>" + pieces[0] + "</td><td>" + pieces[1] + "</td><td>" + pieces[2] + "</td></tr>\n"
  186. f.close()
  187. return temp + "</tbody></table>"
  188. def get_footer():
  189. return """
  190. </div>
  191. </body>
  192. </html>
  193. """
  194. def main(argv):
  195. global Debug_Point
  196. help_string = 'Knight.py --ROM=$NAME [--DEBUG=$NUMBER] [--WINDOW=$NUMBER] [--MEMORY=$SIZE]\n'
  197. try:
  198. opts, args = getopt.getopt(argv,"R:D:W:M:P:",["ROM=","DEBUG=","WINDOW=", "MEMORY=", "POSIX-MODE"])
  199. except getopt.GetoptError:
  200. print (help_string)
  201. sys.exit(2)
  202. for opt, arg in opts:
  203. if opt == '-h':
  204. print (help_string)
  205. sys.exit()
  206. elif opt in ("-R", "--ROM"):
  207. global ROM_Name
  208. ROM_Name = arg
  209. elif opt in ("-D", "--DEBUG"):
  210. global Debug_Point
  211. Debug_Point = int(arg)
  212. elif opt in ("-W", "--WINDOW"):
  213. global Current_Page
  214. Current_Page = int(arg, 16)
  215. elif opt in ("-M", "--MEMORY"):
  216. global Memory_Size
  217. if arg.endswith('K'):
  218. Memory_Size = (int(arg[:-1]) * 1024)
  219. elif arg.endswith('M'):
  220. Memory_Size = (int(arg[:-1]) * 1024 * 1024)
  221. elif arg.endswith('G'):
  222. Memory_Size = (int(arg[:-1]) * 1024 * 1024 * 1024)
  223. elif opt in ("-P", "--POSIX-MODE"):
  224. global POSIX_MODE
  225. POSIX_MODE = True
  226. subprocess.call("./bin/dis " + ROM_Name + " >| z_disassembled", shell=True)
  227. Reset_lilith()
  228. Current_IP = 0
  229. Memory_Size = 16 * 1024
  230. Current_Page = 0
  231. Watchpoints = {0}
  232. Count=0
  233. Debug_Point = 0
  234. ROM_Name = "rom"