Mercurial > repos > blastem
diff analyze.py @ 6:b231162c8fdd
Add some logic analyzer captures, a Python script for analyzing said captures and a higher level analysis of the output
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 06 Nov 2012 01:57:36 -0800 |
parents | |
children | 006008a3f370 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/analyze.py Tue Nov 06 01:57:36 2012 -0800 @@ -0,0 +1,165 @@ +#!/usr/bin/env python + +#0 - !SE +#1 - !CAS +#2 - A0 +#3 - A1 +#------ +#4 - A2 +#5 - A3 +#6 - A7 +#7 - EDCLK +#------ +#8 - !HSYNC +#9 - A4 +#A - A5 +#B - A6 +#------ +#C - !RAS +#D - !WB/!WE +#E - !DT/!OE +#F - SC + + +#VRAM swizzling +#A0 = V0 +#A1 = V1 +#A8 = V2 +#A9 = V3 +#A10 = V4 +#A11 = V5 +#A12 = V6 +#A13 = V7 +#A14 = V8 +#A15 = V9 +#--guesses follow-- +#A2 = V10 +#A3 = V11 +#A4 = V12 +#A5 = V13 +#A6 = V14 +#A7 = V15 + + +def get_addr(sample): + return ((sample >> 2) & 0xF) | ((sample >> 5) & 0x70) | ((sample << 1) & 0x80) + +def swizzle_addr(addr): + return (addr & 0x0003) | ((addr >> 6) & 0x03FC) | ((addr << 8) & 0xFC00) + +def print_addr_op(addr, addr_format, mode, samplenum, triggerpos, rate): + print '{0:{1}} ({2:{1}}) {3}@{4} ns'.format(swizzle_addr(addr), addr_format, addr, mode, (samplenum - triggerpos)*rate) + +def detect_rise(last, sample, bit): + mask = 1 << bit + return (not last & mask) and (sample & mask) + +def detect_fall(last, sample, bit): + mask = 1 << bit + return (last & mask) and (not sample & mask) + +def detect_high(sample, bit): + mask = 1 << bit + return sample & mask + + +cas = 0x1 +ras = 0xC +edclk = 0x7 +hsync = 0x8 +wewb = 0xD +oedt = 0xE +sc = 0xF + +last = False +state = 'begin' +triggerpos = 0 +readcounter = 0 +sillyread = 0 +lastaddr = -1 +edclk_ticks = 0 +sc_ticks = 0 +tick_start = False +#f = open('street_fighter_vram_100mhz_hsync_trig_2.ols') +#f = open('street_fighter_vram_50mhz_hsync_trig.ols') +from sys import argv,exit +if len(argv) < 2: + print 'usage: analyze.py filename' + exit(1) +if '-b' in argv: + addr_format = '016b' +else: + addr_format = '04X' +f = open(argv[1]) +for line in f: + if line.startswith(';TriggerPosition'): + _,_,triggerpos = line.partition(':') + triggerpos = int(triggerpos.strip()) + elif line.startswith(';Rate'): + _,_,rate = line.partition(':') + #convert to nanoseconds between samples + rate = (1.0/float(rate.strip())) * 1000000000.0 + elif not line.startswith(';'): + sample,_,samplenum = line.partition('@') + samplenum = int(samplenum.strip()) + sample = int(sample, 16) + if detect_rise(last, sample, edclk): + edclk_ticks += 1 + if detect_rise(last, sample, sc): + sc_ticks += 1 + if not (last is False): + #detect falling edge of !HSYNC + if detect_fall(last, sample, hsync): + if readcounter: + print readcounter, 'reads,', sillyread, 'redundant reads' + readcounter = sillyread = 0 + if not tick_start is False: + float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0) + print 'EDCLK:', edclk_ticks, ' ticks, {0}MHz'.format(float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) + print 'SC:', sc_ticks, ' ticks, {0}MHz'.format(float(sc_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) + tick_start = samplenum + edclk_ticks = sc_ticks = 0 + print 'HSYNC Start' + #detect rising edge of !HSYNC + elif detect_rise(last, sample, hsync): + if not tick_start is False: + float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0) + print 'EDCLK:', edclk_ticks, ' ticks, {0}MHz'.format(float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) + print 'SC:', sc_ticks, ' ticks, {0}MHz'.format(float(sc_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) + tick_start = samplenum + edclk_ticks = sc_ticks = 0 + print 'HSYNC End' + if state == 'begin': + #detect falling edge of !RAS + if detect_fall(last, sample, ras): + state = 'ras' + row = get_addr(sample) + mode = 'ram' if detect_high(sample, oedt) else 'read transfer' + elif detect_fall(last, sample, cas): + state = 'cas' + elif state == 'ras': + if detect_fall(last, sample, cas): + state = 'begin' + col = get_addr(sample) + addr = (row << 8) | col + if mode == 'ram': + state = 'ras_cas' + else: + print_addr_op(addr, addr_format, mode, samplenum, triggerpos, rate) + lastaddr = addr + #print '{0:04X} {1} - {2:02X}:{3:02X} - {0:016b}'.format(addr, mode, row, col) + elif state == 'cas': + if detect_fall(last, sample, ras): + state = 'begin' + print 'refresh@{0} ns'.format((samplenum - triggerpos)*rate) + elif state == 'ras_cas': + if detect_fall(last, sample, oedt): + readcounter += 1 + if addr == lastaddr: + sillyread += 1 + print_addr_op(addr, addr_format, 'read', samplenum, triggerpos, rate) + state = 'begin' + elif detect_fall(last, sample, wewb): + print_addr_op(addr, addr_format, 'write', samplenum, triggerpos, rate) + state = 'begin' + last = sample