Most compatible way to jump to game image on hardware - making my own cart

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

MrD
Very interested
Posts: 69
Joined: Sun Jan 26, 2014 4:29 pm

Most compatible way to jump to game image on hardware - making my own cart

Post by MrD » Fri Jun 19, 2020 8:26 am

My Game Raccoon Revision 1 SD card flashcart is working great. :)

Here's a video of the current menu interface (sadly lacking an animated raccoon mascot for the loading screns). You can read about R0 and R1 in the GR thread in the Cartridge subforum.

https://cdn.discordapp.com/attachments/ ... 200527.mp4

It works on every retail dump I can make or rip from compilations. Since Wiz 'n' Liz, Zero Tolerance and Hard Wired work, I'm confident that the hardware and software logic I'm using to switch control to games is appropriate. (If there any other freely available retail titles of the era other than these three, I'm interested.)

However, when it comes to homebrew games, demoscene productions and Sonic 1,2,3/K mods, compatibility is only around 50%. I've made some spreadsheets showing the compatibility on the current version of my board and menu system. (They also serve as a rough guide for me to tell which mod/game is which, so I apologise for the crudeness of the notes. :) )

These are all on a PAL Model 1 Mega Drive with TMSS.

Sonic mods compatibility table:
https://docs.google.com/spreadsheets/d/ ... a7/pubhtml

Demo prods compatibility table:
https://docs.google.com/spreadsheets/d/ ... U0/pubhtml

Homebrew compatibility table:
https://docs.google.com/spreadsheets/d/ ... MF/pubhtml

Very briefly: the GR board has 8 megabytes of Flash memory which I treat as two 4 megabyte banks ( 0) bootable menu + 1) game writing area ) switched by a PIC. To change from the system RAM-resident menu software to the installed game image, I perform the following steps:

- Write to TIME (which is mapped to a bi-directional register on the cart which the PIC can access) to signal that a bank switch is required. The installed image is now in 0x000000-0x3FFFFF.
- The contents of 0x000000.l are copied to a7.
- The contents of 0x000004.l are copied to a0, then jmp (a0)

This should be all that's necessary, and for the most part it is. I expected that games would not hold any assumptions about the state of the system upon boot, but it seems that some games do - certain titles wouldn't start, some would have broken controls, others garbage graphics. One example is the title screen of Sonic's Fun & Easy Adventure which assumes both RAM (spinning SEGA is garbage) and VRAM state (title screen garbage tiles) are zeros. You can simulate this in an emulator if you prepend something that fills these areas with nonzeroes before booting SF&EA.

To fix that, I added a small 'anti-bootstrap' that tries to clean up after the GR menu before booting:

- The VRAM, VSRAM and CRAM are set to zero.
- The RAM-resident menu copies anti-bootstrap to the end of RAM overwriting the stack and jumps to it.
- The anti-bootstrap clears all system RAM before itself to zero.
- Game boots.

The idea is hopefully to have all of the RAM I can set to zero, except the anti-bootstrap itself which lives where the stack would, so would be overwritten by games without being read.

Unfortunately, even with the anti-bootstrap, compatibility is still around 50% for non-retail games. I'm not sure why this is. I suspect that it could be one of the following:

- Interrupt state. The GR menu can't use interrupts because I'm constantly bankswitching out the ROM-resident menu firmware (for writing the game image to Flash), so I disable all interrupts immediately and use Vcounter wait loops for timing. Do games expect interrupts to begin enabled?
- VDP registers. I don't clean these up because it would be surely really silly for a game to assume anything about these? Is there a 'best' state to leave the VDP in? I've added a mode where if you hold Start, my cart performs the TMSS sequence only and then jumps to the anti-bootstrap without copying anything to VRAM or setting VDP state which does fix some demos. (This is the 'emergency boot' in the spreadsheets.)
- Z80 state. I only interact with the Z80 enough to silence the PSG and FM and to write an infinite loop to Z80 RAM space. Is there a 'best' state to leave the Z80 in?

I'm not thrilled about bending over backwards for certain games. I'd rather have my cart not provide too much assistance to the target game, so folks would write their software properly. :p Tanglewood (demo and itch.io bundle version), Phantom Gear, Curse of Illmore and Pringles all work great.

However, one common factor in the games that don't work is that they all seem to use SGDK - this is both demo prods and homebrew games. If a game doesn't use SGDK, chances are it'll work on my cart. Every RetroSouls game on Itchio except Misplaced fails to boot.

Given the above, I feel it's my cart that's doing something wrong rather than the games.

- Does SGDK have any SRAM handling by default? If the default simplest library startup begins with a routine for detecting SRAM size for example, it's possible that it's getting confused. Sonic mods like Classic Heroes and Dr. Yundong can detect that the GR cart has no SRAM though. There's nothing I can do about this, but it would explain the faults.
- Does SGDK have any specific VDP state it expects? When most games that don't work attempt to boot, there's a momentary frame where a row of small glitchy squares (like 2x2, bigger than cramdots) appear in a horizontal line for a single frame. Sometimes a row of green ]]]]] characters will appear on screen until I reset the system.

Also it's possible that these games are all just NTSC only, but they seem to work under mednafen in 50 Hz mode.

Apologies for the rambling thread, but I thought you might be interested in my progress. Any thoughts on my approach would be very welcome. I can send the source and a compiled menu rom image (with the GR cart interaction simulated) if anybody wants to see that.

The anti-bootstrap/boot sequence looks like this:

Code: Select all

        ; The RAM resident code is compiled to run from $FF0000.
        ; It'll be copied into position by the entry point.
        ; At the address of $FF0000+CODELENGTH, the static RAM memory
        ; map with my global variables in begins.
        rorg    RAM_START
game_raccoon_ram_resident_assembled_block_begin:    

; game_raccoon_start_emergency:
; Do the handshake without affecting VDP, then boot game immediately.
game_raccoon_start_emergency:
        move.w  #GAME_RACCOON_TIME_WRITE_MAGIC_NUMBER_GR_HANDSHAKE,d0
        TIME_write_d0_w
emergency_handshake_loop_until_deisolated:
        GAME_RACCOON_isolation_test
        bne     emergency_handshake_loop_until_deisolated        
        jmp     game_raccoon_game_partition_boot_sequence
        
; game_raccoon_game_partition_boot_sequence:
; Signal to the PIC that we want to boot the currently installed game,
; wait for deisolation, install the anti-bootstrap sequence at the very
; end of RAM, jump to anti-bootstrap, erase all Game Raccoon RAM-resident
; and VRAM-resident data, and jump to game entry point.
game_raccoon_game_partition_boot_sequence:
        move.w  #GAME_RACCOON_TIME_WRITE_MAGIC_NUMBER_BOOT_CURRENT_GAME_PARTITION,d0
        TIME_write_d0_w
game_raccoon_game_partition_boot_sequence_loop_until_deisolated:
        GAME_RACCOON_isolation_test
        bne     game_raccoon_game_partition_boot_sequence_loop_until_deisolated
        ; Alright, we've switched to the game partition!
        ; We CANNOT return to the boot partition by any means now.
        ; All ROM-resident data is inaccessible.
        ; Clear VDP state and VRAM.
        jsr     vdp_clear_all_cram        
        jsr     vdp_clear_all_vram        
        jsr     vdp_clear_all_vsram      
        ; Write a zero to TIME which may help compatibility with some homebrew.
        ; This will be ignored by the PIC.
        move.w  #0,d0
        TIME_write_d0_w
        ; Copy the anti-bootstrap to the end of RAM where the stack lives,
        ; destroying the stack as we go.
        ; The anti-bootstrap erases as much as it can and then finally
        ; jumps to the new game ROM image.        
        lea     game_raccoon_anti_bootstrap_start,a0
        lea     GAME_RACCOON_ANTI_BOOTSTRAP_DESTINATION,a1
        move.w  #(GAME_RACCOON_ANTI_BOOTSTRAP_BLOCK_COPY_LENGTH_LONGS-1),d0
game_raccoon_anti_bootstrap_copy_next_long:
        move.l  (a0)+,(a1)+
        dbf     d0,game_raccoon_anti_bootstrap_copy_next_long        
        jmp     GAME_RACCOON_ANTI_BOOTSTRAP_DESTINATION
        
; Anti-bootstrap:
; ---------------
; RAM Layout:
; START                                                                  END
; [RAM-resident Game Raccoon stuff] [RAM variables]                  [Stack]
; After anti-bootstrap installation:
; [RAM-resident Game Raccoon stuff] [RAM variables]         [Anti-bootstrap]
; After anti-bootstrap execution:
;                                                           [Anti-bootstrap]
; The new game should immediately clobber the anti-bootstrap's lingering stuff
; when it starts.        
        align   4
game_raccoon_anti_bootstrap_start:         
        ; Erase the Game Raccoon RAM-resident part up until the 
        ; game_raccoon_anti_bootstrap_erase_next_long label.
        lea     RAM_START,a0
        move.w  #(GAME_RACCOON_ANTI_BOOTSTRAP_ERASE_LENGTH_LONGS-1),d0
        move.l  #0,d1        
        jmp     GAME_RACCOON_ANTI_BOOTSTRAP_DESTINATION+game_raccoon_anti_bootstrap_erase_next_long-game_raccoon_anti_bootstrap_start
        align   4        
game_raccoon_anti_bootstrap_erase_next_long:        
        move.l  d1,(a0)+
        dbf     d0,game_raccoon_anti_bootstrap_erase_next_long
        ; Everything is erased except the previous two lines
        ; and the following three. HIT IT!
        move.l  (CART_STACK_POSITION),a7           ; Load the stack pointer starting value from the cart.
        move.l  (CART_ENTRY_POINT),a0              ; And jump to the entry point given in the cart image header!
        jmp     (a0)                            
game_raccoon_anti_bootstrap_end = *        
        
GAME_RACCOON_ANTI_BOOTSTRAP_BLOCK_COPY_LENGTH_LONGS = game_raccoon_anti_bootstrap_end-game_raccoon_anti_bootstrap_start
        
GAME_RACCOON_ANTI_BOOTSTRAP_DESTINATION = (RAM_END-(GAME_RACCOON_ANTI_BOOTSTRAP_BLOCK_COPY_LENGTH_LONGS*4)) 

GAME_RACCOON_ANTI_BOOTSTRAP_ERASE_LENGTH_LONGS = (((GAME_RACCOON_ANTI_BOOTSTRAP_DESTINATION+(game_raccoon_anti_bootstrap_erase_next_long-game_raccoon_anti_bootstrap_start))-RAM_START)/4)
; Anti-bootstrap stuff end.    
When the GR menu starts, it silences the sound chips with the following code:

Code: Select all

        macro z80_bus_request_engage
        move.w  #$0100,(MM_Z80_BUS_REQUEST)
        endm

        macro z80_wait_bus_available
l\?     btst    #0,(MM_Z80_BUS_REQUEST)
        bne     l\?
        endm

        macro z80_bus_request_disengage
        move.w  #$0000,(MM_Z80_BUS_REQUEST)
        endm

        macro z80_reset_engage
        move.w  #$0000,(MM_Z80_RESET)
        endm

        macro z80_reset_disengage
        move.w  #$0100,(MM_Z80_RESET)
        endm
        
z80_initialise:
        z80_bus_request_engage
        z80_reset_disengage
        z80_wait_bus_available

        lea     MM_Z80_MEMORY_SPACE,a0

        move.b  #$C3,(a0)+                         ; Put a [jp $0000] at $0000.
        move.b  #$00,(a0)+
        move.b  #$00,(a0)

        z80_reset_engage
        z80_bus_request_disengage
        z80_reset_disengage
        rts
        
; psg_fm_initialise:
; Invalidates all registers.        
; The sound chips are on the Z80 bus, so we request it as above
; then send the values we need.
psg_fm_initialise:
        z80_bus_request_engage
        z80_wait_bus_available

        ; Silence the SN76489, by setting attenuation of all channels to F (full attenuation = silence).
        lea     MM_SN76489_PSG,a0
        move.b  #(PSG_LATCH_BIT|PSG_CHANNEL_0|PSG_TYPE_VOLUME_DATA|$F),(a0)  
        nop        
        move.b  #(PSG_LATCH_BIT|PSG_CHANNEL_1|PSG_TYPE_VOLUME_DATA|$F),(a0)  
        nop       
        move.b  #(PSG_LATCH_BIT|PSG_CHANNEL_2|PSG_TYPE_VOLUME_DATA|$F),(a0)         
        nop
        move.b  #(PSG_LATCH_BIT|PSG_CHANNEL_3|PSG_TYPE_VOLUME_DATA|$F),(a0)  
        
        ; Silence the YM2612:
        lea     MM_YM2612_ADDRESS_P1,a0
        lea     MM_YM2612_DATA_P1,a1
        ; For each of the six channels (lower three bits), note off all four operators (upper four bits).
        YM2612_wait
        move.b  #YM2612_28_NOTE_ON_CONTROL,(a0)
        YM2612_wait
        move.b  #%00000000|YM2612_28_CHANNEL_0,(a1)
        YM2612_wait
        move.b  #%00000000|YM2612_28_CHANNEL_1,(a1)
        YM2612_wait
        move.b  #%00000000|YM2612_28_CHANNEL_2,(a1)
        YM2612_wait
        move.b  #%00000000|YM2612_28_CHANNEL_3,(a1)
        YM2612_wait
        move.b  #%00000000|YM2612_28_CHANNEL_4,(a1)
        YM2612_wait
        move.b  #%00000000|YM2612_28_CHANNEL_5,(a1)
        ; For each of the three channels in each of the two parts, set
        ; the TL of each operator within each channel to 127.
        move.w  #(2-1),d0                                                             ; Two parts.
psg_fm_initialise_next_part:
        move.b  #$40,d1                                                               ; 40h is the data slot for the TLs of all operators across all channels.
        move.w  #(16-1),d2                                                            ; 16 entries across TL struct.
psg_fm_initialise_next_targeted_data_slot:
        YM2612_wait
        move.b  d1,(a0)                                                               ; Write to ADDRESS_P* the data slot we're targeting.
        addi.b  #1,d1                                                                 ; Advance targeted data slot to next across the TL row.
        YM2612_wait
        move.b  #127,(a1)                                                             ; Write to DATA_P* the maximum TL (minimum volume) value to the current slot.
        dbf     d2,psg_fm_initialise_next_targeted_data_slot        
        lea     MM_YM2612_ADDRESS_P2,a0                                               ; Swap to the other Part.
        lea     MM_YM2612_DATA_P2,a1
        dbf     d0,psg_fm_initialise_next_part
                
        z80_bus_request_disengage
        rts       

raq
Interested
Posts: 11
Joined: Sat Mar 06, 2010 11:42 am

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by raq » Fri Jun 19, 2020 11:48 am

Hi, you need to simulate a hard reset, see if the following helps, written in gnu as, must be executed in 68K WRAM

Code: Select all

    .... code to switch banks

    move.w  #0x2700,%sr                     | disable all interrupts
    sub.l   %a0,%a0                         | init pointer to beginning of ROM
0:  move.w  %a0,0x00a10008                  | clear IO control
    move.l  %a0,0x00a1000a                  |  registers
    move.l  (%a0)+,%a7                      | Set Stack Pointer
    move.l  (%a0),%a0                       | Get Reset address
    jmp     (%a0)                           | Jump to code entry point
You can or should do other things like clear VRAM/CRAM/VSRAM before jumping into the above code, thou technically it shouldn't be needed. The reason for the I/O control register clear is that most genesis games check these registers to determine a 'hot reset' from a 'cold reset'. Hot resets don't initialise the system...

MrD
Very interested
Posts: 69
Joined: Sun Jan 26, 2014 4:29 pm

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by MrD » Fri Jun 19, 2020 2:10 pm

Thank you. :) Hmm, I haven't cleared the IO control registers. I don't see how that would cause games to not boot... ohhhhh I see. Right! Now that is interesting, yes!

Also it's good to know that interrupts should begin disabled.

Sik
Very interested
Posts: 925
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by Sik » Fri Jun 19, 2020 5:30 pm

Yeah, interrupts have to be disabled because that's what 68000 does on reboot (remember not all systems have TMSS so on those the game is the bootstrap). And yeah, the state of the I/O ports on boot is how games tell apart soft reset from hard reset. Also, Z80 should be left reset on boot as well (and Reset button will indeed make the Z80 go into reset).

One thing you may want to do: make sure to leave "SEGA" in $A14000 (i.e. don't clear the register). That should help fix a few early games that don't do TMSS properly.
Sik is pronounced as "seek", not as "sick".

MrD
Very interested
Posts: 69
Joined: Sun Jan 26, 2014 4:29 pm

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by MrD » Sat Jun 20, 2020 1:24 pm

With IO reset and Z80 reset added, compatibility for demoscene and homebrew goes up from 50% to 90%ish. :D Thank you! All the SGDK-based software works now: all the Retro Souls games and the Resistance demos.

My verdict:
Image

I'm not convinced it's necessary... despite it clearly being necessary haha. It seems like an odd thing to require, not a single retail game relies on it to cold boot successfully. (Wait a moment... if games check the IO registers to determine whether it's a reset, that would explain the few games that started acting normally after the anti-bootstrap was added but before the IO fix. I wonder if I took the anti-bootstrap out and left the IO fix in, they'd initialise themselves properly now. The lightbulbs are coming on in my head, slowly. :D )

Photos of all the stuff that now works due to this last fix, which I'll probably use on my website somewhere.
https://imgur.com/a/O9pR9l7

New spreadsheet with homebrew/demo prod compatibility:
This spreadsheet only shows things that were previously marked as 'Yes' in the Crashed column. Everything marked 'No' has been fixed with this change.
https://docs.google.com/spreadsheets/d/ ... Mc/pubhtml

Most things that don't work aren't because of not booting any more, with very few exceptions. Griel's Quest is very strange. To all appearances it works, but as far as I can tell I'm supposed to visit the end castle first in order to learn that it's locked, then visit four other areas to get keys. But when I leave the cutscene at the castle, the controller doesn't respond on the map any more and I can't select anywhere except the castle.

Sonic mods compatibility is unchanged.

raq
Interested
Posts: 11
Joined: Sat Mar 06, 2010 11:42 am

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by raq » Sat Jun 20, 2020 4:12 pm

Glad it helped :D :D :D

The reason to clear I/O control registers...
Here is some code that SEGA asked all developers to use, pretty sure 95%+ of games use it. The full code is called ICD_BLK4 and its in the DTS archives somewhere.

Code: Select all


_ColdBoot:                              |
    tst.l    0x00a10008.l               | on a power cycle MD hardware initialises
    jbne     0f                         |  the I/O control ports to 0x00
    tst.w    0x00a1000c.l		| on a reset they
0:  jbne     _WarmBoot 			|  keep there value

    ...code to setup 68K register
    ...code to disable TMSS
    ...code to setup VDP registers
    ...code to initialise Z80
    ...code to clear WRAM
    ...code to clear VRAM
    ...code to clear CRAM
    ...code to clear VSRAM
    ...code to init PSG
    
_WarmBoot:
    tst.w    0x00c00004.l               | dummy read of VDP to reset VCTRL
Also some other routines are only run when power cycled, like score board init, SRAM init etc... Now lets take for example that your menu code enables TMSS (by writing 0 to TMSS register, which BTW is the power on state) before starting the game ROM but left I/O control ports, the vast majority (all?) of games won't boot because of TMSS which will always be skipped by the above, because your menu code sets up I/O control registers (to use pad). A lot of games/demos rely on this initialised state but some don't, all depends on the developer. Thats why you were only reaching 50% before. Not sure whats happening with that last 10%, any chance of looking at the source code?

MrD
Very interested
Posts: 69
Joined: Sun Jan 26, 2014 4:29 pm

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by MrD » Sun Jun 21, 2020 2:05 pm

Now lets take for example that your menu code enables TMSS (by writing 0 to TMSS register, which BTW is the power on state) before starting the game ROM but left I/O control ports, the vast majority (all?) of games won't boot because of TMSS which will always be skipped by the above, because your menu code sets up I/O control registers (to use pad)
I know you're giving an example, but to be clear my menu has always done the normal 'region check, if necessary 'SEGA' TMSS' stuff first and never cleared it. :) With that arrangement all the retail images I tried worked great even before I cleared the RAM/VRAM, or added the IO register clear / Z80 reset after you suggested it. :) It's only SGDK games that really misbehaved by not clearing the IO register.

One hack that's come to life after putting in the IO register clear is Dr. Yundong, which I'm really pleased about! Every other Sonic game or hack I've tried had no problems with setting up VDP state before, but Dr. Yundong wasn't setting the sprite base address or horizontal scroll table location or flags correctly so the scrolling was all scrambled up and the sprites were missing.

Edit - Hmm, I'm going through the Sonic hacks again and the results are fascinating! :) Dr. Robotnik's Creature Capture had very strange behaviour - it would move Robotnik like the attract mode then go into a reboot loop inside GHZ, but that's fixed now. Sonic Green Snake would show Nyancat on a loop, it doesn't do that any more. Erazor was (more) strange - inhuman all the time and no Deaths counter. Sonic Mania Style works a little more but certain combinations of actions will crash it just less frequently. Other hacks like Back To The Origin are unchanged.

raq
Interested
Posts: 11
Joined: Sat Mar 06, 2010 11:42 am

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by raq » Sun Jun 21, 2020 5:40 pm

Do these hacks work in emulation? Not the highly accurate ones :D
The reason is I believe some of these hacks create exception errors by accident, the most common is reading or writing mis-aligned words, this will, at best! crash on actual hardware but can do other stange things. If the GR runs all retail games properly I'd be pretty sure your hardware is absolutely fine :D :D :D

raq
Interested
Posts: 11
Joined: Sat Mar 06, 2010 11:42 am

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by raq » Sun Jun 21, 2020 6:44 pm

Hmmmm... Sonic - Return To The Origin seems to only work in fusion.
Blastem comes up with a nice message for the same ROM:-

[*] 'Read from VDP data port while writes are configured. CPU is now frozen. VDP Address 4, CD:5'

Not much use I know but this suggests the hack is not accessing hardware correctly. Probably the VDP has been setup for a write command, vertical blank comes along and there's a VDP read somewhere, on actual hardware this will halt the machine. Quite a few hacks/mods access hardware incorrectly and were probably only tested with an emulator, more likely fusion, so I wouldn't worry too much about these style of ROMs.

Sik
Very interested
Posts: 925
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by Sik » Mon Jun 22, 2020 9:46 am

If BlastEm barfs at a hack you can probably assume the issue is the hack :​P

And yeah, games rely on telling apart between cold and warm boot not only because of the init skip stuff (not sure why Sega insisted on that), but also because most games don't reset the options when you press the Reset button, and if the settings aren't initialized properly this will cause trouble as the game is stuck with invalid values. Robocop 3 is prone to crash, for example.
Sik is pronounced as "seek", not as "sick".

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

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by Chilly Willy » Mon Jun 22, 2020 1:06 pm

Well, at least by having the code written to flash, you don't have the problem of games that write over top of the rom area to crash early versions of rom-backup systems and emulators. I've posted a number of patch files over at Sega-16 that cure the startup problems with a few different games that do things like that. The other common early protection scheme was to check for an already running Genny and crash since only a backup-system with a menu would leave the system in a setup state. I seem to remember reading about a third-party multi-game MD system where one of the games included actually crashed because of the multi-game menu. Might have been about a different system than the MD, though. Been a while since I saw the article.

Oh, forgot... to get a few games to run, you might need to clear the work ram. Some games assume the memory is clear at the start, which allowed for some interesting tricks done by swapping carts on the fly. :lol:

TmEE co.(TM)
Very interested
Posts: 2397
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by TmEE co.(TM) » Mon Jun 22, 2020 5:49 pm

You could see what TMSS itself does when starting a game : http://www.tmeeco.eu/SMD/TMSSCODE.ASM
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

MrD
Very interested
Posts: 69
Joined: Sun Jan 26, 2014 4:29 pm

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by MrD » Mon Jun 22, 2020 9:28 pm

Sik wrote:
Mon Jun 22, 2020 9:46 am
If BlastEm barfs at a hack you can probably assume the issue is the hack :​P

And yeah, games rely on telling apart between cold and warm boot not only because of the init skip stuff (not sure why Sega insisted on that), but also because most games don't reset the options when you press the Reset button, and if the settings aren't initialized properly this will cause trouble as the game is stuck with invalid values. Robocop 3 is prone to crash, for example.
I've noticed that options issue in a few games yeah, it's very strange when you go into a game's options menu and it's set everything to Lives 0, Continues 0, heh. :D

To answer you and raq, I haven't tried any of these mods in BlastEm yet as I didn't want their uniqueness to be spoiled for me before I tried them on the real system. :) I only tried roms in emulators when their behaviour was very bizarre - things like Sonic 2 Good Edition (which is genius) only working in emulators deliberately (I assume that's part of the joke too), or Erazor having permanent inhuman mode from the get-go and making absolutely no sense.

I didn't know that BlastEm was that informative with its errors; that's really useful to know! That lets me go back and verify a whole lot of things. (My experience with BlastEm is turning it on and putting it to one side for later when I saw the interface was unusual.)

Stef
Very interested
Posts: 3048
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by Stef » Tue Jun 23, 2020 10:28 am

A reason why SGDK games were definitely heavily impacted by the lack of IO clearing is that indeed, SGDK will consider that we are in a soft reset and a lot of stuff won't be cleared / re-initialized properly, the first thing i think of and that can cause a lot of trouble is "initialized variables" (!= 0) which won't be initialized because of that. I think SGDK itself use some even if i try to avoid that... I let the developer to handle by itself how to reset state on soft reset (which a lot of developer doesn't handle properly to be honest as that is definitely not trivial). An easy way to get it right and avoid troubles is to force SYS_hardReset() even on soft reset and keep persistent data (score or stuff like that) in SRAM if possible.

MrD
Very interested
Posts: 69
Joined: Sun Jan 26, 2014 4:29 pm

Re: Most compatible way to jump to game image on hardware - making my own cart

Post by MrD » Tue Jun 23, 2020 11:10 am

I hope I haven't offended you Stef in singling out SGDK. I don't mean anything as a criticism, I'm just interested in how everything works.

Edit - I'm putting together a new spreadsheet of Sonic mods changed by the IO fix, and I'm trying Griel's Quest again. It turns out that on the level select menu, for some bonkers reason buttons A and C are 'confirm' and B is 'back', which is outrageous!

Post Reply