Coverage for MC6809/components/cpu6809_trace.py: 18%

43 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-06 19:50 +0100

1#!/usr/bin/env python 

2 

3""" 

4 MC6809 - 6809 CPU emulator in Python 

5 ======================================= 

6 

7 Create trace lines for every OP call. 

8 

9 :copyleft: 2014 by the MC6809 team, see AUTHORS for more details. 

10 :license: GNU GPL v3 or above, see LICENSE for more details. 

11""" 

12 

13 

14import logging 

15import sys 

16 

17from MC6809.components.cpu_utils.instruction_call import PrepagedInstructions 

18from MC6809.components.MC6809data.MC6809_data_utils import MC6809OP_DATA_DICT 

19 

20 

21log = logging.getLogger("DragonPy.cpu6809.trace") 

22 

23 

24class InstructionTrace(PrepagedInstructions): 

25 def __init__(self, *args, **kwargs): 

26 super().__init__(*args, **kwargs) 

27 self.cfg = self.cpu.cfg 

28 self.get_mem_info = self.cpu.cfg.mem_info.get_shortest 

29 

30 self.__origin_instr_func = self.instr_func 

31 self.instr_func = self.__call_instr_func 

32 

33# def __getattribute__(self, attr, *args, **kwargs): 

34# if attr not in ("__call", "cpu", "memory", "instr_func"): 

35# return InstructionTrace.__call 

36# print attr, args, kwargs 

37# return PrepagedInstructions.__getattribute__(self, attr, *args, **kwargs) 

38# 

39# def __call(self, func, *args, **kwargs): 

40# print func, args, kwargs 

41# raise 

42 

43 def __call_instr_func(self, opcode, *args, **kwargs): 

44 # call the op CPU code method 

45 result = self.__origin_instr_func(opcode, *args, **kwargs) 

46 

47 if opcode in (0x10, 0x11): 

48 log.debug("Skip PAGE 2 and PAGE 3 instruction in trace") 

49 return 

50 

51 op_code_data = MC6809OP_DATA_DICT[opcode] 

52 

53 op_address = self.cpu.last_op_address 

54 

55 ob_bytes = op_code_data["bytes"] 

56 

57 op_bytes = "".join( 

58 f"{value:02x}" 

59 for __, value in self.cpu.memory.iter_bytes(op_address, op_address + ob_bytes) 

60 ) 

61 

62 kwargs_info = [] 

63 if "register" in kwargs: 

64 kwargs_info.append(str(kwargs["register"])) 

65 if "ea" in kwargs: 

66 kwargs_info.append(f"ea:{kwargs['ea']:04x}") 

67 if "m" in kwargs: 

68 kwargs_info.append(f"m:{kwargs['m']:x}") 

69 

70 msg = "{op_address:04x}| {op_bytes:<11} {mnemonic:<7} {kwargs:<19} {cpu} | {cc} | {mem}\n".format( 

71 op_address=op_address, 

72 op_bytes=op_bytes, 

73 mnemonic=op_code_data["mnemonic"], 

74 kwargs=" ".join(kwargs_info), 

75 cpu=self.cpu.get_info, 

76 cc=self.cpu.get_cc_info(), 

77 mem=self.get_mem_info(op_address) 

78 ) 

79 sys.stdout.write(msg) 

80 

81 if not op_bytes.startswith(f"{opcode:02x}"): 

82 self.cpu.memory.print_dump(op_address, op_address + ob_bytes) 

83 self.cpu.memory.print_dump(op_address - 10, op_address + ob_bytes + 10) 

84 assert op_bytes.startswith(f"{opcode:02x}"), f"{op_bytes} doesn't start with {self.opcode:02x}" 

85 

86 return result 

87 

88 

89# ------------------------------------------------------------------------------ 

90 

91 

92def test_run(): 

93 import os 

94 import subprocess 

95 import sys 

96 cmd_args = [ 

97 sys.executable, 

98 os.path.join("..", "DragonPy_CLI.py"), 

99 # "--verbosity", " 1", # hardcode DEBUG ;) 

100 # "--verbosity", "10", # DEBUG 

101 # "--verbosity", "20", # INFO 

102 # "--verbosity", "30", # WARNING 

103 # "--verbosity", "40", # ERROR 

104 "--verbosity", "50", # CRITICAL/FATAL 

105 "--machine", "Dragon32", "run", 

106 # "--machine", "Vectrex", "run", 

107 # "--max_ops", "1", 

108 "--trace", 

109 ] 

110 print(f"Startup CLI with: {' '.join(cmd_args[1:])}") 

111 subprocess.Popen(cmd_args, cwd="..").wait() 

112 

113 

114if __name__ == "__main__": 

115 test_run()