fxdoc/asm/fx@3.10-GetKeyWait_Dispatch...

269 lines
9.4 KiB
Plaintext

This "Dispatcher" function is at the center of a weird scheme involving jump
buffers inside GetKeyWait.
The GetKeyWait function (conditionally) starts by a call to setjmp()
immediately followed by a call to this dispatcher, passing along the return
value of the long jump, which has 12 values, as we'll see shortly.
There are two jump buffers in GetKeyWait, and which one is used depends on a
RAM global that changes value several times along the execution. Hence, the
*state* of this scheme consists of:
-> Which buffer is currently selected;
-> The return value of the long jump.
I believe that the scheme is best viewed as a finite state machine, where each
state change triggers a return to the start of GetKeyWait().
This Dispatcher function implements some of the logic of that state machine.
It starts with a jump-table-based switch which executes code depending on the
return value of the long jump. The executed code does things like:
* Change the currently-selected buffer and return, letting GetKeyWait execute
* Change the currently-seletced buffer and long jump back, changing the long
jump return code and forcing an immediate return to the dispatcher
* Read and write the state of the SHIFT and ALHA modifiers (even though that is
normally handled by GetKey()?)
* Invoke *ENOURMOUS* functions that draw to screen, manipulate the MCS, clear
VRAM, change the Setup parameters, change the on-screen Cursor, print error
messages, remap F-key codes, ... (basically everything).
My best intuition so far is that the two jump buffers are for the add-in and
the main menu, although I'm not sure why there's a need to save state like
this. I have no intuition yet about the meaning of the 12 states. Though I do
suspect that the enormous functions I found are related to starting new
applications, mainly because of %46d which clears the last three eights of the
RAM, and %846 which clears 1024 bytes of probably-VRAM. Both are called from
<80089c12> which is called from <8008a42e> which is called from state #2 (and
does a hell of a lot of MCS-related calls inside its subroutine <80081cea>).
<80089d8a GetKeyWait_Dispatcher>
r4: ??? (return value of setjmp/longmp when called from GetKeyWait_Main)
appears to be some sort of state (one exists per jump buffer)
# If r4>11, give up and return r4 itself.
80089d8a: 4f22 sts.l pr, @-r15
80089d8c: 7ffc add #-4, r15
80089d8e: e60b mov #11, r6
80089d90: 2f42 mov.l r4, @r15
80089d92: 3466 cmp/hi r6, r4
80089d94: 8f02 bf.s <80089d9c>
80089d96: 6243 mov r4, r2
80089d98: a08a bra <80089eb0>
80089d9a: 0009 nop
# Otherwise, jump to 88089da6 + offset_table[r0] (table below)
80089d9c: 4200 shll r2
80089d9e: c71c mova.l <80089e10>, r0
80089da0: 002d mov.w @(r0,r2), r0
80089da2: 0023 braf r0
80089da4: 0009 nop
... (data)
# Offset table
80089e10: 010a 010a 0082 008a 0092 0104 00ae 0104 00bc 00d0 00e6 00fc
# State #2:
# -> Call <8008a42e>()
80089e28: b301 bsr <8008a42e>
80089e2a: 0009 nop
80089e2c: a040 bra <80089eb0>
80089e2e: 0009 nop
# State #3:
# -> Call <8008a4ca>()
80089e30: b34b bsr <8008a4ca>
80089e32: 0009 nop
80089e34: a03c bra <80089eb0>
80089e36: 0009 nop
# State #4:
# -> Call <8008a98a>()
# -> Call <8008a8bc>()
# -> Copy 0x8801b6ce to 0x8801b6cd (possibly stopping this long jump frenzy)
# -> Move to state #5 of setjmp_buffers[1] by performing a long jump
80089e38: b5a7 bsr <8008a98a>
80089e3a: 0009 nop
80089e3c: b53e bsr <8008a8bc>
80089e3e: 0009 nop
80089e40: d282 mov.l 0x8801b6ce, r2
80089e42: e505 mov #5, r5
80089e44: d682 mov.l 0x8801b6cd, r6
80089e46: d783 mov.l %ac9 longjmp, r7
80089e48: d483 mov.l 0x8801b67c, r4
80089e4a: 6120 mov.b @r2, r1
80089e4c: 470b jsr @r7
80089e4e: 2610 mov.b r1, @r6
80089e50: a02e bra <80089eb0>
80089e52: 0009 nop
# State #6:
# -> Set setjmp_buffer_index = 0
# -> Call <8008c5b0>()
80089e54: d681 mov.l 0x8801b6cc, r6
80089e56: e200 mov #0, r2
80089e58: d381 mov.l 0x8008c5b0, r3
80089e5a: 430b jsr @r3
80089e5c: 2620 mov.b r2, @r6
80089e5e: a027 bra <80089eb0>
80089e60: 0009 nop
# State #8:
# -> Set setjmp_buffer_index = 0
# -> Call <8008ac62>()
# -> Go to state #9 of setjmp_buffers[1]
80089e62: d67e mov.l 0x8801b6cc, r6
80089e64: e400 mov #0, r4
80089e66: b6fc bsr <8008ac62>
80089e68: 2640 mov.b r4, @r6
80089e6a: d77a mov.l %ac9 longjmp, r7
80089e6c: d47a mov.l 0x8801b67c, r4
80089e6e: 470b jsr @r7
80089e70: e509 mov #9, r5
80089e72: a01d bra <80089eb0>
80089e74: 0009 nop
# State #9:
# -> If SHIFT is pressed but not ALPHA: PutKey(0x7536 == KEY_CTRL_SHIFT, 0)
# -> Set setjmp_buffer_index = 1
# Note that 0x910 injects codes into a GetKey()-only buffer and notifies
# GetKeyWait() by adding special matrix code values to its buffer. This
# injected SHIFT key will only be seen by GetKey() (which is the one to handle
# the SHIFT/ALPHA feature anyway).
80089e76: d27b mov.l %91b GetShiftAlphaState, r2
80089e78: 420b jsr @r2
80089e7a: 0009 nop
80089e7c: 8801 cmp/eq #1, r0
80089e7e: 8b14 bf <80089eaa>
80089e80: d279 mov.l %910 PutKey, r2
80089e82: 949c mov.w 0x00007536, r4
80089e84: 420b jsr @r2
80089e86: e500 mov #0, r5
80089e88: a00f bra <80089eaa>
80089e8a: 0009 nop
# State #10:
# -> Set setjmp_buffer_index = 1
# -> Call <8008b4e2>()
# -> Go to state #11 of setjmp_buffers[0] (which just resets the index to 0)
80089e8c: d673 mov.l 0x8801b6cc, r6
80089e8e: e101 mov #1, r1
80089e90: d376 mov.l 0x8008b4e2, r3
80089e92: 430b jsr @r3
80089e94: 2610 mov.b r1, @r6
80089e96: d76f mov.l %ac9 longjmp, r7
80089e98: d475 mov.l 0x8801b62c, r4
80089e9a: 470b jsr @r7
80089e9c: e50b mov #11, r5
80089e9e: a007 bra <80089eb0>
80089ea0: 0009 nop
# State #11:
# -> Set setjmp_buffer_index = 0
80089ea2: d66e mov.l 0x8801b6cc, r6
80089ea4: e200 mov #0, r2
80089ea6: a003 bra <80089eb0>
80089ea8: 2620 mov.b r2, @r6
# States #5 and #7
# -> Set setjmp_buffer_index = 1
80089eaa: d66c mov.l 0x8801b6cc, r6
80089eac: e201 mov #1, r2
80089eae: 2620 mov.b r2, @r6
# States #0 and #1, and end of function (normal return)
80089eb0: 60f2 mov.l @r15, r0
80089eb2: 7f04 add #4, r15
80089eb4: 4f26 lds.l @r15+, pr
80089eb6: 000b rts
80089eb8: 0009 nop
---
<8008a42e>
Stack> pr (x:u32) (1024 bytes)
# Set setjmp_buffer_index = 0
# Call <8008a44c>(0x8024cfb4, 85, *r4)
8008a42e: 4f22 sts.l pr, @-r15
8008a430: 7ffc add #-4, r15
8008a432: d76c mov.l 0x8801b6cc, r7
8008a434: e504 mov #4, r5
8008a436: d46d mov.l 0x8024cfb4, r4
8008a438: 62f3 mov r15, r2
8008a43a: 4518 shll8 r5
8008a43c: e100 mov #0, r1
8008a43e: 3258 sub r5, r2
8008a440: e555 mov #85, r5
8008a442: 2710 mov.b r1, @r7
8008a444: a002 bra <8008a44c>
8008a446: 6642 mov.l @r4, r6
8008a448: 2250 mov.b r5, @r2
8008a44a: 72ff add #-1, r2
8008a44c: 3626 cmp/hi r2, r6
8008a44e: 8bfb bf <8008a448>
8008a450: bbdf bsr <80089c12>
8008a452: 0009 nop
8008a454: d566 mov.l 0x8801b6d6, r5
8008a456: d167 mov.l 0x8801b6d2, r1
8008a458: 6251 mov.w @r5, r2
8008a45a: 8551 mov.w @(2,r5), r0
8008a45c: 8111 mov.w r0, @(2,r1)
8008a45e: 6603 mov r0, r6
8008a460: 6023 mov r2, r0
8008a462: 8802 cmp/eq #2, r0
8008a464: 8f18 bf.s <8008a498>
8008a466: 2121 mov.w r2, @r1
8008a468: d463 mov.l 0x8801b6d0, r4
8008a46a: e201 mov #1, r2
8008a46c: d363 mov.l 0x8008c1ea, r3
8008a46e: 430b jsr @r3
8008a470: 2420 mov.b r2, @r4
8008a472: 2008 tst r0, r0
8008a474: 8b08 bf <8008a488>
8008a476: d15f mov.l 0x8801b6d2, r1
8008a478: e0ff mov #-1, r0
8008a47a: d651 mov.l 0x8801b6cd, r6
8008a47c: 600c extu.b r0, r0
8008a47e: e203 mov #3, r2
8008a480: 8111 mov.w r0, @(2,r1)
8008a482: e008 mov #8, r0
8008a484: a01d bra <8008a4c2>
8008a486: 2620 mov.b r2, @r6
8008a488: d15a mov.l 0x8801b6d2, r1
8008a48a: e501 mov #1, r5
8008a48c: e400 mov #0, r4
8008a48e: 8511 mov.w @(2,r1), r0
8008a490: b04d bsr <8008a52e>
8008a492: 6603 mov r0, r6
8008a494: a015 bra <8008a4c2>
8008a496: 0009 nop
8008a498: 0729 movt r7
8008a49a: d559 mov.l 0x8801b6de, r5
8008a49c: d156 mov.l 0x8801b6d0, r1
8008a49e: 6063 mov r6, r0
8008a4a0: d64e mov.l %aca setjmp, r6
8008a4a2: d44f mov.l 0x8801b62c, r4
8008a4a4: 8151 mov.w r0, @(2,r5)
8008a4a6: 2170 mov.b r7, @r1
8008a4a8: 460b jsr @r6
8008a4aa: 2521 mov.w r2, @r5
8008a4ac: d24d mov.l 0x8801b6cc, r2
8008a4ae: 6403 mov r0, r4
8008a4b0: e100 mov #0, r1
8008a4b2: 2f02 mov.l r0, @r15
8008a4b4: bc69 bsr <80089d8a>
8008a4b6: 2210 mov.b r1, @r2
8008a4b8: d746 mov.l %ac9 longjmp, r7
8008a4ba: d447 mov.l 0x8801b5dc, r4
8008a4bc: 470b jsr @r7
8008a4be: e503 mov #3, r5
8008a4c0: e006 mov #6, r0
8008a4c2: 7f04 add #4, r15
8008a4c4: 4f26 lds.l @r15+, pr
8008a4c6: 000b rts
8008a4c8: 0009 nop