-
Notifications
You must be signed in to change notification settings - Fork 1
/
MemoryMapModel.sbp
649 lines (506 loc) · 20.7 KB
/
MemoryMapModel.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
'---------------------------
' SRAM Memory Model
'---------------------------
Typedef SfcMmcInitFunc = *Function(hCOM AS HANDLE) As BOOL
Typedef SfcMmcNextAddressFunc = *Function(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
Typedef SfcMmcExitFunc = *Function(hCOM AS HANDLE, romBuffer As BytePtr)
' romBufferは、SA1の先頭バイトが削れる問題に対処するためつける
Typedef SfcMmcSramNextAddressFunc = *Function(hSerial As HANDLE, mmodel As *SFC_MMAP_MODEL, bank AS DWord) As DWord
Const SFC_SRAM_MODEL_LENGTH = 3 'sizeof(SFC_SRAM_MODEL)/4-1
Type SFC_ROM_MODEL
adr As DWord ' ROMのアドレス
isLoROM AS BOOL ' アクセス方法
init_cb As SfcMmcInitFunc ' ROM吸い出し前の初期化処理, NULL可
next_cb As SfcMmcNextAddressFunc ' ROMアドレスをすすめる関数, NULLの場合isLoROMからデフォルトのnextAddressが選ばれる, バンク切り替えもここでする
exit_cb As SfcMmcExitFunc ' ROM吸い出し終了処理
End Type
Type SFC_SRAM_MODEL
adr As DWord 'セーブ用SRAMのアドレス
bankStep As DWord 'バンク間の差 (BANK0 70:0000, BANK1 71:0000なら0x010000)
bankSize As DWord 'そのバンクにおけるSRAM領域のサイズ
ctrlBus As DWord 'CEとかOEとかWEとか 書くとDisableになる。例外としてSRAM_CTRL_???の代入が許可されている
init_cb As SfcMmcInitFunc
next_cb As SfcMmcSramNextAddressFunc
exit_cb As SfcMmcExitFunc
End Type
Const MODEL_ARRAY_SIZE = 8'sizeof(SFC_MMAP_MODEL)/sizeof(VoidPtr)-1
Type SFC_MMAP_MODEL
sram As SFC_SRAM_MODEL
rom As SFC_ROM_MODEL
End Type
Const LoROM_OFFSET_ADR = &H008000
Const HiROM_START_ADR = &HC00000
TypeDef MODEL_ARRAY_TYPE = DWord '本当はVoidPtrのほうが良いけどキャストが面倒
' MemoryModelを決定する
Function GetMmapModel(info As *SFC_CART_INFO, isWrite AS BOOL, model As *SFC_MMAP_MODEL) As BOOL
' コールバックは省略可能
model->rom.init_cb = NULL
model->rom.next_cb = NULL
model->rom.exit_cb = NULL
model->sram.init_cb = NULL
model->sram.next_cb = NULL
model->sram.exit_cb = NULL
Select Case info->MapType
Case SFC_MAP_LoROM
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_HiROM
' &H206000
' SUPER DONKEY KONG 2 は 30:6000h ~
model->sram.adr = &H306000
model->sram.bankStep = &H010000
model->sram.bankSize = &H002000
model->sram.ctrlBus = CBUS_RST or CBUS_ROMSEL
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
'テイルズオブファンタジアなど
Case SFC_MAP_ExHiROM
model->sram.adr = &HB06000
model->sram.bankStep = &H010000
model->sram.bankSize = &H002000
model->sram.ctrlBus = CBUS_RST or CBUS_ROMSEL
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
model->rom.init_cb = NULL
model->rom.next_cb = AddressOf(ExHiROM_nextAddress)
model->rom.exit_cb = NULL
Case SFC_MAP_SA1
if isWrite Then
model->sram.adr = &H006000
model->sram.bankStep = &H010000
model->sram.bankSize = &H002000
model->sram.ctrlBus = CBUS_RST
model->sram.init_cb = AddressOf(SA1_SRAM_WRITE_init)
model->sram.next_cb = AddressOf(SA1_SRAM_WRITE_nextAddress)
model->sram.exit_cb = AddressOf(SA1_SRAM_WRITE_exit)
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
Else
model->sram.adr = &H400000
model->sram.bankStep = &H010000
model->sram.bankSize = &H010000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
End If
Case SFC_MAP_SDD1
model->sram.adr = &H806000
model->sram.bankStep = &H010000
model->sram.bankSize = &H002000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
model->rom.init_cb = AddressOf(SDD1_init)
model->rom.next_cb = AddressOf(SDD1_nextAddress)
model->rom.exit_cb = NULL
Case SFC_MAP_GSU
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H010000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_SPC7110
model->sram.adr = &H306000
model->sram.bankStep = &H010000
model->sram.bankSize = &H002000
model->sram.ctrlBus = CBUS_RST or CBUS_ROMSEL
model->sram.init_cb = AddressOf(SPC7110_SRAM_init)
model->sram.next_cb = NULL
model->sram.exit_cb = AddressOf(SPC7110_SRAM_exit)
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
model->rom.init_cb = AddressOf(SPC7110_init)
model->rom.next_cb = AddressOf(SPC7110_nextAddress)
model->rom.exit_cb = NULL
Case SFC_MAP_SpLoROM
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST 'or CBUS_ROMSEL
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
model->rom.init_cb = NULL
model->rom.next_cb = AddressOf(SpLoROM_nextAddress)
model->rom.exit_cb = NULL
Case SFC_MAP_BSX
model->sram.adr = &H105000
model->sram.bankStep = &H010000
model->sram.bankSize = &H001000
model->sram.ctrlBus = CBUS_RST or CBUS_ROMSEL
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_ST010
model->sram.adr = &H680000
model->sram.bankStep = &H010000
model->sram.bankSize = &H001000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_ST018
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_CX4_2DC0N
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
model->rom.init_cb = AddressOf(CX4_init_x2)
model->rom.next_cb = AddressOf(LoROM_nextAddress)
model->rom.exit_cb = NULL
Case SFC_MAP_CX4_1DC0N
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
model->rom.init_cb = AddressOf(CX4_init_x3)
model->rom.next_cb = AddressOf(LoROM_nextAddress)
model->rom.exit_cb = NULL
Case SFC_MAP_SF_MENU
model->sram.adr = &H700000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_XBAND
model->sram.adr = &HE00000
model->sram.bankStep = &H008000
model->sram.bankSize = &H008000 ' 32kbit x2 SRAM
model->sram.ctrlBus = CBUS_RST
model->sram.init_cb = AddressOf(XBAND_init)
model->sram.next_cb = NULL 'AddressOf(XBAND_SRAM_nextAddress)
model->sram.exit_cb = AddressOf(XBAND_exit)
model->rom.adr = HiROM_START_ADR
model->rom.isLoROM = FALSE
model->rom.init_cb = AddressOf(XBAND_init)
model->rom.next_cb = AddressOf(XBAND_nextAddress)
model->rom.exit_cb = AddressOf(XBAND_exit)
'JRA PAT用(Flash)
Case SFC_MAP_JRAPAT
model->sram.adr = &HC00000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST or CBUS_ROMSEL
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case SFC_MAP_SFTURBO
model->sram.adr = &H608000
model->sram.bankStep = &H010000
model->sram.bankSize = &H008000
model->sram.ctrlBus = CBUS_RST' or CBUS_ROMSEL
model->rom.adr = LoROM_OFFSET_ADR
model->rom.isLoROM = TRUE
Case Else
debug
DBM("Internal Error: Memory model is undefined.")
End Select
/*
If model->rom.next_cb = NULL Then
If model->rom.isLoROM Then
model->rom.next_cb = AddressOf(LoROM_nextAddress)
Else
model->rom.next_cb = AddressOf(HiROM_nextAddress)
End If
End If*/
End Function
'------------------------------
' Memory Controller Functions
'------------------------------
' ============== common memory mapping LoROM/HiROM =============
Function LoROM_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
LoROM_nextAddress = adr + readSize
if (LoROM_nextAddress And &HFFFF) < &H8000 Then LoROM_nextAddress += &H8000
End Function
Function HiROM_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
HiROM_nextAddress = adr + readSize
End Function
Function SramGeneric_nextAddress(hSerial As HANDLE, mmodel As *SFC_MMAP_MODEL, bank AS DWord) As DWord
SramGeneric_nextAddress = mmodel->sram.adr + bank * mmodel->sram.bankStep
End Function
' ============== SpLoROM =============
Function SpLoROM_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
SpLoROM_nextAddress = adr + readSize
if (SpLoROM_nextAddress And &HFFFF) < &H8000 Then SpLoROM_nextAddress += &H8000
if SpLoROM_nextAddress = &H408000 Then
SpLoROM_nextAddress = &H808000
DBM(ex"\r\nSpLoROM アドレスジャンプ $80:8000~")
End If
End Function
' ============== ExHiROM =============
Function ExHiROM_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
ExHiROM_nextAddress = adr + readSize
' $C0:0000~$FF:FFFFまで吸ったら次は$40:0000~$7F:FFFF
if ExHiROM_nextAddress > &HFFFFFF Then ExHiROM_nextAddress = &H400000
End Function
' ============== SDD1 =============
Function SDD1_init(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
' 最初はROMバンク0~3を吸い出す
SDD1_SetBanks(hCOM, 0)
SDD1_PrintBanks(hCOM)
SDD1_init = TRUE
End Function
Function SDD1_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
SDD1_nextAddress = adr + readSize
If SDD1_nextAddress > &HFFFFFF Then
'ROMバンク0-3を吸い出したので、4-7バンクを吸い出す
SDD1_SetBanks(hCOM, 4)
SDD1_PrintBanks(hCOM)
SDD1_nextAddress = HiROM_START_ADR
End If
End Function
'SDD1のバンクをセットアップ
'SNESバンクC0, D0, E0, F0にbankStartから始まるROMバンク(1MByteごと)を割り当て
Sub SDD1_SetBanks(hCOM As HANDLE, bankStart As Long)
Dim buf[3] As Byte, i As Long
DBM(sprintfStr("Setting S-DD1 bank %d-%d...", bankStart, bankStart + 3))
For i = 0 To 3
buf[i] = (bankStart + i) As Byte
Next i
SendControl(hCOM, CBUS_RST Or CBUS_OE)
WriteROM(hCOM, buf, 0, &H004804, 4, FALSE)
SendControl(hCOM, CBUS_DEFAULT)
End Sub
'現在のSDD1のバンク設定をGUIに出力
Sub SDD1_PrintBanks(hCOM As HANDLE)
Dim buf[3] As Byte, i As Long
SendControl(hCOM, CBUS_DEFAULT)
ReadROM(hCOM, buf, 0, &H004804, 4, FALSE)
For i = 0 To 3
DBM(sprintfStr("%X00000h-%XFFFFFh : ROM bank%d", &HC + i, &HC + i, buf[i]))
Next i
End Sub
' ============== SA1 =============
Function SA1_SRAM_WRITE_init(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
SA1_SramInit(hSerial)
End Function
Function SA1_SRAM_WRITE_nextAddress(hSerial As HANDLE, mmodel As *SFC_MMAP_MODEL, bank AS DWord) As DWord
SA1_SramBankSel(hSerial, bank As Byte)
SA1_SRAM_WRITE_nextAddress = mmodel->sram.adr
End Function
Function SA1_SRAM_WRITE_exit(hCOM AS HANDLE, info As *SFC_CART_INFO, romBuffer As BytePtr)
SA1_SramExit(hCOM, romBuffer)
End Function
/*
Sub SA1_Init(hSerial As HANDLE)
SetCPU_Clock(hSerial, HKAC_CLOCK_CPU_OVERCLOCKED)
SetCPU_Clock(hSerial, HKAC_CLOCK_CPU_ENABLED)
Sleep(500)
End Sub
Sub SA1_DeInit(hSerial As HANDLE)
SetCPU_Clock(hSerial, HKAC_CLOCK_NORMAL)
End Sub
Sub SA1_BankCtrl(hSerial As HANDLE, startBank As Long)
SetCartRegister(&H00, &H2220, startBank + 0, FALSE)
SetCartRegister(&H00, &H2221, startBank + 1, FALSE)
SetCartRegister(&H00, &H2222, startBank + 2, FALSE)
SetCartRegister(&H00, &H2223, startBank + 3, FALSE)
End Sub
*/
Sub SA1_SramInit(hSerial As HANDLE)
'SA-1レジスタセットアップ
' バス釣り:OVERCLOCKだと成功する, NORMALだと書きこぼしがある
' 星:OVERCLOCKだと下記こぼす, NORMALだと成功する
' -> WRITEパルス伸ばして解決
SetCPU_Clock(hCOM,HKAC_CLOCK_CPU_ENABLED) 'Enable CPU Clock for Writing SA-1 Register
Sleep(500)
SetCartRegister(&H00, &H2224, &H00, FALSE) 'SNES CPU BW-RAM Mapping to 6000h-7FFFh (W)
SetCartRegister(&H00, &H2226, &H80, FALSE) 'SNES CPU BW-RAM Write Enable (W)
SetCartRegister(&H00, &H2228, &H00, FALSE) 'BW-RAM Write-Protected Area (W)
Sleep(100)
End Sub
Sub SA1_SramBankSel(hSerial As HANDLE, bank As Byte)
'SA-1 SRAM バンク切り替え
SetCartRegister(&H00, &H2224, bank As Byte , FALSE) 'SNES CPU BW-RAM Mapping to 6000h-7FFFh (W)
SetCartRegister(&H00, &H2226, &H80 , FALSE) 'SNES CPU BW-RAM Write Enable (W)
End Sub
Sub SA1_SramExit(hSerial As HANDLE, sramBuffer As BytePtr)
'SRAMを最後まで書き込んだ後、何故かSRAMの先頭バイトが0x00になってしまうので再度書き込み
SendControl(hSerial,CBUS_RST OR CBUS_ROMSEL OR CBUS_OE OR CBUS_WE)
SetCartRegister(&H00, &H2224, 0 , FALSE) 'SNES CPU BW-RAM Mapping to 6000h-7FFFh (W)
SetCartRegister(&H00, &H2226, &H80, FALSE) 'SNES CPU BW-RAM Write Enable (W)
SetCartRegister(&H00, &H6000, sramBuffer[0], FALSE) 'Rewrite First Byte
Sleep(100)
SetCartRegister(&H00, &H2226, &H00, FALSE) 'SNES CPU BW-RAM Write Enable (W)
'CPUクロックを停止してフィニッシュ
SetCPU_Clock(hCOM, HKAC_CLOCK_NORMAL)
End Sub
' ============== SPC7110 =============
Function SPC7110_init(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
DBM("Checking SPC7110...")
If SPC7110_SetBanks(hSerial, 1, FALSE) = FALSE or _
SPC7110_SetBanks(hCOM, 0, FALSE) = FALSE Then
ErrMes(hMainWnd, ex"SPC7110のセットアップに失敗しました。\nSA-1追加回路が接続されているか確認し、Arduinoを再起動してください。", "SPC7110 Bank Control Error", 0)
ExitSub
End If
SPC7110_PrintBanks(hCOM)
SPC7110_init = TRUE
End Function
Function SPC7110_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
SPC7110_nextAddress = adr + readSize
If SPC7110_nextAddress > &HFFFFFF Then
'ROMバンク0-3を吸い出したので、4-7バンクを吸い出す
DBM("")
SPC7110_SetBanks(hSerial, 1, FALSE) 'D0:1,E0:2,F0:3 ... F0:0000にデータROMのバンク3をマップ
SPC7110_nextAddress = HiROM_START_ADR + &H300000 'F0:0000からリスタート
End If
End Function
Function SPC7110_SRAM_init(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
SPC7110_SetBanks(hCOM, 0, TRUE) 'SRAM ENABLE
End Function
Function SPC7110_SRAM_exit(hCOM AS HANDLE, info As *SFC_CART_INFO, romBuffer As BytePtr)
SPC7110_SetBanks(hCOM, 0, FALSE) 'SRAM DISABLE
End Function
Const SNES_SPC7110_VBANKS_COUNT = 3
Const SNES_SPC7110_MMC_REG_SIZE = SNES_SPC7110_VBANKS_COUNT+2
Const SNES_SPC7110_MMC_ADR = &H4830
Function SPC7110_SetBanks(hCOM As HANDLE,bank As Long,bSRAM_Enable As BOOL) As BOOL
Dim buf[SNES_SPC7110_MMC_REG_SIZE] As Byte, i As Long
If bSRAM_Enable Then
DBM("[SPC7110]SRAM Enable")
Else
DBM("[SPC7110]SRAM Disable")
End If
'RESET
SendControl(hCOM,CBUS_WE or CBUS_ROMSEL or CBUS_OE)
For i=0 To SNES_SPC7110_VBANKS_COUNT-1
buf[i+1] = (bank+i) As Byte
DBM(sprintfStr("[SPC7110]SET_VBANK%X:%0d ",i,buf[i+1]))
Next i
buf[0]=(bSRAM_Enable<<7) As Byte
buf[4]=&H03 '3バンク変更する
SendControl(hCOM, CBUS_RST or CBUS_ROMSEL or CBUS_OE)
WriteROM(hCOM, buf, 0, SNES_SPC7110_MMC_ADR, SNES_SPC7110_MMC_REG_SIZE, FALSE)
SendControl(hCOM, CBUS_DEFAULT)
ReadROM(hCOM, buf, 0, SNES_SPC7110_MMC_ADR, SNES_SPC7110_MMC_REG_SIZE, FALSE)
'check bank
SPC7110_SetBanks=TRUE
For i=0 To SNES_SPC7110_VBANKS_COUNT-1
If buf[i+1] <> bank+i Then SPC7110_SetBanks=FALSE : ExitFor
Next i
If SPC7110_SetBanks=FALSE Then
DBM("bank change failed")
End If
End Function
Sub SPC7110_PrintBanks(hCOM As HANDLE)
Dim buf[SNES_SPC7110_MMC_REG_SIZE] As Byte, i As Long ' SendControl(hCOM,CBUS_RST or CBUS_WE)
SendControl(hCOM, CBUS_DEFAULT)
ReadROM(hCOM, buf, 0, SNES_SPC7110_MMC_ADR, SNES_SPC7110_MMC_REG_SIZE, FALSE)
If buf[0] And &H80 Then
DBM("SRAM-ENABLE")
Else
DBM("SRAM-DISABLE")
End If
For i = 1 To SNES_SPC7110_VBANKS_COUNT
DBM(sprintfStr("%X00000h-%XFFFFFh : ROM bank%d", & HC + i, & HC + i, buf[i]))
Next i
DBM("Logical-MaxBank : " + Str$(buf[4]))
End Sub
' ============== CX4 =============
Function CX4_init_x2(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
DBM("CX4 for ROCKMAN X2")
' https://sd2snes.de/files/cx4_notes.txt
/*
$7f52: ROM configuration select
LoROM: 0: 2x 8Mbit (A21 switches between ROM /CE1 and /CE2)
1: 1x 16Mbit (maybe A22 switches but 40-7f/c0-ff are inactive)
HiROM: 0: 2x 8Mbit (A20 switches)
1: 2x 16Mbit (A21 switches)
*/
' Set ROM configuration to 2xROM (8Mx2)
SetCartRegister(0, &H7f52, 0)
CX4_init_x2 = TRUE
End Function
Function CX4_init_x3(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
DBM("CX4 for ROCKMAN X3")
' Set ROM configuration to 1xROM (16Mx1)
SetCartRegister(0, &H7f52, 1)
CX4_init_x3 = TRUE
End Function
' ============== XBAND =============
Function XBAND_init(hSerial AS HANDLE, info As *SFC_CART_INFO) As BOOL
/*
https://problemkaputt.de/fullsnes.htm#snescartxbandmisc
D00000h-DFFFFFh 1MB ROM (executed here, not at C00000h-CFFFFFh)
E00000h-E0FFFFh 64K SRAM (in two 32Kx8 chips) (unknown if BOTH have battery)
FBC000h-FBC17Fh I/O Ports (unknown functions?)
FBC180h-FBC1BFh I/O Ports (Rockwell Modem Chip)
FBFC02h I/O Port (unknown functions?)
here→FBFE00h I/O Port (unknown functions?)
FFC000h I/O Port (unknown functions?)
004F02h I/O Port (unknown functions?)
00F000h Dummy/strobe read?
00FFE0h Dummy/strobe read?
*/
/*
FE02h - ControlReg (aka reghere)
;control bits for control register ;aka "kControlReg"? and/or "kCtlRegSoft"?
0 EnTwoRam: equ $01 ;<-- maybe disable one of the two SRAMs?
1 EnSafeRom: equ $02 ;<-- maybe SRAM read-only? or FlashROM?
2 RomHi: equ $04 ;
3 EnInternal: equ $08 ;<-- maybe disable ports C000h..C1FFh?
4 EnFixedInternal: equ $10 ;<-- maybe whatever related to above?
5 EnSNESExcept: equ $20 ;
6-7 Unknown/unused
*/
/*
XBAND LED: (正面から)
LED1: ???
LED3: モデム?
LED5: 電源?
*/
Const XBAND_LED_POWER = &H20
Const XBAND_LED_MODEM = &H08
Const XBAND_LED_LED1 = &H02
Const XBAND_LED_ALL = XBAND_LED_POWER or XBAND_LED_MODEM or XBAND_LED_LED1
Const XBAND_CTRL_EnTwoRam = &H01
Const XBAND_CTRL_EnSafeRom = &H02
Const XBAND_IOP_BANK = &HFB
Const XBAND_IOP_CTRL_REG = &HFE02
Const XBAND_IOP_LED_DATA = &HC168
Const XBAND_IOP_LED_DIR = &HC16A
' 2つ目のSRAMを有効にする
SetCartRegister(XBAND_IOP_BANK, XBAND_IOP_CTRL_REG, XBAND_CTRL_EnTwoRam or XBAND_CTRL_EnSafeRom, FALSE)
'なんとなくLEDを光らせる
SetCartRegister(XBAND_IOP_BANK, XBAND_IOP_LED_DATA, XBAND_LED_ALL, FALSE)
SetCartRegister(XBAND_IOP_BANK, XBAND_IOP_LED_DIR, XBAND_LED_ALL, FALSE)
XBAND_init = TRUE
End Function
' 呼ばれるたびにLEDの点灯パターンを変える関数
Sub XBAND_LedBlink(hSerial As HANDLE)
Dim led As Long, reg As Byte
ReadROM(hSerial, VarPtr(reg), 0, XBAND_IOP_BANK<<16 or XBAND_IOP_LED_DATA, 1, FALSE)
reg = (NOT(reg) And XBAND_LED_ALL) AS Byte
led = ((reg>>1) And 1) or (((reg>>3) And 1)<<1) or (((reg>>5) And 1)<<2)
led = ((led+1) Mod 8) AS Byte
reg = (((led And 1)<<1) or ((led And 2)<<2) or ((led And 4)<<3) ) As Byte
SetCartRegister(XBAND_IOP_BANK, XBAND_IOP_LED_DATA, reg, FALSE)
End Sub
Function XBAND_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
if (adr And &H020000) And ((adr and &HFFFF)=&H8000) Then XBAND_LedBlink(hSerial)
XBAND_nextAddress = HiROM_nextAddress(hSerial, adr, readSize)
End Function
Function XBAND_SRAM_nextAddress(hSerial As HANDLE, mmodel As *SFC_MMAP_MODEL, bank AS DWord) As DWord
XBAND_LedBlink(hSerial)
XBAND_SRAM_nextAddress = mmodel->sram.adr + bank * mmodel->sram.bankStep
End Function
Function XBAND_exit(hCOM AS HANDLE, info As *SFC_CART_INFO, romBuffer As BytePtr)
SetCartRegister(XBAND_IOP_BANK, XBAND_IOP_LED_DATA, &H00, FALSE)
End Function
' ============== FILE ACCESS =============
Function RomImage_nextAddress(hSerial As HANDLE, adr AS DWord, readSize AS DWord) As DWord
RomImage_nextAddress = adr + readSize
End Function
' ======================== MEMORY MODEL CALLBACKS ========================