URL
https://opencores.org/ocsvn/s80186/s80186/trunk
Subversion Repositories s80186
[/] [s80186/] [trunk/] [scripts/] [debug] - Rev 2
Compare with Previous | Blame | View Log
#!/usr/bin/env python
# Copyright Jamie Iles, 2017
#
# This file is part of s80x86.
#
# s80x86 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.
#
# s80x86 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 s80x86. If not, see <http://www.gnu.org/licenses/>.
import cmd
from shlex import split
import distorm3
from py8086sim.Cpu import JTAGCPU, GPR, Flag
regdict = {
'AX': GPR.AX,
'CX': GPR.CX,
'DX': GPR.DX,
'BX': GPR.BX,
'SP': GPR.SP,
'BP': GPR.BP,
'SI': GPR.SI,
'DI': GPR.DI,
'ES': GPR.ES,
'CS': GPR.CS,
'SS': GPR.SS,
'DS': GPR.DS,
'IP': GPR.IP
}
class Debugger(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.c = JTAGCPU("debugger")
self._update_prompt()
def _update_prompt(self):
self.prompt = 'debug {0:04x}:{1:04x}> '.format(
self.c.read_reg(GPR.CS), self.c.read_reg(GPR.IP))
def do_reset(self, line):
'''Reset the CPU'''
self.c.reset()
self._update_prompt()
return False
def do_disassemble(self, line):
'''Disassemble the instruction at CS:IP'''
cs = self.c.read_reg(GPR.CS)
ip = self.c.read_reg(GPR.IP)
buf = [chr(self.c.read_mem8(cs, ip + i)) for i in xrange(15)]
instruction = distorm3.Decode(ip, ''.join(buf), distorm3.Decode16Bits)[0]
_, size, instruction, _ = instruction
hexbytes = ['{0:02x}'.format(ord(b)) for b in buf[:size]]
print('{0:s}\t{1:s}'.format(' '.join(hexbytes), instruction.lower()))
return False
def do_regs(self, line):
'''Display the CPU registers'''
regnames = ['AX', 'CX', 'DX', 'BX', 'SP', 'BP', 'SI', 'DI', 'ES',
'CS', 'SS', 'DS', 'IP']
for name in regnames:
print('{name}: {val:04x}'.format(name=name,
val=self.c.read_reg(GPR.names[name])))
flagnames = ['CF', 'PF', 'AF', 'ZF', 'SF', 'TF', 'IF', 'DF', 'OF']
flags = self.c.read_flags()
set_flags = filter(lambda x: flags & Flag.names[x], flagnames)
print('FLAGS: {0:04x} {1:s}'.format(self.c.read_flags(),
' '.join(set_flags)))
return False
def do_step(self, line):
'''Single step the CPU'''
self.c.step()
self._update_prompt()
return False
def do_write_reg(self, line):
'''Write a GPR
REG := VAL'''
tokens = split(line)
assert len(tokens) == 2
self.c.write_reg(regdict[tokens[0]], int(tokens[1], 16))
self._update_prompt()
return False
def do_in16(self, line):
'''Read a 16-bit IO port'''
tokens = split(line)
assert len(tokens) == 1
print('{0:04x}'.format(self.c.read_io16(int(tokens[0], 16))))
self._update_prompt()
return False
def do_out16(self, line):
'''Write a 16-bit IO port'''
tokens = split(line)
assert len(tokens) == 2
self.c.write_io16(int(tokens[0], 16), int(tokens[1], 16))
self._update_prompt()
return False
def do_in8(self, line):
'''Read a 8-bit IO port'''
tokens = split(line)
assert len(tokens) == 1
print('{0:04x}'.format(self.c.read_io8(int(tokens[0], 16))))
self._update_prompt()
return False
def do_out8(self, line):
'''Write a 8-bit IO port'''
tokens = split(line)
assert len(tokens) == 2
self.c.write_io8(int(tokens[0], 16), int(tokens[1], 16))
self._update_prompt()
return False
def do_w16(self, line):
'''Write a 16-bit value to memory'''
tokens = split(line)
assert len(tokens) == 2
seg, offset = tokens[0].split(':')
self.c.write_mem16(int(seg, 16), int(offset, 16), int(tokens[1], 16))
self._update_prompt()
return False
def do_r16(self, line):
'''Read a 16-bit value from memory'''
tokens = split(line)
assert len(tokens) == 1
seg, offset = tokens[0].split(':')
v = self.c.read_mem16(int(seg, 16), int(offset, 16))
print('{0:04x}'.format(v))
self._update_prompt()
return False
def do_EOF(self, line):
print('')
return True
Debugger().cmdloop()