syslinux-3.08-2 sources from FC4
[bootcd.git] / syslinux / conio.inc
1 ;; $Id: conio.inc,v 1.12 2005/01/04 22:17:17 hpa Exp $
2 ;; -----------------------------------------------------------------------
3 ;;   
4 ;;   Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
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         - module-dependent
19 ;;   cwritestr, crlf            - writestr.inc
20 ;;   writehex*                  - writehex.inc
21 ;;
22
23 ;
24 ; loadkeys:     Load a LILO-style keymap; SI and DX:AX set by searchdir
25 ;
26                 section .text
27
28 loadkeys:
29                 and dx,dx                       ; Should be 256 bytes exactly
30                 jne loadkeys_ret
31                 cmp ax,256
32                 jne loadkeys_ret
33
34                 mov bx,trackbuf
35                 mov cx,1                        ; 1 cluster should be >= 256 bytes
36                 call getfssec
37
38                 mov si,trackbuf
39                 mov di,KbdMap
40                 mov cx,256 >> 2
41                 rep movsd
42
43 loadkeys_ret:   ret
44                 
45 ;
46 ; get_msg_file: Load a text file and write its contents to the screen,
47 ;               interpreting color codes.  Is called with SI and DX:AX
48 ;               set by routine searchdir
49 ;
50 get_msg_file:
51                 push es
52                 shl edx,16                      ; EDX <- DX:AX (length of file)
53                 mov dx,ax
54                 mov ax,xfer_buf_seg             ; Use for temporary storage
55                 mov es,ax
56
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 get_msg_chunk:  push edx                        ; EDX = length of file
62                 xor bx,bx                       ; == xbs_textbuf
63                 mov cx,[BufSafe]
64                 call getfssec
65                 pop edx
66                 push si                         ; Save current cluster
67                 xor si,si                       ; == xbs_textbuf
68                 mov cx,[BufSafeBytes]           ; Number of bytes left in chunk
69 print_msg_file:
70                 push cx
71                 push edx
72                 es lodsb
73                 cmp al,1Ah                      ; DOS EOF?
74                 je msg_done_pop
75                 push si
76                 mov cl,[UsingVGA]
77                 inc cl                          ; 01h = text mode, 02h = graphics
78                 call [NextCharJump]             ; Do what shall be done
79                 pop si
80                 pop edx
81                 pop cx
82                 dec edx
83                 jz msg_done
84                 loop print_msg_file
85                 pop si
86                 jmp short get_msg_chunk
87 msg_done_pop:
88                 add sp,byte 6                   ; Drop pushed EDX, CX
89 msg_done:
90                 pop si
91                 pop es
92                 ret
93 msg_putchar:                                    ; Normal character
94                 cmp al,0Fh                      ; ^O = color code follows
95                 je msg_ctrl_o
96                 cmp al,0Dh                      ; Ignore <CR>
97                 je msg_ignore
98                 cmp al,0Ah                      ; <LF> = newline
99                 je msg_newline
100                 cmp al,0Ch                      ; <FF> = clear screen
101                 je msg_formfeed
102                 cmp al,19h                      ; <EM> = return to text mode
103                 je msg_novga
104                 cmp al,18h                      ; <CAN> = VGA filename follows
105                 je msg_vga
106                 jnb .not_modectl
107                 cmp al,10h                      ; 10h to 17h are mode controls
108                 jae msg_modectl
109 .not_modectl:
110
111 msg_normal:     call write_serial_displaymask   ; Write to serial port
112                 test [DisplayMask],cl
113                 jz msg_ignore                   ; Not screen
114                 test byte [DisplayCon],01h
115                 jz msg_ignore
116                 mov bl,[TextAttribute]
117                 mov bh,[BIOS_page]
118                 mov ah,09h                      ; Write character/attribute
119                 mov cx,1                        ; One character only
120                 int 10h                         ; Write to screen
121                 mov al,[CursorCol]
122                 inc ax
123                 cmp al,[VidCols]
124                 ja msg_line_wrap                ; Screen wraparound
125                 mov [CursorCol],al
126
127 msg_gotoxy:     mov bh,[BIOS_page]
128                 mov dx,[CursorDX]
129                 mov ah,02h                      ; Set cursor position
130                 int 10h
131 msg_ignore:     ret
132 msg_ctrl_o:                                     ; ^O = color code follows
133                 mov word [NextCharJump],msg_setbg
134                 ret
135 msg_newline:                                    ; Newline char or end of line
136                 mov si,crlf_msg
137                 call write_serial_str_displaymask
138 msg_line_wrap:                                  ; Screen wraparound
139                 test [DisplayMask],cl
140                 jz msg_ignore
141                 mov byte [CursorCol],0
142                 mov al,[CursorRow]
143                 inc ax
144                 cmp al,[VidRows]
145                 ja msg_scroll
146                 mov [CursorRow],al
147                 jmp short msg_gotoxy
148 msg_scroll:     xor cx,cx                       ; Upper left hand corner
149                 mov dx,[ScreenSize]
150                 mov [CursorRow],dh              ; New cursor at the bottom
151                 mov bh,[ScrollAttribute]
152                 mov ax,0601h                    ; Scroll up one line
153                 int 10h
154                 jmp short msg_gotoxy
155 msg_formfeed:                                   ; Form feed character
156                 mov si,crff_msg
157                 call write_serial_str_displaymask
158                 test [DisplayMask],cl
159                 jz msg_ignore
160                 xor cx,cx
161                 mov [CursorDX],cx               ; Upper lefthand corner
162                 mov dx,[ScreenSize]
163                 mov bh,[TextAttribute]
164                 mov ax,0600h                    ; Clear screen region
165                 int 10h
166                 jmp msg_gotoxy
167 msg_setbg:                                      ; Color background character
168                 call unhexchar
169                 jc msg_color_bad
170                 shl al,4
171                 test [DisplayMask],cl
172                 jz .dontset
173                 mov [TextAttribute],al
174 .dontset:
175                 mov word [NextCharJump],msg_setfg
176                 ret
177 msg_setfg:                                      ; Color foreground character
178                 call unhexchar
179                 jc msg_color_bad
180                 test [DisplayMask],cl
181                 jz .dontset
182                 or [TextAttribute],al           ; setbg set foreground to 0
183 .dontset:
184                 jmp short msg_putcharnext
185 msg_vga:
186                 mov word [NextCharJump],msg_filename
187                 mov di, VGAFileBuf
188                 jmp short msg_setvgafileptr
189
190 msg_color_bad:
191                 mov byte [TextAttribute],07h    ; Default attribute
192 msg_putcharnext:
193                 mov word [NextCharJump],msg_putchar
194                 ret
195
196 msg_filename:                                   ; Getting VGA filename
197                 cmp al,0Ah                      ; <LF> = end of filename
198                 je msg_viewimage
199                 cmp al,' '
200                 jbe msg_ret                     ; Ignore space/control char
201                 mov di,[VGAFilePtr]
202                 cmp di,VGAFileBufEnd
203                 jnb msg_ret
204                 mov [di],al                     ; Can't use stosb (DS:)
205                 inc di
206 msg_setvgafileptr:
207                 mov [VGAFilePtr],di
208 msg_ret:        ret
209
210 msg_novga:
211                 call vgaclearmode
212                 jmp short msg_initvars
213
214 msg_viewimage:
215                 push es
216                 push ds
217                 pop es                          ; ES <- DS
218                 mov si,VGAFileBuf
219                 mov di,VGAFileMBuf
220                 push di
221                 call mangle_name
222                 pop di
223                 call searchdir
224                 pop es
225                 jz msg_putcharnext              ; Not there
226                 call vgadisplayfile
227                 ; Fall through
228
229                 ; Subroutine to initialize variables, also needed
230                 ; after loading a graphics file
231 msg_initvars:
232                 pusha
233                 mov bh,[BIOS_page]
234                 mov ah,03h                      ; Read cursor position
235                 int 10h
236                 mov [CursorDX],dx
237                 popa
238                 jmp short msg_putcharnext       ; Initialize state machine
239
240 msg_modectl:
241                 and al,07h
242                 mov [DisplayMask],al
243                 jmp short msg_putcharnext
244
245 ;
246 ; write_serial: If serial output is enabled, write character on serial port
247 ; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0
248 ;
249 write_serial_displaymask:
250                 test byte [DisplayMask], 04h
251                 jz write_serial.end
252 write_serial:
253                 pushfd
254                 pushad
255                 mov bx,[SerialPort]
256                 and bx,bx
257                 je .noserial
258                 push ax
259                 mov ah,[FlowInput]
260 .waitspace:
261                 ; Wait for space in transmit register
262                 lea dx,[bx+5]                   ; DX -> LSR
263                 in al,dx
264                 test al,20h
265                 jz .waitspace
266
267                 ; Wait for input flow control
268                 inc dx                          ; DX -> MSR
269                 in al,dx
270                 and al,ah
271                 cmp al,ah
272                 jne .waitspace  
273 .no_flow:               
274
275                 xchg dx,bx                      ; DX -> THR
276                 pop ax
277                 call slow_out                   ; Send data
278 .noserial:      popad
279                 popfd
280 .end:           ret
281
282 ;
283 ; write_serial_str: write_serial for strings
284 ; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0
285 ;
286 write_serial_str_displaymask:
287                 test byte [DisplayMask], 04h
288                 jz write_serial_str.end
289
290 write_serial_str:
291 .loop           lodsb
292                 and al,al
293                 jz .end
294                 call write_serial
295                 jmp short .loop
296 .end:           ret
297
298 ;
299 ; pollchar: check if we have an input character pending (ZF = 0)
300 ;
301 pollchar:
302                 pushad
303                 mov ah,11h              ; Poll keyboard
304                 int 16h
305                 jnz .done               ; Keyboard response
306                 mov dx,[SerialPort]
307                 and dx,dx
308                 jz .done                ; No serial port -> no input
309                 add dx,byte 5           ; DX -> LSR
310                 in al,dx
311                 test al,1               ; ZF = 0 if data pending
312                 jz .done
313                 inc dx                  ; DX -> MSR
314                 mov ah,[FlowIgnore]     ; Required status bits
315                 in al,dx
316                 and al,ah
317                 cmp al,ah
318                 setne al
319                 dec al                  ; Set ZF = 0 if equal
320 .done:          popad
321                 ret
322
323 ;
324 ; getchar: Read a character from keyboard or serial port
325 ;
326 getchar:
327                 RESET_IDLE
328 .again:
329                 DO_IDLE
330                 mov ah,11h              ; Poll keyboard
331                 int 16h
332                 jnz .kbd                ; Keyboard input?
333                 mov bx,[SerialPort]
334                 and bx,bx
335                 jz .again
336                 lea dx,[bx+5]           ; DX -> LSR
337                 in al,dx
338                 test al,1
339                 jz .again
340                 inc dx                  ; DX -> MSR
341                 mov ah,[FlowIgnore]
342                 in al,dx
343                 and al,ah
344                 cmp al,ah
345                 jne .again
346 .serial:        xor ah,ah               ; Avoid confusion
347                 xchg dx,bx              ; Data port
348                 in al,dx
349                 ret
350 .kbd:           mov ah,10h              ; Get keyboard input
351                 int 16h
352                 cmp al,0E0h
353                 jnz .not_ext
354                 xor al,al
355 .not_ext:
356                 and al,al
357                 jz .func_key
358                 mov bx,KbdMap           ; Convert character sets
359                 xlatb
360 .func_key:      ret
361
362 %ifdef DEBUG_TRACERS
363 ;
364 ; debug hack to print a character with minimal code impact
365 ;
366 debug_tracer:   pushad
367                 pushfd
368                 mov bp,sp
369                 mov bx,[bp+9*4]         ; Get return address
370                 mov al,[cs:bx]          ; Get data byte
371                 inc word [bp+9*4]       ; Return to after data byte
372                 call writechr
373                 popfd
374                 popad
375                 ret
376 %endif  ; DEBUG_TRACERS
377
378                 section .data
379                 ; This is a word to pc_setint16 can set it
380 DisplayCon      dw 01h                  ; Console display enabled
381
382 ScrollAttribute db 07h                  ; Grey on white (normal text color)
383
384                 section .bss
385                 alignb 2
386 NextCharJump    resw 1                  ; Routine to interpret next print char
387 CursorDX        equ $
388 CursorCol       resb 1                  ; Cursor column for message file
389 CursorRow       resb 1                  ; Cursor row for message file
390 ScreenSize      equ $
391 VidCols         resb 1                  ; Columns on screen-1
392 VidRows         resb 1                  ; Rows on screen-1
393
394 ; Serial console stuff...
395 BaudDivisor     resw 1                  ; Baud rate divisor
396 FlowControl     equ $
397 FlowOutput      resb 1                  ; Outputs to assert for serial flow
398 FlowInput       resb 1                  ; Input bits for serial flow
399 FlowIgnore      resb 1                  ; Ignore input unless these bits set
400
401 TextAttribute   resb 1                  ; Text attribute for message file
402 DisplayMask     resb 1                  ; Display modes mask