bradgrantham-apple2e/graph_cycles_before_new_insn.py
Brad Grantham 49f098f6dc Add counts and grapher for instruction progress
instructions_by_first_appearance_clock.csv is emitted from branch
"cpu_progression".  It contains the number of instructions processed
before the first time a particular instruction was encountered.

graph_cycles_before_new_insn.py emits an ASCII graph from that data,
linear or algorithmic depending on variable in the source.
2017-01-05 15:19:40 -08:00

185 lines
4.0 KiB
Python

import csv
import math
mnemonics = {
0x69: "ADC #oper",
0x65: "ADC oper",
0x75: "ADC oper,X",
0x6D: "ADC oper",
0x7D: "ADC oper,X",
0x79: "ADC oper,Y",
0x61: "ADC (oper,X)",
0x71: "ADC (oper),Y",
0x29: "AND #oper",
0x25: "AND oper",
0x35: "AND oper,X",
0x2D: "AND oper",
0x3D: "AND oper,X",
0x39: "AND oper,Y",
0x21: "AND (oper,X)",
0x31: "AND (oper),Y",
0x0A: "ASL A",
0x06: "ASL oper",
0x16: "ASL oper,X",
0x0E: "ASL oper",
0x1E: "ASL oper,X",
0x90: "BCC oper",
0xB0: "BCS oper",
0xF0: "BEQ oper",
0x24: "BIT oper",
0x2C: "BIT oper",
0x30: "BMI oper",
0xD0: "BNE oper",
0x10: "BPL oper",
0x00: "BRK",
0x50: "BVC oper",
0x70: "BVC oper",
0x18: "CLC",
0xD8: "CLD",
0x58: "CLI",
0xB8: "CLV",
0xC9: "CMP #oper",
0xC5: "CMP oper",
0xD5: "CMP oper,X",
0xCD: "CMP oper",
0xDD: "CMP oper,X",
0xD9: "CMP oper,Y",
0xC1: "CMP (oper,X)",
0xD1: "CMP (oper),Y",
0xE0: "CPX #oper",
0xE4: "CPX oper",
0xEC: "CPX oper",
0xC0: "CPY #oper",
0xC4: "CPY oper",
0xCC: "CPY oper",
0xC6: "DEC oper",
0xD6: "DEC oper,X",
0xCE: "DEC oper",
0xDE: "DEC oper,X",
0xCA: "DEC",
0x88: "DEC",
0x49: "EOR #oper",
0x45: "EOR oper",
0x55: "EOR oper,X",
0x4D: "EOR oper",
0x5D: "EOR oper,X",
0x59: "EOR oper,Y",
0x41: "EOR (oper,X)",
0x51: "EOR (oper),Y",
0xE6: "INC oper",
0xF6: "INC oper,X",
0xEE: "INC oper",
0xFE: "INC oper,X",
0xE8: "INX",
0xC8: "INY",
0x4C: "JMP oper",
0x6C: "JMP (oper)",
0x20: "JSR oper",
0xA9: "LDA #oper",
0xA5: "LDA oper",
0xB5: "LDA oper,X",
0xAD: "LDA oper",
0xBD: "LDA oper,X",
0xB9: "LDA oper,Y",
0xA1: "LDA (oper,X)",
0xB1: "LDA (oper),Y",
0xA2: "LDX #oper",
0xA6: "LDX oper",
0xB6: "LDX oper,Y",
0xAE: "LDX oper",
0xBE: "LDX oper,Y",
0xA0: "LDY #oper",
0xA4: "LDY oper",
0xB4: "LDY oper,X",
0xAC: "LDY oper",
0xBC: "LDY oper,X",
0x4A: "LSR A",
0x46: "LSR oper",
0x56: "LSR oper,X",
0x4E: "LSR oper",
0x5E: "LSR oper,X",
0xEA: "NOP",
0x09: "ORA #oper",
0x05: "ORA oper",
0x15: "ORA oper,X",
0x0D: "ORA oper",
0x1D: "ORA oper,X",
0x19: "ORA oper,Y",
0x01: "ORA (oper,X)",
0x11: "ORA (oper),Y",
0x48: "PHA",
0x08: "PHP",
0x68: "PLA",
0x28: "PHP",
0x2A: "ROL A",
0x26: "ROL oper",
0x36: "ROL oper,X",
0x2E: "ROL oper",
0x3E: "ROL oper,X",
0x6A: "ROR A",
0x66: "ROR oper",
0x76: "ROR oper,X",
0x6E: "ROR oper",
0x7E: "ROR oper,X",
0x40: "RTI",
0x60: "RTS",
0xE9: "SBC #oper",
0xE5: "SBC oper",
0xF5: "SBC oper,X",
0xED: "SBC oper",
0xFD: "SBC oper,X",
0xF9: "SBC oper,Y",
0xE1: "SBC (oper,X)",
0xF1: "SBC (oper),Y",
0x38: "SEC",
0xF8: "SED",
0x78: "SEI",
0x85: "STA oper",
0x95: "STA oper,X",
0x8D: "STA oper",
0x9D: "STA oper,X",
0x99: "STA oper,Y",
0x81: "STA (oper,X)",
0x91: "STA (oper),Y",
0x86: "STX oper",
0x96: "STX oper,Y",
0x8E: "STX oper",
0x84: "STY oper",
0x94: "STY oper,X",
0x8C: "STY oper",
0xAA: "TAX",
0xA8: "TAY",
0xBA: "TSX",
0x8A: "TXA",
0x9A: "TXS",
0x98: "TYA",
};
# 'a,'bs/ ..............\(.............\) \([0-9A-Z][0-9A-Z]\).*/0x\2: "\1",/
logarithmic = False
maxm = 0
insns = []
for (time, insn) in csv.reader(open("instructions_by_first_appearance_clock.csv")):
time = int(time)
insn = int("0x" + insn.strip(), 16)
insns.append((time, insn))
maxm = max(maxm, time)
width = 52
if logarithmic:
print "logarithmic chart"
maxm = math.log(maxm)
else:
print "linear chart"
maxm = 407 # XXX
for (time, insn) in insns:
if logarithmic:
bar = '*' * min(width, int(math.log(1 + time) * width / maxm))
else:
bar = '*' * min(width, int(time * width / maxm))
print "%02X %-14s %6d : %s" % (insn, '"%s"' % mnemonics[insn], time, bar)