CopyDEtoHL_32bit: ; s03_A084 ; Copies value pointed to by de to hl ld a, [de] ld [hl+], a inc de ld a, [de] ld [hl+], a inc de ld a, [de] ld [hl+], a inc de ld a, [de] ld [hl+], a ret AddDEToHL_32bit: ; s03_A090 ; Adds value pointed to by de to value pointed to by hl ld a, [de] add [hl] ld [hl+], a inc de ld a, [de] adc [hl] ld [hl+], a inc de ld a, [de] adc [hl] ld [hl+], a inc de ld a, [de] adc [hl] ld [hl], a ret s03_A0A0: dl $FFFFFFFF DecHL_32bit: ; s03_A0A4 ; Decrements 32-bit value at hl, checks if result is 0 push hl ld de, s03_A0A0 call AddDEToHL_32bit pop hl ; Checks 4-byte value at hl is 0 ld a, [hl+] and a ret nz ld a, [hl+] and a ret nz ld a, [hl+] and a ret nz ld a, [hl+] and a ret Multiplier: ds 4 ; s03_A0B8 CalcResult: ds 4 ; s03_A0BC Clean32bit: dl $00000000 ; s03_A0C0 MulDEToHL_32bit: ; s03_A0C4 ; Multiplies value at de with value at hl, stores in hl push hl ; Copy DE to the Multiplier push hl push de ld hl, Multiplier call CopyDEtoHL_32bit pop de pop hl ; Clear the result value push hl ld hl, CalcResult ld de, Clean32bit call CopyDEtoHL_32bit pop de ; Add HL (now DE) Multiplier times to CalcResult .loop push de ld hl, CalcResult call AddDEToHL_32bit pop de push de ld hl, Multiplier call DecHL_32bit pop de jr nz, .loop ; Copy the result back to HL pop hl ld de, CalcResult jp CopyDEtoHL_32bit s03_A0F3: ds 4 ; Initial value: $5D0B1C11 s03_A0F7: dl $35E79125 s03_A0FB: dl $56596b10 s03_A0FF: ds 4 ; Initial value: $7FFFFB0A s03_A103: dl $1b080733 s03_A107: ds 4 ; Initialized with A103 s03_A10B: dw s03_A10D: db s03_A10E: db s03_A10F: ; (u16)s03_A10B = ((u16)s03_A10B / 2) * s03_A10D + s03_A10E ld hl, s03_A10B ld a, [hl+] ld h, [hl] ld l, a and a srl h rr l ld d, h ld e, l ld hl, 0 ld a, [s03_A10D] ld c, a and a jr z, .end .loop add hl, de dec c jr nz, .loop .end ld a, [s03_A10E] ld c, a ld b, 0 add hl, bc ld a, h ld [s03_A10B + 1], a ld a, l ld [s03_A10B], a ret s03_A13A: ; Main decryption routine .outer_loop ld hl, s03_A107 ld de, s03_A103 call CopyDEtoHL_32bit ; Initialize values ld hl, s03_A0F3 + 1 ld de, s03_A10B ld a, [hl+] ld [de], a inc de ; s03_A10B + 1 xor a ld [de], a inc de ; s03_A10D ld a, [hl+] ld [de], a inc de ; s03_A10E ld a, [hl] ld [de], a ld hl, Buffer ld bc, 0 ; Problem with this routine: Writing to SRAM!!! ; This means that whatever is in hl's buffer is useless on next bootup, so we ; need to make sure to start from a clean save file. .loop ; s03_A15A push hl push bc call s03_A10F ; (u16)s03_A10B = ((u16)s03_A10B / 2) * s03_A10D + s03_A10E pop bc pop hl ; Exor the buffer xor [hl] ld [hl+], a ; Reset HL to Buffer every $200 bytes inc bc ld a, b cp $2 jr nz, .s03_A16F ld bc, 0 ld hl, Buffer .s03_A16F push hl ld hl, s03_A107 call DecHL_32bit pop hl jr nz, .loop ld hl, s03_A0F3 ld de, s03_A0F7 call MulDEToHL_32bit ld hl, s03_A0F3 ld de, s03_A0FB call AddDEToHL_32bit ld hl, s03_A0FF call DecHL_32bit jr nz, .outer_loop ret Buffer: ds $200 ; s03_A567