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