I've been trying my hand at z80 assembly recently, so I'll be using this thread as needed for questions along the way. I'm using Spasm for an assembler, and a TI-84+ emulated with WabbitEmu for debugging.
To begin, I've run into a wall trying to get direct port input to work as I need it to. I'm making a program that requires detection of button press and release events, and though for the most part it functions properly, I seem to be getting some sporadic input that I cannot trace. Here's a simplified version of my code:
Code:
This listens for any arrow keypress. When one is pressed, the rectangle is inverted on the screen, and inverted again when it is released. While an arrow is held, nothing is drawn.
My problem occurs when the key is held. Occasionally, the port reads in $FF even though an arrow is pressed, causing the program to detect a false key release and invert the rectangle. This produces an unwanted flickering effect. I attempted adding some nops for delay between writing to and reading from the port, but that didn't help. Also, I've tried debugging in WabbitEmu, but I can't seem to produce the issue when stepping through, only when the program is running at full speed.
What exactly am I messing up here?
To begin, I've run into a wall trying to get direct port input to work as I need it to. I'm making a program that requires detection of button press and release events, and though for the most part it functions properly, I seem to be getting some sporadic input that I cannot trace. Here's a simplified version of my code:
Code:
.nolist
#include "ti83plus.inc"
.list
.org $9D93
.db t2ByteTok, tAsmCmp
bcall(_RunIndicOff)
bcall(_ClrLCDFull)
KeyLoop:
ld a, %11111101 ; Check for [CLEAR] to exit (Port FD)
call DirectInput
bit 6, a
jr NZ, CheckArrows
ld a, $FF ; Reset key port
out (1), a
ret ; Exit program
CheckArrows:
ld a, %11111110 ; Check arrow pad (Port FE)
call DirectInput
push af
cp $FF
jr Z, noKeysPressed ; If an arrow key is pressed
ld a, (last_key)
cp $FF ; If last_key was not arrow
jr NZ, StoreLastKey
call InvertRectangle ; Called on key press
jr StoreLastKey
noKeysPressed:
ld a, (last_key)
cp $FF
jr Z, StoreLastKey
call InvertRectangle ; Called on key release
StoreLastKey:
pop af
ld (last_key), a
jr KeyLoop
;##############
;# Procedures #
;##############
;inputs: a = key group
;outputs: a = key code
;destroys: a, b
DirectInput:
ld b,a
ld a, $FF ;Reset the keypad
out (1),a
ld a,b
out (1),a
nop
nop
in a,(1)
ret
;inputs: none
;outputs: none
;destroys: hl, de
InvertRectangle:
ld hl, 0
ld de, $0A0A
bcall(_InvertRect)
ret
; Data
last_key: .db $FF ; Keep track of last key pressed
This listens for any arrow keypress. When one is pressed, the rectangle is inverted on the screen, and inverted again when it is released. While an arrow is held, nothing is drawn.
My problem occurs when the key is held. Occasionally, the port reads in $FF even though an arrow is pressed, causing the program to detect a false key release and invert the rectangle. This produces an unwanted flickering effect. I attempted adding some nops for delay between writing to and reading from the port, but that didn't help. Also, I've tried debugging in WabbitEmu, but I can't seem to produce the issue when stepping through, only when the program is running at full speed.
What exactly am I messing up here?