Skip to content

Commit ca3fd62

Browse files
authored
Merge pull request #17 from VitorVilela7/super-rtype
Add Super R-Type
2 parents 0ece285 + 738ed39 commit ca3fd62

14 files changed

+66017
-3
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
\___ \ / /\ \______| | | _ // _ \ / _ \| __|
66
____) / ____ \ | | | | \ \ (_) | (_) | |_
77
|_____/_/ \_\ |_| |_| \_\___/ \___/ \__|
8-
Version 1.3 by Vitor Vilela
8+
Version 1.4 by Vitor Vilela
99
```
1010

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

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

7879
* indcsion (Gradius III testing)
79-
* Erivando_BR (Contra III testing, Contra III trace logs)
80+
* Erivando_BR (Contra III testing, Contra III trace logs and Super R-Type trace logs)
8081
* Jeffrey (Contra III testing)
81-
* kccheng (Contra III testing)
82+
* kccheng (Contra III and Super R-Type testing)
8283
* Rodzilla97 (Contra III bug report)
8384
* slidelljohn (Gradius III bug report and extra help)
8485
* Vitor Vilela (crazy author that did most of the patches)

Super-R-Type/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# SA-1 Root: Super R-Type
2+
Version 1.0, released 2020-12-31
3+
4+
Super R-Type is a classic shooter game made by Irem, being kind of a upgrade from R-Type II.
5+
6+
This SA-1 Root patch removes all slowdown present on the original game and drastically reduces the
7+
loading times.
8+
9+
Special thanks to Erivando_BR for sending me the SA-1 Collection trace log files of Super R-Type,
10+
which made this optimization patch possible to happen.
11+
12+
## How to Patch
13+
14+
Download the latest Super R-Type BPS patch file available on the
15+
[Releases](https://github.com/VitorVilela7/SA1-Root/releases) tab.
16+
17+
You can patch it using [beat](https://www.romhacking.net/utilities/893/)
18+
or [FLIPS](https://sneslab.net/tools/floating.zip), both common .bps patchers.
19+
20+
You can also patch the .asm files directly using
21+
[Asar](https://github.com/RPGHacker/asar).
22+
23+
For more information on how to apply ROM patches, see this SnesLab
24+
article: https://sneslab.net/wiki/How_to_apply_ROM_patches
25+
26+
It works only on the american version of Super R-Type. The japanese version is still being studied,
27+
and it will likely not work with this patch version.
28+
29+
Expected checksums:
30+
31+
### USA Version:
32+
#### Before patching:
33+
* CRC32: 8B22C830
34+
* SHA256: 05C7F6461209020785FBA33007E1830820AA44ADA4B1A6F991D936BF2335B15B
35+
36+
#### After patching
37+
* CRC32: AB3B7626
38+
* SHA256: 1D890871DE7F4FF2EA489F37F3379545BD5F88F97C5FA67CC4AD60C7BD67C703
39+
40+
## Compatibility
41+
42+
It works on both real hardware (sd2snes or SA-1 cart) and emulators (Snes9x and bsnes/higan/ares).
43+
44+
## Technical details
45+
46+
* Remapping mode: full
47+
* Remapping strategy: static
48+
* SA-1 usage: full with parallelism
49+
50+
This game relies on dynamic data pointers, but overall it does not use much of the Super Nintendo
51+
features. The game likes passing 16-bit pointers to RAM, using simple indirection to store into
52+
the registers, but overall the routines are somewhat organized, I didn't have to add dynamic
53+
remappers. The game only uses 32 KB of RAM ($7E:0000-$7E:7FFF), although it initializes 64 KB
54+
($7E:0000-$7E:FFFF). After some adjusts, it got it working with just 32 KB of BW-RAM.
55+
56+
Unlike earlier patches, SA-1 was used as the "master" processor, being responsible for running the
57+
whole game and only routines that really required the SNES CPU were executed on the other processor.
58+
All calls to the SNES CPU are asynchronous and parallel, meaning that the SA-1 requests the SNES CPU
59+
to process a specific routine and continues executing without waiting the SNES CPU to terminate its
60+
job. Some routines were adapted to not cause RAM collision during the parallel execution of the
61+
routines.
62+
63+
Because of the game characteristics, **32 kB (256 Kbit) of BW-RAM is required to the game run**
64+
correctly.
65+
66+
## RAM remap
67+
68+
* ``$0000-$1FFF`` -> ``$6000-$7FFF``
69+
* ``$7E:0000-$7E:7FFF`` -> ``$40:0000-$40:7FFF``
70+
71+
## Credits
72+
73+
Super R-Type - SA-1 Root wouldn't be that awesome without help from these people:
74+
75+
* Erivando_BR (trace logs)
76+
* kccheng (testing)
77+
* Vitor Vilela (patch author)
78+
* You (for using it :D)
79+
80+
## Contacting me
81+
82+
You can contact me though the following links:
83+
84+
* My Website: https://www.sneslab.net/
85+
* My Github profile: https://github.com/VitorVilela7
86+
* My Twitter profile: https://twitter.com/HackerVilela
87+
* My Patreon: https://www.patreon.com/vitorvilela
88+
* My personal blog: https://vilela.sneslab.net/
89+

Super-R-Type/asm/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Instructions
2+
============
3+
4+
Apply sa1.asm to the USA version of Super R-Type. Alternatively, use the do.sh script.
5+
6+
You can also patch the .asm files directly using [Asar](https://github.com/RPGHacker/asar).
7+

Super-R-Type/asm/databank.asm

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
macro remap_wram_base(addr, old, new, size)
2+
assert read1(<addr>+0) == $A9
3+
4+
if !strict == 1
5+
assert read<size>(<addr>+1) == <old>
6+
endif
7+
8+
org <addr>
9+
LDA<new>
10+
endmacro
11+
12+
macro remap_wram(addr)
13+
%remap_wram_base(<addr>, $7E, ".B #$40", 1)
14+
endmacro
15+
16+
macro remap_wram_local(addr)
17+
%remap_wram_base(<addr>, $00, ".B #$40", 1)
18+
endmacro
19+
20+
macro remap_wram_16(addr)
21+
%remap_wram_base(<addr>, $007E, ".W #$0040", 2)
22+
endmacro
23+
24+
; Bank 7E
25+
%remap_wram($008010)
26+
%remap_wram($0080A8)
27+
%remap_wram($008406)
28+
%remap_wram($008514)
29+
%remap_wram($00916F)
30+
%remap_wram($0091B6)
31+
%remap_wram($009206)
32+
%remap_wram($00982F)
33+
%remap_wram($009858)
34+
%remap_wram($009881)
35+
%remap_wram($0098A9)
36+
%remap_wram($0098FA)
37+
38+
; Indirect pointers building
39+
%remap_wram($00A1A6)
40+
%remap_wram_16($00A1CF)
41+
42+
; Indirect pointers that uses local RAM
43+
macro remap_indirect(orig, addr)
44+
assert read1(<addr>+0) == $A0
45+
46+
if !strict == 1
47+
assert read2(<addr>+1) == <orig>
48+
endif
49+
50+
org <addr>
51+
LDY.W #$6000|<orig>
52+
53+
endmacro
54+
55+
%remap_wram_local($008936)
56+
%remap_wram_local($0089AF)
57+
58+
;these below doesn't work because the game often uses the pointers with DB set to $7E,
59+
;I made TLR remap differently the indexes by consequence.
60+
;%remap_indirect($189A, $008933)
61+
;%remap_indirect($189A, $0089AC)
62+
;%remap_indirect($1892, $009651)
63+
;%remap_indirect($1832, $009647)
64+
;%remap_indirect($1862, $00964C)
65+
66+
; DMA parameters
67+
; Other DMA are either static, ROM-only or unused...
68+
%remap_wram($008329)
69+
%remap_wram($00834F)
70+
%remap_wram($00838C)
71+
%remap_wram_local($0083C2)
72+
73+
macro remap_mvn(b1, b2, addr)
74+
if !strict == 1
75+
assert read1(<addr>+0) == $54
76+
assert read1(<addr>+1) == <b1>
77+
assert read1(<addr>+2) == <b2>
78+
endif
79+
80+
!sb1 = <b1>
81+
!sb2 = <b2>
82+
83+
if !sb1&$FE == $7E
84+
!sb1 #= !sb1-$7E+$40
85+
endif
86+
87+
if !sb2&$FE == $7E
88+
!sb2 #= !sb2-$7E+$40
89+
endif
90+
91+
assert !sb1 == $40 || !sb1 == $41 || !sb2 == $40 || !sb2 == $41
92+
assert !sb1 != $7E && !sb2 != $7E && !sb1 != $7F && !sb2 != $7F
93+
94+
org <addr>
95+
MVN !sb1, !sb2
96+
endmacro
97+
98+
%remap_mvn($7E, $7E, $008720)
99+
%remap_mvn($7E, $7E, $008744)
100+
%remap_mvn($7E, $05, $009B81)
101+
%remap_mvn($7E, $05, $009BA4)
102+
%remap_mvn($7E, $05, $009BB6)
103+
%remap_mvn($7E, $05, $00A183)
104+
105+
macro remap_indirect_jump(dest, addr)
106+
assert read1(<addr>+0) == $DC
107+
108+
if !strict == 1
109+
assert read2(<addr>+1) == <dest>
110+
endif
111+
112+
!res #= <dest>|$6000
113+
114+
assert !res >= $6000 && !res <= $7FFF
115+
116+
org <addr>
117+
JMP.W [!res]
118+
endmacro
119+
120+
%remap_indirect_jump($0010, $008253)
121+
%remap_indirect_jump($1801, $0084D4)
122+
%remap_indirect_jump($1801, $00872D)
123+
%remap_indirect_jump($00F5, $008758)
124+
%remap_indirect_jump($00F5, $008791)
125+
%remap_indirect_jump($00F5, $0087D7)
126+
%remap_indirect_jump($00F5, $00881A)
127+
128+
; Format: <address to store>, <value to store>
129+
; Remap the WRAM specific to BWRAM.
130+
131+
; It's worth commenting that the address is incremented by 5,
132+
; while the code only read the first four values. It's suggestive
133+
; that the table was supposed to be incremented by 4.
134+
135+
; It's very likely a bug, but we have to remain the original behavior
136+
org $0480BC
137+
db $02,$21,$00,$00,$07
138+
db $42,$60,$00,$09,$42
139+
db $00,$00,$16,$21,$00
140+
db $00,$00,$00
141+
142+

Super-R-Type/asm/do.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rm srtype.sfc; cp srtype_base.sfc srtype.sfc && asar -Dstrict=1 sa1.asm srtype.sfc

0 commit comments

Comments
 (0)