@@ -26,21 +26,22 @@ def compute_romsize(filesize):
26
26
return size_header , actualsize
27
27
28
28
#-----------------------------------------------------------------------------------------
29
- def calc_checksum (file ):
29
+ def calc_checksum (file , header_start ):
30
30
file .seek (0 , os .SEEK_SET )
31
+ checksum_addr = header_start + 0xDC
31
32
32
- checksum = 0xFF * 2 # Default checksum bytes at FFDC and FFDD
33
+ checksum = 0xFF * 2 # Default checksum bytes at 7FDC and 7FDD
33
34
address = 0
34
35
while True :
35
36
c = file .read (4096 )
36
37
if c == b'' :
37
38
break
38
39
39
40
checksum += sum (c )
40
- relative_ffdc = 0xFFDC - address
41
+ relative_ffdc = checksum_addr - address
41
42
if relative_ffdc >= 0 and relative_ffdc < len (c ):
42
43
# This block contains the checksum bytes. Exclude them from the result.
43
- checksum -= sum (c [0xFFDC - address :0xFFDC - address + 4 ])
44
+ checksum -= sum (c [checksum_addr - address :checksum_addr - address + 4 ])
44
45
45
46
address += len (c )
46
47
@@ -67,9 +68,9 @@ def get_file_byte(file, address):
67
68
return file .read (1 )[0 ]
68
69
69
70
#-----------------------------------------------------------------------------------------
70
- def validate_sfc (file ):
71
+ def validate_sfc (file , minsize ):
71
72
file .seek (0 , os .SEEK_END )
72
- if file .tell () < 0x10000 :
73
+ if file .tell () < minsize : # Double on hirom.
73
74
return "file is too small to contain a valid cartridge header."
74
75
75
76
# Kind of hard to find any special signature to verify.
@@ -96,6 +97,7 @@ def main(args=None, output_file=None):
96
97
""" )
97
98
98
99
parser .add_argument ('path' , help = 'Path to SFC or SMC file. Must be headerless.' )
100
+ parser .add_argument ("-m" , "--mode" , required = True , choices = ['lorom' , 'hirom' ], help = 'Cartridge mode' )
99
101
parser .add_argument ("--fix" , action = "store_true" , help = 'Make changes to the given file. Otherwise, just print info about it.' )
100
102
parser .add_argument ("-q" , "--quiet" , action = 'store_true' , help = 'Suppress output.' )
101
103
args = parser .parse_args (args = args )
@@ -104,38 +106,44 @@ def main(args=None, output_file=None):
104
106
if args .fix :
105
107
mode = "r+b"
106
108
109
+ header_start = 0x7F00
110
+ min_size = 0x8000
111
+ if args .mode == "hirom" :
112
+ header_start = 0xFF00
113
+ min_size = 0x10000
114
+
107
115
with open (args .path , mode ) as f :
108
116
f .seek (0 , os .SEEK_END )
109
117
mprint (f"File size: { f .tell ()} bytes" )
110
118
111
- validation_error = validate_sfc (f )
119
+ validation_error = validate_sfc (f , min_size )
112
120
if validation_error :
113
121
mprint (f"Validation error: { validation_error } " )
114
122
mprint ("Does this file have an SMC header? Those are not supported." )
115
123
return
116
124
117
125
size_header , full_size = compute_romsize (f .tell ())
118
126
mprint (f"Computed size header value: { size_header } " )
119
- f .seek (0xFFD7 , os .SEEK_SET )
127
+ f .seek (header_start + 0xD7 , os .SEEK_SET )
120
128
mprint (f"Current size header value: { f .read (1 )[0 ]} " )
121
129
mprint (f"Full size: { full_size // 1024 } KiB" )
122
130
123
131
if args .fix :
124
132
pad_file (f , full_size )
125
- f .seek (0xFFD7 , os .SEEK_SET )
133
+ f .seek (header_start + 0xD7 , os .SEEK_SET )
126
134
f .write (bytes ([size_header ]))
127
135
128
- f .seek (0xFFDC , os .SEEK_SET )
136
+ f .seek (header_start + 0xDC , os .SEEK_SET )
129
137
current_checksum_bytes = f .read (4 )
130
138
mprint (f"Current checksum bytes: { format_checksum_bytes (current_checksum_bytes )} " )
131
139
132
- checksum = calc_checksum (f )
140
+ checksum = calc_checksum (f , header_start )
133
141
xchecksum = checksum ^ 0xFFFF
134
142
checksum_bytes = bytes ([xchecksum & 0xFF , xchecksum >> 8 , checksum & 0xFF , checksum >> 8 ])
135
143
mprint (f"Computed checksum bytes: { format_checksum_bytes (checksum_bytes )} " )
136
144
137
145
if args .fix :
138
- f .seek (0xFFDC , os .SEEK_SET )
146
+ f .seek (header_start + 0xDC , os .SEEK_SET )
139
147
f .write (checksum_bytes )
140
148
141
149
if __name__ == "__main__" :
0 commit comments