-
Notifications
You must be signed in to change notification settings - Fork 4
/
getchar.s
120 lines (109 loc) · 2.73 KB
/
getchar.s
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
; vim:syntax=z8a:ts=8
;
; msTERM
; getchar and other keyboard routines
;
; Copyright (c) 2019 joshua stein <jcs@jcs.org>
;
; Permission to use, copy, modify, and distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;
.module getchar
.include "mailstation.inc"
.globl _lptrecv
.area _DATA
; scancode_table holds three tables of ascii characters which
; '_getchar' uses to determine which character to return, depending on
; the scancode pressed and the state of the shift and caps lock keys.
.include "scancodes.inc"
keyboardbuffer:
.ds 2 ; scancode buffer for _getchar
capslock:
.db #0
.area _CODE
; unsigned char peekkey(void)
; check for a scancode using the firmware, then look it up in the scancode
; table (respecting the shift key and caps lock as control) and return the
; ascii value of the key in the l register
_peekkey::
ld de, #keyboardbuffer
push de
call get_keycode_from_buffer
pop de
ld a, (keyboardbuffer) ; check for caps lock first
cp #0x60
jr z, is_caps_lock
jr not_caps_lock
is_caps_lock:
ld a, (keyboardbuffer + 1) ; check flags
bit 0, a ; set=pressed, reset=released
jp nz, caps_down
ld a, #0 ; caps lock released
ld (capslock), a
jr nokey
caps_down:
ld a, #1
ld (capslock), a
jr nokey
not_caps_lock:
ld a, (keyboardbuffer + 1) ; check flags
bit 0, a ; set=pressed, reset=released
jp z, nokey ; key was released, bail
bit 6, a ; when set, shift was held down
jr z, lowercase
capital:
ld hl, #scancode_table_uppercase
jr char_offset
lowercase:
ld a, (capslock)
cp #1
jr z, as_control
ld hl, #scancode_table
jr char_offset
as_control:
ld hl, #scancode_table_control
jr char_offset
char_offset:
push hl
ld hl, #50
push hl
call _delay
pop hl
pop hl
ld a, (keyboardbuffer)
ld b, #0
ld c, a
add hl, bc
ld a, (hl)
ld h, #0
ld l, a
ret
nokey:
ld h, #0
ld l, #0
ret
; unsigned char getkey(void)
; peekkey() but loops until a key is available
_getkey::
call _peekkey
ld a, l
cp #0
jp z, _getkey
ret
; int getchar(void)
; uses _getkey and filters out non-printables, returns in l register
_getchar::
call _getkey
ld a, l
cp a, #META_KEY_BEGIN
jr nc, _getchar ; a >=
ret