Skip to content

Function KEY() is broken (or at least does not work as expected) #270

@kochs-online

Description

@kochs-online

Boy, did I have a hard time figuring this one out! 😅 BASICally (pun intended) had to learn Assembler first…

So, I was trying to use KEY() for target pet8032 and because the list of keyboard scancodes does not include the PET/CBM [chiclet, graphics and business] keyboard I tried to find out which scancodes I would have to use.

After learning about all the quirks of the Commodore keyboard matrix and a lot of trial & error I was pretty sure 1007 ($03EF) would be the scancode for the RETURN key on a PET/CBM business keyboard: It's wired in row $03 of the matrix and will pull down bit 4, resulting in a bit mask of 11110111 ($EF) when pressed.

But to my surprise KEY(1007) returns FALSE while pressing RETURN. What's happening?!

After quite a few more hours of experimenting and scratching my head I ended up writing a small sample programm:

KEY(1007)

And then disassembled it (using the WFDis Interactive 6502 Disassembler):

[…]   ; launcher and some initialization
L0422               lda #$ef
                    ldy #$03
                    sty $e810   ; store $03 to keyboard row select port (DDR A)
                    and $e812   ; accumulator AND bit mask of keyboard column bits (DDR B)
                    bne L0432
                    lda #$ff   ; return TRUE
                    bne L0439
L0432               lda #$00   ; return FALSE
                    bne L0439
                    jmp L0439
L0439               jmp $b3ff   ; exit to BASIC

This will always return FALSE if anything else than 0 (well almost; see below) is written to the accumulator and used for the AND opcode in $0429.

Example:

    11110111   [accumulator]
AND 11110111   [keyboard column bits at $E812]
    ========
    11110111   [result in accumulator]

This will NOT set the zero flag of the status register and BNE at $042C will trigger and branch to $0432.

Using the inverse binary value of the key's bit mask (here: 00001000) does work, but this is rather counter-intuitive, I guess.

Replacing opcode AND with CMP should work as intended.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdocumentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions