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