How to use SRAM Support in ATGames Firecore with "Neto MD-DOS".

Discussion in 'Engineering & Reverse Engineering' started by Esrael, Jun 24, 2020.

  1. Esrael

    Esrael

    Tech Member
    227
    80
    28
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    Originally the Tectoy MD 2017 which uses the Redkid 2500 processor (the same used in ATGames portables units), does not have support for Save RAM when you run a game loaded to SDRAM. But i have found a way to add support in these systems with a custom O.S. Here I will try to explain how to use this feature in your hack.

    First we need a way to detect if game is running over an ATGames or a classic system to allow game running on both machines. An easy way is using operator ABCD, which behave different for invalid operations and gives a safe way to detect the system.

    The following code can be used to detect system.
    Code (Text):
    1.  
    2. ;===============================================================================      
    3. ; Função para determinar se o processador é o Redkid 2500 usando o operador ABCD
    4. ; que retorna resultado diferente do processador M68000
    5. ; - Retorna verdadeiro ou falso em carry flag
    6. ; ->>>
    7. ;===============================================================================
    8. Is_Redkid_2500:                                                  ; Check_Console
    9.                 movem.l A0/D0-D3, -(A7)
    10.                 moveq   #$00, D0              
    11.                 st      D0                                          
    12.                 moveq   #(((ABCD_Test_End-ABCD_Test)/$04)-$01), D1
    13.                 moveq   #$00, D2
    14.                 moveq   #$00, D3          
    15.                 lea     ABCD_Test(PC), A0                                                                                                                                
    16. Check_Console_Loop:
    17.                 move.b  (A0)+, D2                                            
    18.                 move.b  (A0)+, D3                                            
    19. Check_Console_MD_17_Detected:
    20.                 abcd    D2, D3                                                          
    21.                 cmp.b   (A0)+, D3                                          
    22.                 bne.s   Check_Console_MD_17_Found                                      
    23.                 tst.b   (A0)+                                                                                                  
    24.                 dbra    D1, Check_Console_Loop                                  
    25.                 sf      D0                                            
    26. Check_Console_MD_17_Found:
    27.                 andi.w  #$00FF, D0
    28.                 movem.l (A7)+, A0/D0-D3              
    29.                 rts
    30. ABCD_Test:  ;  operador 1 / operador 2 / resultado MD clássico / resultado MD 17
    31.                 dc.b    10, 10, 26, 20
    32.                 dc.b    11, 11, 28, 22
    33.                 dc.b    12, 12, 30, 24
    34.                 dc.b    13, 13, 32, 26
    35.                 dc.b    14, 14, 34, 28
    36.                 dc.b    15, 15, 36, 30
    37. ABCD_Test_End:            
    38. ;===============================================================================      
    39. ; Função para determinar se o processador é o Redkid 2500 usando o operador ABCD
    40. ; que retorna resultado diferente do processador M68000
    41. ; <<<-
    42. ;===============================================================================
    43.  
    To not call the check hardware routine every time you want to access SRAM. You can create a variable and then check hardware at startup to init the created variable.

    Code (Text):
    1.  
    2.                 move.b  #dt_SEGA_Mapper, (Device_Type_Flag).w
    3.                 bsr.s   Is_Redkid_2500
    4.                 beq.s   Exit_Check_Device
    5.                 move.b  #dt_Redkid_2500, (Device_Type_Flag).w
    6. Exit_Check_Device:
    7.                 rts
    8.  
    One thing to know, is how SDRAM works in the redkid 2500. The entire SDRAM area can be used as RAM memory ( This can be a problem to games which has some protection routine which try to write to ROM area, Sonic 3D as example require a patch or crash when you Access the Special Stage ), but you cannot write a single byte, only word and dword can be written. For read you can use byte mode.

    When using the "Neto MD DOS" O.S . in these systems the address above 0x400000 is reserved to SRAM, if your ROM has a reader with SRAM information. The word of end of SRAM in te ROM header is used to determine the SRAM size.

    When writing to SDRAM as SRAM you must write 0xFF to high byte of word, or the content of memory will be corrupted after system reset. ( For some odd reason if you leave the high byte of word in 0x00, the SDRAM is corrupted after a reset ).

    Now, some examples for read and write to SRAM:

    Reading:
    Code (Text):
    1.  
    2.                 moveq   #$40, D0
    3.                 cmpi.b  #dt_Redkid_2500, (Device_Type_Flag).w
    4.                 beq.s   Load_Data_From_SRAM
    5.                 moveq   #$20, D0
    6.                 move.b  #SRAM_Enable_Flag, (SEGA_Mapper_Ctrl_Reg_0)
    7.                 bsr.s   Load_Data_From_SRAM
    8.                 move.b  #SRAM_Disable_Flag, (SEGA_Mapper_Ctrl_Reg_0)
    9.                 rts
    10. ;-------------------------------------------------------------------------------                                            
    11. Load_Data_From_SRAM:
    12.                 swap.w  D0
    13.                 movea.l D0, A0
    14.            
    15. Loop_Load_Data_From_SRAM:                                      
    16.                 move.b  $0001(A0), (A1)+
    17.                 addq.l  $02, A0          
    18.                 dbra    D1, Loop_Load_Data_From_SRAM  
    19.                 rts
    20.  
    Writing:
    Code (Text):
    1.  
    2.                 moveq   #$40, D0
    3.                 cmpi.b  #dt_Redkid_2500, (Device_Type_Flag).w
    4.                 beq.s   Save_Data_To_SRAM
    5.                 moveq   #$20, D0
    6.                 move.b  #SRAM_Enable_Flag, (SEGA_Mapper_Ctrl_Reg_0)
    7.                 bsr.s   Save_Data_To_SRAM
    8.                 move.b  #SRAM_Disable_Flag, (SEGA_Mapper_Ctrl_Reg_0)
    9.                 rts
    10. ;-------------------------------------------------------------------------------                                            
    11. Save_Data_To_SRAM:
    12.                 swap.w  D0
    13.                 movea.l D0, A0
    14.            
    15.                 moveq  #-$01, D0
    16. Loop_Save_Data_To_SRAM:                                      
    17.                 move.b  (A1)+, D0
    18.                 move.w  D0, (A0)+          
    19.                 dbra    D1, Loop_Save_Data_To_SRAM  
    20.                 rts
    21.  
    The variables
    Code (Text):
    1.  
    2. SEGA_Mapper_Ctrl_Reg_0 equ $00A130F1
    3.  
    4. SRAM_Disable_Flag equ $00
    5. SRAM_Enable_Flag equ $01
    6.  
    7. dt_Redkid_2500 equ 'R'
    8. dt_SEGA_Mapper equ 'S'
    9.  
    10. Device_Type_Flag equ $FFFFFFFC ; any free RAM Address
    11.  
    Best regards:
    --------------
    Neto.
     
    Last edited: Jun 25, 2020