Contents of /tags/mkinitrd-6_1_1/isolinux/getc.inc
Parent Directory | Revision Log
Revision 841 -
(show annotations)
(download)
Mon May 4 16:31:54 2009 UTC (15 years, 4 months ago) by niro
File size: 7146 byte(s)
Mon May 4 16:31:54 2009 UTC (15 years, 4 months ago) by niro
File size: 7146 byte(s)
tagged 'mkinitrd-6_1_1'
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 |