aboutsummaryrefslogtreecommitdiff
path: root/src/keybuf.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/keybuf.s')
-rw-r--r--src/keybuf.s94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/keybuf.s b/src/keybuf.s
new file mode 100644
index 0000000..cf24e77
--- /dev/null
+++ b/src/keybuf.s
@@ -0,0 +1,94 @@
+ .fopt compiler,"cc65 v 2.12.9"
+ .setcpu "6502"
+ .smart on
+ .autoimport on
+ .case on
+ .debuginfo off
+ .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2
+ .export _keybuf_init, _keybuf_poll_kbd, _keybuf_cgetc
+
+NO_KEY = $FF
+max_buf_len = 12 ; aka buffer size
+
+BUFFER_BASE = $F0
+
+keybuf_head = BUFFER_BASE
+keybuf_tail = BUFFER_BASE+1
+keybuf = BUFFER_BASE+2
+keybuf_end = keybuf + max_buf_len
+
+CH = $02FC
+
+ .segment "CODE"
+
+; void __fastcall__ keybuf_init(void)
+_keybuf_init:
+ lda #keybuf
+ sta keybuf_head
+ sta keybuf_tail
+ rts
+
+; void __fastcall__ keybuf_poll_kbd(void)
+_keybuf_poll_kbd:
+ lda CH
+ cmp #NO_KEY
+ beq kbpoll_done
+
+ ; got a key, see if room in buffer
+ ldx keybuf_tail
+ cpx #keybuf_end+1
+ bcs kbpoll_done
+
+ ; buffer not full, so store key in buffer
+ sta 0,x
+ inc keybuf_tail
+
+ ; clear keyboard register
+ lda #NO_KEY
+ sta CH
+
+kbpoll_done:
+ rts
+
+
+; char __fastcall__ keybuf_is_empty(void)
+_keybuf_is_empty:
+ ldx #0
+ sec
+ lda keybuf_tail
+ sbc keybuf_head
+ rts
+
+
+; char __fastcall__ keybuf_cgetc(void)
+
+; Note: 0 means "no key pressed", which means we
+; can't return character code 0 (not a big deal).
+; If this is a problem, we could change the return
+; type to int, and return -1 instead.
+
+_keybuf_cgetc:
+ ldx keybuf_head
+ cpx keybuf_tail
+ beq check_ch
+
+ ; got a key, stuff it in CH
+ lda 0,x
+ sta CH
+ inc keybuf_head
+
+call_cgetc:
+ ; ...and return the ASCII code
+ jmp _fuji_cgetc
+
+check_ch:
+ jsr _keybuf_init
+
+ ldx CH
+ cpx #NO_KEY
+ bne call_cgetc
+
+ inx ; was $FF, now 0
+ txa ; aka return(0)
+ rts
+