2 ;; -----------------------------------------------------------------------
4 ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
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.
12 ;; -----------------------------------------------------------------------
17 ;; Simple file handling library (open, getc, ungetc)
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.
25 ; open: Input: mangled filename in DS:DI
26 ; Output: ZF set on file not found or zero length
28 ; openfd: Input: file handle in SI
31 ; getc: Output: CF set on end of file
32 ; Character loaded in AL
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
52 stc ; If we exit here -> EOF
58 ; Buffer empty -- load another set
60 cmp ecx,trackbufsize >> SECTOR_SHIFT
62 mov ecx,trackbufsize >> SECTOR_SHIFT
63 getc_oksize: sub [FSectors],ecx ; Reduce remaining clusters
65 push es ; ES may be != DS, save old ES
70 call getfssec ; Load a trackbuf full of data
71 mov [FNextClust],si ; Store new next pointer
72 pop si ; SI -> newly loaded data
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
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
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.
100 ; Otherwise AL = first character after whitespace
103 skipspace_loop: call getc
112 skipspace_eof: cmp al,al ; Set ZF
115 skipspace_eoln: add al,0FFh ; Set CF, clear ZF
119 ; getint: Load an integer from the getc file.
120 ; Return CF if error; otherwise return integer in EBX
124 gi_getnum: cmp di,NumBufEnd ; Last byte in NumBuf
133 call ungetc ; Unget non-numeric
134 gi_loaded: mov byte [di],0
136 ; Fall through to parseint
139 ; parseint: Convert an integer to a number in EBX
140 ; Get characters from string in DS:SI
142 ; DS:SI points to first character after number
144 ; Syntaxes accepted: [-]dec, [-]0+oct, [-]0x+hex, val+K, val+M
150 xor eax,eax ; Current digit (keep eax == al)
151 mov ebx,eax ; Accumulator
153 xor bp,bp ; Used for negative flag
157 xor bp,1 ; Set unary minus flag
165 mov cl,10 ; Base = decimal
166 jmp short pi_foundbase
170 jb pi_km ; Value is zero
176 mov cl,8 ; Base = octal
177 jmp short pi_foundbase
179 mov al,'0' ; No numeric value accrued yet
180 mov cl,16 ; Base = hex
183 jc pi_km ; Not a (hex) digit
185 jae pi_km ; Invalid for base
186 imul ebx,ecx ; Multiply accumulated by base
187 add ebx,eax ; Add current digit
189 jmp short pi_foundbase
191 dec si ; Back up to last non-numeric
201 neg ebx ; Value was negative
209 pi_isk: shl ebx,10 ; x 2^10
211 pi_ism: shl ebx,20 ; x 2^20
215 ; unhexchar: Convert a hexadecimal digit in AL to the equivalent number;
216 ; return CF=1 if not a hex digit
220 jb uxc_ret ; If failure, CF == 1 already
225 uxc_1: or al,20h ; upper case -> lower case
227 jb uxc_ret ; If failure, CF == 1 already
230 sub al,'a'-10 ; CF <- 0
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.
246 mov dl,1 ; Empty line -> empty string.
260 jmp short gl_fillloop
262 je gl_ret ; CF clear!
266 jnz gl_fillloop ; Ignore multiple spaces
267 mov al,' ' ; Ctrl -> space
270 gl_eoln: clc ; End of line is not end of file
273 gl_ret: pushf ; We want the last char to be space!