summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xanalyze_olp.py69
-rw-r--r--io.c19
-rw-r--r--io.h1
3 files changed, 80 insertions, 9 deletions
diff --git a/analyze_olp.py b/analyze_olp.py
index 4d7b935..4befb83 100755
--- a/analyze_olp.py
+++ b/analyze_olp.py
@@ -18,6 +18,16 @@ def detect_high(sample, bit):
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 @@ def analyze_refresh(chanmap, datafile):
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 @@ def main(args):
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 --git a/io.c b/io.c
index 312a10a..acc41b8 100644
--- a/io.c
+++ b/io.c
@@ -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 @@ void process_device(char * device_type, io_port * port)
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 @@ cleanup_sock:
}
} 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 @@ void map_bindings(io_port *ports, keybinding *bindings, int numbindings)
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 @@ uint8_t io_data_read(io_port * port, uint32_t current_cycle)
}
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 --git a/io.h b/io.h
index 7ec7326..9d80038 100644
--- a/io.h
+++ b/io.h
@@ -10,6 +10,7 @@
#include "romdb.h"
enum {
+ IO_GAMEPAD2,
IO_GAMEPAD3,
IO_GAMEPAD6,
IO_MOUSE,