-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from VitorVilela7/super-rtype
Add Super R-Type
- Loading branch information
Showing
14 changed files
with
66,017 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.