"Hagar the Horrible'
21 x 30cm, backer board 4mm, Hagar 4mm
21 x 30cm, backer board 4mm, Hagar 4mm
May 07, 2024, 03:35:10 pm
PORT_START("mainpcb:12BADC.0") /* 400000 - steering wheel */
PORT_BIT( 0xfff, 0x800, IPT_POSITIONAL ) PORT_POSITIONS(0xfff) PORT_WRAPS PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_NAME("Steering Wheel")
import sys
BYTES_EXPECTED = 2048
EDGE_BASE_HARDDRIV = 0x2C1D
EDGE_BASE_STRTDRIV = 0x295D
def load_byte_array(filename):
global BYTES_EXPECTED
with open(filename, mode='rb') as file: # b is important -> binary
fileContent = file.read().hex()
data = []
byte_count = 0
this_byte = ""
for c in fileContent:
this_byte += c
if len(this_byte) == 2:
data.append(int(this_byte, 16))
this_byte = ""
byte_count += 1
if byte_count != BYTES_EXPECTED:
print("Error! Unexpected number of bytes in {}. Expecting={}, actual={} ".format(filename, BYTES_EXPECTED, byte_count))
exit(1)
#print("{}".format((fileContent)))
return data
def save_byte_array(filename, byte_array):
# make file
newFile = open(filename, "wb")
# write to file
newFileByteArray = bytearray(byte_array)
newFile.write(newFileByteArray)
def load_nvram(nvram_path):
global BYTES_EXPECTED
mainpcb_200e = load_byte_array(nvram_path + "mainpcb_200e")
mainpcb_210e = load_byte_array(nvram_path + "mainpcb_210e")
# Combine the data...
nvram = []
for i in range(0, BYTES_EXPECTED):
nvram.append((mainpcb_200e[i] << 8) | mainpcb_210e[i])
return nvram
def save_nvram(nvram_path, nvram):
global BYTES_EXPECTED
mainpcb_200e = []
mainpcb_210e = []
# split the data...
for i in range(0, BYTES_EXPECTED):
mainpcb_200e.append((nvram[i] >> 8)&0xff)
mainpcb_210e.append(nvram[i]&0xff)
save_byte_array(nvram_path + "mainpcb_200e", mainpcb_200e)
save_byte_array(nvram_path + "mainpcb_210e", mainpcb_210e)
def patcen_to_int(patcen):
if (patcen&0xf000) == 0xf000:
return -1 * (0x1000 - patcen&0x0fff)
else:
return patcen
def int_to_patcen(i_patcen):
if i_patcen < 0:
return 0xf000 | (0x1000 + i_patcen)
else:
return i_patcen
def get_edge(cntsptrn, patcen, start_edge, undo=False):
edge = start_edge
i_patcen = patcen_to_int(patcen)
# Leave the sign 'as is' when undoing, flip the sign when redoing...
cntsptrn *= 1 if undo else -1
i_patcen *= 1 if undo else -1
edge += cntsptrn
edge += i_patcen
return edge
def validate_edge_base(edge_base, exit_on_error=True):
if edge_base == EDGE_BASE_HARDDRIV:
print("Hard/Race Drivin' style edge detected - OK".format(hex(edge_base)))
elif edge_base == EDGE_BASE_STRTDRIV:
print("Street Drivin' style edge detected - OK".format(hex(edge_base)))
else:
print("Error! Unexpected edge base {} detected. Expecting either Hard/Race Drivin' edge base {} or Street Drivin' edge base {})".format(hex(edge_base),hex(EDGE_BASE_HARDDRIV), hex(EDGE_BASE_HARDDRIV)))
if exit_on_error:
if input('Continue anyway?') != 'y':
exit(0)
def do_read(nvram_path):
nvram = load_nvram(nvram_path)
cntsptrn = "?"
patcen = "?"
edge = "?"
for i in range(0, BYTES_EXPECTED):
#for i in range(0x210, 0x218):
temp = "ADDR:0x{:04X} - 0x{:04X} {:<8}".format(i, nvram[i], f"({nvram[i]})")
if i == 0x212:
temp = temp + " CNTSPTRN"
cntsptrn = nvram[i]
elif i == 0x213:
temp = temp + " PATCEN"
patcen = nvram[i]
elif i == 0x214:
temp = temp + " EDGE"
edge = nvram[i]
print(temp)
i_patcen = patcen_to_int(patcen)
print(f"Read complete. CNTSPTRN:{hex(cntsptrn)} ({cntsptrn}) PATCEN:{hex(patcen)} ({i_patcen}) EDGE:{hex(edge)}")
# Check the edge looks right...
edge_base = get_edge(cntsptrn, patcen, edge, undo=True)
validate_edge_base(edge_base, exit_on_error=False)
def do_diff(nvram_path_a, nvram_path_b):
global BYTES_EXPECTED
a = load_nvram(nvram_path_a)
b = load_nvram(nvram_path_b)
diff_count = 0
for i in range(0, BYTES_EXPECTED):
if a[i] != b[i]:
temp = "ADDR:0x{:04X} - A:0x{:04X} {:<8} DIFF B:0x{:04X} {:<8}".format(i, a[i], f"({a[i]})", b[i], f"({b[i]})")
if i == 0x212:
temp = temp + " CNTSPTRN"
elif i == 0x213:
temp = temp + " PATCEN"
diff_count += 1
print(temp)
print(f"{diff_count} differences detected.")
def do_reset(nvram_path, cntsptrn, i_patcen):
nvram = load_nvram(nvram_path);
# Check the edge looks right and if it doesn't, ask user if they want to continue...
edge_base = get_edge(nvram[0x212], nvram[0x213], nvram[0x214], undo=True)
validate_edge_base(edge_base, exit_on_error=True)
cntsptrn = cntsptrn
patcen = int_to_patcen(i_patcen)
edge = get_edge(cntsptrn, patcen, edge_base, undo=False)
nvram[0x212] = cntsptrn
nvram[0x213] = int_to_patcen(i_patcen)
nvram[0x214] = edge
save_nvram(nvram_path, nvram)
print(f"CNTSPTRN reset to {cntsptrn}, PATCEN reset to {i_patcen}. OK")
def clean_path(my_path):
if not my_path.endswith('/'):
my_path = my_path + '/'
return my_path
def show_usage():
print("Nvram Helper")
print("------------")
print("")
print("Usage:")
print(" python3 nvram_helper.py read <nvram_directory>")
print(" python3 nvram_helper.py diff <nvram_directory_a> <nvram_directory_b>")
print(" python3 nvram_helper.py reset <nvram_directory> <cntsptrn> <patcen>")
print("Examples:")
print(" python3 nvram_helper.py read nvram/harddrivcb")
print(" python3 nvram_helper.py diff nvram/harddrivcb nvram/strtdriv")
print(" python3 nvram_helper.py reset nvram/harddrivcb 1024 0")
print(" python3 nvram_helper.py reset nvram/racedrivcb 1024 0")
print(" python3 nvram_helper.py reset nvram/strtdriv 512 0")
exit(0)
#print("{}".format(sys.argv))
if len(sys.argv) < 2:
show_usage()
cmd = sys.argv[1]
if cmd == 'read':
if len(sys.argv) < 3:
print(f"Not enough arguments.")
exit(1)
do_read(clean_path(sys.argv[2]))
elif cmd == 'diff':
if len(sys.argv) < 4:
print(f"Not enough arguments.")
exit(1)
do_diff(clean_path(sys.argv[2]), clean_path(sys.argv[3]))
elif cmd == 'reset':
if len(sys.argv) < 5:
print(f"Not enough arguments.")
exit(1)
do_reset(clean_path(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4]))
elif cmd.lower() in ["h", "-h", "help", "/help", "/h", "?", "--h"]:
show_usage()
else:
print(f"Unknown command '{cmd}'.")
show_usage()