Magellan Linux

Contents of /trunk/mkinitrd-magellan/isolinux/getc.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File size: 7146 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 ;; $Id: getc.inc,v 1.1 2007-09-01 22:44:04 niro Exp $
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 openfd.ret
37 openfd:
38 pushf
39 mov [FBytes],ax
40 mov [FBytes+2],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 .ret: ret
50
51 getc:
52 stc ; If we exit here -> EOF
53 mov ecx,[FBytes]
54 jecxz .ret
55 mov si,[FPtr]
56 cmp si,[EndOfGetCBuf]
57 jb .loaded
58 ; Buffer empty -- load another set
59 mov ecx,[FSectors]
60 cmp ecx,trackbufsize >> SECTOR_SHIFT
61 jna .oksize
62 mov ecx,trackbufsize >> SECTOR_SHIFT
63 .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 .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 .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 .loop: call getc
104 jc .eof
105 cmp al,1Ah ; DOS EOF
106 je .eof
107 cmp al,0Ah
108 je .eoln
109 cmp al,' '
110 jbe .loop
111 ret ; CF = ZF = 0
112 .eof: cmp al,al ; Set ZF
113 stc ; Set CF
114 ret
115 .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 .getnum: cmp di,NumBufEnd ; Last byte in NumBuf
125 jae .loaded
126 push di
127 call getc
128 pop di
129 jc .loaded
130 stosb
131 cmp al,'-'
132 jnb .getnum
133 call ungetc ; Unget non-numeric
134 .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 .begin: lodsb
155 cmp al,'-'
156 jne .not_minus
157 xor bp,1 ; Set unary minus flag
158 jmp short .begin
159 .not_minus:
160 cmp al,'0'
161 jb .err
162 je .octhex
163 cmp al,'9'
164 ja .err
165 mov cl,10 ; Base = decimal
166 jmp short .foundbase
167 .octhex:
168 lodsb
169 cmp al,'0'
170 jb .km ; Value is zero
171 or al,20h ; Downcase
172 cmp al,'x'
173 je .ishex
174 cmp al,'7'
175 ja .err
176 mov cl,8 ; Base = octal
177 jmp short .foundbase
178 .ishex:
179 mov al,'0' ; No numeric value accrued yet
180 mov cl,16 ; Base = hex
181 .foundbase:
182 call unhexchar
183 jc .km ; Not a (hex) digit
184 cmp al,cl
185 jae .km ; Invalid for base
186 imul ebx,ecx ; Multiply accumulated by base
187 add ebx,eax ; Add current digit
188 lodsb
189 jmp short .foundbase
190 .km:
191 dec si ; Back up to last non-numeric
192 lodsb
193 or al,20h
194 cmp al,'k'
195 je .isk
196 cmp al,'m'
197 je .ism
198 dec si ; Back up
199 .fini: and bp,bp
200 jz .ret ; CF=0!
201 neg ebx ; Value was negative
202 .done: clc
203 .ret: pop bp
204 pop ecx
205 pop eax
206 ret
207 .err: stc
208 jmp short .ret
209 .isk: shl ebx,10 ; x 2^10
210 jmp short .done
211 .ism: shl ebx,20 ; x 2^20
212 jmp short .done
213
214
215 section .bss
216 alignb 4
217 NumBuf resb 15 ; Buffer to load number
218 NumBufEnd resb 1 ; Last byte in NumBuf
219 FBytes resd 1 ; Number of bytes left in getc file
220 FSectors resd 1 ; Number of sectors in getc file
221 FNextClust resw 1 ; Pointer to next cluster in d:o
222 FPtr resw 1 ; Pointer to next char in buffer
223
224 ;
225 ; unhexchar: Convert a hexadecimal digit in AL to the equivalent number;
226 ; return CF=1 if not a hex digit
227 ;
228 section .text
229 unhexchar:
230 cmp al,'0'
231 jb .ret ; If failure, CF == 1 already
232 cmp al,'9'
233 ja .notdigit
234 sub al,'0' ; CF <- 0
235 ret
236 .notdigit: or al,20h ; upper case -> lower case
237 cmp al,'a'
238 jb .ret ; If failure, CF == 1 already
239 cmp al,'f'
240 ja .err
241 sub al,'a'-10 ; CF <- 0
242 ret
243 .err: stc
244 .ret: ret
245
246 ;
247 ;
248 ; getline: Get a command line, converting control characters to spaces
249 ; and collapsing streches to one; a space is appended to the
250 ; end of the string, unless the line is empty.
251 ; The line is terminated by ^J, ^Z or EOF and is written
252 ; to ES:DI. On return, DI points to first char after string.
253 ; CF is set if we hit EOF.
254 ;
255 getline:
256 call skipspace
257 mov dl,1 ; Empty line -> empty string.
258 jz .eof ; eof
259 jc .eoln ; eoln
260 call ungetc
261 .fillloop: push dx
262 push di
263 call getc
264 pop di
265 pop dx
266 jc .ret ; CF set!
267 cmp al,' '
268 jna .ctrl
269 xor dx,dx
270 .store: stosb
271 jmp short .fillloop
272 .ctrl: cmp al,10
273 je .ret ; CF clear!
274 cmp al,26
275 je .eof
276 and dl,dl
277 jnz .fillloop ; Ignore multiple spaces
278 mov al,' ' ; Ctrl -> space
279 inc dx
280 jmp short .store
281 .eoln: clc ; End of line is not end of file
282 jmp short .ret
283 .eof: stc
284 .ret: pushf ; We want the last char to be space!
285 and dl,dl
286 jnz .xret
287 mov al,' '
288 stosb
289 .xret: popf
290 ret