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