Mercurial > repos > blastem
view analyze_olp.py @ 1374:8f404b1fa572
Go back to resetting the refresh counter after a DMA. Probably not quite correct as it is probably reset on VDP triggered refresh, but this is close enough for now given the general limitations with my refresh code. VDP FIFO Testing seems to be passing 100% reliably again (was occassionally failing still with the last commit)
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 23 May 2017 23:47:40 -0700 |
parents | 6854ab93d182 |
children | b1ad6339de4f |
line wrap: on
line source
#!/usr/bin/env python from zipfile import ZipFile from sys import exit, argv 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 def detect_low(sample, bit): mask = 1 << bit return not sample & mask def get_value(sample, bits): value = 0 for i in xrange(0, len(bits)): bit = bits[i] value |= (sample >> bit & 1) << i return value def swizzle_mode4(row, col): return (col & 1) | (row << 1) | (col << 8 & 0xFE00) def analyze_delays(chanmap, datafile): if 'M68K_CLK' in chanmap: m68k_clk = chanmap['M68K CLK'] elif 'CLK' in chanmap: m68k_clk = chanmap['CLK'] m_as = chanmap['!AS'] ram_oe = chanmap['RAM !LOE/!RFSH'] ram_ce = chanmap['RAM !CE'] last = False prev = False prevRefresh = False clks = 0 as_start = 0 for line in datafile.readlines(): line = line.strip() if line and not line.startswith(';'): sample,_,num = line.partition('@') sample = int(sample, 16) if not (last is False): if detect_rise(last, sample, m68k_clk): clks = clks + 1 if detect_rise(last, sample, m_as): as_clks = clks - as_start if as_clks > 2: if not (prev is False): print '!AS held for', as_clks, 'cycles starting (delay of ' + str(as_clks - 2) + ') at', as_start, 'and ending at', clks, 'delta since last delay:', as_start - prev else: print '!AS held for', as_clks, 'cycles starting (delay of ' + str(as_clks - 2) + ') at', as_start, 'and ending at', clks prev = as_start elif detect_fall(last, sample, m_as): as_start = clks if detect_fall(last, sample, ram_oe) and detect_high( sample, ram_ce): if prevRefresh is False: print 'RAM refresh at ', clks else: print 'RAM refresh at', clks, 'delta since last:', clks-prevRefresh prevRefresh = clks last = sample def analyze_refresh(chanmap, datafile): if 'M68K_CLK' in chanmap: m68k_clk = chanmap['M68K CLK'] elif 'CLK' in chanmap: m68k_clk = chanmap['CLK'] ram_oe = chanmap['RAM !LOE/!RFSH'] ram_ce = chanmap['RAM !CE'] clks = 0 last = False prevRefresh = False for line in datafile.readlines(): line = line.strip() if line and not line.startswith(';'): sample,_,num = line.partition('@') sample = int(sample, 16) if not (last is False): if detect_rise(last, sample, m68k_clk): clks = clks + 1 if detect_fall(last, sample, ram_oe) and detect_high( sample, ram_ce): if prevRefresh is False: print 'RAM refresh at ', clks else: print 'RAM refresh at', clks, 'delta since last:', clks-prevRefresh prevRefresh = clks last = sample table_start = 0x3800 table_end = table_start + 0x600 sat_start = 0x3E00 #0x3F00 sat_xname = sat_start + 0x80 sat_end = sat_start + 0x100 def analyze_vram(chanmap, datafile): address_bits = [chanmap['AD{0}'.format(i)] for i in xrange(0, 8)] ras = chanmap['!RAS'] cas = chanmap['!CAS'] hsync = chanmap['!HSYNC'] state = 'begin' last = False for line in datafile.readlines(): line = line.strip() if line and not line.startswith(';'): sample,_,num = line.partition('@') sample = int(sample, 16) if not (last is False): if detect_fall(last, sample, hsync): print 'HSYNC low @ {0}'.format(num) elif detect_rise(last, sample, hsync): print 'HSYNC high @ {0}'.format(num) if state == 'begin': if detect_fall(last, sample, ras): state = 'ras' row = get_value(sample, address_bits) elif detect_fall(last, sample, cas): state = 'cas' elif state == 'ras': if detect_fall(last, sample, cas): col = get_value(sample, address_bits) address = swizzle_mode4(row, col) if address < table_end and address >= table_start: offset = (address - table_start)/2 desc = 'Map Row {0} Col {1}'.format(offset / 32, offset & 31) elif address >= sat_start and address < sat_xname: offset = address - sat_start desc = 'Sprite {0} Y Read'.format(offset) elif address >= sat_xname and address < sat_end: offset = address - sat_xname desc = 'Sprite {0} X/Name Read'.format(offset / 2) else: desc = 'Tile {0} Row {1}'.format(address / 32, ((address / 4) & 7) + (0.5 if address & 2 else 0)) print '{0:02X}:{1:02X} - {2:04X} @ {3} - {4}'.format(row, col, address, num, desc) state = 'begin' elif state == 'cas': if detect_fall(last, sample, ras): print 'refresh @ {0}'.format(num) state = 'begin' last = sample def main(args): if len(args) < 2: print 'Usage: analyze_olp.py filename' exit(1) olpfile = ZipFile(args[1], "r") channelfile = olpfile.open('channel.labels') channels = [line.strip() for line in channelfile.readlines()] channelfile.close() print channels chanmap = {} for i in xrange(0, len(channels)): chanmap[channels[i]] = i datafile = olpfile.open('data.ols') #analyze_delays(chanmap, datafile) analyze_vram(chanmap, datafile) datafile.close() #datafile = olpfile.open('data.ols') #analyze_refresh(chanmap, datafile) if __name__ == '__main__': main(argv)