<copy paste from my own forum:
https://board.byuu.org/viewtopic.php?f= ... 166#p57166>
I rewrote my BS Memory flash emulation to use type 1 cartridges instead of type 2 cartridges, since only type 1 cartridges actually exist. I may or may not bother with type 2. Kind of annoying to emulate something that's impossible to test.
I ran my own hardware tests to clarify some things, and discovered some new information.
First, the MCC has two types of write-enable for the BS memory carts.
$0c5000.d7 enables the query interface
$0d5000.d7 enables the write command (the one that clears bits)
If you don't set $0c5000.d7 and commit the change (by writing $0e5000.d7), then all writes to the BS memory cart will fail, and all reads will be the ROM data. It will act exactly like a ROM cartridge. If you do set it, then you can write values to it to query status registers, vendor information, erase data, and write bytes.
If you don't *also* set $0d5000.d7, then all writes (type 1 flash commands $10 and $40) will fail. However, *erases still work!* even if you don't set $0d5000.d7. Both the 64K page erase, and the entire-chip erase work regardless of $0d5000.d7.
Obviously, if $0c5000.d7 is clear, there's no way to trigger a write, so for write commands to work, you must have both $0c5000.d7 and $0d5000.d7 set.
Next, $0f5000.d7 is truly bizarre. If I write $0f5000.d7=1, then I can read any one $0x5000 status register. The second time I try and read one, the entire SNES deadlocks until I reset it. If I write $0f500.d7 before every read, then I read back the same exact values I normally get from $0x5000.
This does not appear to be an extra page of extended bits, at least not on my system.
I still don't emulate $01500.d7 IRQs. Unsure how exactly those work.
Okay, now for the flash carts themselves ... there are no two-byte commands as with bsnes-plus.
Writes act on the current mode, and then change the mode, but only when the low 16-bits of the address are all zeroes. So $c00000 and $cf0000 will work for writing $75 to get vendor information, but $c08000 will not. I'm guessing in LoROM configuration that it's the decoded low 16-bits? But I didn't verify that.
So with this setup, if you write $10 to write a byte, or $20 to erase a page, or even $a7 to erase the entire chip (which ostensibly doesn't need another byte of data), nothing will happen until the next write, which doesn't care about the address (other than $20 using the upper eight bits instead of the data bus bits to determine which page to clear.)
nocash mentioned $97 being some kind of alternate full-chip erase mode ... it does nothing here, whereas $a7 does.
Revenant had $40 as an alternate write command, and I can confirm that does indeed work. Weird.
$10, $20, $40, $a7 writes seem to kick the mode to $70 automatically. Games seem to do it anyway, but it doesn't appear necessary to do so.
Reading from mode $70 always returns a single status byte, no matter what the address is.
Reading from $71 always returns zeroes, except in three cases that I can see:
(address&$ffff) == 2
(address&$ffff) == 4
(address&$ffff) == 6
The last one is usually zero, but if perform an erase command, the value changes around. I've seen $70 and $8f from it.
I'm going to guess that (address&$ffff) == 0 is something too, but so far it only returns zeroes for me.
Reading from mode $75 returns vendor information. In this case, it looks at the low 8-bits of the address.
(address&$ff) == 0 ? return 'M'
(address&$ff) == 2 ? return 'P'
(address&$ff) == 4 ? return 4 (unknown purpose)
(address&$ff) == 6 ? return type << 4 | log2(size >> 10);
All other addresses return ... noise. I tried four different BS memory packs, and all four had different values in every single byte, and the values never changed. The values are not ROM values, and they're not open bus.
Here, see if you can make any sense out of it:
Code:
[Cartridge 1] => 4d 50 04 1a 00 00 20 31 22 99
c0ff00 4d 1c 50 16 04 ef 1a 7d 00 bf 00 6e 20 eb 31 05
c0ff10 22 73 99 52 f6 cb 4a d3 64 fb 7e 78 1a d8 20 27
c0ff20 55 cd 4c e4 f7 58 2f df 27 d7 75 a8 e6 3a b0 28
c0ff30 f4 9b 2e 21 fe fa c8 3c 99 af a6 9f f0 ff 13 a2
c0ff40 50 b6 fa e4 af ad 0f 30 2c 9d b3 7d 73 96 ee 85
c0ff50 00 34 14 a2 77 63 70 79 23 33 f5 64 d7 e1 8a e8
c0ff60 e9 94 68 30 b8 6d ce 71 ba ff e7 64 93 82 9e 7b
c0ff70 12 29 5a 8c 6a cf e5 bc 6a 98 bb 4d 8f a0 9d 61
c0ff80 8e e9 36 a6 f0 28 7b 8a 4b df d9 6b 49 06 12 82
c0ff90 68 0e 15 a4 db 9d ab 5d 6c 35 b3 37 75 0e 46 60
c0ffa0 11 e7 19 1b 2e 7d 99 ac bf 0e 9a 8f 3a e2 98 07
c0ffb0 94 ec 4a e3 e2 fb f2 7e 16 1e 7b fd 11 2a 03 f6
c0ffc0 d5 00 20 89 9e 32 0d bd 75 69 ed fa 2f dc 06 01
c0ffd0 78 2b df 4b 3f 3f 1e d4 de 7a 93 5a 1e 43 51 ae
c0ffe0 fc d2 20 21 54 f3 0b e7 ff ef 8b dd 93 52 d6 c5
c0fff0 32 66 30 b8 6c 5f 0a f3 83 e5 7f f8 0f f3 2e 64
[Cartridge 2] => 4d 50 04 1a 00 00 20 41 12 33
c0ff00 4d e7 50 d5 04 ef 1a df 00 6f 00 ff 20 59 41 94
c0ff10 12 2c 33 b3 47 6d 73 ed 6c d6 ff fd 48 00 13 03
c0ff20 03 a8 a3 63 ed 69 bf de ef fd fe ff de ce a5 12
c0ff30 b2 33 a0 a9 e7 ef 9f f1 4b 7d de 7f fc 40 20 51
c0ff40 b1 64 03 82 a9 7f df da ca e7 ba f7 34 5a c0 44
c0ff50 a0 26 1f 2e b7 0b 3b a5 bb bb 35 be b0 d6 41 48
c0ff60 1a 47 16 4c 97 c3 53 fa fa 7e df ff b0 1e a6 60
c0ff70 f6 84 a4 0f 1f ad ed 3f ef ff af e9 1c 80 34 80
c0ff80 87 98 8a 14 fb 7d f6 fa 2e 3d ef fc c1 d3 93 65
c0ff90 55 05 ed 47 bd e3 17 1b 3b fb 7d 75 39 64 4d 61
c0ffa0 02 c6 28 50 e6 df a9 7e fe 7f e3 fd 2b 43 af 04
c0ffb0 1c 3c 67 92 69 ab 7a bd 7f af a5 f7 03 cb 80 de
c0ffc0 4a 58 21 48 fe 73 87 bf 7d 6e ff fd 08 84 5a 30
c0ffd0 18 07 92 69 9f fd ff 75 7a cf ef 8e 48 d2 e5 5a
c0ffe0 1a 83 60 74 4f de 72 b7 bf f3 fb fb 09 81 a3 69
c0fff0 38 64 57 94 ed 7a f1 fd bf ff e3 fb 82 15 e2 94
[Cartridge 3] => 4d 50 04 1a 00 01 40 41 70 59
c0ff00 4d ab 50 7a 04 0b 1a fe 00 34 01 fc 40 f6 41 02
c0ff10 70 89 59 89 fe 97 bd bd 9f 54 df 7a bc 8a c6 bf
c0ff20 03 94 f9 88 3d d3 f7 fd 36 7e e7 fe cf 6f ed 19
c0ff30 93 94 1e 6a ac 0f fb d9 53 72 c7 fe f7 92 db 0e
c0ff40 0e 2a 1b 23 5b d4 9b fd be fb 67 5c 24 d1 7f 56
c0ff50 b8 44 c6 2e 13 a5 fe ef e5 d7 ad 3a 7b 3e d7 03
c0ff60 02 bf dc e1 f4 6b f7 d9 31 56 3a 58 21 30 9e 62
c0ff70 bd b0 ea 59 79 7b 34 6c 77 ba 27 fd a1 1a 98 91
c0ff80 3a 3e 9c 3b d9 ac b7 e7 76 cf 2c fd fc 3f f9 1b
c0ff90 2e aa 32 ed 9e ce b7 1c 39 fb f3 b7 3f 58 05 46
c0ffa0 09 93 17 80 6f e6 f6 04 ef ed 0f bf c1 26 7b 74
c0ffb0 84 a3 36 b2 86 0a b4 fd 6b b3 85 f6 54 12 60 94
c0ffc0 5f 91 3a 78 a4 03 d7 18 ef 89 5c 7f 1d 47 2c 20
c0ffd0 bd 57 f2 00 da a2 1e 87 7f f0 e0 b9 2d 35 2b ab
c0ffe0 70 6f c5 7b 9d 90 17 5d bd f7 dd fe 01 6a 3d fd
c0fff0 1e f3 ac 8b df ba b6 dc 27 c6 ab 79 35 98 87 ac
[Cartridge 4] => 4d 50 04 1a 00 91 90 70 31 03
c0ff00 4d 42 50 ca 04 bc 1a 7f 00 fe 91 ed 90 6a 70 28
c0ff10 31 90 03 9c c2 ff 5f 47 dd fb 7e bd 01 00 cc 02
c0ff20 37 22 5c 40 5a f7 e7 f5 df fe fe d7 10 00 4b 94
c0ff30 95 8a f5 0e 65 de eb fd ba 3b fe ff b7 4c e0 28
c0ff40 23 46 46 31 ee ff ff fb ff ff ff f9 4f 18 92 54
c0ff50 e8 03 40 00 f7 66 7f 3d ff d7 eb 5f 00 32 12 40
c0ff60 a2 29 95 80 97 bb fe 77 fe de 3f eb 07 60 98 c8
c0ff70 83 a9 64 a0 fd 6e ff ed fe ff eb fb 25 36 c8 48
c0ff80 a9 38 c2 44 5d 79 7b 7f ff 77 f7 ff 44 1b 62 9d
c0ff90 a8 02 04 60 ff df ff f9 bf b7 de 3d 22 b2 25 02
c0ffa0 1b c3 23 04 f7 6f 9d bf bf ff fd 9f b2 e3 eb 3a
c0ffb0 40 0f 4b 06 fd 2f eb ec ff f7 bf f9 84 47 06 94
c0ffc0 02 00 67 50 ff ef ce bb fb bf fb 3f 4e 38 62 04
c0ffd0 56 60 5b 11 fe a9 bf 9f f7 ab 8f de b1 40 0c ea
c0ffe0 26 70 15 05 ef be ee eb ff ff fd f3 08 08 5a a0
c0fff0 60 46 81 04 f7 ff e2 3e ff 5f ff fb 80 a2 e6 61
One pack had an RPG Tsukuru 2 save on it, and I get the exact same 256 values back even after I later erased the cartridge. If it was reading data from the BS-X Town cart ROM/SRAM/PSRAM, then it'd be the same values for all cartridges, but it isn't.
Again note it only looks at address&$ff. You can read from $c00000 or $c1fe00 and get the same data. If you try and read from $c0ff02, it starts from address 2, not 0, so it's not a counter.
More fun ... there's a ton of mirrors of the three readout modes.
$70 mirrors to $76 - $7d, and I also saw it at $6d and then stopped because what the hell >_<
$71 mirrors to $72 - $74, and probably to more areas.
I didn't try and enumerate all 256 values because some of them are write/erase commands.
I'll need to write a fancier test that tries all 256 values and maps out what they do, I guess.