strreplace: clean up and simplify
[profile/ivi/syslinux.git] / core / conio.inc
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4 ;;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
5 ;;
6 ;;   This program is free software; you can redistribute it and/or modify
7 ;;   it under the terms of the GNU General Public License as published by
8 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
10 ;;   (at your option) any later version; incorporated herein by reference.
11 ;;
12 ;; -----------------------------------------------------------------------
13
14 ;;
15 ;; conio.inc
16 ;;
17 ;; Console I/O code, except:
18 ;;   writechr, writestr_early   - module-dependent
19 ;;   writestr, crlf             - writestr.inc
20 ;;   writehex*                  - writehex.inc
21 ;;
22
23 ;
24 ; loadkeys:     Load a LILO-style keymap; file is open on the top of the
25 ;               getc stack.
26 ;
27                 section .text16
28
29 loadkeys:
30                 mov cx,256
31                 mov di,trackbuf
32                 call readc
33                 jc .done                                ; EOF already?
34
35                 ; Make sure we are at EOF now...
36                 call getc
37                 jnc .done                       ; We should be at EOF now!
38
39                 ; It was okay, we can now move it into the KbdMap
40                 mov si,trackbuf
41                 mov di,KbdMap
42                 mov cx,256 >> 2
43                 rep movsd
44
45 .done:
46                 call close
47                 ret
48
49 ;
50 ; get_msg_file: Load a text file and write its contents to the screen,
51 ;               interpreting color codes.  Call with the file already
52 ;               on the top of the open/getc stack.
53 ;
54 ;               Assumes CS == DS == ES.
55 ;
56 get_msg_file:
57                 mov byte [TextAttribute],07h    ; Default grey on white
58                 mov byte [DisplayMask],07h      ; Display text in all modes
59                 call msg_initvars
60
61 print_msg_file:
62 .getc:
63                 call getc
64                 jc .done
65                 cmp al,1Ah                      ; DOS EOF?
66                 je .done
67                 movzx cx,byte [UsingVGA]
68                 and cl,01h
69                 inc cx                          ; CL <- 01h = text mode,
70                                                 ;       02h = graphics mode
71                 call [NextCharJump]             ; Do what shall be done
72                 jmp .getc
73 .done:
74                 jmp close                       ; Tailcall!
75
76 msg_putchar:                                    ; Normal character
77                 cmp al,0Fh                      ; ^O = color code follows
78                 je msg_ctrl_o
79                 cmp al,0Dh                      ; Ignore <CR>
80                 je msg_ignore
81                 cmp al,0Ah                      ; <LF> = newline
82                 je msg_newline
83                 cmp al,0Ch                      ; <FF> = clear screen
84                 je msg_formfeed
85                 cmp al,07h                      ; <BEL> = beep
86                 je msg_beep
87                 cmp al,19h                      ; <EM> = return to text mode
88                 je msg_novga
89                 cmp al,18h                      ; <CAN> = VGA filename follows
90                 je msg_vga
91                 jnb .not_modectl
92                 cmp al,10h                      ; 10h to 17h are mode controls
93                 jae msg_modectl
94 .not_modectl:
95
96 msg_normal:     call write_serial_displaymask   ; Write to serial port
97                 test [DisplayMask],cl
98                 jz msg_ignore                   ; Not screen
99                 test byte [DisplayCon],01h
100                 jz msg_ignore
101                 mov bl,[TextAttribute]
102                 mov bh,[BIOS_page]
103                 mov ah,09h                      ; Write character/attribute
104                 mov cx,1                        ; One character only
105                 int 10h                         ; Write to screen
106                 mov al,[CursorCol]
107                 inc ax
108                 cmp al,[VidCols]
109                 ja msg_line_wrap                ; Screen wraparound
110                 mov [CursorCol],al
111
112 msg_gotoxy:     mov bh,[BIOS_page]
113                 mov dx,[CursorDX]
114                 mov ah,02h                      ; Set cursor position
115                 int 10h
116 msg_ignore:     ret
117
118 msg_beep:       mov ax,0E07h                    ; Beep
119                 xor bx,bx
120                 int 10h
121                 ret
122
123 msg_ctrl_o:                                     ; ^O = color code follows
124                 mov word [NextCharJump],msg_setbg
125                 ret
126 msg_newline:                                    ; Newline char or end of line
127                 mov si,crlf_msg
128                 call write_serial_str_displaymask
129 msg_line_wrap:                                  ; Screen wraparound
130                 test [DisplayMask],cl
131                 jz msg_ignore
132                 mov byte [CursorCol],0
133                 mov al,[CursorRow]
134                 inc ax
135                 cmp al,[VidRows]
136                 ja msg_scroll
137                 mov [CursorRow],al
138                 jmp short msg_gotoxy
139 msg_scroll:     xor cx,cx                       ; Upper left hand corner
140                 mov dx,[ScreenSize]
141                 mov [CursorRow],dh              ; New cursor at the bottom
142                 mov bh,[ScrollAttribute]
143                 mov ax,0601h                    ; Scroll up one line
144                 int 10h
145                 jmp short msg_gotoxy
146 msg_formfeed:                                   ; Form feed character
147                 mov si,crff_msg
148                 call write_serial_str_displaymask
149                 test [DisplayMask],cl
150                 jz msg_ignore
151                 xor cx,cx
152                 mov [CursorDX],cx               ; Upper lefthand corner
153                 mov dx,[ScreenSize]
154                 mov bh,[TextAttribute]
155                 mov ax,0600h                    ; Clear screen region
156                 int 10h
157                 jmp msg_gotoxy
158 msg_setbg:                                      ; Color background character
159                 call unhexchar
160                 jc msg_color_bad
161                 shl al,4
162                 test [DisplayMask],cl
163                 jz .dontset
164                 mov [TextAttribute],al
165 .dontset:
166                 mov word [NextCharJump],msg_setfg
167                 ret
168 msg_setfg:                                      ; Color foreground character
169                 call unhexchar
170                 jc msg_color_bad
171                 test [DisplayMask],cl
172                 jz .dontset
173                 or [TextAttribute],al           ; setbg set foreground to 0
174 .dontset:
175                 jmp short msg_putcharnext
176 msg_vga:
177                 mov word [NextCharJump],msg_filename
178                 mov di, VGAFileBuf
179                 jmp short msg_setvgafileptr
180
181 msg_color_bad:
182                 mov byte [TextAttribute],07h    ; Default attribute
183 msg_putcharnext:
184                 mov word [NextCharJump],msg_putchar
185                 ret
186
187 msg_filename:                                   ; Getting VGA filename
188                 cmp al,0Ah                      ; <LF> = end of filename
189                 je msg_viewimage
190                 cmp al,' '
191                 jbe msg_ret                     ; Ignore space/control char
192                 mov di,[VGAFilePtr]
193                 cmp di,VGAFileBufEnd
194                 jnb msg_ret
195                 mov [di],al                     ; Can't use stosb (DS:)
196                 inc di
197 msg_setvgafileptr:
198                 mov [VGAFilePtr],di
199 msg_ret:        ret
200
201 msg_novga:
202                 call vgaclearmode
203                 jmp short msg_initvars
204
205 msg_viewimage:
206                 mov si,[VGAFilePtr]
207                 mov byte [si],0                 ; Zero-terminate filename
208                 mov si,VGAFileBuf
209                 mov di,VGAFileMBuf
210                 pm_call pm_mangle_name
211                 call core_open
212                 jz msg_putcharnext              ; Not there
213                 call vgadisplayfile
214                 ; Fall through
215
216                 ; Subroutine to initialize variables, also needed
217                 ; after loading a graphics file
218 msg_initvars:
219                 pusha
220                 mov bh,[BIOS_page]
221                 mov ah,03h                      ; Read cursor position
222                 int 10h
223                 mov [CursorDX],dx
224                 popa
225                 jmp short msg_putcharnext       ; Initialize state machine
226
227 msg_modectl:
228                 and al,07h
229                 mov [DisplayMask],al
230                 jmp short msg_putcharnext
231
232 ;
233 ; write_serial: If serial output is enabled, write character on serial port
234 ; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0
235 ;
236 write_serial_displaymask:
237                 test byte [DisplayMask], 04h
238                 jz write_serial.end
239 write_serial:
240                 pushfd
241                 pushad
242                 mov bx,[SerialPort]
243                 and bx,bx
244                 je .noserial
245                 push ax
246                 mov ah,[FlowInput]
247 .waitspace:
248                 ; Wait for space in transmit register
249                 lea dx,[bx+5]                   ; DX -> LSR
250                 in al,dx
251                 test al,20h
252                 jz .waitspace
253
254                 ; Wait for input flow control
255                 inc dx                          ; DX -> MSR
256                 in al,dx
257                 and al,ah
258                 cmp al,ah
259                 jne .waitspace
260 .no_flow:
261
262                 xchg dx,bx                      ; DX -> THR
263                 pop ax
264                 slow_out dx,al                  ; Send data
265 .noserial:      popad
266                 popfd
267 .end:           ret
268
269 ;
270 ; write_serial_str: write_serial for strings
271 ; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0
272 ;
273 write_serial_str_displaymask:
274                 test byte [DisplayMask], 04h
275                 jz write_serial_str.end
276
277 write_serial_str:
278 .loop           lodsb
279                 and al,al
280                 jz .end
281                 call write_serial
282                 jmp short .loop
283 .end:           ret
284
285 ;
286 ; pollchar: check if we have an input character pending (ZF = 0)
287 ;
288 pollchar:
289                 pushad
290                 mov ah,11h              ; Poll keyboard
291                 int 16h
292                 jnz .done               ; Keyboard response
293                 mov dx,[SerialPort]
294                 and dx,dx
295                 jz .done                ; No serial port -> no input
296                 mov ax,[SerialTail]     ; Already-queued input?
297                 cli
298                 cmp ax,[SerialHead]
299                 jne .done_sti           ; If so, return ZF = 0
300                 add dx,5                ; DX -> LSR
301                 in al,dx
302                 test al,1               ; ZF = 0 if data pending
303                 jz .done_sti
304                 inc dx                  ; DX -> MSR
305                 mov ah,[FlowIgnore]     ; Required status bits
306                 in al,dx
307                 and al,ah
308                 cmp al,ah
309                 setne al
310                 dec al                  ; Set ZF = 0 if equal
311 .done_sti:      sti
312 .done:          popad
313                 ret
314
315 ;
316 ; getchar: Read a character from keyboard or serial port
317 ;
318 getchar.sti_again:
319                 sti
320 getchar:
321 .again:
322                 call do_idle
323                 mov ah,11h              ; Poll keyboard
324                 int 16h
325                 jnz .kbd                ; Keyboard input?
326                 mov bx,[SerialPort]
327                 and bx,bx
328                 jz .again
329                 mov ax,[SerialTail]
330                 cli
331                 cmp ax,[SerialHead]
332                 jne .serial_queued
333                 lea dx,[bx+5]           ; DX -> LSR
334                 in al,dx
335                 test al,1
336                 jz .sti_again
337                 inc dx                  ; DX -> MSR
338                 mov ah,[FlowIgnore]
339                 in al,dx
340                 and al,ah
341                 cmp al,ah
342                 jne .sti_again
343 .serial:        xor ah,ah               ; Avoid confusion
344                 mov dx,bx               ; Data port
345                 in al,dx                ; Read data
346                 sti
347                 jmp .done
348 .serial_queued:
349                 sti                     ; We already know we'll consume data
350                 xchg bx,ax
351                 push ds
352                 mov ax,aux_seg + (aux.serial >> 4)
353                 mov ds,ax
354                 mov al,[bx]
355                 pop ds
356                 inc bx
357                 and bx,serial_buf_size-1
358                 mov [SerialTail],bx
359                 jmp .done
360
361 .kbd:           mov ah,10h              ; Get keyboard input
362                 int 16h
363                 cmp al,0E0h
364                 jnz .not_ext
365                 xor al,al
366 .not_ext:
367                 and al,al
368                 jz .func_key
369                 mov bx,KbdMap           ; Convert character sets
370                 xlatb
371 .func_key:
372 .done:
373                 jmp reset_idle          ; Character received
374
375 %ifdef DEBUG_TRACERS
376 ;
377 ; debug hack to print a character with minimal code impact
378 ;
379 debug_tracer:   pushad
380                 pushfd
381                 mov bp,sp
382                 mov bx,[bp+9*4]         ; Get return address
383                 mov al,[cs:bx]          ; Get data byte
384                 inc word [bp+9*4]       ; Return to after data byte
385                 call writechr
386                 popfd
387                 popad
388                 ret
389 %endif  ; DEBUG_TRACERS
390
391                 section .data16
392 %if IS_ISOLINUX == 0                    ; Defined elsewhere for ISOLINUX
393 crlf_msg        db CR, LF
394 null_msg        db 0
395 %endif
396 crff_msg        db CR, FF, 0
397
398                 section .config
399                 ; This is a word to pc_setint16 can set it
400 DisplayCon      dw 01h                  ; Console display enabled
401
402 ScrollAttribute db 07h                  ; Grey on white (normal text color)
403
404                 section .bss16
405                 alignb 2
406 NextCharJump    resw 1                  ; Routine to interpret next print char
407 CursorDX        equ $
408 CursorCol       resb 1                  ; Cursor column for message file
409 CursorRow       resb 1                  ; Cursor row for message file
410 ScreenSize      equ $
411 VidCols         resb 1                  ; Columns on screen-1
412 VidRows         resb 1                  ; Rows on screen-1
413
414 ; Serial console stuff; don't put this in .config becasue we don't want
415 ; loading a new config file to undo this setting.
416                 section .data16
417                 alignz 4
418 SerialPort      dw 0                    ; Serial port base (or 0 for no serial port)
419 BaudDivisor     dw 115200/9600          ; Baud rate divisor
420 FlowControl     equ $
421 FlowOutput      db 0                    ; Outputs to assert for serial flow
422 FlowInput       db 0                    ; Input bits for serial flow
423 FlowIgnore      db 0                    ; Ignore input unless these bits set
424 FlowDummy       db 0                    ; Unused
425
426                 section .bss16
427 TextAttribute   resb 1                  ; Text attribute for message file
428 DisplayMask     resb 1                  ; Display modes mask
429
430                 section .text16
431 %include "serirq.inc"