Skip to content

Commit

Permalink
Add Super R-Type
Browse files Browse the repository at this point in the history
  • Loading branch information
VitorVilela7 committed Dec 31, 2020
1 parent 0ece285 commit 738ed39
Show file tree
Hide file tree
Showing 14 changed files with 66,017 additions and 3 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\___ \ / /\ \______| | | _ // _ \ / _ \| __|
____) / ____ \ | | | | \ \ (_) | (_) | |_
|_____/_/ \_\ |_| |_| \_\___/ \___/ \__|
Version 1.3 by Vitor Vilela
Version 1.4 by Vitor Vilela
```

SA-1 Root is a project for enabling and accelerating games using the SA-1 chip.
Expand All @@ -15,6 +15,7 @@ high hardware compatibility and keeping most of the game aspects intact.
So far the following games are available:
* [Contra III](Contra-III) v1.1
* [Gradius III](Gradius-III) v1.5
* [Super R-Type](Super-R-Type) v1.0
* Super Mario World ([SA-1 Pack only](https://github.com/VitorVilela7/SA1-Pack))

What is it?
Expand Down Expand Up @@ -76,9 +77,9 @@ Credits
SA-1 Root wouldn't be that awesome without help from these people:

* indcsion (Gradius III testing)
* Erivando_BR (Contra III testing, Contra III trace logs)
* Erivando_BR (Contra III testing, Contra III trace logs and Super R-Type trace logs)
* Jeffrey (Contra III testing)
* kccheng (Contra III testing)
* kccheng (Contra III and Super R-Type testing)
* Rodzilla97 (Contra III bug report)
* slidelljohn (Gradius III bug report and extra help)
* Vitor Vilela (crazy author that did most of the patches)
Expand Down
89 changes: 89 additions & 0 deletions Super-R-Type/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# SA-1 Root: Super R-Type
Version 1.0, released 2020-12-31

Super R-Type is a classic shooter game made by Irem, being kind of a upgrade from R-Type II.

This SA-1 Root patch removes all slowdown present on the original game and drastically reduces the
loading times.

Special thanks to Erivando_BR for sending me the SA-1 Collection trace log files of Super R-Type,
which made this optimization patch possible to happen.

## How to Patch

Download the latest Super R-Type BPS patch file available on the
[Releases](https://github.com/VitorVilela7/SA1-Root/releases) tab.

You can patch it using [beat](https://www.romhacking.net/utilities/893/)
or [FLIPS](https://sneslab.net/tools/floating.zip), both common .bps patchers.

You can also patch the .asm files directly using
[Asar](https://github.com/RPGHacker/asar).

For more information on how to apply ROM patches, see this SnesLab
article: https://sneslab.net/wiki/How_to_apply_ROM_patches

It works only on the american version of Super R-Type. The japanese version is still being studied,
and it will likely not work with this patch version.

Expected checksums:

### USA Version:
#### Before patching:
* CRC32: 8B22C830
* SHA256: 05C7F6461209020785FBA33007E1830820AA44ADA4B1A6F991D936BF2335B15B

#### After patching
* CRC32: AB3B7626
* SHA256: 1D890871DE7F4FF2EA489F37F3379545BD5F88F97C5FA67CC4AD60C7BD67C703

## Compatibility

It works on both real hardware (sd2snes or SA-1 cart) and emulators (Snes9x and bsnes/higan/ares).

## Technical details

* Remapping mode: full
* Remapping strategy: static
* SA-1 usage: full with parallelism

This game relies on dynamic data pointers, but overall it does not use much of the Super Nintendo
features. The game likes passing 16-bit pointers to RAM, using simple indirection to store into
the registers, but overall the routines are somewhat organized, I didn't have to add dynamic
remappers. The game only uses 32 KB of RAM ($7E:0000-$7E:7FFF), although it initializes 64 KB
($7E:0000-$7E:FFFF). After some adjusts, it got it working with just 32 KB of BW-RAM.

Unlike earlier patches, SA-1 was used as the "master" processor, being responsible for running the
whole game and only routines that really required the SNES CPU were executed on the other processor.
All calls to the SNES CPU are asynchronous and parallel, meaning that the SA-1 requests the SNES CPU
to process a specific routine and continues executing without waiting the SNES CPU to terminate its
job. Some routines were adapted to not cause RAM collision during the parallel execution of the
routines.

Because of the game characteristics, **32 kB (256 Kbit) of BW-RAM is required to the game run**
correctly.

## RAM remap

* ``$0000-$1FFF`` -> ``$6000-$7FFF``
* ``$7E:0000-$7E:7FFF`` -> ``$40:0000-$40:7FFF``

## Credits

Super R-Type - SA-1 Root wouldn't be that awesome without help from these people:

* Erivando_BR (trace logs)
* kccheng (testing)
* Vitor Vilela (patch author)
* You (for using it :D)

## Contacting me

You can contact me though the following links:

* My Website: https://www.sneslab.net/
* My Github profile: https://github.com/VitorVilela7
* My Twitter profile: https://twitter.com/HackerVilela
* My Patreon: https://www.patreon.com/vitorvilela
* My personal blog: https://vilela.sneslab.net/

7 changes: 7 additions & 0 deletions Super-R-Type/asm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Instructions
============

Apply sa1.asm to the USA version of Super R-Type. Alternatively, use the do.sh script.

You can also patch the .asm files directly using [Asar](https://github.com/RPGHacker/asar).

142 changes: 142 additions & 0 deletions Super-R-Type/asm/databank.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
macro remap_wram_base(addr, old, new, size)
assert read1(<addr>+0) == $A9
if !strict == 1
assert read<size>(<addr>+1) == <old>
endif
org <addr>
LDA<new>
endmacro

macro remap_wram(addr)
%remap_wram_base(<addr>, $7E, ".B #$40", 1)
endmacro

macro remap_wram_local(addr)
%remap_wram_base(<addr>, $00, ".B #$40", 1)
endmacro

macro remap_wram_16(addr)
%remap_wram_base(<addr>, $007E, ".W #$0040", 2)
endmacro

; Bank 7E
%remap_wram($008010)
%remap_wram($0080A8)
%remap_wram($008406)
%remap_wram($008514)
%remap_wram($00916F)
%remap_wram($0091B6)
%remap_wram($009206)
%remap_wram($00982F)
%remap_wram($009858)
%remap_wram($009881)
%remap_wram($0098A9)
%remap_wram($0098FA)

; Indirect pointers building
%remap_wram($00A1A6)
%remap_wram_16($00A1CF)

; Indirect pointers that uses local RAM
macro remap_indirect(orig, addr)
assert read1(<addr>+0) == $A0
if !strict == 1
assert read2(<addr>+1) == <orig>
endif
org <addr>
LDY.W #$6000|<orig>

endmacro

%remap_wram_local($008936)
%remap_wram_local($0089AF)

;these below doesn't work because the game often uses the pointers with DB set to $7E,
;I made TLR remap differently the indexes by consequence.
;%remap_indirect($189A, $008933)
;%remap_indirect($189A, $0089AC)
;%remap_indirect($1892, $009651)
;%remap_indirect($1832, $009647)
;%remap_indirect($1862, $00964C)

; DMA parameters
; Other DMA are either static, ROM-only or unused...
%remap_wram($008329)
%remap_wram($00834F)
%remap_wram($00838C)
%remap_wram_local($0083C2)

macro remap_mvn(b1, b2, addr)
if !strict == 1
assert read1(<addr>+0) == $54
assert read1(<addr>+1) == <b1>
assert read1(<addr>+2) == <b2>
endif
!sb1 = <b1>
!sb2 = <b2>
if !sb1&$FE == $7E
!sb1 #= !sb1-$7E+$40
endif
if !sb2&$FE == $7E
!sb2 #= !sb2-$7E+$40
endif
assert !sb1 == $40 || !sb1 == $41 || !sb2 == $40 || !sb2 == $41
assert !sb1 != $7E && !sb2 != $7E && !sb1 != $7F && !sb2 != $7F
org <addr>
MVN !sb1, !sb2
endmacro

%remap_mvn($7E, $7E, $008720)
%remap_mvn($7E, $7E, $008744)
%remap_mvn($7E, $05, $009B81)
%remap_mvn($7E, $05, $009BA4)
%remap_mvn($7E, $05, $009BB6)
%remap_mvn($7E, $05, $00A183)

macro remap_indirect_jump(dest, addr)
assert read1(<addr>+0) == $DC
if !strict == 1
assert read2(<addr>+1) == <dest>
endif
!res #= <dest>|$6000
assert !res >= $6000 && !res <= $7FFF
org <addr>
JMP.W [!res]
endmacro

%remap_indirect_jump($0010, $008253)
%remap_indirect_jump($1801, $0084D4)
%remap_indirect_jump($1801, $00872D)
%remap_indirect_jump($00F5, $008758)
%remap_indirect_jump($00F5, $008791)
%remap_indirect_jump($00F5, $0087D7)
%remap_indirect_jump($00F5, $00881A)

; Format: <address to store>, <value to store>
; Remap the WRAM specific to BWRAM.

; It's worth commenting that the address is incremented by 5,
; while the code only read the first four values. It's suggestive
; that the table was supposed to be incremented by 4.

; It's very likely a bug, but we have to remain the original behavior
org $0480BC
db $02,$21,$00,$00,$07
db $42,$60,$00,$09,$42
db $00,$00,$16,$21,$00
db $00,$00,$00


1 change: 1 addition & 0 deletions Super-R-Type/asm/do.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rm srtype.sfc; cp srtype_base.sfc srtype.sfc && asar -Dstrict=1 sa1.asm srtype.sfc
Loading

0 comments on commit 738ed39

Please sign in to comment.