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 ;; Bostom 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
46 mov [FClust],ax ; Number of clusters
47 mov [FNextClust],si ; Cluster pointer
48 mov ax,[EndOfGetCBuf] ; Pointer at end of buffer ->
49 mov [FPtr],ax ; nothing loaded yet
54 stc ; If we exit here -> EOF
60 ; Buffer empty -- load another set
65 getc_oksize: sub [FClust],cx ; Reduce remaining clusters
67 push es ; ES may be != DS, save old ES
72 call getfssec ; Load a trackbuf full of data
73 mov [FNextClust],si ; Store new next pointer
74 pop si ; SI -> newly loaded data
76 getc_loaded: lodsb ; Load a byte, increment SI
77 mov [FPtr],si ; Update next byte pointer
78 dec dword [FBytes] ; Update bytes left counter
83 ; ungetc: Push a character (in AL) back into the getc buffer
84 ; Note: if more than one byte is pushed back, this may cause
85 ; bytes to be written below the getc buffer boundary. If there
86 ; is a risk for this to occur, the getcbuf base address should
98 ; skipspace: Skip leading whitespace using "getc". If we hit end-of-line
99 ; or end-of-file, return with carry set; ZF = true of EOF
100 ; ZF = false for EOLN; otherwise CF = ZF = 0.
102 ; Otherwise AL = first character after whitespace
105 skipspace_loop: call getc
114 skipspace_eof: cmp al,al ; Set ZF
117 skipspace_eoln: add al,0FFh ; Set CF, clear ZF
121 ; getint: Load an integer from the getc file.
122 ; Return CF if error; otherwise return integer in EBX
126 gi_getnum: cmp di,NumBufEnd ; Last byte in NumBuf
135 call ungetc ; Unget non-numeric
136 gi_loaded: mov byte [di],0
138 ; Fall through to parseint
141 ; parseint: Convert an integer to a number in EBX
142 ; Get characters from string in DS:SI
144 ; DS:SI points to first character after number
146 ; Syntaxes accepted: [-]dec, [-]0+oct, [-]0x+hex, val+K, val+M
152 xor eax,eax ; Current digit (keep eax == al)
153 mov ebx,eax ; Accumulator
155 xor bp,bp ; Used for negative flag
159 xor bp,1 ; Set unary minus flag
167 mov cl,10 ; Base = decimal
168 jmp short pi_foundbase
172 jb pi_km ; Value is zero
178 mov cl,8 ; Base = octal
179 jmp short pi_foundbase
181 mov al,'0' ; No numeric value accrued yet
182 mov cl,16 ; Base = hex
185 jc pi_km ; Not a (hex) digit
187 jae pi_km ; Invalid for base
188 imul ebx,ecx ; Multiply accumulated by base
189 add ebx,eax ; Add current digit
191 jmp short pi_foundbase
193 dec si ; Back up to last non-numeric
203 neg ebx ; Value was negative
211 pi_isk: shl ebx,10 ; x 2^10
213 pi_ism: shl ebx,20 ; x 2^20
217 ; unhexchar: Convert a hexadecimal digit in AL to the equivalent number;
218 ; return CF=1 if not a hex digit
222 jb uxc_ret ; If failure, CF == 1 already
227 uxc_1: or al,20h ; upper case -> lower case
229 jb uxc_ret ; If failure, CF == 1 already
232 sub al,'a'-10 ; CF <- 0
239 ; getline: Get a command line, converting control characters to spaces
240 ; and collapsing streches to one; a space is appended to the
241 ; end of the string, unless the line is empty.
242 ; The line is terminated by ^J, ^Z or EOF and is written
243 ; to ES:DI. On return, DI points to first char after string.
244 ; CF is set if we hit EOF.
248 mov dl,1 ; Empty line -> empty string.
262 jmp short gl_fillloop
264 je gl_ret ; CF clear!
268 jnz gl_fillloop ; Ignore multiple spaces
269 mov al,' ' ; Ctrl -> space
272 gl_eoln: clc ; End of line is not end of file
275 gl_ret: pushf ; We want the last char to be space!