# HG changeset patch # User Michael Pavone # Date 1483507132 28800 # Node ID 3e24de8d80735c708bf677eac63aa57df91ec5ec # Parent 494234e7e88fd93c80694b4ba15574ac79ff94e6 Add support for SMS controllers diff -r 494234e7e88f -r 3e24de8d8073 analyze_olp.py --- a/analyze_olp.py Tue Jan 03 21:18:42 2017 -0800 +++ b/analyze_olp.py Tue Jan 03 21:18:52 2017 -0800 @@ -18,6 +18,16 @@ 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: @@ -83,7 +93,61 @@ print 'RAM refresh at', clks, 'delta since last:', clks-prevRefresh prevRefresh = clks last = sample - + + +table_start = 0x3800 +table_end = table_start + 0x600 +sat_start = 0x3F00 #0x3E00 +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: @@ -98,7 +162,8 @@ for i in xrange(0, len(channels)): chanmap[channels[i]] = i datafile = olpfile.open('data.ols') - analyze_delays(chanmap, datafile) + #analyze_delays(chanmap, datafile) + analyze_vram(chanmap, datafile) datafile.close() #datafile = olpfile.open('data.ols') #analyze_refresh(chanmap, datafile) diff -r 494234e7e88f -r 3e24de8d8073 io.c --- a/io.c Tue Jan 03 21:18:42 2017 -0800 +++ b/io.c Tue Jan 03 21:18:52 2017 -0800 @@ -25,6 +25,7 @@ #define MIN_POLL_INTERVAL 6840 const char * device_type_names[] = { + "SMS gamepad", "3-button gamepad", "6-button gamepad", "Mega Mouse", @@ -653,15 +654,15 @@ if (!strncmp(device_type, "gamepad", gamepad_len)) { if ( - (device_type[gamepad_len] != '3' && device_type[gamepad_len] != '6') + (device_type[gamepad_len] != '3' && device_type[gamepad_len] != '6' && device_type[gamepad_len] != '2') || device_type[gamepad_len+1] != '.' || device_type[gamepad_len+2] < '1' || device_type[gamepad_len+2] > '8' || device_type[gamepad_len+3] != 0 - ) - { + ) { warning("%s is not a valid gamepad type\n", device_type); - } else if (device_type[gamepad_len] == '3') - { + } else if (device_type[gamepad_len] == '3') { port->device_type = IO_GAMEPAD3; + } else if (device_type[gamepad_len] == '2') { + port->device_type = IO_GAMEPAD2; } else { port->device_type = IO_GAMEPAD6; } @@ -803,7 +804,7 @@ } } else #endif - if (ports[i].device_type == IO_GAMEPAD3 || ports[i].device_type == IO_GAMEPAD6) { + if (ports[i].device_type == IO_GAMEPAD3 || ports[i].device_type == IO_GAMEPAD6 || ports[i].device_type == IO_GAMEPAD2) { printf("IO port %s connected to gamepad #%d with type '%s'\n", io_name(i), ports[i].device.pad.gamepad_num + 1, device_type_names[ports[i].device_type]); } else { printf("IO port %s connected to device '%s'\n", io_name(i), device_type_names[ports[i].device_type]); @@ -821,7 +822,8 @@ for (int j = 0; j < 3; j++) { if ((ports[j].device_type == IO_GAMEPAD3 - || ports[j].device_type ==IO_GAMEPAD6) + || ports[j].device_type == IO_GAMEPAD6 + || ports[j].device_type == IO_GAMEPAD2) && ports[j].device.pad.gamepad_num == num ) { @@ -1364,6 +1366,9 @@ } switch (port->device_type) { + case IO_GAMEPAD2: + input = ~port->input[GAMEPAD_TH1]; + break; case IO_GAMEPAD3: { input = port->input[th ? GAMEPAD_TH1 : GAMEPAD_TH0]; diff -r 494234e7e88f -r 3e24de8d8073 io.h --- a/io.h Tue Jan 03 21:18:42 2017 -0800 +++ b/io.h Tue Jan 03 21:18:52 2017 -0800 @@ -10,6 +10,7 @@ #include "romdb.h" enum { + IO_GAMEPAD2, IO_GAMEPAD3, IO_GAMEPAD6, IO_MOUSE,