Romhacking.net
Romhacking => Programming => Topic started by: Sarah Shinespark on October 21, 2020, 09:05:24 am
-
I see this code all the time at the start of text display code in Arcana. This is more me being exasperated at it than asking help, but can anyone make sense of all this multiplication and addition? Does 4216 affect the stack or something? Code before this is the main event handler so it wouldn't have pushed something recently.
$87/9797 22 39 8A 80 JSL $808A39[$80:8A39] A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A39 20 3D 8A JSR $8A3D [$80:8A3D] A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A3D DA PHX A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A3E 48 PHA A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A3F DA PHX A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A40 64 02 STZ $02 [$00:1E02] A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A42 E2 10 SEP #$10 A:0000 X:0008 Y:9540 P:envmxdIzC
$80/8A44 AA TAX A:0000 X:0008 Y:0040 P:envmXdIzC
$80/8A45 8E 02 42 STX $4202 [$80:4202] A:0000 X:0000 Y:0040 P:envmXdIZC
$80/8A48 FA PLX A:0000 X:0000 Y:0040 P:envmXdIZC
$80/8A49 8E 03 42 STX $4203 [$80:4203] A:0000 X:0008 Y:0040 P:envmXdIzC
$80/8A4C EA NOP A:0000 X:0008 Y:0040 P:envmXdIzC
$80/8A4D EA NOP A:0000 X:0008 Y:0040 P:envmXdIzC
$80/8A4E AF 16 42 80 LDA $804216[$80:4216] A:0000 X:0008 Y:0040 P:envmXdIzC
$80/8A52 85 00 STA $00 [$00:1E00] A:0000 X:0008 Y:0040 P:envmXdIZC
$80/8A54 FA PLX A:0000 X:0008 Y:0040 P:envmXdIZC
$80/8A55 8E 03 42 STX $4203 [$80:4203] A:0000 X:0000 Y:0040 P:envmXdIZC
$80/8A58 A5 01 LDA $01 [$00:1E01] A:0000 X:0000 Y:0040 P:envmXdIZC
$80/8A5A 18 CLC A:0000 X:0000 Y:0040 P:envmXdIZC
$80/8A5B 6D 16 42 ADC $4216 [$80:4216] A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A5E FA PLX A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A5F FA PLX A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A60 8E 02 42 STX $4202 [$80:4202] A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A63 FA PLX A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A64 8E 03 42 STX $4203 [$80:4203] A:0000 X:0008 Y:0040 P:envmXdIzc
$80/8A67 EA NOP A:0000 X:0008 Y:0040 P:envmXdIzc
$80/8A68 EA NOP A:0000 X:0008 Y:0040 P:envmXdIzc
$80/8A69 6F 16 42 80 ADC $804216[$80:4216] A:0000 X:0008 Y:0040 P:envmXdIzc
$80/8A6D 85 01 STA $01 [$00:1E01] A:0000 X:0008 Y:0040 P:envmXdIZc
$80/8A6F 90 04 BCC $04 [$8A75] A:0000 X:0008 Y:0040 P:envmXdIZc
$80/8A75 FA PLX A:0000 X:0008 Y:0040 P:envmXdIZc
$80/8A76 8E 03 42 STX $4203 [$80:4203] A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A79 A5 02 LDA $02 [$00:1E02] A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A7B 18 CLC A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A7C 6D 16 42 ADC $4216 [$80:4216] A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A7F 85 02 STA $02 [$00:1E02] A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A81 C2 10 REP #$10 A:0000 X:0000 Y:0040 P:envmXdIZc
$80/8A83 60 RTS A:0000 X:0000 Y:0040 P:envmxdIZc
$80/8A3C 6B RTL A:0000 X:0000 Y:0040 P:envmxdIZc
-
https://en.wikibooks.org/wiki/Super_NES_Programming/SNES_Hardware_Registers
-
I already know putting two values in 4202 and 4203 will produce the product in 4216, it's all the PHX that are confusing me.
-
This code just stores 2 copies of X in the stack, no big deal.
What's confusing is that it pushes 3 bytes at the beginning, but pulls 6 bytes during execution. These 3 additional pulls must be pulling bytes of the return address. Is that what you were asking?
Can your logger log stack pointer as well? That should make things clear.
-
I was confused by that part (the differing number of pushes and pulls) too when I read the log, but given the SEP #10, it should have gone from a 16-bit X register to an 8-bit register before it starts pulling from the stack, if I'm reading the processor flag documentation correctly. Both X and A were 16-bit, so 6 bytes were pushed then.
-
Here's without Squelch:
$87/9797 22 39 8A 80 JSL $808A39[$80:8A39] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FF3 P:envmxdIzC HC:0216 VC:249 FC:13 I:00
$80/8A39 20 3D 8A JSR $8A3D [$80:8A3D] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FF0 P:envmxdIzC HC:0270 VC:249 FC:13 I:00
$80/8A3D DA PHX A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FEE P:envmxdIzC HC:0316 VC:249 FC:13 I:00
$80/8A3E 48 PHA A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FEC P:envmxdIzC HC:0350 VC:249 FC:13 I:00
$80/8A3F DA PHX A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FEA P:envmxdIzC HC:0384 VC:249 FC:13 I:00
$80/8A40 64 02 STZ $02 [$00:1E02] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE8 P:envmxdIzC HC:0418 VC:249 FC:13 I:00
$80/8A42 E2 10 SEP #$10 A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE8 P:envmxdIzC HC:0452 VC:249 FC:13 I:00
$80/8A44 AA TAX A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE8 P:envmXdIzC HC:0476 VC:249 FC:13 I:00
$80/8A45 8E 02 42 STX $4202 [$80:4202] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FE8 P:envmXdIZC HC:0494 VC:249 FC:13 I:00
$80/8A48 FA PLX A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FE8 P:envmXdIZC HC:0524 VC:249 FC:13 I:00
$80/8A49 8E 03 42 STX $4203 [$80:4203] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE9 P:envmXdIzC HC:0596 VC:249 FC:13 I:00
$80/8A4C EA NOP A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE9 P:envmXdIzC HC:0626 VC:249 FC:13 I:00
$80/8A4D EA NOP A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE9 P:envmXdIzC HC:0644 VC:249 FC:13 I:00
$80/8A4E AF 16 42 80 LDA $804216[$80:4216] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE9 P:envmXdIzC HC:0662 VC:249 FC:13 I:00
$80/8A52 85 00 STA $00 [$00:1E00] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE9 P:envmXdIZC HC:0704 VC:249 FC:13 I:00
$80/8A54 FA PLX A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FE9 P:envmXdIZC HC:0738 VC:249 FC:13 I:00
$80/8A55 8E 03 42 STX $4203 [$80:4203] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEA P:envmXdIZC HC:0770 VC:249 FC:13 I:00
$80/8A58 A5 01 LDA $01 [$00:1E01] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEA P:envmXdIZC HC:0800 VC:249 FC:13 I:00
$80/8A5A 18 CLC A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEA P:envmXdIZC HC:0834 VC:249 FC:13 I:00
$80/8A5B 6D 16 42 ADC $4216 [$80:4216] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEA P:envmXdIZc HC:0852 VC:249 FC:13 I:00
$80/8A5E FA PLX A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEA P:envmXdIZc HC:0888 VC:249 FC:13 I:00
$80/8A5F FA PLX A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEB P:envmXdIZc HC:0920 VC:249 FC:13 I:00
$80/8A60 8E 02 42 STX $4202 [$80:4202] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEC P:envmXdIZc HC:0952 VC:249 FC:13 I:00
$80/8A63 FA PLX A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEC P:envmXdIZc HC:0982 VC:249 FC:13 I:00
$80/8A64 8E 03 42 STX $4203 [$80:4203] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIzc HC:1014 VC:249 FC:13 I:00
$80/8A67 EA NOP A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIzc HC:1044 VC:249 FC:13 I:00
$80/8A68 EA NOP A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIzc HC:1062 VC:249 FC:13 I:00
$80/8A69 6F 16 42 80 ADC $804216[$80:4216] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIzc HC:1080 VC:249 FC:13 I:00
$80/8A6D 85 01 STA $01 [$00:1E01] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIZc HC:1122 VC:249 FC:13 I:00
$80/8A6F 90 04 BCC $04 [$8A75] A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIZc HC:1156 VC:249 FC:13 I:00
$80/8A75 FA PLX A:0000 X:0008 Y:0002 D:1E00 DB:80 S:1FED P:envmXdIZc HC:1180 VC:249 FC:13 I:00
$80/8A76 8E 03 42 STX $4203 [$80:4203] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmXdIZc HC:1212 VC:249 FC:13 I:00
$80/8A79 A5 02 LDA $02 [$00:1E02] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmXdIZc HC:1242 VC:249 FC:13 I:00
$80/8A7B 18 CLC A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmXdIZc HC:1276 VC:249 FC:13 I:00
$80/8A7C 6D 16 42 ADC $4216 [$80:4216] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmXdIZc HC:1294 VC:249 FC:13 I:00
$80/8A7F 85 02 STA $02 [$00:1E02] A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmXdIZc HC:1330 VC:249 FC:13 I:00
$80/8A81 C2 10 REP #$10 A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmXdIZc HC:1364 VC:249 FC:13 I:00
$80/8A83 60 RTS A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FEE P:envmxdIZc HC:0024 VC:250 FC:13 I:00
$80/8A3C 6B RTL A:0000 X:0000 Y:0002 D:1E00 DB:80 S:1FF0 P:envmxdIZc HC:0070 VC:250 FC:13 I:00
-
If I've done my math correctly, this routine is multiplying the 16-bit A and X inputs, and storing the 32-bit result at $1e00.
-
All that for 0 x 8?? What a waste of time...
-
I cant understand what is the difference between coding and programming? I found only this review https://differencebtwn.com/difference-between-coding-and-programming
-
They're basically the same thing with different connotations. Coding is writing code. Programming is... writing programs.
October 22, 2020, 04:01:23 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
If I've done my math correctly, this routine is multiplying the 16-bit A and X inputs, and storing the 32-bit result at $1e00.
Thanks again btw, knowing that helped out a LOT. What I thought was unrelated code after the end of interesting code, was just calculating the offset of the text to read next.
Also turns out all the text in the status screen is hard-coded addresses in a long list rather than referencing the text tables with a pointer table. What a waste of space...
-
I already know putting two values in 4202 and 4203 will produce the product in 4216, it's all the PHX that are confusing me.
I would say it's simply a delay because the real CPU needs some time to calculate the result (looks to be about 8 cycles, from code I've seen in other games), but it's doing that BEFORE writing the values.
The ACTUAL needed delay, I'm not sure if it is known.
I do know early in emulation days, it doesn't seem like it was known, since it wasn't mentioned. So that's one source of ROM hacks possibly being incompatible with real hardware, but even then I don't think it was until the late 2000s that byuu tried to figure it out and wrote probably one of the first emulators to support that limitation (certainly earlier SNES9x and ZSNES would not emulate the necessary delay for properly-calculated results allow $4216 to give the correct result instantly).
-
The ACTUAL needed delay, I'm not sure if it is known.
1 CPU cycle per significant bit (https://github.com/higan-emu/higan/blob/64ca3a173f85b8403136755325938921df25f332/higan/sfc/cpu/timing.cpp#L79) of the $4202 input, totaling 8 to use the entire input. The delay in the posted code cleverly uses two NOPs (4 cycles) followed by LDA $804216, the latter being 4 bytes long and therefore costing 4 cycles to read before it can be executed.