Routines |
Prev: F335 | Up: Map | Next: F408 |
This wipes the game window, sets its attributes, draws prompts, then sits in a loop waiting for the player to make their key choices. The chosen keys (defined by port and mask) are stored in the table at keydefs. Finally the user is asked to confirm their key choices.
Used by the routine at check_menu_keys.
|
||||
Start loop (infinite) - loops until the user confirms the key selection.
Clear the game window.
|
||||
choose_keys | F350 | CALL wipe_game_window | Wipe the game screen | |
F353 | LD A,$07 | Set game window attributes to attribute_WHITE_OVER_BLACK | ||
F355 | CALL set_game_window_attributes | |||
Draw key choice prompts.
|
||||
F358 | LD B,$06 | Set B for six iterations | ||
F35A | LD HL,$F2AD | Point HL at define_key_prompts | ||
Start loop (once per prompt)
|
||||
ck_prompts_loop | F35D | PUSH BC | Preserve the loop counter | |
F35E | LD E,(HL) | Read screen address | ||
F35F | INC HL | |||
F360 | LD D,(HL) | |||
F361 | INC HL | |||
F362 | LD B,(HL) | Read string length | ||
F363 | INC HL | |||
Draw the prompt's glyphs.
Start loop (once per character)
|
||||
ck_draw_prompt | F364 | PUSH BC | Preserve string length | |
Bug: The next load is needless (plot_glyph does it already).
|
||||
F365 | LD A,(HL) | Read a glyph | ||
F366 | CALL plot_glyph | Plot a single glyph (indirectly) | ||
F369 | INC HL | Advance the string pointer | ||
F36A | POP BC | Restore string length | ||
F36B | DJNZ ck_draw_prompt | ...loop (once per character) | ||
F36D | POP BC | Restore the loop counter | ||
F36E | DJNZ ck_prompts_loop | ...loop (once per prompt) | ||
Wipe key definitions.
|
||||
F370 | LD HL,$F06B | Point HL at keydefs | ||
F373 | LD B,$0A | Set B for 10 iterations | ||
F375 | XOR A | Zero A in preparation | ||
Start loop
|
||||
ck_clear_keydef | F376 | LD (HL),A | Zero a byte of keydef | |
F377 | INC HL | Advance HL | ||
F378 | DJNZ ck_clear_keydef | ...loop | ||
Now scan for keys.
|
||||
F37A | LD B,$05 | Set B for five iterations: left/right/up/down/fire | ||
F37C | LD HL,$F32B | Point HL at key_name_screen_addrs | ||
Start loop (once per direction+fire)
|
||||
ck_keyscan_loop | F37F | PUSH BC | Preserve the loop counter | |
F380 | LD E,(HL) | Read screen address | ||
F381 | INC HL | |||
F382 | LD D,(HL) | |||
F383 | INC HL | |||
F384 | PUSH HL | Preserve screen address | ||
F385 | LD ($F3E9),DE | Self modify the "LD DE,$xxxx" at ck_plot_glyph to load the screen address | ||
F389 | LD A,$FF | Set the debounce flag. This is only set to zero once we've checked the whole keyboard and no keys are pressed, at which point it gets set to zero | ||
Start loop (infinite)
|
||||
ck_keyscan_inner | F38B | EX AF,AF' | Bank the debounce flag | |
F38C | LD HL,$F2E1 | Point HL at keyboard_port_hi_bytes[-1] | ||
F38F | LD D,$FF | Initialise the port index | ||
Start loop
|
||||
ck_try_next_port | F391 | INC HL | Advance HL to the next port high byte | |
F392 | INC D | Increment the port index | ||
F393 | LD A,(HL) | Read the port high byte | ||
F394 | OR A | Have we reached the end of keyboard_port_hi_bytes? ($00) | ||
F395 | JR Z,ck_keyscan_inner | ...loop if so (zero in A becomes new debounce flag) | ||
F397 | LD B,A | Read port high byte | ||
F398 | LD C,$FE | Read port $FE | ||
F39A | IN A,(C) | Read the keyboard port | ||
F39C | CPL | Invert the bits to turn active low into active high | ||
F39D | LD E,A | Copy the result into E so we can restore it each time | ||
F39E | LD C,$20 | Create a mask with bit 5 set | ||
Test bits 4,3,2,1,0
|
||||
ck_keyscan_detect | F3A0 | SRL C | Shift the mask right | |
F3A2 | JR C,ck_try_next_port | Jump (to try next port) if the mask bit got shifted out | ||
F3A4 | LD A,C | Mask the result | ||
F3A5 | AND E | |||
F3A6 | JR Z,ck_keyscan_detect | ...loop while no keys are pressed | ||
We arrive here if a key was pressed.
|
||||
F3A8 | EX AF,AF' | Unbank the debounce flag | ||
F3A9 | OR A | Is it set? | ||
F3AA | JR NZ,ck_keyscan_inner | Restart the loop if so (A is debounce flag) | ||
F3AC | LD A,D | Bank the port index | ||
F3AD | EX AF,AF' | |||
F3AE | LD HL,$F06A | Point HL at the byte before keydefs | ||
Start loop
|
||||
ck_next_keydef | F3B1 | INC HL | Advance to the next keydef | |
F3B2 | LD A,(HL) | Read the keydef.port | ||
F3B3 | OR A | Is it an empty slot? | ||
F3B4 | JR Z,ck_assign_keydef | Jump if so (assign keydef) | ||
F3B6 | CP B | Does the port high byte match? | ||
F3B7 | INC HL | Advance HL (interleaved) | ||
F3B8 | JR NZ,ck_next_keydef | ...loop if different | ||
F3BA | LD A,(HL) | Read keydef.mask | ||
F3BB | CP C | Does the mask match? | ||
F3BC | JR NZ,ck_next_keydef | ...loop if different | ||
F3BE | JP ck_keyscan_inner | ...loop (infinite) (mask in A becomes new debounce flag) | ||
Assign key definition.
|
||||
ck_assign_keydef | F3C1 | LD (HL),B | Store port | |
F3C2 | INC L | |||
F3C3 | LD (HL),C | Store mask | ||
F3C4 | EX AF,AF' | Unbank the port index | ||
F3C5 | LD B,A | Multiply it by 5 | ||
F3C6 | ADD A,A | |||
F3C7 | ADD A,A | |||
F3C8 | ADD A,B | |||
F3C9 | LD HL,$F302 | Point HL one byte prior to keycode_to_glyph. This is off-by-one to compensate for the upcoming preincrement | ||
F3CC | ADD A,L | Combine | ||
F3CD | LD L,A | |||
F3CE | JR NC,ck_find_key_glyph | |||
F3D0 | INC H | |||
Skip entries until the mask carries out.
|
||||
ck_find_key_glyph | F3D1 | INC HL | Advance the glyph pointer | |
F3D2 | RR C | Shift mask | ||
F3D4 | JR NC,ck_find_key_glyph | ...loop until the mask carries out | ||
F3D6 | LD B,$01 | Set length to 1 | ||
F3D8 | LD A,(HL) | Load the glyph | ||
F3D9 | OR A | Test the top bit | ||
F3DA | JP P,ck_plot_glyph | Jump if clear (JP P => positive) | ||
If the top bit was set then it's a special key, like SPACE or ENTER.
|
||||
F3DD | AND $7F | Extract the byte offset into special_key_names | ||
F3DF | LD DE,$F2EB | Point DE at special_key_names | ||
F3E2 | LD L,A | Widen byte offset into HL | ||
F3E3 | LD H,$00 | |||
F3E5 | ADD HL,DE | Combine | ||
F3E6 | LD B,(HL) | First byte is length of special key name | ||
F3E7 | INC HL | Advance HL to point at glyphs | ||
Plot.
|
||||
ck_plot_glyph | F3E8 | LD DE,$40D5 | Point DE at (a self modified screen address) | |
Start loop (draw key)
|
||||
ck_plot_glyph_loop | F3EB | PUSH BC | Preserve the loop counter | |
Bug: The next load is needless (plot_glyph does it already).
|
||||
F3EC | LD A,(HL) | Read a glyph | ||
F3ED | CALL plot_glyph | Plot a single glyph (indirectly) | ||
F3F0 | INC HL | Advance to next glyph index | ||
F3F1 | POP BC | Restore the loop counter | ||
F3F2 | DJNZ ck_plot_glyph_loop | ...loop (draw key) | ||
F3F4 | POP HL | Restore screen address | ||
F3F5 | POP BC | Restore the loop counter | ||
F3F6 | DEC B | ...loop (once per direction+fire) | ||
F3F7 | JR NZ,ck_keyscan_loop | |||
Delay loop.
This delays execution by approximately a third of a second (~1.25M T-states).
|
||||
F3F9 | LD BC,$FFFF | Set BC to $FFFF | ||
ck_delay | F3FC | DEC BC | Count down until it's zero | |
F3FD | LD A,B | |||
F3FE | OR C | |||
F3FF | JR NZ,ck_delay | |||
Wait for the user's confirmation.
|
||||
F401 | CALL user_confirm | Wait for the user to confirm by pressing 'Y' or 'N' | ||
F404 | RET Z | If Z set 'Y' was pressed so return | ||
F405 | JP NZ,choose_keys | ...loop (infinite) |
Prev: F335 | Up: Map | Next: F408 |