More cleanups; try to get rid of the now-obsolete definition of
[profile/ivi/syslinux.git] / getc.inc
1 ;; $Id$
2 ;; -----------------------------------------------------------------------
3 ;;   
4 ;;   Copyright 1994-2002 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 ;; getc.inc
16 ;;
17 ;; Simple file handling library (open, getc, ungetc)
18 ;;
19
20 ;
21 ; open,getc:    Load a file a character at a time for parsing in a manner
22 ;               similar to the C library getc routine.  Only one simultaneous
23 ;               use is supported.  Note: "open" trashes the trackbuf.
24 ;
25 ;               open:   Input:  mangled filename in DS:DI
26 ;                       Output: ZF set on file not found or zero length
27 ;
28 ;               openfd: Input:  file handle in SI
29 ;                       Output: none
30 ;
31 ;               getc:   Output: CF set on end of file
32 ;                               Character loaded in AL
33 ;
34 open:
35                 call searchdir
36                 jz open_return
37 openfd:
38                 pushf
39                 mov [FBytes1],ax
40                 mov [FBytes2],dx
41                 mov eax,[FBytes]
42                 add eax,SECTOR_SIZE-1
43                 shr eax,SECTOR_SHIFT
44                 mov [FSectors],eax      ; Number of sectors
45                 mov [FNextClust],si     ; Cluster pointer
46                 mov ax,[EndOfGetCBuf]   ; Pointer at end of buffer ->
47                 mov [FPtr],ax           ;  nothing loaded yet
48                 popf                    ; Restore no ZF
49 open_return:    ret
50
51 getc:
52                 stc                     ; If we exit here -> EOF
53                 mov ecx,[FBytes]
54                 jecxz getc_ret
55                 mov si,[FPtr]
56                 cmp si,[EndOfGetCBuf]
57                 jb getc_loaded
58                 ; Buffer empty -- load another set
59                 mov ecx,[FSectors]
60                 cmp ecx,trackbufsize >> SECTOR_SHIFT
61                 jna getc_oksize
62                 mov ecx,trackbufsize >> SECTOR_SHIFT
63 getc_oksize:    sub [FSectors],ecx      ; Reduce remaining clusters
64                 mov si,[FNextClust]
65                 push es                 ; ES may be != DS, save old ES
66                 push ds
67                 pop es
68                 mov bx,getcbuf
69                 push bx
70                 call getfssec           ; Load a trackbuf full of data
71                 mov [FNextClust],si     ; Store new next pointer
72                 pop si                  ; SI -> newly loaded data
73                 pop es                  ; Restore ES
74 getc_loaded:    lodsb                   ; Load a byte, increment SI
75                 mov [FPtr],si           ; Update next byte pointer
76                 dec dword [FBytes]      ; Update bytes left counter
77                 clc                     ; Not EOF
78 getc_ret:       ret
79
80 ;
81 ; ungetc:       Push a character (in AL) back into the getc buffer
82 ;               Note: if more than one byte is pushed back, this may cause
83 ;               bytes to be written below the getc buffer boundary.  If there
84 ;               is a risk for this to occur, the getcbuf base address should
85 ;               be moved up.
86 ;
87 ungetc:
88                 mov si,[FPtr]
89                 dec si
90                 mov [si],al
91                 mov [FPtr],si
92                 inc dword [FBytes]
93                 ret
94
95 ;
96 ; skipspace:    Skip leading whitespace using "getc".  If we hit end-of-line
97 ;               or end-of-file, return with carry set; ZF = true of EOF
98 ;               ZF = false for EOLN; otherwise CF = ZF = 0.
99 ;
100 ;               Otherwise AL = first character after whitespace
101 ;
102 skipspace:
103 skipspace_loop: call getc
104                 jc skipspace_eof
105                 cmp al,1Ah                      ; DOS EOF
106                 je skipspace_eof
107                 cmp al,0Ah
108                 je skipspace_eoln
109                 cmp al,' '
110                 jbe skipspace_loop
111                 ret                             ; CF = ZF = 0
112 skipspace_eof:  cmp al,al                       ; Set ZF
113                 stc                             ; Set CF
114                 ret
115 skipspace_eoln: add al,0FFh                     ; Set CF, clear ZF
116                 ret
117
118 ;
119 ; getint:       Load an integer from the getc file.
120 ;               Return CF if error; otherwise return integer in EBX
121 ;
122 getint:
123                 mov di,NumBuf
124 gi_getnum:      cmp di,NumBufEnd        ; Last byte in NumBuf
125                 jae gi_loaded
126                 push di
127                 call getc
128                 pop di
129                 jc gi_loaded
130                 stosb
131                 cmp al,'-'
132                 jnb gi_getnum
133                 call ungetc             ; Unget non-numeric
134 gi_loaded:      mov byte [di],0
135                 mov si,NumBuf
136                 ; Fall through to parseint
137
138 ;
139 ; parseint:     Convert an integer to a number in EBX
140 ;               Get characters from string in DS:SI
141 ;               Return CF on error
142 ;               DS:SI points to first character after number
143 ;
144 ;               Syntaxes accepted: [-]dec, [-]0+oct, [-]0x+hex, val+K, val+M
145 ;
146 parseint:
147                 push eax
148                 push ecx
149                 push bp
150                 xor eax,eax             ; Current digit (keep eax == al)
151                 mov ebx,eax             ; Accumulator
152                 mov ecx,ebx             ; Base
153                 xor bp,bp               ; Used for negative flag
154 pi_begin:       lodsb
155                 cmp al,'-'
156                 jne pi_not_minus
157                 xor bp,1                ; Set unary minus flag
158                 jmp short pi_begin
159 pi_not_minus:
160                 cmp al,'0'
161                 jb pi_err
162                 je pi_octhex
163                 cmp al,'9'
164                 ja pi_err
165                 mov cl,10               ; Base = decimal
166                 jmp short pi_foundbase
167 pi_octhex:
168                 lodsb
169                 cmp al,'0'
170                 jb pi_km                ; Value is zero
171                 or al,20h               ; Downcase
172                 cmp al,'x'
173                 je pi_ishex
174                 cmp al,'7'
175                 ja pi_err
176                 mov cl,8                ; Base = octal
177                 jmp short pi_foundbase
178 pi_ishex:
179                 mov al,'0'              ; No numeric value accrued yet
180                 mov cl,16               ; Base = hex
181 pi_foundbase:
182                 call unhexchar
183                 jc pi_km                ; Not a (hex) digit
184                 cmp al,cl
185                 jae pi_km               ; Invalid for base
186                 imul ebx,ecx            ; Multiply accumulated by base
187                 add ebx,eax             ; Add current digit
188                 lodsb
189                 jmp short pi_foundbase
190 pi_km:
191                 dec si                  ; Back up to last non-numeric
192                 lodsb
193                 or al,20h
194                 cmp al,'k'
195                 je pi_isk
196                 cmp al,'m'
197                 je pi_ism
198                 dec si                  ; Back up
199 pi_fini:        and bp,bp
200                 jz pi_ret               ; CF=0!
201                 neg ebx                 ; Value was negative
202 pi_done:        clc
203 pi_ret:         pop bp
204                 pop ecx
205                 pop eax
206                 ret
207 pi_err:         stc
208                 jmp short pi_ret
209 pi_isk:         shl ebx,10              ; x 2^10
210                 jmp short pi_done
211 pi_ism:         shl ebx,20              ; x 2^20
212                 jmp short pi_done
213
214 ;
215 ; unhexchar:    Convert a hexadecimal digit in AL to the equivalent number;
216 ;               return CF=1 if not a hex digit
217 ;
218 unhexchar:
219                 cmp al,'0'
220                 jb uxc_ret              ; If failure, CF == 1 already
221                 cmp al,'9'
222                 ja uxc_1
223                 sub al,'0'              ; CF <- 0
224                 ret
225 uxc_1:          or al,20h               ; upper case -> lower case
226                 cmp al,'a'
227                 jb uxc_ret              ; If failure, CF == 1 already
228                 cmp al,'f'
229                 ja uxc_err
230                 sub al,'a'-10           ; CF <- 0
231                 ret
232 uxc_err:        stc
233 uxc_ret:        ret
234
235 ;
236 ;
237 ; getline:      Get a command line, converting control characters to spaces
238 ;               and collapsing streches to one; a space is appended to the
239 ;               end of the string, unless the line is empty.
240 ;               The line is terminated by ^J, ^Z or EOF and is written
241 ;               to ES:DI.  On return, DI points to first char after string.
242 ;               CF is set if we hit EOF.
243 ;
244 getline:
245                 call skipspace
246                 mov dl,1                ; Empty line -> empty string.
247                 jz gl_eof               ; eof
248                 jc gl_eoln              ; eoln
249                 call ungetc
250 gl_fillloop:    push dx
251                 push di
252                 call getc
253                 pop di
254                 pop dx
255                 jc gl_ret               ; CF set!
256                 cmp al,' '
257                 jna gl_ctrl
258                 xor dx,dx
259 gl_store:       stosb
260                 jmp short gl_fillloop
261 gl_ctrl:        cmp al,10
262                 je gl_ret               ; CF clear!
263                 cmp al,26
264                 je gl_eof
265                 and dl,dl
266                 jnz gl_fillloop         ; Ignore multiple spaces
267                 mov al,' '              ; Ctrl -> space
268                 inc dx
269                 jmp short gl_store
270 gl_eoln:        clc                     ; End of line is not end of file
271                 jmp short gl_ret
272 gl_eof:         stc
273 gl_ret:         pushf                   ; We want the last char to be space!
274                 and dl,dl
275                 jnz gl_xret
276                 mov al,' '
277                 stosb
278 gl_xret:        popf
279                 ret