# View Page Source

Revision (current)
Last Updated by adelikat on 6/9/2019 7:37 PM

```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):

STA \$23
REP #\$20
LDA \$3A
EOR #\$8020
STA \$3A
LDA \$38
ASL A
ASL A
CLC
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"

!!Encounters

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

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

This determines encounters.

!!Pre-emptive attack on encounter

LDA \$07F9
CMP #\$02
BEQ \$12 []
LDA #\$C8
JSR \$0342 [[rand]]
LDX #\$0002
CMP #\$BE
BCS \$06
DEX
CMP #\$AA
BCS \$01
DEX
[]
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.

!!Accuracy of physical attacks

LDA \$12,x
AND #\$00FF
PHA
LDX \$15A1
LDA \$12,x
AND #\$00FF
SEC
SBC \$01,s [[push value]]
BCS \$03 []
LDA #\$0000
[]
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 []
LDX \$15B0
LDA \$35,x
ORA #\$10
STA \$35,x
[]
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]]

!!Another RNG-related routine

STY \$2A
REP #\$20
LDA \$38
ASL A
ASL A
CLC
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)

!!Initial damage routine

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

!!Magic damage (attack value)

LDX \$15A1
LDA \$13,X
JSR \$97D1 [[?]]
REP #\$20
AND #\$00FF
PHA
LDA \$0546
AND #\$00FF
CLC
STA \$054E
LSR A
CLC
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.

!! Critical hit

LDA #\$1E
STA \$02
LDA \$159E [[?]]
BIT #\$80
BEQ \$02 []
ASL \$02
[]
LDX \$15A1
LDA \$3C,X
LSR A
BCC \$02 []
LSR \$02
[]
LDA \$02
JSR \$0342 [[RAND]]
LSR \$02
CMP \$02
BNE \$1C []
REP #\$20
LDA \$0554 [[DMG]]
ASL A
CMP #\$270F
BCC \$03 []
LDA #\$270F
[]
STA \$0554
SEP #\$20
LDA #\$00
RTS
[]
LDA #\$14
STA \$02
LDA \$159E
BIT #\$80
BEQ \$02[]
ASL \$02
[]
LDX \$15A1
LDA \$3C,X
LSR A
LSR A
BCC \$02[]
LSR \$02
[]
LDA \$02
JSR \$0342 [[RAND]]
LSR \$02
CMP \$02
BNE \$18 []
REP #\$20
LDA \$0054 [[DMG]]
ASL A
CMP #\$270F
BCC \$03 []
LDA #\$270F
[]
STA \$0554
SEP #\$20
LDA #\$01
[]
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.```