Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide 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 niro 532 ;; $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