This page documents information about . Many of the tricks demonstrated here are near impossible in real time and documented for the purposes of creating Tool-assisted Speedruns.

First of all, C002AB is multiplication routine. It takes m23*m24 and stores it in m26-27 (2 bytes). C002E2 is the division routine.

Here's how the RNG works:

The RNG is stored in 7E0038-7E003B.

The RNG is modified by functions like these (not exhaustive):

Address C00342
STA $23
REP #$20
LDA $3A
EOR #$8020
STA $3A
LDA $38
ASL A
ASL A
CLC
ADC $38
ADC $3A
STA $38
SEP #$20
XBA
STA $24
JSR $02AB [multiplication]
LDA $27
RTS

Translation:
(16 bits)
m23:=A AND 0xFF
m3A:=m3A XOR 0x8020
A:=4*m38 AND 0xFFFF
A:=A+m38
if A>0xFFFF then C:=1 else C:=0
m38:=(A+m3A+C) AND 0xFFFF
m24:=m38 >> 8
m26:=m23*m24
return (m26 >> 8) [A]

The function calculates a random number between 0 and (A AND 0xFF)-1. We'll call this function rand(X), for a random number between 0 and X-1.

All jumps to this routine use "JSR $0342"

Address C02A89
LDA #$FA
JSR $0342 [rand]
CMP #$96
BCS $18 [3]
CMP #$8E
BCC $02 [1]
BRA $08 [2]
[1]
CMP #$32
BCS $0E [3]
CMP #$2A
BCC $0A [3]
[2]
LDA #$01
STA $07F9
LDA #$06
STA $07EA
[3]
RTS

Translation:
A:=rand(250)
if 142<=A<150 or 42<=A<50 then [encounter]

This determines encounters.

Address C086DC
LDA $07F9
CMP #$02
BEQ $12 [1]
LDA #$C8
JSR $0342 [rand]
LDX #$0002
CMP #$BE
BCS $06
DEX
CMP #$AA
BCS $01
DEX
[1]
TXA
STA $159A
BEQ $0D
RTS

Translation:
if m7F9==2 [boss battle] then Type:=0 exit
A:=rand(200)
if 190<=A<200 then Type:=2 exit
if 170<=A<190 then Type:=1 exit
Type:=0

Type 0: no pre-empt
Type 1: ally pre-empt
Type 2: enemy pre-empt

The function determines whether or not a pre-empt occurs. If an ally pre-empt occurs, all allies get a free round to attack first. If an enemy pre-empt occurs, all enemies get a free round to attack first. Boss battles cannot have pre-empts.

Address C08B9D
LDA $12,x
AND #$00FF
PHA
LDX $15A1
LDA $12,x
AND #$00FF
ADC #$0028
SEC
SBC $01,s [push value]
BCS $03 [1]
LDA #$0000
[1]
STA $2C
PLA
SEP #$20
LDA #$05
STA $30
JSR $02E2 [division m32:=int(m2C/m30)]
INC $32
INC $32
LDA $32
JSR $0342
DEC $32
CMP $32
BCC $09 [2]
LDX $15B0
LDA $35,x
ORA #$10
STA $35,x
[2]
RTS

Translation:

A:=DefAgl AND 0xFF
S:=A
A:=AtkAgl AND 0xFF
A:=A+40
A:=A-S
if A<0 then A:=0
m2C:=A
m30:=5
m32:=int(m2C/m30)+2
A:=rand(m32)
if A==m32-1 then [attack miss] else [attack hit]

Address C00363
STY $2A
REP #$20
LDA $38
ASL A
ASL A
CLC
ADC $38
ADC $3A
STA $38
STA $24
SEP #$20
JSR $025F [multiplication]
LDY $28
RTS

Y:=m2A AND 0xFFFF
A:=4*m38 AND 0xFFFF
A:=A+m38
if A>0xFFFF then C:=1 else C:=0
m38:=(A+m3A+C) AND 0xFFFF
m24:=m38
return m24*Y >> 16 [Y]

This is another rng-modifying function. The only difference between this function and rand(X) is that address m3A does not XOR by 0x8020, and that the multiplication uses 16-bits of RNG, rather than 8-bit.
Call this function rand2(Y)

Address C08BDB
REP #$20
STZ $0554
LDA $054E [atk]
SEC
SBC $0550 [def]
BCS $06 [1]
LDY #$0001
JMP $8C1F [4]
[1]
STA $2A
SEP #$20
LDA #$0A
STA $24
LDA $15AB
BIT #$80
BNE $02 [2]
LSR $24
[2]
JSR $0288 [multiplication m26:=m2A(16bit)*m24]
LDA #$00
XBA
LDA $24
TAY
LDX $26
STX $0554
BEQ $0B [3]
STX $2C
LDA #$0A
STA $30
JSR $02E2 [division m32:=int(m2C/m30)]
LDY $32
[3]
JSR $0363 [rand2]
INY
[4]
LDX $15B0
REP #$21
TYA
ADC $0554
STA $0554
CMP #$270F
BCC $03 [5]
LDA #$270F
[5]
STA $0554
SEP #$20
RTS

Translation:
m554:=0
A:=m54E [atk]
A:=A-m550 [def]
if A<0 then Damage:=1 exit
m2A:=A
if [enemy attack] then m24:=5 else m24:=10
m26:=m24*m2A
if m26==0 then Damage:=rand2(m24)+1 exit
m554:=m26
m2C:=m26
m30:=10
Y:=int(m2C/m30)
m554:=m554+rand2(Y)+1
if m554>9999 then m554:=9999
Damage:=m554

This routine calculates the initial damage. This is the final damage if it is magic/item attack. If it is physical attack, there may be critical hit applied later.

This routine only executes if the attack does not miss.

Address C0964C
LDX $15A1
LDA $13,X
JSR $97D1 [?]
REP #$20
AND #$00FF
PHA
LDA $0546
AND #$00FF
CLC
ADC $01,S [push value]
STA $054E
LSR A
CLC
ADC $054E
STA $054E
PLA
SEP #$20
RTS

Translation:

S:=Wisdom [cannot exceed 255]
A:=m546 [basepower of spell/item] [cannot exceed 255]
A:=A+S
A:=A+int(A/2)
AtkValue:=A

This routine calculates the attack value of a spell/item.

Address C08A69
LDA #$1E
STA $02
LDA $159E [?]
BIT #$80
BEQ $02 [1]
ASL $02
[1]
LDX $15A1
LDA $3C,X
LSR A
BCC $02 [2]
LSR $02
[2]
LDA $02
JSR $0342 [RAND]
LSR $02
CMP $02
BNE $1C [4]
REP #$20
LDA $0554 [DMG]
ASL A
ADC $0554 [DMG]
CMP #$270F
BCC $03 [3]
LDA #$270F
[3]
STA $0554
SEP #$20
LDA #$00
JSR $AAD2 [GREATEST ATTACK?]
RTS
[4]
LDA #$14
STA $02
LDA $159E
BIT #$80
BEQ $02[5]
ASL $02
[5]
LDX $15A1
LDA $3C,X
LSR A
LSR A
BCC $02[6]
LSR $02
[6]
LDA $02
JSR $0342 [RAND]
LSR $02
CMP $02
BNE $18 [8]
REP #$20
LDA $0054 [DMG]
ASL A
CMP #$270F
BCC $03 [7]
LDA #$270F
[7]
STA $0554
SEP #$20
LDA #$01
JSR $AAD2 [CRUSHING ATTACK?]
[8]
RTS

Translation:

m2:=30
if [unknown thing] then m2:=2*m2
if [modifier] then m2:=int(m2/2)
A:=rand(m2)
if A==int(m2/2) then m554:=max(3*m554,9999) exit [greatest attack]
m2:=20
if [unknown thing] then m2:=2*m2
if [modifier2] then m2:=int(m2/2)
A:=rand(m2)
if A==int(m2/2) then m554:=max(2*m554,9999) exit [crushing attack]

This routine first determines whether an attack is a GREATEST ATTACK (1/30 probability). If it is, damage is multiplied by 3, max damage 9999. If an attack is not a GREATEST ATTACK, the routine determines whether an attack is a CRUSHING ATTACK (1/20 probability). If so, damage is multiplied by 2.

This routine only executes if the attack does not miss. The CRUSHING ATTACK part only executes if the attack is not a GREATEST ATTACK.

- GameResources - we have resource pages for other games too!
- Common Tricks - tricks common to many games
- Boss Fighting Guide - tricks specific to boss fights

GameResources/SNES/MagicKnightRayearth/RNG last edited by adelikat on 6/9/2019 7:37 PM

Page History Latest diff List referrers View Source