-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCONSOLE.ASM
321 lines (274 loc) · 9.2 KB
/
CONSOLE.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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
; ******************************************************************************
; CONSOLE DRIVER
; ******************************************************************************
; Driver: Console driver implementation utilizing a COM channel.
; Lets programs control, print and read to the console. The input and
; output is asynchronous and buffered by the driver.
; This implementation uses a COM channel to communicate with a terminal
; to serve as a console for the user.
; ------------------------------------------------------------------------------
; Constants
; ------------------------------------------------------------------------------
CONS_BUF_LEN EQU 0xFF ; Needs to be a power of two - 1
CONS_COM_CH EQU 0x00 ; Which COM channel to allocate
; Variables
; ------------------------------------------------------------------------------
BSS
CONS_OUT_HEAD DEFB 0x00 ; Console buffer pointers
CONS_OUT_TAIL DEFB 0x00
CONS_IN_HEAD DEFB 0x00
CONS_IN_TAIL DEFB 0x00
CONS_COM_STATUS DEFB 0x00 ; Temporary storage for COM status
ALIGN 256 ; Buffers needs to be page aligned
CONS_OUTBUF DEFS 0x100 ; Console output buffer
ALIGN 256
CONS_INBUF DEFS 0x100 ; Console input buffer
CODE
; Macros
; ------------------------------------------------------------------------------
ITOADDR MACRO BUFFER,REG
IF BUFFER==OUT
LD HL,CONS_OUTBUF
ELSE
LD HL,CONS_INBUF
ENDIF
LD L,REG
ENDM
ISEMPTY MACRO BUFFER
IF BUFFER==OUT
LD A,(CONS_OUT_HEAD)
LD C,A
LD A,(CONS_OUT_TAIL)
ELSE
LD A,(CONS_IN_HEAD)
LD C,A
LD A,(CONS_IN_TAIL)
ENDIF
CP C
ENDM
ISFULL MACRO BUFFER
IF BUFFER==OUT
LD A,(CONS_OUT_TAIL)
INC A
AND CONS_BUF_LEN ; Modulus Length
LD C,A
LD A,(CONS_OUT_HEAD)
ELSE
LD A,(CONS_IN_TAIL)
INC A
AND CONS_BUF_LEN ; Modulus Length
LD C,A
LD A,(CONS_IN_HEAD)
ENDIF
CP C
ENDM
BUF_ADV MACRO POINTER
LD HL,POINTER ; Load pointer
LD A,(HL)
INC A ; Increase pointer
AND CONS_BUF_LEN ; Modulus Length
LD (HL),A ; Save pointer
ENDM
; ------------------------------------------------------------------------------
; Title: Initiate the CONSOLE driver
; Name: CONS_INIT
;
; Entry: [No arguments]
; Exit: [No value]
; Registers: AF
; ------------------------------------------------------------------------------
CONS_INIT:
XOR A
LD (CONS_IN_TAIL),A
LD (CONS_IN_HEAD),A
LD (CONS_OUT_TAIL),A
LD (CONS_OUT_HEAD),A
LD (CONS_COM_STATUS),A
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Write a character to the console
; Desc: Write a character to the console at the current position. The
; output is buffered by the driver and is therefore decoupled from
; the hardware module.
; Name: CONS_WRITE_CHAR
;
; Entry: B = Character
; Exit: [No value]
; Registers: A,B,C,HL
; ------------------------------------------------------------------------------
CONS_WRITE_CHAR:
ISFULL OUT
RET Z ; If full, return
LD A,(CONS_OUT_TAIL) ; Push character to buffer
ITOADDR OUT,A
LD (HL),B
BUF_ADV CONS_OUT_TAIL
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Read a character from the console
; Desc: The input is buffered by the driver and is therefore decoupled
; from the hardware.
; Name: CONS_READ_CHAR
;
; Entry: [No arguments]
; Exit: B = Character
; Registers: A,B,C,HL
; ------------------------------------------------------------------------------
CONS_READ_CHAR:
LD A,(CONS_IN_HEAD) ; Check if buffer is empty
LD C,A
LD A,(CONS_IN_TAIL)
CP C
JP Z,CONS_READ_CHAR ; Empty, check again
LD A,(CONS_IN_HEAD) ; Read character into variable buffer
LD C,A
ITOADDR IN,C
LD B,(HL)
BUF_ADV CONS_IN_HEAD
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Read line with echo
; Desc: Read characters into a buffer and echo them until enter is read.
; Then null terminate the buffer and return.
; Name: CONS_READ_LINE_ECHO
;
; Entry: DE = Buffer pointer to read characters into
; Exit: [No value]
; Registers: A,B,C,HL,DE
; ------------------------------------------------------------------------------
CONS_READ_LINE_ECHO:
CALL CONS_READ_CHAR ; Read a character from console
LD A,ASCII_CR ; Check for ENTER
CP B
JP Z,CONS_READ_END
LD A,ASCII_BS ; Check for BACKSPACE
CP B
JP Z,CONS_READ_BACKSPACE
LD A,ASCII_ESC ; Ignore ESC
CP B
JP Z,CONS_READ_LINE_ECHO
LD A,B ; Store character
LD (DE),A
INC DE ; Increment buffer pointer
CALL CONS_WRITE_CHAR ; Echo character
JP CONS_READ_LINE_ECHO ; Read next...
CONS_READ_BACKSPACE:
LD B,ASCII_BS
CALL CONS_WRITE_CHAR ; Send backspace
DEC DE ; Decrement buffer pointer
JP CONS_READ_LINE_ECHO ; Read next...
CONS_READ_END:
XOR A ; Null terminate buffer
LD (DE),A
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Write a NULL terminated string to the console
; Name: CONS_WRITE_STRING
;
; Entry: DE = Buffer pointer
; Exit: [No value]
; Registers: A,B,C,HL,DE
; ------------------------------------------------------------------------------
CONS_WRITE_STRING:
LD A,(DE) ; Retrieve character
LD B,A
XOR A ; Check for end of string
CP B
RET Z
CALL CONS_WRITE_CHAR ; Write character to console
INC DE ; Increment buffer pointer
JP CONS_WRITE_STRING ; Write next...
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Send a character if buffer is not empty
; Desc: Uses the COM driver to actually send a character from the output
; buffer.
; Name: CONS_PROCESS_SEND
;
; Entry: [No arguments]
; Exit: [No value]
; Registers: A,B,C,HL
; ------------------------------------------------------------------------------
CONS_ISR_SEND:
ISEMPTY OUT
LD C,CONS_COM_CH
JP Z,COM_TX_OFF
CALL COM_TX_ON
LD A,(CONS_OUT_HEAD)
LD C,A
ITOADDR OUT,C
LD B,(HL)
LD C,CONS_COM_CH
CALL COM_WRITE
BUF_ADV CONS_OUT_HEAD
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Read a character into the buffer
; Desc: Uses the COM driver to actually read a character into the input
; buffer.
; Name: CONS_PROCESS_RECEIVE
;
; Entry: [No arguments]
; Exit: [No value]
; Registers: A,B,C,HL
; ------------------------------------------------------------------------------
CONS_ISR_RECEIVE:
LD C,CONS_COM_CH
CALL COM_READ
LD B,A
ISFULL IN
RET Z ; If full, return
LD A,(CONS_IN_TAIL)
ITOADDR IN,A
LD (HL),B
BUF_ADV CONS_IN_TAIL
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Process pending send and receive requests
; Desc: Sends or receives characters from the hardware module depending on
; the status. This function should be called everytime an interrupt
; is triggered by the hardware module.
; Name: CONS_PROCESS
;
; Entry: [No arguments]
; Exit: [No value]
; Registers: A,B,C,D,HL
; ------------------------------------------------------------------------------
CONS_ISR:
LD C,CONS_COM_CH ; Retrieve status word from COM channel
CALL COM_STATUS
LD (CONS_COM_STATUS),A
BIT 6,A ; Check if character is available
CALL NZ,CONS_ISR_RECEIVE
LD A,(CONS_COM_STATUS) ; Check if hw buffer is empty, if so,
BIT 5,A ; send next character
CALL NZ,CONS_ISR_SEND
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; Title: Cyclic main procedure
; Desc: Should be called periodically by OS. The purpose of this is to
; initiate transmission when needed.
; Name: CONS_PROCESS
;
; Entry: [No arguments]
; Exit: [No value]
; Registers: A,B,C,D,HL
; ------------------------------------------------------------------------------
CONS_MAIN:
LD C,CONS_COM_CH ; Return if Tx is already ongoing
CALL COM_TX_STATE
CP COM_TX_STATE_ON
RET Z
CALL CONS_ISR_SEND ; Start transmission
RET
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; END: Driver
; ------------------------------------------------------------------------------