aboutsummaryrefslogtreecommitdiff
path: root/src/keybuf.s
blob: cf24e771c57733e22609eddcbc19fe0161284af6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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