-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRomHeader.sbp
694 lines (595 loc) · 19.8 KB
/
RomHeader.sbp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
' Internal Rom HederとそれをパースしたSFC_CART_INFO構造体関連
'-----------------
' Rom Header Defines
'-----------------
Const SFC_SPEC_HEADER_SIZE=&H20+&H10
Const SFC_SPEC_HEADER_ADDR=&HFFC0-&H10
' ROMヘッダーのマッピング情報
' MapModeの下位4ビット
Enum SFC_MAP_TYPE_RAW
SFC_MAP_RAW_LoROM = 0
SFC_MAP_RAW_HiROM = 1
SFC_MAP_RAW_SDD1= 2
SFC_MAP_RAW_SA1 = 3
SFC_MAP_RAW_ExHiROM = 5
SFC_MAP_RAW_SPC7110 = &H0A
End Enum
Const SFC_CHIPSET_BSX = &HE5
Const SFC_CHIPSET_CX4 = &HF3
Const SFC_CHIPSET_ST018 = &HF5
Const SFC_CHIPSET_ST010 = &HF6
' HKACが判断したマッピングID
' ROM, SRAMへのアクセス方法を識別
' SFC_MAP_TYPE_RAWと違って連番
Enum SFC_MAP_TYPE
SFC_MAP_LoROM = 0
SFC_MAP_HiROM
SFC_MAP_ExHiROM
SFC_MAP_SA1
SFC_MAP_SDD1
SFC_MAP_GSU
SFC_MAP_SPC7110
SFC_MAP_XBAND
SFC_MAP_SFTURBO
SFC_MAP_SpLoROM '衛星対応カートリッジでかつLoROMで3MBのもの(ダビスタ)
SFC_MAP_BSX
SFC_MAP_JRAPAT
SFC_MAP_ST018
SFC_MAP_ST010
SFC_MAP_SF_MENU 'SFメモリカートリッジ
SFC_MAP_CX4_2DC0N ' ロックマンX2, 8Mbit ROM x2
SFC_MAP_CX4_1DC0N ' ロックマンX3, 16Mbit ROM x1
SFC_MAP_TYPE__NUM
End Enum
' ↑のラベル
Dim SFC_MAP_TYPE_LABEL[SFC_MAP_TYPE__NUM] = [
"LoROM" ,
"HiROM" ,
"ExHiROM" ,
"SA-1" ,
"S-DD1" ,
"SuperFX" ,
"SPC7110" ,
"XBAND BIOS" ,
"Sufami Turbo" ,
"SpecialLoROM" ,
"BS-X" ,
"LoROM + FlashSave" ,
"LoROM with ST018 " ,
"LoROM with ST010 " ,
"MX15001 (SFメモリ)",
"CX4 for RockMan X2",
"CX4 for RockMan X3",
"<invalid mapper id>"
] AS BytePtr
'スーファミヘッダから取得した情報
'後の都合のいい処理がしてある。
'生ヘッダを見たければrawHeaderにアクセス
Type SFC_CART_INFO
Title[23] As Byte 'ゲームタイトル
MapType As Long 'SFC_MAP_TYPE ... ROM/RAMのアクセス方法を識別するコード
Chipset As Byte 'Cartridge parts contents
RomSize As DWord 'Game ROM Size (byte)
SramSize As DWord 'Save SRAM Size(byte)
Country As Byte '国コード
Version As Byte 'ROMバージョン
CheckSum1 As Word 'チェックサム
CheckSum2 As Word 'チェックサムのNOT
hasExtraHeader As BOOL '拡張ヘッダ(FFB0h-FFBFh)があるかどうか
enableChecksum As BOOL 'チェックサムが有効かどうかMENU PROGRAMとかBSMC等
isFastRom As BOOL 'false: SlowRrom
' isLoROM As BOOL 'ROMのマッピングがLoROMなもの。SFC_MAP_LoROM, SA1, SpLoROM, SF_MENUなどでTRUEになる
isBSX As BOOL 'BSMCスロットがあるかどうか(衛星放送対応カートリッジかどうか)
isFlashSave As BOOL 'FLASHセーブかどうか
MakerCode As Word 'メーカーコード
GameCode[4] As Byte 'ゲームコードの文字列(Extraheaderがある時のみ有効)
' AddrOffset As DWord 'ROMの開始アドレス
rawHeader As SFC_CART_HEADER
EndType
' Raw ROM-Header (FFB0h~)
Type Align(1) SFC_CART_HEADER
MakerCode AS Word '未使用のこともある
GameCode AS DWord
dummy0[5] AS Byte
FlashSize AS Byte
ExRamSize AS Byte
SpecialVer AS Byte
ChipsetSub As Byte
'------------------
GameTitle[20] As Byte ' FFC0h
MapMode AS Byte ' FFD5h
Chipset AS Byte ' FFD6h
RomSize AS Byte ' FFD7h
SramSize AS Byte ' FFD8h
CountryID AS Byte ' FFD9h
OldMakerCode As Byte ' FFDAh
Version As Byte ' FFDBh
Checksum1 AS Word ' FFDCh
Checksum2 As Word ' FFDEh
End Type
'-----------------
' Header Functions
'-----------------
'生のROMヘッダをSFC_CART_INFOに
Sub SloveCartInfo(data As * SFC_CART_HEADER, info As * SFC_CART_INFO)
'カートリッジのヘッダエリアのデータをSFC_CART_INFOへ格納
Dim i As Long
memcpy(VarPtr(info->rawHeader), data, Sizeof(SFC_CART_HEADER))
'タイトル取得
memcpy(info, data->GameTitle, 21)
If info->Title[i] = 0 Then
lstrcpy(info->Title, "CART CONNECTION ERR")
Else
'右からスペースをNULL文字で埋めル
For i = 20 To 0 Step -1
If info->Title[i] <> &H20 And info->Title[i] <> 0 Then exitfor
info->Title[i] = 0
Next i
End If
info->Title[21] = 0 ' NULL文字挿入
info->Chipset = data->Chipset
info->Country = data->CountryID
info->Version = data->Version
info->CheckSum1 = data->Checksum1
info->CheckSum2 = data->Checksum2
info->isFastRom = data->MapMode And &H10
info->enableChecksum = TRUE ' 仮決定
info->isFlashSave = FALSE ' 仮決定
' 拡張ヘッダがあるかチェック
' MarkerCodeとGameCodeがASCIIコードから外れてたら拡張ヘッダナシと判定
Dim p As BytePtr
p = VarPtr(data->MakerCode)
info->hasExtraHeader = TRUE
For i = 0 To 5
If (p[i] < &H20) Or (p[i] > &H7F) Then
info->hasExtraHeader = FALSE
ExitFor
End If
Next i
' 拡張ヘッダの情報セット
If info->hasExtraHeader Then
info->MakerCode = data->MakerCode
lstrcpy(info->GameCode, Dw2Str(info->rawHeader.GameCode))
If lstrcmp(info->GameCode, " ") = 0 Then lstrcpy(info->GameCode, "????")
Else
' 拡張ヘッダが無い場合、OldMakerCodeからMakerCodeを作成
Dim old_gc[2] AS Byte
wsprintf(old_gc, "%02X", data->OldMakerCode)
info->MakerCode = GetWord(old_gc)
End If
' MapTypeを仮決定。MapModeから判定できない特殊なものは後で決定される
Select Case (data->MapMode And &H0F)
Case 0
info->MapType = SFC_MAP_LoROM
Case 1
info->MapType = SFC_MAP_HiROM
Case 2
info->MapType = SFC_MAP_SDD1
Case 3
info->MapType = SFC_MAP_SA1
Case 5
info->MapType = SFC_MAP_ExHiROM
Case &H0A
info->MapType = SFC_MAP_SPC7110
Case Else
info->MapType = SFC_MAP_LoROM
End Select
' ChipsetからMapTypeを検討
Select Case info->Chipset
Case SFC_CHIPSET_BSX
info->MapType = SFC_MAP_BSX
Case SFC_CHIPSET_CX4
' 同じCX4でもロックマンX2かX3かでMapTypeを変えなきゃならない
' ゲームタイトルからX2かX3か判定する。
' 海外版でも文字数が同じなのでこの手法が使える
If info->Title[9] = GetByte("2") Then
info->MapType = SFC_MAP_CX4_2DC0N
ElseIf info->Title[9] = GetByte("3") Then
info->MapType = SFC_MAP_CX4_1DC0N
Else
DBM("[WAN] Failed to detect CX4 ROM Type.")
info->MapType = SFC_MAP_CX4_1DC0N
End If
Case SFC_CHIPSET_ST018
info->MapType = SFC_MAP_ST018
Case SFC_CHIPSET_ST010
info->MapType = SFC_MAP_ST010
info->SramSize = 4 * 1024 ' ST010内蔵RAM
End Select
if (info->Chipset >> 4) = &H01 then
info->MapType = SFC_MAP_GSU
End If
' ROM / SRAMサイズ計算
if info->MapType = SFC_MAP_SPC7110 Then
info->RomSize = 5 << 20
ElseIf data->RomSize<>0 Then
info->RomSize = &H0400 << data->RomSize
Else
info->RomSize = 0
End If
If data->SramSize<>0 Then
info->SramSize = &H0400 << data->SramSize
Elseif info->hasExtraHeader And data->ExRamSize<>0 Then
info->SramSize = &H0400 << data->ExRamSize
Elseif info->MapType = SFC_MAP_ST010 Then
' ST010内蔵RAM
info->SramSize = 4 * 1024
Else
info->SramSize = 0
End If
'メーカがEJ(NTT DATA)ならFlashSaveカセット
If info->MakerCode = &H4A45 Then
info->isFlashSave = TRUE
info->MapType = SFC_MAP_JRAPAT
End If
if info->isFlashSave Then
if info->hasExtraHeader Then
info->SramSize = (1024 << data->FlashSize) As DWord
Else
' Flashサイズが無いので仮決定(JRAPAT共通サイズ)
info->SramSize = (1024 * 128) As DWord
End If
End If
'SpecialLoROMはLoROMの衛星対応カートリッジで3MB目を吸うときにバンク切り替えが必要
'品番がSHVC-ZxxJであるものは衛星対応カートリッジ
'ここではダビスタ96とサウンドノベルツクールとBSXがヒットするはず。
'BSXは1MBなのでバンク切り替え必要なし
If info->GameCode[0] = Asc("Z") And info->GameCode[3] = Asc("J") Then
info->isBSX = TRUE
If info->MapType = SFC_MAP_LoROM Then
If info->RomSize>1024 * 1024 * 2 Then
info->MapType = SFC_MAP_SpLoROM
info->RomSize = 1024 * 1024 * 3
End If
End If
End If
If lstrcmp("MENU PROGRAM", info->Title) = 0 Then
' SFメモリカセット
info->MapType = SFC_MAP_SF_MENU
info->enableChecksum = FALSE
ElseIf lstrcmp("SUPER FORMATION SOCCE", info->Title) = 0 Then
'SUPER FOMATION SOCCERのタイトルーオーバランを修正
lstrcat(info->Title, "R")
info->MapType = SFC_MAP_LoROM
Elseif lstrcmp("XBND", info->GameCode) = 0 Then
info->MapType = SFC_MAP_XBAND
Else If lstrcmp("A9PJ", info->GameCode) = 0 Then
' スーファミターボ
info->MapType = SFC_MAP_SFTURBO
info->RomSize = 256 * 1024
info->CheckSum1 = &H35CC ' チェックサムが空のでつける
info->CheckSum2 = &HCA33
End If
EndSub
' those country codes are from fullsnes.
Enum SFC_COUNTRY
SFC_COUNTRY_JAPAN = 0
SFC_COUNTRY_ENGLISH
SFC_COUNTRY_PAL
SFC_COUNTRY_SWEDEN
SFC_COUNTRY_FINLAND
SFC_COUNTRY_DENMARK
SFC_COUNTRY_FRANCE
SFC_COUNTRY_HOLLAND
SFC_COUNTRY_SPAIN
SFC_COUNTRY_GERMANY
SFC_COUNTRY_ITALY
SFC_COUNTRY_CHINA
SFC_COUNTRY_INDONESIA
SFC_COUNTRY_KOREA
SFC_COUNTRY_A
SFC_COUNTRY_CANADA
SFC_COUNTRY_BRAZIL
SFC_COUNTRY_AUSTRALIA
SFC_COUNTRY_X
SFC_COUNTRY_Y
SFC_COUNTRY_Z
SFC_COUNTRY__NUM
End Enum
' ↑のラベル, 決まってない国コードはISO 3166-1から
Dim SFC_COUNTRY_LABEL[SFC_COUNTRY__NUM*2+2] = [
"J", "Japan" ,
"E", "USA" ,
"P", "Europe" ,
"W", "Sweden" ,
"FIN", "Finland" ,
"DNK", "Denmark" ,
"F", "France" ,
"H", "Holland" ,
"S", "Spain" ,
"D", "Germany" ,
"I", "Italy" ,
"C", "China" ,
"IDN", "Indonesia" ,
"K", "South Korea" ,
"A", "Common (0Eh)" ,
"N", "Canada" ,
"B", "Brazil" ,
"U", "Australia" ,
"X", "Other (12h)" ,
"Y", "Other (13h)" ,
"Z", "Other (14h)" ,
"?", "Unknown"
] AS BytePtr
Function GetCountryString(country_code AS Byte) As BytePtr
if country_code >= SFC_COUNTRY__NUM Then country_code = SFC_COUNTRY__NUM
GetCountryString = SFC_COUNTRY_LABEL[country_code*2+1]
End Function
Function GetCountryCodeString(country_code AS Byte) As BytePtr
if country_code >= SFC_COUNTRY__NUM Then country_code = SFC_COUNTRY__NUM
GetCountryCodeString = SFC_COUNTRY_LABEL[country_code*2]
End Function
Enum SPECIAL_ROM_TYPE
SPECIAL_ROM_TYPE_NORMAL = 0
SPECIAL_ROM_TYPE_NP
End Enum
Function MakeRomFileName(buf As BytePtr, buflen As Long, info As *SFC_CART_INFO, special As SPECIAL_ROM_TYPE) As Long
Dim rom_title[MAX_PATH] AS Byte
Dim ver As Long
ver = 10 + (info->Version) As Long
wsprintf(rom_title, "%s (%s) (V%d.%d)",
info->Title, GetCountryCodeString(info->Country), ver / 10, ver Mod 10)
if special = SPECIAL_ROM_TYPE_NP then
lstrcat(rom_title, " (NP)")
End If
memcpy(buf, rom_title, buflen-1)
buf[buflen-1] = 0
End Function
Function GetMappingString(maptype AS Long) As BytePtr
if maptype >= SFC_MAP_TYPE__NUM Then maptype = SFC_MAP_TYPE__NUM
GetMappingString = SFC_MAP_TYPE_LABEL[maptype]
End Function
Function GetChipsetString(info As *SFC_CART_INFO)(pIsKnown As *BOOL) AS BytePtr
Dim label AS BytePtr, isKnown=TRUE As BOOL
'http://snesemu.black-ship.net/misc/hardware/-from%20nsrt.edgeemu.com-chipinfo.htm
Select Case info->Chipset>>4
Case &H00
Select Case info->Chipset And &H0F
Case &H00 : label = "ROM"
Case &H01 : label = "ROM+RAM"
Case &H02 : label = "ROM+RAM+BAT"
Case &H03 : label = "ROM+DSP"
Case &H04 : label = "ROM+DSP+RAM"
Case &H05 : label = "ROM+DSP+RAM+BAT"
Case Else : label = "ROM (?)" : isKnown=FALSE
End Select
Case &H01 'SuperFX
Select Case info->Chipset And &H0F
Case &H03 : label = "[SFX]ROM+MARIO+RAM"
Case &H04 : label = "[SFX]ROM+GSU+RAM"
Case &H05 : label = "[SFX]ROM+GSU+RAM+BAT"
Case &H0A : label = "[SFX]ROM+GSU1+RAM+BAT"
Case Else : label = "[SFX]ROM+GSU (?)" : isKnown=FALSE
End Select
Case &H02 : label = "ROM+OBC1+RAM+BAT"
Case &H03
If info->Chipset = &H34 Then
label = "ROM+SA-1+RAM"
Elseif info->Chipset = &H35 then
label = "ROM+SA-1+RAM+BAT"
Else
label = "ROM+SA1 (?)" : isKnown=FALSE
End If
Case &H04
If (info->Chipset And &H0F) = 3 Then
label = "ROM+SDD1"
Elseif info->Chipset = &H45 then
label = "ROM+SDD1+RAM+BAT"
Else
label = "ROM+SDD1 [unknown:4xh]" : isKnown=FALSE
End If
Case &H05 : label = "S-RTC+RAM+BAT"
Case &H0E
Select Case info->Chipset And &H0F
Case &H03 : label = "ROM+SGBCPU+ICD2+2xRAM+GB slot"
Case &H05 : label = "ROM+PSRAM+MCC-BSC+SRAM+BAT"
Case Else : label = "ROM+Co-processor (?)" : isKnown=FALSE
End Select
Case &H0F
Select Case info->rawHeader.ChipsetSub
Case &H00
if info->Chipset = &HF5 Then
label = "ROM+SPC7110+RAM+BAT"
Elseif info->Chipset = &HF9 Then
label = "ROM+SPC7110+RTC+RAM+BAT"
Else
label = "ROM+SPC7110 (?)" : isKnown=FALSE
End If
Case &H01
If info->RomSize=&H100000 Then
label = "ROM+ST010"
Else
label = "ROM+ST011"
End If
Case &H02 : label = "ROM+ST018+RAM+BAT"
Case &H10 : label = "ROM+CX4"
Case Else : label = "ROM+Co-processor (?)" : isKnown=FALSE
End Select
Case Else
label = "ROM (? unknown chipset)" : isKnown=FALSE
End Select
GetChipsetString = label
if pIsKnown Then SetDWord(pIsKnown, isKnown)
End Function
' 生ヘッダ関連
Function RawHeader_GetRomSpeedString(mapMode As Byte) As BytePtr
If (mapMode And &H10) Then
RawHeader_GetRomSpeedString = "Fast"
Else
RawHeader_GetRomSpeedString = "Slow"
End If
End Function
Function RawHeader_GetRomMapString(mapMode As Byte) As BytePtr
Select Case (mapMode And &H0F)
Case SFC_MAP_RAW_LoROM
RawHeader_GetRomMapString = "LoROM"
Case SFC_MAP_RAW_HiROM
RawHeader_GetRomMapString = "HiROM"
Case SFC_MAP_RAW_SDD1
RawHeader_GetRomMapString = "S-DD1"
Case SFC_MAP_RAW_SA1
RawHeader_GetRomMapString = "SA-1"
Case SFC_MAP_RAW_ExHiROM
RawHeader_GetRomMapString = "ExHiROM"
Case SFC_MAP_RAW_SPC7110
RawHeader_GetRomMapString = "SPC7110"
Case Else
RawHeader_GetRomMapString = "unknown"
End Select
End Function
Function ceil(var As Single) As Long
ceil = Int(var)
if var - ceil > 0 Then ceil++
End Function
Const HEADER_INFO_TEXT_LEN = 1024
Function GenerateHeaderInfoText(header As *SFC_CART_INFO, text_buffer as BytePtr, text_len AS SIZE_T) As BOOL
Dim info AS StringClass
info.allocStr(HEADER_INFO_TEXT_LEN)
info.cat(ex"\r\n==== Cartridge infomation ====")
info.sprintf(ex"\r\n- Title: %s ", header->Title As DWord)
Dim publisher_text AS BytePtr
publisher_text = GetMakerString(header->MakerCode)
if lstrlen(publisher_text) < 15 Then
info.sprintf(ex"\r\n- Publisher: %c%c/%s", _
header->MakerCode As DWord, (header->MakerCode >> 8) As DWord, publisher_text As DWord)
Else
info.sprintf(ex"\r\n- Publisher: %c%c \r\n - %s", _
header->MakerCode As DWord, (header->MakerCode >> 8) As DWord, publisher_text As DWord)
Endif
If header->hasExtraHeader Then
info.cat(ex"\r\n- GameCode : SHVC-"): info.cat(header->GameCode)
End If
info.sprintf(ex"\r\n- Version : %d.%d", (1+header->Version/10) As DWord, header->Version Mod 10)
info.sprintf(ex"\r\n- Region : %s/(%s) [%02Xh]", GetCountryString(header->Country) As DWord, GetCountryCodeString(header->Country) As DWord, header->Country)
info.sprintf(ex"\r\n- Checksum : %04Xh ~= %04Xh", header->CheckSum2, header->CheckSum1)
if (NOT(header->CheckSum2) And &HFFFF) <> header->CheckSum1 then _
info.cat(ex"\r\n -> checksum broken.")
Dim model AS SFC_MMAP_MODEL, lastbank As DWord
GetMmapModel(header, FALSE, VarPtr(model))
Dim fastrom[1] = ["Slow", "Fast"] As BytePtr
Dim lohi[1] = ["Hi","Lo"] As BytePtr
info.sprintf(ex"\r\n- RomType : Mode%02X, %s%sROM", _
header->rawHeader.MapMode As DWord, _
fastrom[header->isFastRom And 1] As DWord, _
lohi[model.rom.isLoROM And 1] As DWord)
' ダイアログの左に表示されているので削る(BSXだと表示があふれる)
' info.sprintf(ex"\r\n- Mapping : %s", GetMappingString(header->MapType) As DWord)
Dim chipset_text AS BytePtr
chipset_text = GetChipsetString(header)
if lstrlen(chipset_text) < 15 Then
info.sprintf(ex"\r\n- Chipset : %02Xh %s", header->Chipset, chipset_text As DWord)
Else
info.sprintf(ex"\r\n- Chipset : %02Xh\r\n - %s", header->Chipset, chipset_text As DWord)
End If
info.cat(ex"\r\n- SaveType: ")
If header->isFlashSave Then
info.cat("FLASH")
Elseif header->SramSize = 0 Then
info.cat("None")
Elseif header->MapType = SFC_MAP_ST010 Then
info.cat("ST010 Internal RAM")
Else
info.cat("SRAM")
End If
if header->SramSize Then
lastbank = (model.sram.adr + (model.sram.bankStep) * (ceil(header->SramSize/model.sram.bankSize-1))) + model.sram.bankSize-1
info.sprintf(ex"\r\n - Map: $%02X:%04X-$%02X:%04X %dbank", _
model.sram.adr>>16, model.sram.adr And &HFFFF, _
lastbank>>16, lastbank And &HFFFF, _
ceil(header->SramSize/model.sram.bankSize))
End If
If header->hasExtraHeader Then
if header->rawHeader.SpecialVer <> 0 Then
info.sprintf(ex"\r\n- SpecialVersion: %02Xh", header->rawHeader.SpecialVer)
Endif
End If
If header->isBSX Then info.cat(ex"\r\nBS Memory Slot detected.")
' If header->hasExtraHeader Then info.cat(ex"\r\nExtra Header detected.")
if header->CheckSum1 <> ((NOT(header->CheckSum2)) And &HFFFF) Then
info.cat(ex"\r\ninvalid header: checksum is incorrect.")
End If
info.cat(ex"\r\n")
#ifdef _DEBUG
Dim filenametest[124] AS BytePtr
MakeRomFileName(filenametest, 124, header,0)
info.cat(ex"DBG:FN:")
info.cat(filenametest)
#endif
Dim copy_size AS SIZE_T
if text_len < info.length() Then
copy_size = text_len
Else
copy_size = info.length()
End If
memcpy(text_buffer, info.ptr, copy_size)
End Function
' ヘッダかどうか判定
Function isSnesHeader(header As * SFC_CART_INFO) As BOOL
Dim i As Long
For i = 0 To 19
If header->rawHeader.GameTitle[i] < &H20 Then
If Not(i>4 And header->rawHeader.GameTitle[i] = 0) Then GoTo * ISH_ERR
End If
Next i
'サイズチェック
'If header->RomSize > &H0D Then GoTo * ISH_ERR 'Over 64Mbit
Dim isKnown As BOOL
GetChipsetString(header, VarPtr(isKnown))
If isKnown = FALSE Then GoTo * ISH_ERR
if header->Country >= SFC_COUNTRY__NUM then GoTo * ISH_ERR
if (header->RomSize = 0) And (header->CheckSum1 = 0) And (header->CheckSum2 = 0) then Goto *ISH_ERR
isSnesHeader = TRUE
ExitFunction
*ISH_ERR
isSnesHeader = FALSE
End Function
' Checksumが一致してるかチェック
Function CheckChecksum(info As *SFC_CART_INFO, actualSum AS Word) As BOOL
If info->CheckSum2 = (actualSum And &HFFFF) and info->CheckSum1 = (not(actualSum) And &HFFFF) Then
CheckChecksum = TRUE
Else
CheckChecksum = FALSE
End If
End Function
'チェックサム計算(Byte単位)
Function SumSnesChecksum(data As BytePtr,length As DWord) As DWord
Dim i As DWord
SumSnesChecksum=0
Do
SumSnesChecksum += data[i]
If i+1 => length Then ExitDo
i++
Loop
End Function
'チェックサム計算(ROM単位)
Function CalcSnesChecksum(info As *SFC_CART_INFO, rom As BytePtr, size As DWord) AS Word
CalcSnesChecksum = SumSnesChecksum(rom, size) As Word
if (info->MapType = SFC_MAP_SpLoROM) And (info->RomSize = 3*1024*1024) And size = info->RomSize Then
'Special LoROM 3MBの時はラスト8Mbitを再加算
CalcSnesChecksum += SumSnesChecksum(rom+1024*1024*2, 1024*1024)
Else if info->RomSize <> size Then
' ファイル入力時で実サイズとヘッダで差がある場合
Dim quarterSize As DWord
quarterSize = info->RomSize>>2
'trim済みっぽいとき
if size = quarterSize*3 Then
'DBM("[CalcSnesChecksum] trimmed?")
CalcSnesChecksum += SumSnesChecksum(rom+quarterSize*2, quarterSize)
End If
End If
End Function
' Trimできるかチェック, できるならトリム済みサイズを返す
' 2M+1M とかのROMはヘッダ上は4MB, この場合4MBで保存するとOverdump扱いとなるらしい。no-introのDBもTrim済みのROMでCRCを出しているはず
Function checkRomTrimmable(rom As BytePtr, romSize As DWord) AS DWord
Dim trimSum As Word
Dim trimQuarterSize As DWord
trimQuarterSize = romSize>>2
debug
if isSameBin(rom + trimQuarterSize*2, rom + trimQuarterSize*3, trimQuarterSize) Then
DBMf("[TrimRom] trimbale")
DBMf("[TrimRom] size=%d KB, %Xh",((trimQuarterSize*3)/1024) AS DWord, (trimQuarterSize*3) As DWord)
checkRomTrimmable = trimQuarterSize*3
Else
checkRomTrimmable = 0
End If
End Function