-
Notifications
You must be signed in to change notification settings - Fork 175
/
console_01_input_proc_getc.asm
529 lines (334 loc) · 9.97 KB
/
console_01_input_proc_getc.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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
INCLUDE "config_private.inc"
SECTION code_driver
SECTION code_driver_terminal_input
PUBLIC console_01_input_proc_getc
EXTERN console_01_input_proc_echo, l_setmem_hl, asm_b_array_clear
EXTERN console_01_input_proc_oterm, l_inc_sp, l_jpix, l_offset_ix_de
EXTERN asm_b_array_push_back, asm_b_array_at, asm_toupper, error_zc, error_mc
EXTERN device_return_error, device_set_error
console_01_input_proc_getc:
; enter : ix = & FDSTRUCT.JP
;
; exit : success
;
; a = hl = char
; carry reset
;
; fail
;
; hl = 0 on stream error, -1 on eof
; carry set
;
; uses : af, hl
push bc
push de
call getc
pop de
pop bc
ret c ; if error
ld l,a
ld h,0 ; a = hl = char
ret
getc:
bit 5,(ix+6)
jr nz, line_mode
char_mode:
call state_machine_0 ; get char from device
ret c ; if driver error
push af ; save char
call console_01_input_proc_echo ; output to terminal
pop af ; a = char
ret
line_mode:
; try to get char from edit buffer
ld hl,17
call l_offset_ix_de ; hl = & FDSTRUCT.read_index
ld c,(hl)
inc hl
ld b,(hl) ; bc = read_index
inc hl ; hl = & FDSTRUCT.b_array
; bc = read_index
; hl = & FDSTRUCT.b_array
ld a,(hl) ; examine b_array.data
inc hl
or (hl)
dec hl
jr z, char_mode ; if edit buffer does not exist
bit 6,(ix+7)
jr nz, line_mode_readline ; if ioctl pushed edit buffer
call line_mode_editbuf_1
ret nc ; if char retrieved from edit buffer
line_mode_readline:
; hl = & FDSTRUCT.b_array
dec hl
dec hl ; hl = & FDSTRUCT.read_index
xor a
call l_setmem_hl - 4 ; FDSTRUCT.read_index = 0
push hl ; save b_array *
ld a,ITERM_MSG_READLINE_BEGIN
call console_01_input_proc_oterm ; inform output terminal that new line is starting
pop hl ; hl = b_array *
push hl
bit 6,(ix+7)
jr z, line_mode_readline_1
res 6,(ix+7)
; ioctl pushed edit buffer into terminal
; need to echo buffer chars to output terminal
ld e,(hl)
inc hl
ld d,(hl) ; de = b_array.data
inc hl
ld c,(hl)
inc hl
ld b,(hl) ; bc = b_array.size
ex de,hl
push_loop:
ld a,b
or c
jr z, readline_loop
ld a,(hl)
cp CHAR_LF
jr nz, put_raw_0
ld a,'?' ; changed escaped LF to '?'
put_raw_0:
push bc
push hl
call console_01_input_proc_echo ; send char to output terminal
pop hl
pop bc
inc hl
dec bc
jr push_loop
line_mode_readline_1:
call asm_b_array_clear ; empty the edit buffer
readline_loop:
; stack = & FDSTRUCT.b_array
; print cursor
ld a,(ix+6) ; a = ioctl_f0 flags
add a,a
jr nc, cursor_print_end ; if echo off
bit 1,(ix+7)
jr z, cursor_print_end ; if no cursor
ld c,CHAR_CURSOR_LC
and $30 ; isolate cook and caps flags
cp $30
jr nz, cursor_print ; if !cook || !caps
ld c,CHAR_CURSOR_UC
cursor_print:
ld a,ITERM_MSG_PRINT_CURSOR
call console_01_input_proc_oterm ; instruct output terminal to print cursor
cursor_print_end:
; read char from device
; stack = & FDSTRUCT.b_array
call state_machine_0 ; a = next char
; erase cursor
bit 7,(ix+6)
jr z, cursor_erase_end ; if echo off
bit 1,(ix+7)
jr z, cursor_erase_end ; if no cursor
pop hl
push hl ; hl = & FDSTRUCT.b_array
push af
call edit_buff_params ; de = char *edit_buffer, bc = int edit_buffer_len
ld a,ITERM_MSG_ERASE_CURSOR
bit 6,(ix+6)
jr z, cursor_not_pwd ; if not password mode
ld a,ITERM_MSG_ERASE_CURSOR_PWD
ld e,CHAR_PASSWORD
cursor_not_pwd:
call console_01_input_proc_oterm ; instruct output terminal to erase cursor
pop af
cursor_erase_end:
; process char
; a = char (carry on error with hl = 0 or -1)
; stack = & FDSTRUCT.b_array
jr c, readline_error ; if device reports error
bit 7,(ix+7)
jr nz, escaped_char ; if this is an escaped char
cp CHAR_CAPS
jr z, readline_loop ; change cursor
cp CHAR_BS
jr nz, escaped_char ; if not backspace
; backspace
; stack = & FDSTRUCT.b_array
pop hl
push hl
call edit_buff_params
; de = b_array.data
; bc = b_array.size
; stack = & FDSTRUCT.b_array
ld a,b
or c
jr nz, not_empty ; if edit buffer is not empty
; cannot backspace
bell:
ld a,ITERM_MSG_BELL
call console_01_input_proc_oterm ; send to output terminal
jr readline_loop
not_empty:
bit 7,(ix+6)
jr z, skip_bs ; if echo off
push bc ; save b_array.size
ld a,ITERM_MSG_BS
bit 6,(ix+6)
jr z, not_password_mode
ld a,ITERM_MSG_BS_PWD
ld e,CHAR_PASSWORD
not_password_mode:
call console_01_input_proc_oterm ; instruct output terminal to backspace
pop bc ; bc = b_array.size
skip_bs:
pop hl
push hl
inc hl
inc hl ; hl = & b_array.size
dec bc ; b_array.size --
ld (hl),c
inc hl
ld (hl),b ; erase last char of edit buffer
jp readline_loop
escaped_char:
; a = char
; stack = & FDSTRUCT.b_array
; first check if char is rejected by driver
ld c,a
push bc
ld a,ITERM_MSG_REJECT
call l_jpix
pop bc
jr nc, bell ; if terminal rejected the char
; append char to edit buffer
; c = char
; stack = & FDSTRUCT.b_array
pop hl
push hl
call asm_b_array_push_back ; append char to edit buffer
jr c, bell ; if failed because buffer is full
; c = char
; stack = & FDSTRUCT.b_array
ld a,c
bit 7,(ix+7)
jr z, put_raw ; if not an escaped char
cp CHAR_LF
jr nz, put_raw
ld a,'?' ; changed escaped LF to '?'
put_raw:
push af
ld c,a
ld a,ITERM_MSG_INTERRUPT
call l_jpix
pop bc
jr nc, interrupt_received
ld a,b
push af
call console_01_input_proc_echo ; send char to output terminal
pop af ; a = char
cp CHAR_LF
jp nz, readline_loop
readline_done:
readline_error:
; return a char from the edit buffer
; hl = 0 or -1 if error
; stack = & FDSTRUCT.b_array
push hl
ld a,ITERM_MSG_READLINE_END
call console_01_input_proc_oterm ; inform output terminal that editing is done
pop hl
ex (sp),hl ; hl = & FDSTRUCT.b_array
ld bc,0 ; read_index = 0
call line_mode_editbuf_1
jp nc, l_inc_sp - 2 ; if char successfully retrieved from buffer
pop hl ; hl = 0 or -1
ret
interrupt_received:
set 0,(ix+6) ; place device in error state
jr readline_done
edit_buff_params:
; hl = & FDSTRUCT.b_array
ld e,(hl)
inc hl
ld d,(hl) ; de = b_array.data
inc hl
ld c,(hl)
inc hl
ld b,(hl) ; bc = b_array.size
ret
line_mode_editbuf_1:
; enter : bc = read_index
; hl = & FDSTRUCT.b_array
;
; exit : success char available
;
; a = char from edit buffer
; carry reset
;
; fail no char in edit buffer
;
; hl = & FDSTRUCT.b_array
; carry set
push hl ; save & FDSTRUCT.b_array
call asm_b_array_at ; read char in edit buffer at index bc
ld a,l ; a = char from edit buffer
pop hl ; hl = & FDSTRUCT.b_array
ret c ; if char not available
inc bc ; read_index ++
dec hl
ld (hl),b
dec hl
ld (hl),c ; store new read_index
ret
state_machine_0:
; return char in A or carry set with hl = 0 or -1 on driver error
res 7,(ix+7) ; clear escaped char indicator
ld a,(ix+16) ; a = pending char
or a
jr z, state_machine_1 ; if no pending char
ld (ix+16),0 ; clear pending char
jr state_machine_2 ; process pending char
state_machine_1:
ld a,(ix+6)
and $03 ; check device state
jp nz, device_return_error
ld a,ITERM_MSG_GETC
call l_jpix ; get char from device
jp c, device_set_error
state_machine_2:
cp CHAR_CR
jr nz, not_cr
bit 0,(ix+7)
ret z ; if not doing crlf conversion
jr state_machine_1 ; reject CR
not_cr:
or a ; indicate no error
bit 4,(ix+6)
ret z ; if cook mode disabled
sm_cook:
cp CHAR_CAPS
jr z, sm_capslock
cp CHAR_ESC
jr z, sm_escape
; regular character
bit 3,(ix+6)
call nz, asm_toupper ; if caps lock active
or a ; indicate no error
ret
sm_capslock:
ld a,(ix+6)
xor $08 ; toggle caps lock bit
ld (ix+6),a
and $20
jr z, state_machine_1 ; read another if char mode
ld a,CHAR_CAPS
ret
sm_escape:
ld a,ITERM_MSG_GETC
call l_jpix ; get char from device
set 7,(ix+7) ; indicate an escaped char
ret nc ; return raw char if no error
sm_esc_exit:
ld a,CHAR_ESC ; store ESC as pending char
; fall through to sm_exit
sm_exit:
; stateful exit
ld (ix+16),a ; store pending char
ret