Mercurial > repos > blastem
comparison 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 |
comparison
equal
deleted
inserted
replaced
4:6f6a2d7cc889 | 6:b231162c8fdd |
---|---|
1 #!/usr/bin/env python | |
2 | |
3 #0 - !SE | |
4 #1 - !CAS | |
5 #2 - A0 | |
6 #3 - A1 | |
7 #------ | |
8 #4 - A2 | |
9 #5 - A3 | |
10 #6 - A7 | |
11 #7 - EDCLK | |
12 #------ | |
13 #8 - !HSYNC | |
14 #9 - A4 | |
15 #A - A5 | |
16 #B - A6 | |
17 #------ | |
18 #C - !RAS | |
19 #D - !WB/!WE | |
20 #E - !DT/!OE | |
21 #F - SC | |
22 | |
23 | |
24 #VRAM swizzling | |
25 #A0 = V0 | |
26 #A1 = V1 | |
27 #A8 = V2 | |
28 #A9 = V3 | |
29 #A10 = V4 | |
30 #A11 = V5 | |
31 #A12 = V6 | |
32 #A13 = V7 | |
33 #A14 = V8 | |
34 #A15 = V9 | |
35 #--guesses follow-- | |
36 #A2 = V10 | |
37 #A3 = V11 | |
38 #A4 = V12 | |
39 #A5 = V13 | |
40 #A6 = V14 | |
41 #A7 = V15 | |
42 | |
43 | |
44 def get_addr(sample): | |
45 return ((sample >> 2) & 0xF) | ((sample >> 5) & 0x70) | ((sample << 1) & 0x80) | |
46 | |
47 def swizzle_addr(addr): | |
48 return (addr & 0x0003) | ((addr >> 6) & 0x03FC) | ((addr << 8) & 0xFC00) | |
49 | |
50 def print_addr_op(addr, addr_format, mode, samplenum, triggerpos, rate): | |
51 print '{0:{1}} ({2:{1}}) {3}@{4} ns'.format(swizzle_addr(addr), addr_format, addr, mode, (samplenum - triggerpos)*rate) | |
52 | |
53 def detect_rise(last, sample, bit): | |
54 mask = 1 << bit | |
55 return (not last & mask) and (sample & mask) | |
56 | |
57 def detect_fall(last, sample, bit): | |
58 mask = 1 << bit | |
59 return (last & mask) and (not sample & mask) | |
60 | |
61 def detect_high(sample, bit): | |
62 mask = 1 << bit | |
63 return sample & mask | |
64 | |
65 | |
66 cas = 0x1 | |
67 ras = 0xC | |
68 edclk = 0x7 | |
69 hsync = 0x8 | |
70 wewb = 0xD | |
71 oedt = 0xE | |
72 sc = 0xF | |
73 | |
74 last = False | |
75 state = 'begin' | |
76 triggerpos = 0 | |
77 readcounter = 0 | |
78 sillyread = 0 | |
79 lastaddr = -1 | |
80 edclk_ticks = 0 | |
81 sc_ticks = 0 | |
82 tick_start = False | |
83 #f = open('street_fighter_vram_100mhz_hsync_trig_2.ols') | |
84 #f = open('street_fighter_vram_50mhz_hsync_trig.ols') | |
85 from sys import argv,exit | |
86 if len(argv) < 2: | |
87 print 'usage: analyze.py filename' | |
88 exit(1) | |
89 if '-b' in argv: | |
90 addr_format = '016b' | |
91 else: | |
92 addr_format = '04X' | |
93 f = open(argv[1]) | |
94 for line in f: | |
95 if line.startswith(';TriggerPosition'): | |
96 _,_,triggerpos = line.partition(':') | |
97 triggerpos = int(triggerpos.strip()) | |
98 elif line.startswith(';Rate'): | |
99 _,_,rate = line.partition(':') | |
100 #convert to nanoseconds between samples | |
101 rate = (1.0/float(rate.strip())) * 1000000000.0 | |
102 elif not line.startswith(';'): | |
103 sample,_,samplenum = line.partition('@') | |
104 samplenum = int(samplenum.strip()) | |
105 sample = int(sample, 16) | |
106 if detect_rise(last, sample, edclk): | |
107 edclk_ticks += 1 | |
108 if detect_rise(last, sample, sc): | |
109 sc_ticks += 1 | |
110 if not (last is False): | |
111 #detect falling edge of !HSYNC | |
112 if detect_fall(last, sample, hsync): | |
113 if readcounter: | |
114 print readcounter, 'reads,', sillyread, 'redundant reads' | |
115 readcounter = sillyread = 0 | |
116 if not tick_start is False: | |
117 float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0) | |
118 print 'EDCLK:', edclk_ticks, ' ticks, {0}MHz'.format(float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) | |
119 print 'SC:', sc_ticks, ' ticks, {0}MHz'.format(float(sc_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) | |
120 tick_start = samplenum | |
121 edclk_ticks = sc_ticks = 0 | |
122 print 'HSYNC Start' | |
123 #detect rising edge of !HSYNC | |
124 elif detect_rise(last, sample, hsync): | |
125 if not tick_start is False: | |
126 float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0) | |
127 print 'EDCLK:', edclk_ticks, ' ticks, {0}MHz'.format(float(edclk_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) | |
128 print 'SC:', sc_ticks, ' ticks, {0}MHz'.format(float(sc_ticks)/((rate * (samplenum-tick_start)) / 1000.0)) | |
129 tick_start = samplenum | |
130 edclk_ticks = sc_ticks = 0 | |
131 print 'HSYNC End' | |
132 if state == 'begin': | |
133 #detect falling edge of !RAS | |
134 if detect_fall(last, sample, ras): | |
135 state = 'ras' | |
136 row = get_addr(sample) | |
137 mode = 'ram' if detect_high(sample, oedt) else 'read transfer' | |
138 elif detect_fall(last, sample, cas): | |
139 state = 'cas' | |
140 elif state == 'ras': | |
141 if detect_fall(last, sample, cas): | |
142 state = 'begin' | |
143 col = get_addr(sample) | |
144 addr = (row << 8) | col | |
145 if mode == 'ram': | |
146 state = 'ras_cas' | |
147 else: | |
148 print_addr_op(addr, addr_format, mode, samplenum, triggerpos, rate) | |
149 lastaddr = addr | |
150 #print '{0:04X} {1} - {2:02X}:{3:02X} - {0:016b}'.format(addr, mode, row, col) | |
151 elif state == 'cas': | |
152 if detect_fall(last, sample, ras): | |
153 state = 'begin' | |
154 print 'refresh@{0} ns'.format((samplenum - triggerpos)*rate) | |
155 elif state == 'ras_cas': | |
156 if detect_fall(last, sample, oedt): | |
157 readcounter += 1 | |
158 if addr == lastaddr: | |
159 sillyread += 1 | |
160 print_addr_op(addr, addr_format, 'read', samplenum, triggerpos, rate) | |
161 state = 'begin' | |
162 elif detect_fall(last, sample, wewb): | |
163 print_addr_op(addr, addr_format, 'write', samplenum, triggerpos, rate) | |
164 state = 'begin' | |
165 last = sample |