Hacking ROP to use SRAM instead of Serial EEPROM

For anything related to cart (SRAM, SF2 mapper, audio, CD mode 1, ...)

Moderator: BigEvilCorporation

Whipon
Interested
Posts: 14
Joined: Thu Jul 07, 2011 3:09 am

Hacking ROP to use SRAM instead of Serial EEPROM

Post by Whipon » Thu Jul 07, 2011 3:17 am

Good night:
I have some basic 68k asm knowledge, and I'm experienced using MESS to hack Genesis games, among other systems. However I need to do something that I never did before, and I need help:
I want to hack Rings of Power, so it saves using SRAM instead of Serial EEPROM. I've seen this done before with Megaman - Willy Wars and Wonder Boy in Monster World. Searching the web, I found the mapper used in Rings of Power is very simillar to the one used in those games.
Honestly, I don't know where to start. I would appreciatte any help you can provide me to begin this project.
Thanks in advance ^^.
Whipon.

User avatar
HardWareMan
Very interested
Posts: 704
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Thu Jul 07, 2011 3:45 am

There was a time when my friend brought a pirate cartridge ROP and complained that he is not saved. The interesting thing was that inside this cartridge was the SRAM and battery. After a long debugging this game in GENS I realized - this type of memory does not fit here, we need EEPROM. Moreover, x24c01, which has more simplier protocol, rather than simply 24c01. There are read and write procedures in ROM. Given that the I2C protocol are more complex than simple SRAM access, then it is quite possible to replace those procedures to SRAM access. Good luck.


* * *
OK, here we go:

Code: Select all

ROM:00042E34 ; =============== S U B R O U T I N E =======================================
ROM:00042E34
ROM:00042E34
ROM:00042E34 I2C_Start:                              ; CODE XREF: sub_42FD8+20p
ROM:00042E34                                         ; I2C_Read_Byte+30p ...
ROM:00042E34                 nop
ROM:00042E36                 nop
ROM:00042E38                 nop
ROM:00042E3A                 nop
ROM:00042E3C                 nop
ROM:00042E3E                 move.w  #$C0,($200000).l ; 'L'
ROM:00042E46                 nop
ROM:00042E48                 nop
ROM:00042E4A                 nop
ROM:00042E4C                 nop
ROM:00042E4E                 nop
ROM:00042E50                 nop
ROM:00042E52                 nop
ROM:00042E54                 move.w  #$40,($200000).l ; '@'
ROM:00042E5C                 nop
ROM:00042E5E                 nop
ROM:00042E60                 nop
ROM:00042E62                 nop
ROM:00042E64                 nop
ROM:00042E66                 nop
ROM:00042E68                 nop
ROM:00042E6A                 move.w  #0,($200000).l
ROM:00042E72                 nop
ROM:00042E74                 rts
ROM:00042E74 ; End of function I2C_Start
ROM:00042E74
ROM:00042E76
ROM:00042E76 ; =============== S U B R O U T I N E =======================================
ROM:00042E76
ROM:00042E76
ROM:00042E76 I2C_Stop:                               ; CODE XREF: sub_42FD8+28p
ROM:00042E76                                         ; I2C_Read_Byte+B8p ...
ROM:00042E76                 move.w  #0,($200000).l
ROM:00042E7E                 nop
ROM:00042E80                 nop
ROM:00042E82                 nop
ROM:00042E84                 nop
ROM:00042E86                 nop
ROM:00042E88                 nop
ROM:00042E8A                 move.w  #$40,($200000).l ; '@'
ROM:00042E92                 nop
ROM:00042E94                 nop
ROM:00042E96                 nop
ROM:00042E98                 nop
ROM:00042E9A                 nop
ROM:00042E9C                 move.w  #$C0,($200000).l ; 'L'
ROM:00042EA4                 nop
ROM:00042EA6                 nop
ROM:00042EA8                 nop
ROM:00042EAA                 nop
ROM:00042EAC                 nop
ROM:00042EAE                 move.w  #$80,($200000).l ; 'А'
ROM:00042EB6                 nop
ROM:00042EB8                 rts
ROM:00042EB8 ; End of function I2C_Stop
ROM:00042EB8
ROM:00042EBA
ROM:00042EBA ; =============== S U B R O U T I N E =======================================
ROM:00042EBA
ROM:00042EBA
ROM:00042EBA I2C_Write_Bit:                          ; CODE XREF: I2C_Read_Byte+40p
ROM:00042EBA                                         ; I2C_Read_Byte+44p ...
ROM:00042EBA                 lsl.w   #1,d0
ROM:00042EBC                 roxr.b  #1,d1
ROM:00042EBE                 bclr    #6,d1
ROM:00042EC2                 move.w  d1,($200000).l
ROM:00042EC8                 nop
ROM:00042ECA                 nop
ROM:00042ECC                 nop
ROM:00042ECE                 nop
ROM:00042ED0                 bset    #6,d1
ROM:00042ED4                 move.w  d1,($200000).l
ROM:00042EDA                 nop
ROM:00042EDC                 nop
ROM:00042EDE                 nop
ROM:00042EE0                 nop
ROM:00042EE2                 bclr    #6,d1
ROM:00042EE6                 move.w  d1,($200000).l
ROM:00042EEC                 rts
ROM:00042EEC ; End of function I2C_Write_Bit
ROM:00042EEC
ROM:00042EEE
ROM:00042EEE ; =============== S U B R O U T I N E =======================================
ROM:00042EEE
ROM:00042EEE
ROM:00042EEE I2C_Read_Bit:                           ; CODE XREF: I2C_Read_Byte:loc_43096p
ROM:00042EEE                                         ; I2C_Read_Byte+88p ...
ROM:00042EEE                 move.w  #$80,($200000).l ; 'А'
ROM:00042EF6                 nop
ROM:00042EF8                 nop
ROM:00042EFA                 nop
ROM:00042EFC                 nop
ROM:00042EFE                 move.w  #$C0,($200000).l ; 'L'
ROM:00042F06                 nop
ROM:00042F08                 nop
ROM:00042F0A                 nop
ROM:00042F0C                 nop
ROM:00042F0E                 nop
ROM:00042F10                 nop
ROM:00042F12                 move.w  ($200000).l,d1
ROM:00042F18                 move.w  #$80,($200000).l ; 'А'
ROM:00042F20                 asl.b   #1,d1
ROM:00042F22                 roxl.w  #1,d0
ROM:00042F24                 rts
ROM:00042F24 ; End of function I2C_Read_Bit
ROM:00042F24
ROM:00042F26
ROM:00042F26 ; =============== S U B R O U T I N E =======================================
ROM:00042F26
ROM:00042F26
ROM:00042F26 I2C_Zero_bit:                           ; CODE XREF: I2C_Read_Byte+AEp
ROM:00042F26                 move.w  #0,($200000).l
ROM:00042F2E                 nop
ROM:00042F30                 nop
ROM:00042F32                 nop
ROM:00042F34                 nop
ROM:00042F36                 nop
ROM:00042F38                 nop
ROM:00042F3A                 nop
ROM:00042F3C                 move.w  #$40,($200000).l ; '@'
ROM:00042F44                 nop
ROM:00042F46                 nop
ROM:00042F48                 nop
ROM:00042F4A                 nop
ROM:00042F4C                 nop
ROM:00042F4E                 nop
ROM:00042F50                 nop
ROM:00042F52                 move.w  #0,($200000).l
ROM:00042F5A                 nop
ROM:00042F5C                 rts
ROM:00042F5C ; End of function I2C_Zero_bit
ROM:00042F5C
ROM:00042F5E
ROM:00042F5E ; =============== S U B R O U T I N E =======================================
ROM:00042F5E
ROM:00042F5E
ROM:00042F5E I2C_One_Bit:                            ; CODE XREF: I2C_Read_Byte:loc_430C6p
ROM:00042F5E                 move.w  #$80,($200000).l ; 'А'
ROM:00042F66                 nop
ROM:00042F68                 nop
ROM:00042F6A                 nop
ROM:00042F6C                 nop
ROM:00042F6E                 nop
ROM:00042F70                 nop
ROM:00042F72                 nop
ROM:00042F74                 move.w  #$C0,($200000).l ; 'L'
ROM:00042F7C                 nop
ROM:00042F7E                 nop
ROM:00042F80                 nop
ROM:00042F82                 nop
ROM:00042F84                 nop
ROM:00042F86                 nop
ROM:00042F88                 nop
ROM:00042F8A                 move.w  #$80,($200000).l ; 'А'
ROM:00042F92                 nop
ROM:00042F94                 rts
ROM:00042F94 ; End of function I2C_One_Bit
ROM:00042F94
ROM:00042F96
ROM:00042F96 ; =============== S U B R O U T I N E =======================================
ROM:00042F96
ROM:00042F96
ROM:00042F96 I2C_Read_Ack:                           ; CODE XREF: I2C_Read_Byte+60p
ROM:00042F96                                         ; I2C_Write_Byte+5Ap ...
ROM:00042F96                 move.w  #$80,($200000).l ; 'А'
ROM:00042F9E                 nop
ROM:00042FA0                 move.w  #$C0,($200000).l ; 'L'
ROM:00042FA8                 nop
ROM:00042FAA                 nop
ROM:00042FAC                 nop
ROM:00042FAE                 nop
ROM:00042FB0                 nop
ROM:00042FB2                 nop
ROM:00042FB4                 nop
ROM:00042FB6                 move.w  ($200000).l,d1
ROM:00042FBC                 move.w  #$80,($200000).l ; 'А'
ROM:00042FC4                 nop
ROM:00042FC6                 rts
ROM:00042FC6 ; End of function I2C_Read_Ack
ROM:00042FC6
ROM:00042FC8
ROM:00042FC8 ; =============== S U B R O U T I N E =======================================
ROM:00042FC8
ROM:00042FC8
ROM:00042FC8 sub_42FC8:                              ; CODE XREF: sub_4323C+Ap
ROM:00042FC8                 move.w  #$A,(word_FF014C).l
ROM:00042FD0                 move.w  #0,(word_FF014E).l
ROM:00042FD0 ; End of function sub_42FC8
ROM:00042FD0
ROM:00042FD8
ROM:00042FD8 ; =============== S U B R O U T I N E =======================================
ROM:00042FD8
ROM:00042FD8
ROM:00042FD8 sub_42FD8:                              ; CODE XREF: I2C_Read_Byte:loc_43034p
ROM:00042FD8                                         ; I2C_Read_Byte+7Ep ...
ROM:00042FD8                 move.w  #$1964,d0
ROM:00042FDC
ROM:00042FDC loc_42FDC:                              ; CODE XREF: sub_42FD8+6j
ROM:00042FDC                 nop
ROM:00042FDE                 dbf     d0,loc_42FDC
ROM:00042FE2                 moveq   #8,d0
ROM:00042FE4
ROM:00042FE4 loc_42FE4:                              ; CODE XREF: sub_42FD8+24j
ROM:00042FE4                 move.w  #$80,($200000).l ; 'А'
ROM:00042FEC                 nop
ROM:00042FEE                 nop
ROM:00042FF0                 nop
ROM:00042FF2                 nop
ROM:00042FF4                 nop
ROM:00042FF6                 nop
ROM:00042FF8                 jsr     I2C_Start
ROM:00042FFC                 dbf     d0,loc_42FE4
ROM:00043000                 jsr     I2C_Stop
ROM:00043004                 rts
ROM:00043004 ; End of function sub_42FD8
ROM:00043004
ROM:00043006
ROM:00043006 ; =============== S U B R O U T I N E =======================================
ROM:00043006
ROM:00043006
ROM:00043006 sub_43006:                              ; CODE XREF: sub_177B4+2Cp
ROM:00043006                                         ; sub_177B4+52p ...
ROM:00043006                 move.l  4(sp),d0
ROM:0004300A                 move.l  8(sp),d1
ROM:0004300E                 movea.l $C(sp),a0
ROM:0004300E ; End of function sub_43006
ROM:0004300E
ROM:00043012
ROM:00043012 ; =============== S U B R O U T I N E =======================================
ROM:00043012
ROM:00043012
ROM:00043012 I2C_Read_Byte:                          ; CODE XREF: I2C_Write_Byte+F4p
ROM:00043012                                         ; sub_4323C+28p
ROM:00043012                 move.w  #0,(word_FF014E).l
ROM:0004301A                 move.w  d1,(word_FF015C).l
ROM:00043020                 move.l  a0,(dword_FF0150).l
ROM:00043026                 move.l  d0,(dword_FF0154).l
ROM:0004302C                 move.l  d1,(dword_FF0158).l
ROM:00043032                 bra.s   loc_43036
ROM:00043034 ; ---------------------------------------------------------------------------
ROM:00043034
ROM:00043034 loc_43034:                              ; CODE XREF: I2C_Read_Byte+82j
ROM:00043034                 bsr.s   sub_42FD8
ROM:00043036
ROM:00043036 loc_43036:                              ; CODE XREF: I2C_Read_Byte+20j
ROM:00043036                 movea.l (dword_FF0150).l,a0
ROM:0004303C                 move.l  (dword_FF0154).l,d0
ROM:00043042                 jsr     I2C_Start
ROM:00043046                 and.w   #$7F,d0 ; ''
ROM:0004304A                 lsl.w   #1,d0
ROM:0004304C                 or.w    #1,d0
ROM:00043050                 lsl.w   #8,d0
ROM:00043052                 jsr     I2C_Write_Bit
ROM:00043056                 jsr     I2C_Write_Bit
ROM:0004305A                 jsr     I2C_Write_Bit
ROM:0004305E                 jsr     I2C_Write_Bit
ROM:00043062                 jsr     I2C_Write_Bit
ROM:00043066                 jsr     I2C_Write_Bit
ROM:0004306A                 jsr     I2C_Write_Bit
ROM:0004306E                 jsr     I2C_Write_Bit
ROM:00043072                 jsr     I2C_Read_Ack
ROM:00043076                 tst.b   d1
ROM:00043078                 bpl.s   loc_43096
ROM:0004307A                 addq.w  #1,(word_FF014E).l
ROM:00043080                 bmi.s   loc_430E2
ROM:00043082                 move.w  (word_FF014E).l,d1
ROM:00043088                 cmp.w   (word_FF014C).l,d1
ROM:0004308E                 bpl.s   loc_430E2
ROM:00043090                 jsr     sub_42FD8
ROM:00043094                 bra.s   loc_43034
ROM:00043096 ; ---------------------------------------------------------------------------
ROM:00043096
ROM:00043096 loc_43096:                              ; CODE XREF: I2C_Read_Byte+66j
ROM:00043096                                         ; I2C_Read_Byte+B2j
ROM:00043096                 jsr     I2C_Read_Bit
ROM:0004309A                 jsr     I2C_Read_Bit
ROM:0004309E                 jsr     I2C_Read_Bit
ROM:000430A2                 jsr     I2C_Read_Bit
ROM:000430A6                 jsr     I2C_Read_Bit
ROM:000430AA                 jsr     I2C_Read_Bit
ROM:000430AE                 jsr     I2C_Read_Bit
ROM:000430B2                 jsr     I2C_Read_Bit
ROM:000430B6                 move.b  d0,(a0)+
ROM:000430B8                 subq.w  #1,(word_FF015C).l
ROM:000430BE                 beq.s   loc_430C6
ROM:000430C0                 jsr     I2C_Zero_bit
ROM:000430C4                 bra.s   loc_43096
ROM:000430C6 ; ---------------------------------------------------------------------------
ROM:000430C6
ROM:000430C6 loc_430C6:                              ; CODE XREF: I2C_Read_Byte+ACj
ROM:000430C6                 jsr     I2C_One_Bit
ROM:000430CA                 jsr     I2C_Stop
ROM:000430CE
ROM:000430CE loc_430CE:                              ; CODE XREF: I2C_Read_Byte+D8j
ROM:000430CE                 movea.l (dword_FF0150).l,a0
ROM:000430D4                 move.l  (dword_FF0154).l,d0
ROM:000430DA                 move.l  (dword_FF0158).l,d1
ROM:000430E0                 rts
ROM:000430E2 ; ---------------------------------------------------------------------------
ROM:000430E2
ROM:000430E2 loc_430E2:                              ; CODE XREF: I2C_Read_Byte+6Ej
ROM:000430E2                                         ; I2C_Read_Byte+7Cj
ROM:000430E2                 move.w  #$FFFF,(word_FF014E).l
ROM:000430EA                 bra.s   loc_430CE
ROM:000430EA ; End of function I2C_Read_Byte
ROM:000430EA
ROM:000430EC
ROM:000430EC ; =============== S U B R O U T I N E =======================================
ROM:000430EC
ROM:000430EC
ROM:000430EC sub_430EC:                              ; CODE XREF: sub_17706+10p
ROM:000430EC                                         ; sub_17706+38p ...
ROM:000430EC                 move.l  4(sp),d0
ROM:000430F0                 movea.l 8(sp),a0
ROM:000430F0 ; End of function sub_430EC
ROM:000430F0
ROM:000430F4
ROM:000430F4 ; =============== S U B R O U T I N E =======================================
ROM:000430F4
ROM:000430F4
ROM:000430F4 I2C_Write_Byte:                         ; CODE XREF: sub_4323C:loc_432DEp
ROM:000430F4                 move.w  #0,(word_FF014E).l
ROM:000430FC                 move.l  a0,(dword_FF0160).l
ROM:00043102                 move.l  d0,(dword_FF0164).l
ROM:00043108                 move.l  d1,-(sp)
ROM:0004310A                 bra.s   loc_43110
ROM:0004310C ; ---------------------------------------------------------------------------
ROM:0004310C
ROM:0004310C loc_4310C:                              ; CODE XREF: I2C_Write_Byte+80j
ROM:0004310C                                         ; I2C_Write_Byte+CAj ...
ROM:0004310C                 jsr     sub_42FD8
ROM:00043110
ROM:00043110 loc_43110:                              ; CODE XREF: I2C_Write_Byte+16j
ROM:00043110                 movea.l (dword_FF0160).l,a0
ROM:00043116                 move.l  (dword_FF0164).l,d0
ROM:0004311C                 jsr     I2C_Start
ROM:00043120                 and.w   #$7F,d0 ; ''
ROM:00043124                 lsl.w   #1,d0
ROM:00043126                 lsl.w   #8,d0
ROM:00043128                 move.w  d0,(word_FF015E).l
ROM:0004312E                 jsr     I2C_Write_Bit
ROM:00043132                 jsr     I2C_Write_Bit
ROM:00043136                 jsr     I2C_Write_Bit
ROM:0004313A                 jsr     I2C_Write_Bit
ROM:0004313E                 jsr     I2C_Write_Bit
ROM:00043142                 jsr     I2C_Write_Bit
ROM:00043146                 jsr     I2C_Write_Bit
ROM:0004314A                 jsr     I2C_Write_Bit
ROM:0004314E                 jsr     I2C_Read_Ack
ROM:00043152                 tst.b   d1
ROM:00043154                 bpl.s   loc_43176
ROM:00043156                 addq.w  #1,(word_FF014E).l
ROM:0004315C                 bmi.w   loc_43232
ROM:00043160                 move.w  (word_FF014E).l,d1
ROM:00043166                 cmp.w   (word_FF014C).l,d1
ROM:0004316C                 bpl.w   loc_43232
ROM:00043170                 jsr     sub_42FD8
ROM:00043174                 bra.s   loc_4310C
ROM:00043176 ; ---------------------------------------------------------------------------
ROM:00043176
ROM:00043176 loc_43176:                              ; CODE XREF: I2C_Write_Byte+60j
ROM:00043176                 move.b  (a0),d0
ROM:00043178                 lsl.w   #8,d0
ROM:0004317A                 jsr     I2C_Write_Bit
ROM:0004317E                 jsr     I2C_Write_Bit
ROM:00043182                 jsr     I2C_Write_Bit
ROM:00043186                 jsr     I2C_Write_Bit
ROM:0004318A                 jsr     I2C_Write_Bit
ROM:0004318E                 jsr     I2C_Write_Bit
ROM:00043192                 jsr     I2C_Write_Bit
ROM:00043196                 jsr     I2C_Write_Bit
ROM:0004319A                 jsr     I2C_Read_Ack
ROM:0004319E                 tst.b   d1
ROM:000431A0                 bpl.s   loc_431C2
ROM:000431A2                 addq.w  #1,(word_FF014E).l
ROM:000431A8                 bmi.w   loc_43232
ROM:000431AC                 move.w  (word_FF014E).l,d1
ROM:000431B2                 cmp.w   (word_FF014C).l,d1
ROM:000431B8                 bpl.s   loc_43232
ROM:000431BA                 jsr     sub_42FD8
ROM:000431BE                 bra.w   loc_4310C
ROM:000431C2 ; ---------------------------------------------------------------------------
ROM:000431C2
ROM:000431C2 loc_431C2:                              ; CODE XREF: I2C_Write_Byte+ACj
ROM:000431C2                 jsr     I2C_Stop
ROM:000431C6                 move.w  #$1518,d0
ROM:000431CA
ROM:000431CA loc_431CA:                              ; CODE XREF: I2C_Write_Byte+D8j
ROM:000431CA                 nop
ROM:000431CC                 dbf     d0,loc_431CA
ROM:000431D0                 clr.l   d0
ROM:000431D2                 move.b  (word_FF015E).l,d0
ROM:000431D8                 lsr.l   #1,d0
ROM:000431DA                 moveq   #1,d1
ROM:000431DC                 move.l  (dword_FF0164).l,d0
ROM:000431E2                 lea     ($FF015F).l,a0
ROM:000431E8                 jsr     I2C_Read_Byte
ROM:000431EC                 tst.w   (word_FF014E).l
ROM:000431F2                 bmi.s   loc_43232
ROM:000431F4                 movea.l (dword_FF0160).l,a0
ROM:000431FA                 move.b  (word_FF015E+1).l,d0
ROM:00043200                 cmp.b   (a0),d0
ROM:00043202                 bpl.s   loc_43222
ROM:00043204                 addq.w  #1,(word_FF014E).l
ROM:0004320A                 bmi.s   loc_43232
ROM:0004320C                 move.w  (word_FF014E).l,d1
ROM:00043212                 cmp.w   (word_FF014C).l,d1
ROM:00043218                 bpl.s   loc_43232
ROM:0004321A                 jsr     sub_42FD8
ROM:0004321E                 bra.w   loc_4310C
ROM:00043222 ; ---------------------------------------------------------------------------
ROM:00043222
ROM:00043222 loc_43222:                              ; CODE XREF: I2C_Write_Byte+10Ej
ROM:00043222                                         ; I2C_Write_Byte+146j
ROM:00043222                 movea.l (dword_FF0160).l,a0
ROM:00043228                 move.l  (dword_FF0164).l,d0
ROM:0004322E                 move.l  (sp)+,d1
ROM:00043230                 rts
ROM:00043232 ; ---------------------------------------------------------------------------
ROM:00043232
ROM:00043232 loc_43232:                              ; CODE XREF: I2C_Write_Byte+68j
ROM:00043232                                         ; I2C_Write_Byte+78j ...
ROM:00043232                 move.w  #$FFFF,(word_FF014E).l
ROM:0004323A                 bra.s   loc_43222
ROM:0004323A ; End of function I2C_Write_Byte
ROM:0004323A
ROM:0004323C
ROM:0004323C ; =============== S U B R O U T I N E =======================================
ROM:0004323C
ROM:0004323C
ROM:0004323C sub_4323C:                              ; CODE XREF: RESET+10Cp
ROM:0004323C                 movem.l d0-d1,-(sp)
ROM:00043240                 clr.w   (word_FF0168).l
ROM:00043246                 jsr     sub_42FC8
ROM:0004324A                 jsr     sub_DCE2
ROM:00043250                 cmp.b   #$E0,d0
ROM:00043254                 beq.s   loc_432B6
ROM:00043256                 moveq   #0,d0
ROM:00043258                 move.l  #$80,d1 ; 'А'
ROM:0004325E                 lea     (unk_FF016A).l,a0
ROM:00043264                 jsr     I2C_Read_Byte
ROM:00043268                 tst.w   (word_FF014E).l
ROM:0004326E                 bmi.w   loc_432F6
ROM:00043272                 moveq   #$7D,d1 ; '}'
ROM:00043274                 clr.w   d0
ROM:00043276                 lea     (unk_FF016A).l,a0
ROM:0004327C
ROM:0004327C loc_4327C:                              ; CODE XREF: sub_4323C+42j
ROM:0004327C                 add.b   (a0)+,d0
ROM:0004327E                 dbf     d1,loc_4327C
ROM:00043282                 clr.w   d1
ROM:00043284                 cmp.b   1(a0),d0
ROM:00043288                 beq.s   loc_4328C
ROM:0004328A                 addq.w  #1,d1
ROM:0004328C
ROM:0004328C loc_4328C:                              ; CODE XREF: sub_4323C+4Cj
ROM:0004328C                 not.w   d0
ROM:0004328E                 cmp.b   (a0),d0
ROM:00043290                 beq.s   loc_43294
ROM:00043292                 addq.w  #1,d1
ROM:00043294
ROM:00043294 loc_43294:                              ; CODE XREF: sub_4323C+54j
ROM:00043294                 swap    d0
ROM:00043296                 move.b  (a0),d0
ROM:00043298                 not.b   d0
ROM:0004329A                 cmp.b   1(a0),d0
ROM:0004329E                 beq.s   loc_432A2
ROM:000432A0                 addq.w  #1,d1
ROM:000432A2
ROM:000432A2 loc_432A2:                              ; CODE XREF: sub_4323C+62j
ROM:000432A2                 swap    d0
ROM:000432A4                 tst.w   d1
ROM:000432A6                 beq.s   loc_43316
ROM:000432A8                 jsr     sub_DCE2
ROM:000432AE                 cmp.b   #(dword_0+$B0),d0
ROM:000432B2                 beq.s   loc_432F6
ROM:000432B4                 bra.s   loc_43316
ROM:000432B6 ; ---------------------------------------------------------------------------
ROM:000432B6
ROM:000432B6 loc_432B6:                              ; CODE XREF: sub_4323C+18j
ROM:000432B6                 move.w  #1,(word_FF0168).l
ROM:000432BE                 lea     (unk_FF016A).l,a0
ROM:000432C4                 moveq   #$7F,d0 ; ''
ROM:000432C6                 clr.l   d1
ROM:000432C8
ROM:000432C8 loc_432C8:                              ; CODE XREF: sub_4323C+8Ej
ROM:000432C8                 move.b  d1,(a0)+
ROM:000432CA                 dbf     d0,loc_432C8
ROM:000432CE                 move.b  #$FF,(byte_FF01E8).l
ROM:000432D6                 lea     (unk_FF016A).l,a0
ROM:000432DC                 moveq   #0,d0
ROM:000432DE
ROM:000432DE loc_432DE:                              ; CODE XREF: sub_4323C+B6j
ROM:000432DE                 jsr     I2C_Write_Byte
ROM:000432E2                 tst.w   (word_FF014E).l
ROM:000432E8                 bmi.s   loc_432F6
ROM:000432EA                 addq.l  #1,a0
ROM:000432EC                 addq.w  #1,d0
ROM:000432EE                 and.w   #$7F,d0 ; ''
ROM:000432F2                 bne.s   loc_432DE
ROM:000432F4                 bra.s   loc_43316
ROM:000432F6 ; ---------------------------------------------------------------------------
ROM:000432F6
ROM:000432F6 loc_432F6:                              ; CODE XREF: sub_4323C+32j
ROM:000432F6                                         ; sub_4323C+76j ...
ROM:000432F6                 move.w  #$FFFF,(word_FF0168).l
ROM:000432FE                 jsr     sub_DCE2
ROM:00043304                 cmp.b   #(dword_0+$B0),d0
ROM:00043308                 beq.s   loc_43310
ROM:0004330A                 cmp.b   #$E0,d0
ROM:0004330E                 bne.s   loc_4332E
ROM:00043310
ROM:00043310 loc_43310:                              ; CODE XREF: sub_4323C+CCj
ROM:00043310                 moveq   #$F,d0
ROM:00043312                 bra.s   loc_4333A
ROM:00043312 ; ---------------------------------------------------------------------------
ROM:00043314                 dc.b $60 ; `
ROM:00043315                 dc.b $18
ROM:00043316 ; ---------------------------------------------------------------------------
ROM:00043316
ROM:00043316 loc_43316:                              ; CODE XREF: sub_4323C+6Aj
ROM:00043316                                         ; sub_4323C+78j ...
ROM:00043316                 jsr     sub_DCE2
ROM:0004331C                 cmp.b   #(dword_0+$B0),d0
ROM:00043320                 beq.s   loc_43328
ROM:00043322                 cmp.b   #$E0,d0
ROM:00043326                 bne.s   loc_4332E
ROM:00043328
ROM:00043328 loc_43328:                              ; CODE XREF: sub_4323C+E4j
ROM:00043328                 move.w  #$F0,d0 ; 'Ё'
ROM:0004332C                 bra.s   loc_4333A
ROM:0004332E ; ---------------------------------------------------------------------------
ROM:0004332E
ROM:0004332E loc_4332E:                              ; CODE XREF: sub_4323C+D2j
ROM:0004332E                                         ; sub_4323C+EAj
ROM:0004332E                 lea     (unk_FF016A).l,a0
ROM:00043334                 movem.l (sp)+,d0-d1
ROM:00043338                 rts
I assume that you must just change I2C_Read_Byte and I2C_Write_Byte functions to simple access to SRAM. Remeber that EEPROM x24c01 has only 128 bytes, so address is 7 bit (must be AND'ed by 0x7F).

Whipon
Interested
Posts: 14
Joined: Thu Jul 07, 2011 3:09 am

Thanks a lot

Post by Whipon » Fri Jul 08, 2011 12:51 am

Thanks a lot HardWareMan.
I'll see if I can modify the code by reading some Genesis SRAM docs.
I've seen the changed code in Megaman: Willy Wars, and most of it are just some NOPs and a few byte modifications. It seems it will not be that easy with this game. But I'll give it a try and report back.
Feel free to note me anything that might be usefull.
Thanks again for the info.

Chilly Willy
Very interested
Posts: 2581
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Jul 08, 2011 2:03 am

SRAM is (nearly) always at 0x200000. It is a byte wide, residing on odd bytes (0x200001, 0x200003, 0x200005, etc). Most emulators and flash carts support up to 32KBytes of sram, meaning from 0x200001 to 0x20FFFF.

You ALWAYS have to write 1 to 0xA130F1 to enable the sram; write 0 to disable the sram. The sram normally starts disabled. While disabled, 0 to 0x3FFFFF is normal rom; while enabled, 0 to 0x1FFFFF is normal rom, but 0x200000 on up will be sram. Therefore, you either need to disable interrupts while accessing sram, or ensure that the interrupt code will NEVER access anything at or above 0x200000 since they can never be sure the sram is enabled or disabled (unless you define variables and are careful to always check them to see the state of the sram). Most people just disable interrupts.

Note that bit 1 is an optional write protect bit. Some carts (like the NeoMyth) implement it. b1 set means the sram is write-protected, while b1 clear means write-enabled. So when reading the sram, you might write 3 to 0xA130F1 to enable write-protected sram, and write 2 to disable the sram (leaving it still write-protected). When writing sram, you need to write 1 to 0xA130F1 to both enable the sram and write-enable it. Note that writing 0 to disable the sram is fine because you cannot write disabled sram, even though it's write-enabled; so writing 2 or 0 is fine for disabling the sram.

Once the sram is enabled, you can read/write the sram like normal ram - just move a byte to or from the proper memory location. Note that since sram is every other byte, you can use the 68000 movep command to move words and longs.

So your read routine might be like this:
assumes offset in bytes in d0
returns byte from that offset in d0

Code: Select all

        move.w  #0x2700,sr          /* disable ints */
        add.l   d0,d0               /* sram is every other byte */
        lea     0x200000,a0
        move.b  #3,0xA130F1         /* SRAM enabled, write protected */
        move.b  1(a0,d0.l),d0       /* read SRAM */
        move.b  #2,0xA130F1         /* SRAM disabled, write protected */
        move.w  #0x2000,sr          /* enable ints */
and your write routine might be like this:
assumes offset in bytes in d0 and data in d1

Code: Select all

        move.w  #0x2700,sr          /* disable ints */
        add.l   d0,d0               /* sram is every other byte */
        lea     0x200000,a0
        move.b  #1,0xA130F1         /* SRAM enabled, write enabled */
        move.b  d1,1(a0,d0.l)       /* write SRAM */
        move.b  #2,0xA130F1         /* SRAM disabled, write protected */
        move.w  #0x2000,sr          /* enable ints */
This code works on emulators, the MD-Pro, the EverdriveMD, and the NeoMyth MD.

Note that if you have a LOT of data to write/read, you could do it all at once. There's no NEED to do it one byte at a time. The above code does it one byte at a time as an example, and because sometimes all you need is a single byte. :)

User avatar
HardWareMan
Very interested
Posts: 704
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Fri Jul 08, 2011 6:55 am

Chilly Willy wrote:Note that if you have a LOT of data to write/read, you could do it all at once. There's no NEED to do it one byte at a time. The above code does it one byte at a time as an example, and because sometimes all you need is a single byte. :)
Since simple I2C EEPROM x24C01 can handle only single byte transaction your example is okay. But don't forget to save all used registers, except those wich with result.

Eke
Very interested
Posts: 821
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Fri Jul 08, 2011 8:44 am

You ALWAYS have to write 1 to 0xA130F1 to enable the sram; write 0 to disable the sram. The sram normally starts disabled. While disabled, 0 to 0x3FFFFF is normal rom; while enabled, 0 to 0x1FFFFF is normal rom, but 0x200000 on up will be sram. Therefore, you either need to disable interrupts while accessing sram, or ensure that the interrupt code will NEVER access anything at or above 0x200000 since they can never be sure the sram is enabled or disabled (unless you define variables and are careful to always check them to see the state of the sram). Most people just disable interrupts.
I see this written a lot but it's actually not entirely correct. The 0xA130F1 write is handled by the cartridge, not the console so it depends 100% on the original cartridge mapper.. And actually, this is only done by a very few MD games (3 or 4) and only when there is confict access between SRAM and ROM data (for example, when ROM is larger than 2MB and SRAM is mapped in the upper 2MB range).

On most games, SRAM & ROM does not conflict and SRAM is enabled by default as soon as you access its addressed area (above $200000 generally, sometime $300000 for larger EA games, but it can be anything, really). If it was not the case, many games would not save on flashcarts as they never write to $A130F1.

The ROM header gives infos about the start/end address for SRAM access but again, it is only used by flashcarts like Everdrive in order to know that when a read/write occurs in that area, it's supposed to be for SRAM.

So if you want to mody Rings of Power save routine, just make sure to use an address that does not conflict with ROM and update the ROM header so that flashcarts can know where SRAM should be mapped. If you are building your own cartridge, updating header is not even necessary.

The routines you want to patch are indeed the "I2C_Read_Byte" and "I2C_Write_Byte" functions but it can be a little bit complicated as you have to find where the address/data is passed, insert move instructions and disable the original I2C functions that write to $200000 and could therefore corrupt SRAM if it's mapped there. The sub_42FD8 routine should also be patched for the same reason.

The last thing to keep in mind is that SRAM, contrary to EEPROM, is accessed sequentially and generally only as BYTE (at least the Everdrive does not support 16-bit access), at either odd or even address (for example, $200001 then $200003, etc). Again, there are some bits in the ROM header that you can set to indicate this for anyone who needs it but I don't think flashcarts do, they probably only support read/write to odd address as it is what the majority of games is doing.

User avatar
HardWareMan
Very interested
Posts: 704
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Fri Jul 08, 2011 9:49 am

Eke wrote:The routines you want to patch are indeed the "I2C_Read_Byte" and "I2C_Write_Byte" functions but it can be a little bit complicated as you have to find where the address/data is passed, insert move instructions and disable the original I2C functions that write to $200000 and could therefore corrupt SRAM if it's mapped there. The sub_42FD8 routine should also be patched for the same reason.
"I2C_Read_Byte" and "I2C_Write_Byte" should be "I2C_Read_Bytes" and "I2C_Write_Bytes" becouse it use counter of bytes:

Code: Select all

Read loop:
ROM:00043096 loc_43096:                              ; CODE XREF: I2C_Read_Byte+66j
ROM:00043096                                         ; I2C_Read_Byte+B2j
ROM:00043096                 jsr     I2C_Read_Bit
ROM:0004309A                 jsr     I2C_Read_Bit
ROM:0004309E                 jsr     I2C_Read_Bit
ROM:000430A2                 jsr     I2C_Read_Bit
ROM:000430A6                 jsr     I2C_Read_Bit
ROM:000430AA                 jsr     I2C_Read_Bit
ROM:000430AE                 jsr     I2C_Read_Bit
ROM:000430B2                 jsr     I2C_Read_Bit
ROM:000430B6                 move.b  d0,(a0)+
ROM:000430B8                 subq.w  #1,(word_FF015C).l
ROM:000430BE                 beq.s   loc_430C6
ROM:000430C0                 jsr     I2C_Zero_bit
ROM:000430C4                 bra.s   loc_43096 


And write:
ROM:0004310C loc_4310C:                              ; CODE XREF: I2C_Write_Byte+80j
ROM:0004310C                                         ; I2C_Write_Byte+CAj ...
ROM:0004310C                 jsr     sub_42FD8
ROM:00043110
ROM:00043110 loc_43110:                              ; CODE XREF: I2C_Write_Byte+16j
ROM:00043110                 movea.l (dword_FF0160).l,a0
ROM:00043116                 move.l  (dword_FF0164).l,d0
ROM:0004311C                 jsr     I2C_Start
ROM:00043120                 and.w   #$7F,d0 ; ''
ROM:00043124                 lsl.w   #1,d0
ROM:00043126                 lsl.w   #8,d0
ROM:00043128                 move.w  d0,(word_FF015E).l
ROM:0004312E                 jsr     I2C_Write_Bit
ROM:00043132                 jsr     I2C_Write_Bit
ROM:00043136                 jsr     I2C_Write_Bit
ROM:0004313A                 jsr     I2C_Write_Bit
ROM:0004313E                 jsr     I2C_Write_Bit
ROM:00043142                 jsr     I2C_Write_Bit
ROM:00043146                 jsr     I2C_Write_Bit
ROM:0004314A                 jsr     I2C_Write_Bit
ROM:0004314E                 jsr     I2C_Read_Ack
ROM:00043152                 tst.b   d1
ROM:00043154                 bpl.s   loc_43176
ROM:00043156                 addq.w  #1,(word_FF014E).l
ROM:0004315C                 bmi.w   loc_43232
ROM:00043160                 move.w  (word_FF014E).l,d1
ROM:00043166                 cmp.w   (word_FF014C).l,d1
ROM:0004316C                 bpl.w   loc_43232
ROM:00043170                 jsr     sub_42FD8
ROM:00043174                 bra.s   loc_4310C
ROM:00043176 ; ---------------------------------------------------------------------------
ROM:00043176
ROM:00043176 loc_43176:                              ; CODE XREF: I2C_Write_Byte+60j
ROM:00043176                 move.b  (a0),d0
ROM:00043178                 lsl.w   #8,d0
ROM:0004317A                 jsr     I2C_Write_Bit
ROM:0004317E                 jsr     I2C_Write_Bit
ROM:00043182                 jsr     I2C_Write_Bit
ROM:00043186                 jsr     I2C_Write_Bit
ROM:0004318A                 jsr     I2C_Write_Bit
ROM:0004318E                 jsr     I2C_Write_Bit
ROM:00043192                 jsr     I2C_Write_Bit
ROM:00043196                 jsr     I2C_Write_Bit
ROM:0004319A                 jsr     I2C_Read_Ack
ROM:0004319E                 tst.b   d1
ROM:000431A0                 bpl.s   loc_431C2
ROM:000431A2                 addq.w  #1,(word_FF014E).l
ROM:000431A8                 bmi.w   loc_43232
ROM:000431AC                 move.w  (word_FF014E).l,d1
ROM:000431B2                 cmp.w   (word_FF014C).l,d1
ROM:000431B8                 bpl.s   loc_43232
ROM:000431BA                 jsr     sub_42FD8
ROM:000431BE                 bra.w   loc_4310C 
Note: read use autoincrement of EEPROM address pointer so it use small loop while write must set address pointer before every write byte.

Code: Select all

ROM:00043036 loc_43036:                              ; CODE XREF: I2C_Read_Byte+20j
ROM:00043036                 movea.l (dword_FF0150).l,a0
ROM:0004303C                 move.l  (dword_FF0154).l,d0
ROM:00043042                 jsr     I2C_Start
ROM:00043046                 and.w   #$7F,d0 ; ''
ROM:0004304A                 lsl.w   #1,d0
ROM:0004304C                 or.w    #1,d0 
* * *
ROM:000430B6                 move.b  d0,(a0)+ 

Write:
ROM:00043110                 movea.l (dword_FF0160).l,a0
ROM:00043116                 move.l  (dword_FF0164).l,d0
ROM:0004311C                 jsr     I2C_Start
ROM:00043120                 and.w   #$7F,d0 ; '' 
ROM:00043124                 lsl.w   #1,d0 
* * *
ROM:00043176                 move.b  (a0),d0 
Everything clear: (a0) is data pointer (stored at $FF0160) and d0 is EEPROM address (stored at $FF0164). It AND'ed with $7F (7 bit, 128 bytes) and shifted left (bit d0 in EEPROM command byte is R/W flag, wich is 0 for write and 1 for read).

Chilly Willy
Very interested
Posts: 2581
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Jul 08, 2011 7:21 pm

Eke wrote:
You ALWAYS have to write 1 to 0xA130F1 to enable the sram; write 0 to disable the sram. The sram normally starts disabled. While disabled, 0 to 0x3FFFFF is normal rom; while enabled, 0 to 0x1FFFFF is normal rom, but 0x200000 on up will be sram. Therefore, you either need to disable interrupts while accessing sram, or ensure that the interrupt code will NEVER access anything at or above 0x200000 since they can never be sure the sram is enabled or disabled (unless you define variables and are careful to always check them to see the state of the sram). Most people just disable interrupts.
I see this written a lot but it's actually not entirely correct. The 0xA130F1 write is handled by the cartridge, not the console so it depends 100% on the original cartridge mapper.. And actually, this is only done by a very few MD games (3 or 4) and only when there is confict access between SRAM and ROM data (for example, when ROM is larger than 2MB and SRAM is mapped in the upper 2MB range).

On most games, SRAM & ROM does not conflict and SRAM is enabled by default as soon as you access its addressed area (above $200000 generally, sometime $300000 for larger EA games, but it can be anything, really). If it was not the case, many games would not save on flashcarts as they never write to $A130F1.

The ROM header gives infos about the start/end address for SRAM access but again, it is only used by flashcarts like Everdrive in order to know that when a read/write occurs in that area, it's supposed to be for SRAM.

So if you want to mody Rings of Power save routine, just make sure to use an address that does not conflict with ROM and update the ROM header so that flashcarts can know where SRAM should be mapped. If you are building your own cartridge, updating header is not even necessary.

The routines you want to patch are indeed the "I2C_Read_Byte" and "I2C_Write_Byte" functions but it can be a little bit complicated as you have to find where the address/data is passed, insert move instructions and disable the original I2C functions that write to $200000 and could therefore corrupt SRAM if it's mapped there. The sub_42FD8 routine should also be patched for the same reason.

The last thing to keep in mind is that SRAM, contrary to EEPROM, is accessed sequentially and generally only as BYTE (at least the Everdrive does not support 16-bit access), at either odd or even address (for example, $200001 then $200003, etc). Again, there are some bits in the ROM header that you can set to indicate this for anyone who needs it but I don't think flashcarts do, they probably only support read/write to odd address as it is what the majority of games is doing.
What you say is only true of CERTAIN carts. To work in all carts, emulators, and flash carts PROPERLY, you must use the "official" methods as flash carts in particular only look for those methods. You'll notice that Sonic 3, even though the sram doesn't conflict with the rom and should be "automatic", always writes 1 to 0xA130F1 as part of the hardware init. You should always use the defined address even when you know the address is more grossly decoded.

You could only get by with less than what I said IF you use a specific cart that you KNOW uses less, or made your own cart. If you plan for people to use existing flash carts, do the right thing. :D

Eke
Very interested
Posts: 821
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Fri Jul 08, 2011 8:59 pm

What you say is only true of CERTAIN carts. To work in all carts, emulators, and flash carts PROPERLY, you must use the "official" methods as flash carts in particular only look for those methods.
No, i say it's true for 99% of MD carts. How would you explain that all these games that NEVER writes $A130F1 save properly in those emulators, flashcarts, etc ? Simply because the method the majority of games is using to access SRAM actually IS the official method, which is the method that was emulated or supported by flashcarts from the start. Again, SRAM bankswitching is used by only a few games, namely Beyond Oasis, Phantasy Star 4, Sonic 3 and .... that's it :wink:
It was during a long time not even emulated and i bet some exotic/cheap flashcarts still doesn't implement it since it doesn't affects compatibilty that much.
You'll notice that Sonic 3, even though the sram doesn't conflict with the rom and should be "automatic", always writes 1 to 0xA130F1 as part of the hardware init
Well, I think Sonic 3 was designed from the beginning to work with S&K. When it is locked in S&K cartridge, Sonic 3 (or any locked game btw) is accessed at $200000-$3FFFFF. It works with Sonic 3 cartridge because the 2MB ROM is mirrored there but it also has backup RAM mapped here, hence why bankswitching was needed.
You could only get by with less than what I said IF you use a specific cart that you KNOW uses less, or made your own cart. If you plan for people to use existing
And what I was saying is that the normal method is enough for games unless you plan to have ROM mapped in the upper 2MB with SRAM, and is already 100% compatible with existing carts/emulators because it's the same method used by quite all SRAM games . And in the context of hacking ROP, there is really no need for complicated SRAM routines :D

Whipon
Interested
Posts: 14
Joined: Thu Jul 07, 2011 3:09 am

Thank you very much to everyone

Post by Whipon » Sat Jul 09, 2011 6:03 pm

You gave me lots of very interesting info. I appreciatte your help.
Tomorrow after my job, I will try to put it in practice.
Thanks a lot ;).

Whipon
Interested
Posts: 14
Joined: Thu Jul 07, 2011 3:09 am

Post by Whipon » Wed Jul 13, 2011 4:45 am

On a side note, I have an Everdrive Cartridge and I want to modify the game to be able to save in it. I've hacked an original ROP cartdridge in the past with my own hacked version of ROP. However, flashing that cart requires to erase the EEPROM through UV and use a special adapter to flash it through the EEPROM programer.

I found an interesting doc:
http://sonicresearch.org/forums/index.p ... topic=2233

Thanks to it I regained confidence, so I edited most of this post.

Sadly, some links in that topic are dead.

At the moment, I plan to map the SRAM to 0x200000. I'll start to play with the rom and see what I can do.

Whipon
Interested
Posts: 14
Joined: Thu Jul 07, 2011 3:09 am

Post by Whipon » Thu Jul 14, 2011 3:13 am

HardWareMan wrote:
Eke wrote:The routines you want to patch are indeed the "I2C_Read_Byte" and "I2C_Write_Byte" functions but it can be a little bit complicated as you have to find where the address/data is passed, insert move instructions and disable the original I2C functions that write to $200000 and could therefore corrupt SRAM if it's mapped there. The sub_42FD8 routine should also be patched for the same reason.
"I2C_Read_Byte" and "I2C_Write_Byte" should be "I2C_Read_Bytes" and "I2C_Write_Bytes" becouse it use counter of bytes:

Code: Select all

Read loop:
ROM:00043096 loc_43096:                              ; CODE XREF: I2C_Read_Byte+66j
ROM:00043096                                         ; I2C_Read_Byte+B2j
ROM:00043096                 jsr     I2C_Read_Bit
ROM:0004309A                 jsr     I2C_Read_Bit
ROM:0004309E                 jsr     I2C_Read_Bit
ROM:000430A2                 jsr     I2C_Read_Bit
ROM:000430A6                 jsr     I2C_Read_Bit
ROM:000430AA                 jsr     I2C_Read_Bit
ROM:000430AE                 jsr     I2C_Read_Bit
ROM:000430B2                 jsr     I2C_Read_Bit
ROM:000430B6                 move.b  d0,(a0)+
ROM:000430B8                 subq.w  #1,(word_FF015C).l
ROM:000430BE                 beq.s   loc_430C6
ROM:000430C0                 jsr     I2C_Zero_bit
ROM:000430C4                 bra.s   loc_43096 


And write:
ROM:0004310C loc_4310C:                              ; CODE XREF: I2C_Write_Byte+80j
ROM:0004310C                                         ; I2C_Write_Byte+CAj ...
ROM:0004310C                 jsr     sub_42FD8
ROM:00043110
ROM:00043110 loc_43110:                              ; CODE XREF: I2C_Write_Byte+16j
ROM:00043110                 movea.l (dword_FF0160).l,a0
ROM:00043116                 move.l  (dword_FF0164).l,d0
ROM:0004311C                 jsr     I2C_Start
ROM:00043120                 and.w   #$7F,d0 ; ''
ROM:00043124                 lsl.w   #1,d0
ROM:00043126                 lsl.w   #8,d0
ROM:00043128                 move.w  d0,(word_FF015E).l
ROM:0004312E                 jsr     I2C_Write_Bit
ROM:00043132                 jsr     I2C_Write_Bit
ROM:00043136                 jsr     I2C_Write_Bit
ROM:0004313A                 jsr     I2C_Write_Bit
ROM:0004313E                 jsr     I2C_Write_Bit
ROM:00043142                 jsr     I2C_Write_Bit
ROM:00043146                 jsr     I2C_Write_Bit
ROM:0004314A                 jsr     I2C_Write_Bit
ROM:0004314E                 jsr     I2C_Read_Ack
ROM:00043152                 tst.b   d1
ROM:00043154                 bpl.s   loc_43176
ROM:00043156                 addq.w  #1,(word_FF014E).l
ROM:0004315C                 bmi.w   loc_43232
ROM:00043160                 move.w  (word_FF014E).l,d1
ROM:00043166                 cmp.w   (word_FF014C).l,d1
ROM:0004316C                 bpl.w   loc_43232
ROM:00043170                 jsr     sub_42FD8
ROM:00043174                 bra.s   loc_4310C
ROM:00043176 ; ---------------------------------------------------------------------------
ROM:00043176
ROM:00043176 loc_43176:                              ; CODE XREF: I2C_Write_Byte+60j
ROM:00043176                 move.b  (a0),d0
ROM:00043178                 lsl.w   #8,d0
ROM:0004317A                 jsr     I2C_Write_Bit
ROM:0004317E                 jsr     I2C_Write_Bit
ROM:00043182                 jsr     I2C_Write_Bit
ROM:00043186                 jsr     I2C_Write_Bit
ROM:0004318A                 jsr     I2C_Write_Bit
ROM:0004318E                 jsr     I2C_Write_Bit
ROM:00043192                 jsr     I2C_Write_Bit
ROM:00043196                 jsr     I2C_Write_Bit
ROM:0004319A                 jsr     I2C_Read_Ack
ROM:0004319E                 tst.b   d1
ROM:000431A0                 bpl.s   loc_431C2
ROM:000431A2                 addq.w  #1,(word_FF014E).l
ROM:000431A8                 bmi.w   loc_43232
ROM:000431AC                 move.w  (word_FF014E).l,d1
ROM:000431B2                 cmp.w   (word_FF014C).l,d1
ROM:000431B8                 bpl.s   loc_43232
ROM:000431BA                 jsr     sub_42FD8
ROM:000431BE                 bra.w   loc_4310C 
Note: read use autoincrement of EEPROM address pointer so it use small loop while write must set address pointer before every write byte.

Code: Select all

ROM:00043036 loc_43036:                              ; CODE XREF: I2C_Read_Byte+20j
ROM:00043036                 movea.l (dword_FF0150).l,a0
ROM:0004303C                 move.l  (dword_FF0154).l,d0
ROM:00043042                 jsr     I2C_Start
ROM:00043046                 and.w   #$7F,d0 ; ''
ROM:0004304A                 lsl.w   #1,d0
ROM:0004304C                 or.w    #1,d0 
* * *
ROM:000430B6                 move.b  d0,(a0)+ 

Write:
ROM:00043110                 movea.l (dword_FF0160).l,a0
ROM:00043116                 move.l  (dword_FF0164).l,d0
ROM:0004311C                 jsr     I2C_Start
ROM:00043120                 and.w   #$7F,d0 ; '' 
ROM:00043124                 lsl.w   #1,d0 
* * *
ROM:00043176                 move.b  (a0),d0 
Everything clear: (a0) is data pointer (stored at $FF0160) and d0 is EEPROM address (stored at $FF0164). It AND'ed with $7F (7 bit, 128 bytes) and shifted left (bit d0 in EEPROM command byte is R/W flag, wich is 0 for write and 1 for read).
Well, I loaded the rom in the MESS debugger:
$FF0160 containts allways the same RAM address ($FFEBC2), and $FFEBC2 contains allways #$2ADE. $FF0164 is allways $0000.
I'm a bit confused, since I allways have the same addresses and values.
Maybe its related to the fact MESS doesn't emulate Serial EEPROM?.

If I understand correctly, I need to store the game data through MOVEP to odd addresses in SRAM. So if $FF0160 its the data pointer, it will determine wich RAM address data will be written to SRAM, right?. I'm confused about this because of the MESS issue detailled above.

Another question: since I will write to odd addresses only, and since I need 128 bytes, my SRAM should be 256 bytes, right?.

User avatar
HardWareMan
Very interested
Posts: 704
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Thu Jul 14, 2011 5:45 am

Whipon wrote:Another question: since I will write to odd addresses only, and since I need 128 bytes, my SRAM should be 256 bytes, right?.
Nope. Consider your SRAM as 128 WORD SRAM with used only low byte. So, you have 128 bytes SRAM in 256 byte address space (odd bytes only).

Whipon
Interested
Posts: 14
Joined: Thu Jul 07, 2011 3:09 am

Post by Whipon » Thu Jul 14, 2011 1:05 pm

HardWareMan wrote:
Whipon wrote:Another question: since I will write to odd addresses only, and since I need 128 bytes, my SRAM should be 256 bytes, right?.
Nope. Consider your SRAM as 128 WORD SRAM with used only low. byte. So, you have 128 bytes SRAM in 256 byte address space (odd bytes only).
Thanks a lot HardwareMan.
What about the data pointer issues I described?.
I wanted to debug it a bit to see what it writes, etc.

User avatar
HardWareMan
Very interested
Posts: 704
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Thu Jul 14, 2011 1:10 pm

Whipon wrote:What about the data pointer issues I described?.
I wanted to debug it a bit to see what it writes, etc.
I don't use MESS, so I don't know what it does or what it don't. In addition, the game can perform some tests of equipment before use. Just do write/read byte to/from (a) and see what you get on real hardware. I think it will be much quicker. And don't forget implement address pointer, wich must increment after every read.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest