aboutsummaryrefslogtreecommitdiff
path: root/timed_getch.s
blob: ba3b0a9dd853724a88dbf9bfb0dec9e290736753 (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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

 .export _timed_getch, _set_jiffy_timer, _agetc, _numgetc, _yngetc, _lcgetc
 .import _cgetc, _cblank, _cursor

 .include "atari.inc"

_set_jiffy_timer: ; called by jsleep() also.
 sei          ; disable IRQ while setting timer
 sta CDTMV3
 stx CDTMV3+1
 cli
 rts

_timed_getch:
 jsr _set_jiffy_timer
wait4key:
 lda CDTMV3   ; has timer counted down to 0?
 ora CDTMV3+1
 beq done     ; yes, return(-1)
 lda CH       ; no, check for a keypress
          ; ...but don't let the capslock or inverse keys count
			 ; as a keypress, here.

 cmp #$ff ; no key pressed
 beq wait4key
 and #$3f ; mask shift/control bits
 cmp #$3c ; caps-lock
 beq wait4key
 cmp #$27 ; inverse (atari) key
 beq wait4key

 jmp _agetc ; user hit a key, read it.
 
done:
 lda #$ff ; return -1
 tax
 rts

; _agetc removes the inverse-video bit, and if
; a control key is pressed, it turns it into the non-control version
; (e.g. ^A = lowercase a). Keys that can't be mapped to regular ASCII
; (such as clear, delete, escape) are replaced with a space.
; extern char lcgetc();
_agetc:
 lda #1      ; show cursor
 jsr _cursor
 sta FR1+2   ; save old cursor status
 lda #1
 jsr _cblank

 jsr _cgetc ; get ATASCII code of keypress

 ; special cases
 cmp #$9b   ; enter key, return as-is
 beq ok
 cmp #$9c   ; delete key, return as-is
 beq ok
 cmp #$7e   ; backspace
 beq ok

 ; everything else
 and #$7f   ; strip bit 7 (inverse)
 bne notnull
 lda #$20   ; map null (heart, ctrl-,) to space
notnull:
 cmp #$20
 bcs notcontrol
 ora #$60   ; 1 - 31 map to 96 - 127
notcontrol:
 cmp #$7c ; | (pipe, vertical bar) allowed as-is.
 beq ok
 cmp #$7b ; rest of range $7b - $7f is unmappable.
 bcc ok   ; (remember, $7e, backspace, was handled above)
 lda #$20
ok:
 pha
 ldx #0
 lda FR1+2
 jsr _cursor
 pla
 ldx #0
 rts

_lcgetc:
 jsr _agetc
 cmp #'A'
 bcc ok
 cmp #'Z'+1
 bcs ok
 eor #$20   ; lowercase it
 bcc ok

_numgetc:
 jsr _agetc
 cmp #$9b
 beq ok
 cmp #$7e   ; backspace
 beq ok
 cmp #$61   ; allow 'a' for "all"
 beq ok
 cmp #$6b   ; allow 'k' for 1000
 beq ok
 cmp #$6d   ; allow 'm' for 1 million
 beq ok
 cmp #$9c   ; shift-del
 beq ok
 cmp #'0'
 bcc _numgetc
 cmp #'9'+1
 bcc ok
 bcs _numgetc

_yngetc:
 sta FR0 ; stash default arg
 jsr _lcgetc
 cmp #'y'  ; return y or n immediately
 beq ok
 cmp #'n'
 beq ok
 lda FR0     ; otherwise, check for default arg
 beq _yngetc ; no default, get another keypress
 rts         ; else return the default