-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkeyb.asm
189 lines (149 loc) · 3.47 KB
/
keyb.asm
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
; ***************************************************************************************
; ***************************************************************************************
; ** Tools for keyboard management
; ** Require setup.asm
KEY_BUFFER_SIZE equ 1
.DATA
OLD_INT9_ADDR dw 2 dup (?)
KEY_BUFFER db KEY_BUFFER_SIZE dup (0)
KEY_BUFFER_PTR dw 0
.CODE
INT9_SETUP:
pusha
push es
; Get current address of int 9 and save it
mov al, 09h
mov ah, 35h
int 21h
mov [OLD_INT9_ADDR], bx
mov [OLD_INT9_ADDR + 2], es
; Set new interrupt
push ds
mov ax, cs
mov ds, ax
mov al, 09h
lea dx, cs:[BespokeInt9]
mov ah, 25h
int 21h
pop ds
pop es
popa
ret
INT9_RESET:
; Before exiting, we must reset int9 to its former address
push ax
push dx
push ds
mov dx, [OLD_INT9_ADDR]
mov ax, [OLD_INT9_ADDR + 2]
mov ds, ax
mov al, 09h
mov ah, 25h
int 21h
pop ds
pop dx
pop ax
ret
READ_KEY_WAIT:
; function reads the buffer and wait for a key to be pressed
; AL contains the key code
push si
push bx
lea si, [KEY_BUFFER]
@@wait_key:
mov bx, [KEY_BUFFER_PTR]
or bx, bx
jz @@wait_key
; adjust the buffer
dec bx
mov [KEY_BUFFER_PTR], bx
mov al, [si+bx]
pop bx
pop si
ret
READ_KEY_NOWAIT:
; function reads the buffer and returns pressed key (if any)
; routine does not wait for a key to be pressed
; AL contains the key code - AH is also modified
mov ax, [KEY_BUFFER_PTR]
or ax, ax
jz @@return_no_key
; adjust the buffer
push si
mov si, offset KEY_BUFFER
dec ax
mov [KEY_BUFFER_PTR], ax
add si, ax
mov al, [si]
pop si
@@return_no_key:
ret
PURGE_KEY_BUFFER:
; purge the key buffer (effectively just setting KEY_BUFFER_PTR to 0)
; disable interrput first to make sure keyboard doesn't get call at the same time
cli
push ax
push di
push ds
mov ax, @DATA
mov ds, ax
mov di, offset KEY_BUFFER_PTR
mov [di], ax
pop ds
pop di
pop ax
sti
ret
; ***************************************************************************************
; ** Below is my new int9
BespokeInt9:
; if you want to keep calling the previous interrupt - add something like this
;push si
;push es
;mov si, [OLD_INT9_ADDR]
;mov ax, [OLD_INT9_ADDR + 2]
;mov es, ax
;call es:si
;pop es
;pop si
;cli ; stop all interrupts
push ax
in al, 60h
mov ah, al
; is it an up key (which we don't care about)
and ah, 80h
jnz @@end_int9
push bx
push si
push ds
mov bx, @DATA
mov ds, bx
; si points to buffer and dx is the current position
mov si, offset KEY_BUFFER
mov bx, [KEY_BUFFER_PTR]
; if overflow then don't bother storing it
inc bx
cmp bx, KEY_BUFFER_SIZE + 1
jz @@pre_end_int9
mov [KEY_BUFFER_PTR], bx
dec bx
add si, bx
mov [si], al
@@pre_end_int9:
pop ds
pop si
pop bx
@@end_int9:
; it seems that this bit below is necessary... but it works without
in al, 61h
mov ah, al
or al, 80h
out 61h, al
xchg al, ah
out 61h, al
; End of interrupt (that is necessary!)
mov al, 20h
out 20h, al
pop ax
;sti
iret