Annotation of /tags/mkinitrd-6_1_12/isolinux/getc.inc
Parent Directory | Revision Log
Revision 939 -
(hide annotations)
(download)
Tue Nov 17 21:24:51 2009 UTC (14 years, 10 months ago) by niro
File size: 7146 byte(s)
Tue Nov 17 21:24:51 2009 UTC (14 years, 10 months ago) by niro
File size: 7146 byte(s)
tagged 'mkinitrd-6_1_12'
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 |