Skip to content

Cursor key disambiguation bits have a race condition #927

@AwesomeDolphin

Description

@AwesomeDolphin

Test Environment (required)

Platform: MEGA65 R6
Core Commit: 03b24c6
ROM Release: V920413
Describe the bug
According to the manual, register $D60F should hold two bits that can be used to disambiguate a cursor up from a shift cursor down. This register returns the correct bits, but not in sync with the key press register.

To Reproduce
Steps to reproduce the behavior:

Run Easy ASM
Enter the following program:
10 !to "testkey",runnable
20 lda #$08
30 sta $d020
35 loop:
40 lda #$00
50 sta $d614
60 lda $d613
70 ldx $d60f
80 and #$80
90 bne loop
100 txa
110 and #$02
120 bne loop
130 brk

Assemble and test
Border will turn orange
Press cursor up and release several times.
Program will crash to monitor after several press/release cycles showing that bit 1 was not set.

Expected behavior
The program should run forever, because the expected case would be that the cursor up bit (bit 1 of d60f) would be set any time the cursor down bit is set (bit 7 of d613). If the cursor down key is not set, the program loops at 90. If the cursor up bit is set, the program loops at 120.

Additional context
I'm trying to figure out how to solve this race condition on my end, and I am not sure that I can. It can't hit on the c64, because if a program ever used the cursor keys as directionals, the user would know to release the cursor key first, then shift. And to press shift first, then the cursor key. Failing to do that would be understood as user error. However, in this case, the user has no control of the timing of the shift and cursor presses, nor the special bits I'm using.

It does, however, strike emulators, and is a known issue with VICE (and other emulators), trying to make a translation. Some software can deal with the implied "shift cursor down" and "shift cursor right" simultaneous presses, and some can't, which is why VICE offers a way to use various keymap tables, some of which do not autoshift keys (positional tables). It also strikes other keys if they are unshifted on the host keyboard, but shifted on the C64 keyboard.

I'm not sure what algorithm I'm suggesting be implemented, because it has a number of cases:

  1. The up key might be pressed by itself, and released: set shift, set cursor up, clear cursor up, clear shift.
  2. The up key might be pressed along with down: I don't think the key mapping has a way to express this
  3. The up key might be pressed, then down pressed, then up released: set shift, set cursor up, clear shift

The issue is similar to reading the TOD clocks out of the CIA, there is no race-free way to do it, so the hardware freezes the registers and requires they be read out in a certain order.

Not sure that you want to implement a keyboard lock, but.... good luck, because VICE has struggled with this one themselves.

Metadata

Metadata

Assignees

No one assigned

    Labels

    newNew report, not classified yet

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions