[Hard+Soft] Memory Base 128
Re: [Hard+Soft] Memory Base 128
The code to check for Memory Base 128 presence is roughly the same.
Code: Select all
;-----------------------------------------------------------------------
; Detect Memory Base 128.
; A = #$00 found.
; A = #$ff not found.
;-----------------------------------------------------------------------
l618c_00: LDA #$03 ; 3 try
STA $e209
l6191_00: INC $e20b
LDA #$a8
JSR l61cc_00 ; write byte (#$a8)
LDA #$00 ; write bit 0 and read joyport
JSR l6200_00
TAY ; save joyport to Y
LDA #$01 ; write bit 1 and read joyport
JSR l6200_00
CPY #$00 ; try again if Y is not zero
BNE l61af_00
CMP #$04 ; try again if the last read nibble is 4
BNE l61af_00
JMP l61c3_00
l61af_00: INC $e20c
DEC $e209
BEQ l61ba_00
JMP l6191_00
l61ba_00: CLA ; mb128 not found
LDX #$03 ; write 3 bits (000)
JSR l61d1_00
LDA #$ff
RTS
l61c3_00: LDA #$00 ; mb128 found
RTS
Re: [Hard+Soft] Memory Base 128
$606f contains a single bit read.
So from the other 2 games, a read sequence is initiated by writing the following bit sequence:
Somewhere along those bits is the read address. A code place too investigate is $60a8.
Code: Select all
l606f_00: STZ $e20b
STZ $e20c
INC <$28
; Send 3 zero bits.
JSR l61c6_00
; Detect mb128
JSR l618c_00
ORA #$00
; There's no mb128 if the N flag is set
BMI l60a5_00
; Send 1 one bit
JSR l61e2_00
; Send byte #$00
CLA
JSR l61cc_00
; Send 2 zero bits
CLA
LDX #$02
JSR l61d1_00
; Send byte #$01
LDA #$01
JSR l61cc_00
; Send byte #$00
CLA
JSR l61cc_00
; Send 4 zero bits
CLA
LDX #$04
JSR l61d1_00
; Read data
JSR l6279_00
; Send 3 zero bits
JSR l61c6_00
; Set return code
LDA #$00
l60a5_00: DEC <$28
RTS
Code: Select all
100 00000000 00000001 00000000 0000
Re: [Hard+Soft] Memory Base 128
Here is 2 utility routines. The first one left shift a 16bits word by 3, storing the result in 3 bytes. The second sends 20bits to the memory base 128.
And now, the read routine:
So the read sequence is initiated by sending with yyyyyyyyyyyyyyyyyyyy the 20 bits long read address.
The 10 bits xxxxxxxxxx are still unknown. So far, the only call to $60a8 found set them to 0.
Just after $60a8 comes the routine to write multiple bytes.
The write sequence is initiated by sending : We can easily conclde that the first bit tells if we are reading or writing.
Next: Figure out how data is stored (i.e. the "filesystem").
Code: Select all
; Left shift a word by 3.
; in: $e206/$e207 input word
; out: $e204/$e205 input word
; $e206/$e207/$e208 input word shifted to the left by 3.
l6220_00: LDA $e206
STA $e204
LDA $e207
STA $e205
STZ $e208
LDX #$03
l6231_00: ASL $e206
ROL $e207
ROL $e208
DEX
BNE l6231_00
RTS
Code: Select all
; Send 20 bits to mb128
; in: $e206/$e207/$e208 20 bits to send.
l623e_00: LDA $e206
JSR l61cc_00 ; Send byte
LDA $e207
JSR l61cc_00 ; Send byte
LDA $e208
LDX #$04
JSR l61d1_00 ; Send 4 bits
RTS
Code: Select all
; Read bytes from mb128.
; in: $10/$11 Output buffer address.
; $12/$13 Read address
; $e200/$e201 ?
; $e204/$e205 Number of bytes to read.
;
l60a8_00: INC <$28 ; Is $28 some kind of lock?
JSR l618c_00 ; Detect mb128
BMI l610b_00 ; There's no mb128 if the N flag is set
STZ $e202
STZ $e203
LDA <$12
STA $e206
LDA <$13
STA $e207 ; addr = ($13 << 8) | $12
JSR l6220_00 ; addr <<= 3
JSR l61e2_00 ; Send bit #1
LDA $e200
JSR l61cc_00 ; Send byte
LDA $e201
LDX #$02
JSR l61d1_00 ; Send 2 bits
JSR l623e_00 ; Send the 20 bits address
l60d6_00: JSR l6253_00 ; Read a byte
STA [$10] ; Store byte
CLC ; Increment the number of byte read
ADC $e202
STA $e202
LDA $e203
ADC #$00
STA $e203
INC <$10 ; Increment storage address
BNE l60f0_00
INC <$11
l60f0_00: LDA $e204 ; Decrement number of bytes to read
BNE l60f8_00
DEC $e205
l60f8_00: DEC $e204
LDA $e204
ORA $e205
BNE l60d6_00 ; Loop until there is nothing to read
JSR l61c6_00 ; Send 3 zero bits
LDA #$00 ; ret = ok
JMP l610d_00
l610b_00: LDA #$01 ; ret = err
l610d_00: DEC <$28 ; Release lock?
ORA #$00
RTS
; Left shift a word by 3.
; in: $e206/$e207 input word
; out: $e204/$e205 input word
; $e206/$e207/$e208 input word shifted to the left by 3.
l6220_00: LDA $e206
STA $e204
LDA $e207
STA $e205
STZ $e208
LDX #$03
l6231_00: ASL $e206
ROL $e207
ROL $e208
DEX
BNE l6231_00
RTS
; Send 20 bits to mb128
; in: $e206/$e207/$e208 20 bits to send.
l623e_00: LDA $e206
JSR l61cc_00 ; Send byte
LDA $e207
JSR l61cc_00 ; Send byte
LDA $e208
LDX #$04
JSR l61d1_00 ; Send 4 bits
RTS
Code: Select all
1_xxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy
The 10 bits xxxxxxxxxx are still unknown. So far, the only call to $60a8 found set them to 0.
Just after $60a8 comes the routine to write multiple bytes.
Code: Select all
; Write bytes from mb128.
; in: $10/$11 Input buffer address.
; $12/$13 Write address
; $e200/$e201 ?
; $e204/$e205 Number of bytes to write.
;
l6112_00: INC <$28
JSR l618c_00 ; Detect mb128
BMI l6185_00 ; There's no mb128 if the N flag is set
STZ $ea11
STZ $ea12
LDA <$12
STA $e206
LDA <$13
STA $e207 ; addr = ($13 << 8) | $12
JSR l6220_00 ; addr <<= 3
JSR l61de_00 ; Send bit #0
LDA $e200
JSR l61cc_00 ; Send byte
LDA $e201
LDX #$02
JSR l61d1_00 ; Send 2 bits
JSR l623e_00 ; Send the 20 bits address
l6140_00: LDA [$10]
JSR l61cc_00 ; Write byte
LDA $ea11
CLC
ADC [$10]
STA $ea11
LDA $ea12
ADC #$00
STA $ea12
INC <$10 ; Increment storage address
BNE l615c_00
INC <$11
l615c_00: LDA $e204 ; Decrement the number of bytes to write
BNE l6164_00
DEC $e205
l6164_00: DEC $e204
LDA $e204
ORA $e205
BNE l6140_00 ; Loop until there is nothing to write
JSR l6279_00 ; Read a single bit
JSR l6279_00 ; Read a single bit
PHA
JSR l61c6_00 ; Send 3 zero bits
PLA
BNE l6180_00 ; Check if the last read bit is not 0
LDA #$00
BRA l6182_00
l6180_00: LDA #$06
l6182_00: JMP l6187_00
l6185_00: LDA #$01
l6187_00: DEC <$28
ORA #$00
RTS
Code: Select all
0_xxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy
Next: Figure out how data is stored (i.e. the "filesystem").
Re: [Hard+Soft] Memory Base 128
The header data for a newly formatted mb128 seems to be
The code that will copy the pre-built savegames (see emedora.bin attached below) to mb128:
Code: Select all
32 06 02 00 d2 d3 d8 cd de b0 bd 31 32 38 00
Code: Select all
789f: lda #$5f
sta $10
lda #$67
sta $11
lda $775f
sta $12
lda $7760
sta $13
jsr $651f
rts
- Attachments
-
- emedora.bin
- (1 KiB) Downloaded 974 times
Re: [Hard+Soft] Memory Base 128
Here's some progress (using Tadaima Yuusha Boshuuchuu and etripator v0.4).
The following routine writes 1024 bytes at the bank #0 of the memory base 128.
The first 16 bytes are copied from $73b1. Bytes 4 to 15 are the infamous "メモリベース128" string.
Unfortunately I don't know what the first 4 bytes stands for.
The following routine writes 1024 bytes at the bank #0 of the memory base 128.
The first 16 bytes are copied from $73b1. Bytes 4 to 15 are the infamous "メモリベース128" string.
Unfortunately I don't know what the first 4 bytes stands for.
Code: Select all
mb128_format: ; $7387
PHP
SEI
PHX
PHY
TII $73b1, $8000, $0010
STZ $8010
TII $8010, $8011, $03ef
LDA #$00
STA <$f8
LDA #$80
STA <$f9
STZ <$fa
LDA #$01
STA <$fb
JSR mb128_write_sectors
PLY
PLX
PLP
RTS
mb128_header: ; $73b1
; ???
.db $30, $06, $00, $00
; メモリベース128
.db $D2, $D3, $D8, $CD, $DE, $B0, $BD, $31, $32, $38, $00, $00
Re: [Hard+Soft] Memory Base 128
The routine $76cf reads the first sectors and check it contains a valid memory base 128 header.
The header is valid if the following conditions are met:
In fact these bytes are set by mb128_read_sectors. It's the sum of the bytes of the sector. So it can be viewed as a CRC.
The header for an empty mb128 is:
If we sum all the bytes except the first 2 ones, we have:
And this is what we have in the first two bytes $30 and $06.
So the substraction/comparaison is just a CRC check. It seems complicated.. Why not just compare the values of $fc,$fd and $f8,$f9?
Anyway, one mystery solved. The 3rd and 4th bytes meaning is still unknown.
I attached the 2 config files used with etripator v0.4. The command line is :
The header is valid if the following conditions are met:
- The string stored at $8004-$800e is valid (equals to メモリベース128)
- The following expression is valid ($f8 and $f9 contains the first 2 bytes of the first sector).
Code: Select all
subw $fc, $f8 subw $fc, $f9 if( ($fd == $f9) && ($fc == $f8) ) ok else not ok
In fact these bytes are set by mb128_read_sectors. It's the sum of the bytes of the sector. So it can be viewed as a CRC.
The header for an empty mb128 is:
Code: Select all
$30, $06, $00, $00, $D2, $D3, $D8, $CD, $DE, $B0, $BD, $31, $32, $38, $00, $00, .... $00
Code: Select all
$D2+$D3+$D8+$CD+$DE+$B0+$BD+$31+$32+$38 = $630
So the substraction/comparaison is just a CRC check. It seems complicated.. Why not just compare the values of $fc,$fd and $f8,$f9?
Anyway, one mystery solved. The 3rd and 4th bytes meaning is still unknown.
Code: Select all
l76cf_00:
PHP
SEI
PHX
PHY
CLX
l76d4_00:
; Read first sector to $8000
LDA #$00
STA <$f8
LDA #$80
STA <$f9
STZ <$fa
LDA #$01
STA <$fb
JSR mb128_read_sectors
; Read succeded if A is zero
CMP #$00
BNE l773d_00
; Store the first 2 bytes to $f8 and $f9
LDA $8000
STA <$f8
LDA $8001
STA <$f9
; Check CRC
; $fd $fc -= $f8
LDA <$fc
SEC
SBC <$f8
STA <$fc
BCS l76fe_00
DEC <$fd
l76fe_00:
; $fd $fc -= $f9
LDA <$fc
SEC
SBC <$f9
STA <$fc
BCS l7709_00
DEC <$fd
l7709_00:
STZ <$fa
LDA <$fd
CMP <$f9
BNE l7717_00
LDA <$fc
CMP <$f8
BEQ l771b_00
l7717_00:
LDA #$01
STA <$fa
; Check if $8004-$800e contains the memory base 128 string (stored at $774a)
l771b_00:
LDA #$04
STA <$f8
LDA #$80
STA <$f9
LDA #$4a
STA <$fc
LDA #$77
STA <$fd
CLY
l772c_00:
LDA [$f8], Y
CMP [$fc], Y
BEQ l7736_00
LDA #$01
STA <$fa
l7736_00:
INY
CPY #$0a
BNE l772c_00
; We assume that everything is ok
LDA <$fa
l773d_00:
CMP #$00
BEQ l7746_00
; It seems that 3 attempts are made if something went wrong.
INX
CPX #$03
BCC l76d4_00
; The end
l7746_00:
PLY
PLX
PLP
RTS
mb128_string: ; $774a
.db $D2, $D3, $D8, $CD, $DE, $B0, $BD, $31, $32, $38
Code: Select all
etripator --cd -l labels.cfg mb128_2.cfg Track02.iso
- Attachments
-
mb128_2.cfg
- (86 Bytes) Downloaded 1006 times
-
labels.cfg
- (1.58 KiB) Downloaded 986 times
Re: [Hard+Soft] Memory Base 128
A quick note about the CRC check. The 2 subtractions are done because the CRC is computed as the sum of the sector bytes starting from the 2nd byte (ie without the CRC bytes). That makes sense.
edit: Woohoo! I can finally read a complete sector.
edit: Woohoo! I can finally read a complete sector.
Re: [Hard+Soft] Memory Base 128
I think I figured out the entry structure. Some bytes are still unknown.
The first 1024 bytes of the memory base 128 contains 64 entries of 16 bytes each.
The first entry is the header of the entry list.
I attached etripator configuration files and output.
The first 1024 bytes of the memory base 128 contains 64 entries of 16 bytes each.
The first entry is the header of the entry list.
- byte 0 : CRC (lsb)
- byte 1 : CRC (msb)
- byte 2 : Total sector count (lsb)
- byte 3 : Total sector count (msb)
- byte 4:F: Header name (メモリベース128)
- byte 0 : Sector index
- byte 1 : Sector count
- byte 2 : Unknown (set to 0 and unused by Tadaima Yuusha Boshuuchuu)
- byte 3 : Unknown (set to 2 and unused by Tadaima Yuusha Boshuuchuu)
- byte 4 : Data CRC (lsb)
- byte 5 : Data CRC (msb)
- byte 6 : Unknown (set to 0 and unused by Tadaima Yuusha Boshuuchuu)
- byte 7 : Unknown (set to 0 and unused by Tadaima Yuusha Boshuuchuu)
- byte 8-f : Entry name (set to ユウシャM128 in Tadaima Yuusha Boshuuchuu)
I attached etripator configuration files and output.
- Attachments
-
mb128.asm
- (95.29 KiB) Downloaded 999 times
-
mb128_2.cfg
- (86 Bytes) Downloaded 1007 times
-
labels.cfg
- (3.32 KiB) Downloaded 972 times