rev |
line source |
pascal@19515
|
1 ;***************************************************************
|
pascal@19515
|
2 ;****** This file is distributed under GPL
|
pascal@19515
|
3 ;***************************************************************
|
pascal@19515
|
4 ideal
|
pascal@19515
|
5 %crefref
|
pascal@19515
|
6 %noincl
|
pascal@19515
|
7 %nomacs
|
pascal@19515
|
8 p386
|
pascal@19515
|
9
|
pascal@19515
|
10 group DGROUP _TEXT,_DATA,_BSS
|
pascal@19515
|
11 assume cs:DGROUP,ds:DGROUP
|
pascal@19515
|
12
|
pascal@19515
|
13 segment _DATA byte public use16 'DATA'
|
pascal@19515
|
14
|
pascal@19515
|
15 msg_hang db "High mem corrupted - not exiting to DOS",0
|
pascal@19515
|
16 global _vcpi_alloc_err:byte
|
pascal@19515
|
17 _vcpi_alloc_err db "vcpi "
|
pascal@19515
|
18 msg_malloc db "malloc() failure",0
|
pascal@19515
|
19 msg_crlf db 13,10,0
|
pascal@19515
|
20
|
pascal@19515
|
21 ends _DATA
|
pascal@19515
|
22
|
pascal@19515
|
23 segment _BSS byte public use16 'BSS'
|
pascal@19515
|
24
|
pascal@19515
|
25 global _heap_top:word
|
pascal@19515
|
26 _heap_top dw ?
|
pascal@19515
|
27 global _no_exit:byte
|
pascal@19515
|
28 _no_exit db ?
|
pascal@19515
|
29 filecnt db ? ; in fact 0 minus file count...
|
pascal@19515
|
30 nextfilename dw ?
|
pascal@19515
|
31
|
pascal@19515
|
32 ends _BSS
|
pascal@19515
|
33
|
pascal@19515
|
34 segment _TEXT byte public use16 'CODE'
|
pascal@19515
|
35
|
pascal@19515
|
36 ;***************************************************************
|
pascal@19515
|
37 ;void puts(const char* s):
|
pascal@19515
|
38 ;void putsz(const char* s):
|
pascal@19515
|
39 ;***************************************************************
|
pascal@19515
|
40 global _puts:near
|
pascal@19515
|
41 proc _puts near
|
pascal@19515
|
42
|
pascal@19515
|
43 pop ax ;caller return address
|
pascal@19515
|
44 pop bx ; s
|
pascal@19515
|
45 push bx
|
pascal@19515
|
46 push ax
|
pascal@19515
|
47 global puts:near ; puts(bx)
|
pascal@19515
|
48 puts:
|
pascal@19515
|
49 call putsz
|
pascal@19515
|
50 mov bx,offset msg_crlf
|
pascal@19515
|
51 jmp putsz
|
pascal@19515
|
52
|
pascal@19515
|
53 global _putsz:near
|
pascal@19515
|
54 _putsz:
|
pascal@19515
|
55 pop ax ;caller return address
|
pascal@19515
|
56 pop bx ; s
|
pascal@19515
|
57 push bx
|
pascal@19515
|
58 push ax
|
pascal@19515
|
59 global putsz:near ; putsz(bx)
|
pascal@19515
|
60 putsz:
|
pascal@19515
|
61 push bx
|
pascal@19515
|
62 call strlen
|
pascal@19515
|
63 pop dx
|
pascal@19515
|
64 xchg ax,cx
|
pascal@19515
|
65 mov bx,1
|
pascal@19515
|
66 mov ah,40h
|
pascal@19515
|
67 jmp dos
|
pascal@19515
|
68
|
pascal@19515
|
69 endp _puts
|
pascal@19515
|
70
|
pascal@19515
|
71
|
pascal@19515
|
72 ;***************************************************************
|
pascal@19515
|
73 ;int open(const char* name, int flags);
|
pascal@19515
|
74 ;***************************************************************
|
pascal@19515
|
75 global _open:near
|
pascal@19515
|
76 proc _open near
|
pascal@19515
|
77
|
pascal@19515
|
78 pop cx ;caller return address
|
pascal@19515
|
79 pop bx ; name
|
pascal@19515
|
80 pop ax ; flags
|
pascal@19515
|
81 push ax
|
pascal@19515
|
82 push bx
|
pascal@19515
|
83 push cx
|
pascal@19515
|
84 global open:near ; open(bx,al)
|
pascal@19515
|
85 open:
|
pascal@19515
|
86 mov dx,bx
|
pascal@19515
|
87 mov ah,3dh
|
pascal@19515
|
88 dos:
|
pascal@19515
|
89 int 21h
|
pascal@19515
|
90 jnc doret
|
pascal@19515
|
91 fail:
|
pascal@19515
|
92 sbb ax,ax ; ax=-1 CF
|
pascal@19515
|
93 cwd
|
pascal@19515
|
94 doret:
|
pascal@19515
|
95 ifndef NO386
|
pascal@19515
|
96 push dx
|
pascal@19515
|
97 push ax
|
pascal@19515
|
98 pop eax
|
pascal@19515
|
99 endif
|
pascal@19515
|
100 ret
|
pascal@19515
|
101
|
pascal@19515
|
102 endp _open
|
pascal@19515
|
103
|
pascal@19515
|
104
|
pascal@19515
|
105 ;***************************************************************
|
pascal@19515
|
106 ;int close(int fd);
|
pascal@19515
|
107 ;***************************************************************
|
pascal@19515
|
108 global _close:near
|
pascal@19515
|
109 proc _close near
|
pascal@19515
|
110
|
pascal@19515
|
111 pop ax ;caller return address
|
pascal@19515
|
112 pop bx ; fd
|
pascal@19515
|
113 push bx
|
pascal@19515
|
114 push ax
|
pascal@19515
|
115 global close:near ; close(bx)
|
pascal@19515
|
116 close:
|
pascal@19515
|
117 mov ah,3Eh
|
pascal@19515
|
118 or bx,bx
|
pascal@19515
|
119 jnz dos
|
pascal@19515
|
120 ret
|
pascal@19515
|
121
|
pascal@19515
|
122 endp _close
|
pascal@19515
|
123
|
pascal@19515
|
124
|
pascal@19515
|
125 ;***************************************************************
|
pascal@19515
|
126 ;int read(int fd, void* data, int sz);
|
pascal@19515
|
127 ;***************************************************************
|
pascal@19515
|
128 global _read:near
|
pascal@19515
|
129 proc _read near
|
pascal@19515
|
130
|
pascal@19515
|
131 mov ah,3fh
|
pascal@19515
|
132 rwio:
|
pascal@19515
|
133 ifndef NO386
|
pascal@19515
|
134 pop dx ;caller return address
|
pascal@19515
|
135 pop ebx ; fd & data
|
pascal@19515
|
136 pop cx ; sz
|
pascal@19515
|
137 push cx
|
pascal@19515
|
138 push ebx
|
pascal@19515
|
139 push dx
|
pascal@19515
|
140 else
|
pascal@19515
|
141 mov bx,sp
|
pascal@19515
|
142 mov cx,[bx+6]
|
pascal@19515
|
143 mov dx,[bx+4]
|
pascal@19515
|
144 mov bx,[bx+2]
|
pascal@19515
|
145 endif
|
pascal@19515
|
146 clc
|
pascal@19515
|
147 jcxz fail
|
pascal@19515
|
148 rwioz:
|
pascal@19515
|
149 ifndef NO386
|
pascal@19515
|
150 push ebx
|
pascal@19515
|
151 pop bx
|
pascal@19515
|
152 pop dx
|
pascal@19515
|
153 endif
|
pascal@19515
|
154 jmp dos
|
pascal@19515
|
155
|
pascal@19515
|
156 endp _read
|
pascal@19515
|
157
|
pascal@19515
|
158
|
pascal@19515
|
159 ;***************************************************************
|
pascal@19515
|
160 ;int write(int fd, const void* data, int sz);
|
pascal@19515
|
161 ;***************************************************************
|
pascal@19515
|
162 global _write:near
|
pascal@19515
|
163 proc _write near
|
pascal@19515
|
164
|
pascal@19515
|
165 mov ah,40h
|
pascal@19515
|
166 jmp rwio
|
pascal@19515
|
167
|
pascal@19515
|
168 endp _write
|
pascal@19515
|
169
|
pascal@19515
|
170
|
pascal@19515
|
171 ;***************************************************************
|
pascal@19515
|
172 ;long lseek(int fd, long sz, int dir);
|
pascal@19515
|
173 ;long rewind(int fd);
|
pascal@19515
|
174 ;***************************************************************
|
pascal@19515
|
175 global _lseek:near
|
pascal@19515
|
176 proc _lseek near
|
pascal@19515
|
177
|
pascal@19515
|
178 ifndef NO386
|
pascal@19515
|
179 pop ax ;caller return address
|
pascal@19515
|
180 pop bx ; fd
|
pascal@19515
|
181 pop ecx ; sz
|
pascal@19515
|
182 pop dx ; dir
|
pascal@19515
|
183 push dx
|
pascal@19515
|
184 push ecx
|
pascal@19515
|
185 push bx
|
pascal@19515
|
186 push ax
|
pascal@19515
|
187 else
|
pascal@19515
|
188 mov bx,sp
|
pascal@19515
|
189 mov dx,[bx+8]
|
pascal@19515
|
190 mov cx,[bx+6]
|
pascal@19515
|
191 mov ax,[bx+4]
|
pascal@19515
|
192 mov bx,[bx+2]
|
pascal@19515
|
193 endif
|
pascal@19515
|
194 lseek:
|
pascal@19515
|
195 xchg ax,dx ; dir
|
pascal@19515
|
196 mov ah,42h
|
pascal@19515
|
197 ifndef NO386
|
pascal@19515
|
198 push ecx
|
pascal@19515
|
199 pop dx
|
pascal@19515
|
200 pop cx
|
pascal@19515
|
201 endif
|
pascal@19515
|
202 jmp dos
|
pascal@19515
|
203
|
pascal@19515
|
204 global _rewind:near
|
pascal@19515
|
205 _rewind:
|
pascal@19515
|
206 pop ax ;caller return address
|
pascal@19515
|
207 pop bx ; fd
|
pascal@19515
|
208 push bx
|
pascal@19515
|
209 push ax
|
pascal@19515
|
210 rewind:
|
pascal@19515
|
211 ifndef NO386
|
pascal@19515
|
212 xor ecx,ecx
|
pascal@19515
|
213 xor dx,dx
|
pascal@19515
|
214 else
|
pascal@19515
|
215 xor ax,ax
|
pascal@19515
|
216 xor cx,cx
|
pascal@19515
|
217 cwd
|
pascal@19515
|
218 endif
|
pascal@19515
|
219 jmp lseek
|
pascal@19515
|
220
|
pascal@19515
|
221 endp _lseek
|
pascal@19515
|
222
|
pascal@19515
|
223
|
pascal@19515
|
224 ;***************************************************************
|
pascal@19515
|
225 ;int strlen(const char* s);
|
pascal@19515
|
226 ;***************************************************************
|
pascal@19515
|
227 global _strlen:near
|
pascal@19515
|
228 proc _strlen near
|
pascal@19515
|
229
|
pascal@19515
|
230 pop ax ;caller return address
|
pascal@19515
|
231 pop bx ; s
|
pascal@19515
|
232 push bx
|
pascal@19515
|
233 push ax
|
pascal@19515
|
234 global strlen:near ; strlen(bx)
|
pascal@19515
|
235 strlen:
|
pascal@19515
|
236 mov cx,bx
|
pascal@19515
|
237 jcxz @@end
|
pascal@19515
|
238 dec bx
|
pascal@19515
|
239 @@lenlp:
|
pascal@19515
|
240 inc bx
|
pascal@19515
|
241 cmp [byte bx],0
|
pascal@19515
|
242 jne @@lenlp
|
pascal@19515
|
243 sub bx,cx
|
pascal@19515
|
244 @@end:
|
pascal@19515
|
245 xchg ax,bx
|
pascal@19515
|
246 ret
|
pascal@19515
|
247
|
pascal@19515
|
248 endp _strlen
|
pascal@19515
|
249
|
pascal@19515
|
250
|
pascal@19515
|
251 ;***************************************************************
|
pascal@19515
|
252 ;int strhead(const char* a,const char* b);
|
pascal@19515
|
253 ;***************************************************************
|
pascal@19515
|
254 global _strhead:near
|
pascal@19515
|
255 proc _strhead near
|
pascal@19515
|
256
|
pascal@19515
|
257 pop cx ;caller return address
|
pascal@19515
|
258 pop ax ; a
|
pascal@19515
|
259 pop bx ; b
|
pascal@19515
|
260 push bx
|
pascal@19515
|
261 push ax
|
pascal@19515
|
262 push cx
|
pascal@19515
|
263 @@loop:
|
pascal@19515
|
264 mov cl,[bx] ; cl = *b++
|
pascal@19515
|
265 inc bx
|
pascal@19515
|
266 or cl,cl ; clear C
|
pascal@19515
|
267 jz fail ; return 0
|
pascal@19515
|
268 xchg ax,bx
|
pascal@19515
|
269 xor cl,[bx] ; cl -= *a++
|
pascal@19515
|
270 and cl,0dfh ; case insensitive
|
pascal@19515
|
271 stc
|
pascal@19515
|
272 jnz fail ; return -1
|
pascal@19515
|
273 inc bx
|
pascal@19515
|
274 xchg ax,bx
|
pascal@19515
|
275 jmp @@loop
|
pascal@19515
|
276
|
pascal@19515
|
277 endp _strhead
|
pascal@19515
|
278
|
pascal@19515
|
279
|
pascal@19515
|
280 ;***************************************************************
|
pascal@19515
|
281 ;char* malloc_or_die(unsigned size);
|
pascal@19515
|
282 ;***************************************************************
|
pascal@19515
|
283 global _malloc_or_die:near
|
pascal@19515
|
284 proc _malloc_or_die near
|
pascal@19515
|
285
|
pascal@19515
|
286 pop ax ;caller return address
|
pascal@19515
|
287 pop cx ; size
|
pascal@19515
|
288 push cx
|
pascal@19515
|
289 push ax
|
pascal@19515
|
290 global malloc_or_die:near ; malloc_or_die(cx)
|
pascal@19515
|
291 malloc_or_die:
|
pascal@19515
|
292 call malloc
|
pascal@19515
|
293 jz _diez
|
pascal@19515
|
294 ret
|
pascal@19515
|
295
|
pascal@19515
|
296 endp _malloc_or_die
|
pascal@19515
|
297
|
pascal@19515
|
298
|
pascal@19515
|
299 ;***************************************************************
|
pascal@19515
|
300 ;int die(const char* msg);
|
pascal@19515
|
301 ;int diez();
|
pascal@19515
|
302 ;int abort();
|
pascal@19515
|
303 ;***************************************************************
|
pascal@19515
|
304 global _die:near
|
pascal@19515
|
305 proc _die near
|
pascal@19515
|
306
|
pascal@19515
|
307 pop ax ;caller return address
|
pascal@19515
|
308 pop bx ; s
|
pascal@19515
|
309 push bx
|
pascal@19515
|
310 push ax
|
pascal@19515
|
311 global die:near ; die(bx)
|
pascal@19515
|
312 die:
|
pascal@19515
|
313 call puts
|
pascal@19515
|
314 global _diez:near
|
pascal@19515
|
315 _diez:
|
pascal@19515
|
316 mov al,[_no_exit]
|
pascal@19515
|
317 cmp al,0
|
pascal@19515
|
318 jne @@hang
|
pascal@19515
|
319 extrn exit:near
|
pascal@19515
|
320 inc ax
|
pascal@19515
|
321 jmp near exit
|
pascal@19515
|
322 @@hang:
|
pascal@19515
|
323 mov bx, offset msg_hang
|
pascal@19515
|
324 call puts
|
pascal@19515
|
325 global _abort:near
|
pascal@19515
|
326 _abort:
|
pascal@19515
|
327 cli
|
pascal@19515
|
328 @@stop:
|
pascal@19515
|
329 hlt
|
pascal@19515
|
330 jmp @@stop
|
pascal@19515
|
331
|
pascal@19515
|
332 endp _die
|
pascal@19515
|
333
|
pascal@19515
|
334
|
pascal@19515
|
335 ;***************************************************************
|
pascal@19515
|
336 ;void next_chunk(struct image_himem *m);
|
pascal@19515
|
337 ;***************************************************************
|
pascal@19515
|
338 proc _next_chunk near
|
pascal@19515
|
339
|
pascal@19515
|
340 pop bx
|
pascal@19515
|
341 pop ax
|
pascal@19515
|
342 push ax
|
pascal@19515
|
343 push bx
|
pascal@19515
|
344 push di
|
pascal@19515
|
345 xchg ax,di
|
pascal@19515
|
346 mov bx,[di] ; m->fd
|
pascal@19515
|
347 call close
|
pascal@19515
|
348 ifndef NO386
|
pascal@19515
|
349 xor eax,eax
|
pascal@19515
|
350 else
|
pascal@19515
|
351 xor ax,ax
|
pascal@19515
|
352 endif
|
pascal@19515
|
353 cwd
|
pascal@19515
|
354 mov [di],ax ; m->fd
|
pascal@19515
|
355 mov bx,[di+28] ; m->state
|
pascal@19515
|
356 cmp al,[bx] ; ""
|
pascal@19515
|
357 jz @@end
|
pascal@19515
|
358 push si
|
pascal@19515
|
359 mov si,bx
|
pascal@19515
|
360 @@scan:
|
pascal@19515
|
361 lodsb
|
pascal@19515
|
362 mov cx,si
|
pascal@19515
|
363 cmp al,','
|
pascal@19515
|
364 jz @@eos
|
pascal@19515
|
365 cmp al,0
|
pascal@19515
|
366 jnz @@scan
|
pascal@19515
|
367 dec cx
|
pascal@19515
|
368 @@eos:
|
pascal@19515
|
369 mov [di+28],cx ; m->state
|
pascal@19515
|
370 dec si
|
pascal@19515
|
371 push [word si]
|
pascal@19515
|
372 mov [byte si],dl ; set temp eos
|
pascal@19515
|
373 xchg ax,dx ; O_RDONLY
|
pascal@19515
|
374 call open
|
pascal@19515
|
375 pop [word si] ; restore string
|
pascal@19515
|
376 pop si
|
pascal@19515
|
377 jc @@die
|
pascal@19515
|
378 mov [di],ax ; m->fd
|
pascal@19515
|
379 mov dx,2 ; SEEK_END
|
pascal@19515
|
380 xchg ax,bx
|
pascal@19515
|
381 ifndef NO386
|
pascal@19515
|
382 xor ecx,ecx
|
pascal@19515
|
383 else
|
pascal@19515
|
384 xor ax,ax
|
pascal@19515
|
385 xor cx,cx
|
pascal@19515
|
386 endif
|
pascal@19515
|
387 call lseek
|
pascal@19515
|
388 @@die:
|
pascal@19515
|
389 mov bx,[di+20] ; m->errmsg
|
pascal@19515
|
390 jc die
|
pascal@19515
|
391 mov bx,[di] ; m->fd
|
pascal@19515
|
392 ifndef NO386
|
pascal@19515
|
393 push eax
|
pascal@19515
|
394 call rewind
|
pascal@19515
|
395 pop eax
|
pascal@19515
|
396 @@end:
|
pascal@19515
|
397 mov [di+22],eax ; m->chunk_size
|
pascal@19515
|
398 else
|
pascal@19515
|
399 push ax
|
pascal@19515
|
400 push dx
|
pascal@19515
|
401 call rewind
|
pascal@19515
|
402 pop dx
|
pascal@19515
|
403 pop ax
|
pascal@19515
|
404 @@end:
|
pascal@19515
|
405 mov [di+22],ax ; m->chunk_size
|
pascal@19515
|
406 mov [di+24],dx
|
pascal@19515
|
407 endif
|
pascal@19515
|
408 pop di
|
pascal@19515
|
409 ret
|
pascal@19515
|
410
|
pascal@19515
|
411 endp _next_chunk
|
pascal@19515
|
412
|
pascal@19515
|
413
|
pascal@19515
|
414 ;***************************************************************
|
pascal@19515
|
415 ;void open_image(const char *name, struct image_himem *m);
|
pascal@19515
|
416 ;struct image_himem {
|
pascal@19515
|
417 ; 0 int fd;
|
pascal@19515
|
418 ; 2 u32 fallback;
|
pascal@19515
|
419 ; 6 u32 size;
|
pascal@19515
|
420 ;10 u32 remaining;
|
pascal@19515
|
421 ;14 u32 buf;
|
pascal@19515
|
422 ;18 u32 *bufv;
|
pascal@19515
|
423 ;20 char *errmsg;
|
pascal@19515
|
424 ;22 u32 chunk_size;
|
pascal@19515
|
425 ;26 void (*next_chunk)(struct image_himem *);
|
pascal@19515
|
426 ;28 u16 state;
|
pascal@19515
|
427 ;};
|
pascal@19515
|
428 ;***************************************************************
|
pascal@19515
|
429 global _open_image:near
|
pascal@19515
|
430 proc _open_image near
|
pascal@19515
|
431
|
pascal@19515
|
432 arg fname :word, \
|
pascal@19515
|
433 m :word = PARAM_SIZE
|
pascal@19515
|
434
|
pascal@19515
|
435 push bp
|
pascal@19515
|
436 mov bp,sp
|
pascal@19515
|
437 push si di
|
pascal@19515
|
438 ifndef NO386
|
pascal@19515
|
439 xor eax,eax ; 1st loop flag + eos
|
pascal@19515
|
440 else
|
pascal@19515
|
441 xor ax,ax ; 1st loop flag + eos
|
pascal@19515
|
442 endif
|
pascal@19515
|
443 mov di,[m]
|
pascal@19515
|
444 cmp [di],ax ; m->fd
|
pascal@19515
|
445 jnz @@alreadydone
|
pascal@19515
|
446 ifndef NO386
|
pascal@19515
|
447 mov [di+6],eax ; m->size = 0L
|
pascal@19515
|
448 else
|
pascal@19515
|
449 mov [di+6],ax ; m->size = 0L
|
pascal@19515
|
450 mov [di+8],ax
|
pascal@19515
|
451 endif
|
pascal@19515
|
452 mov [word di+26],offset _next_chunk
|
pascal@19515
|
453 mov si,[fname]
|
pascal@19515
|
454 mov [di+28],si ; m->state
|
pascal@19515
|
455 @@next:
|
pascal@19515
|
456 push di
|
pascal@19515
|
457 call [word di+26] ; m->next_chunk()
|
pascal@19515
|
458 pop di
|
pascal@19515
|
459 ifndef NO386
|
pascal@19515
|
460 add eax,3
|
pascal@19515
|
461 and al,0FCh
|
pascal@19515
|
462 add [di+6],eax ; m->size += m->chunk_size
|
pascal@19515
|
463 or eax,eax
|
pascal@19515
|
464 jnz @@next
|
pascal@19515
|
465 else
|
pascal@19515
|
466 mov cx,ax
|
pascal@19515
|
467 or cx,dx
|
pascal@19515
|
468 add ax,3
|
pascal@19515
|
469 adc dx,0
|
pascal@19515
|
470 and al,0FCh
|
pascal@19515
|
471 add [di+6],ax ; m->size += m->chunk_size
|
pascal@19515
|
472 adc [di+8],dx
|
pascal@19515
|
473 inc cx
|
pascal@19515
|
474 loop @@next
|
pascal@19515
|
475 endif
|
pascal@19515
|
476 mov [di+28],si ; m->state
|
pascal@19515
|
477 push di
|
pascal@19515
|
478 call [word di+26] ; m->next_chunk()
|
pascal@19515
|
479 pop di
|
pascal@19515
|
480 @@alreadydone:
|
pascal@19515
|
481 push ax
|
pascal@19515
|
482 image_done:
|
pascal@19515
|
483 pop ax
|
pascal@19515
|
484 pop di si bp
|
pascal@19515
|
485 ret
|
pascal@19515
|
486
|
pascal@19515
|
487 endp _open_image
|
pascal@19515
|
488
|
pascal@19515
|
489
|
pascal@19515
|
490 ;***************************************************************
|
pascal@19515
|
491 ;int read_image(struct image_himem *m, void* data, int sz);
|
pascal@19515
|
492 ;***************************************************************
|
pascal@19515
|
493 global _read_image:near
|
pascal@19515
|
494 proc _read_image near
|
pascal@19515
|
495
|
pascal@19515
|
496 arg m :word, \
|
pascal@19515
|
497 data :word, \
|
pascal@19515
|
498 sz :word = PARAM_SIZE
|
pascal@19515
|
499
|
pascal@19515
|
500 push bp
|
pascal@19515
|
501 mov bp,sp
|
pascal@19515
|
502 push si di
|
pascal@19515
|
503 ifndef NO386
|
pascal@19515
|
504 push 0 ; return value
|
pascal@19515
|
505 else
|
pascal@19515
|
506 xor ax,ax
|
pascal@19515
|
507 push ax
|
pascal@19515
|
508 endif
|
pascal@19515
|
509 mov di,[m]
|
pascal@19515
|
510 @@loop:
|
pascal@19515
|
511 mov ax,[word sz]
|
pascal@19515
|
512 mov cx,[di+22] ; m->chunk_size
|
pascal@19515
|
513 cmp ax,cx
|
pascal@19515
|
514 jb @@szok
|
pascal@19515
|
515 cmp [word di+24],0 ; hi m->chunk_size
|
pascal@19515
|
516 jne @@szok
|
pascal@19515
|
517 xchg ax,cx
|
pascal@19515
|
518 @@szok:
|
pascal@19515
|
519 push ax
|
pascal@19515
|
520 push [word data]
|
pascal@19515
|
521 push [word di]
|
pascal@19515
|
522 call _read
|
pascal@19515
|
523 pop cx
|
pascal@19515
|
524 pop bx
|
pascal@19515
|
525 add bx,ax
|
pascal@19515
|
526 pop cx
|
pascal@19515
|
527 xor cx,cx
|
pascal@19515
|
528 sub [di+22],ax
|
pascal@19515
|
529 sbb [di+24],cx
|
pascal@19515
|
530 @@fill:
|
pascal@19515
|
531 test al,3
|
pascal@19515
|
532 je @@filled
|
pascal@19515
|
533 mov [bx],cl
|
pascal@19515
|
534 inc bx
|
pascal@19515
|
535 inc ax
|
pascal@19515
|
536 jmp @@fill
|
pascal@19515
|
537 @@filled:
|
pascal@19515
|
538 add [bp-4-2],ax
|
pascal@19515
|
539 add [word data],ax
|
pascal@19515
|
540 sub [word sz],ax
|
pascal@19515
|
541 jz image_done
|
pascal@19515
|
542 mov cx,[di+22] ; lo m->chunk_size
|
pascal@19515
|
543 or cx,[di+24] ; hi m->chunk_size
|
pascal@19515
|
544 jnz image_done
|
pascal@19515
|
545 or cx,[di+26] ; m->next_chunk
|
pascal@19515
|
546 jz image_done
|
pascal@19515
|
547 push di
|
pascal@19515
|
548 call cx ; m->next_chunk()
|
pascal@19515
|
549 pop di
|
pascal@19515
|
550 mov cx,[di+22] ; lo m->chunk_size
|
pascal@19515
|
551 or cx,[di+24] ; hi m->chunk_size
|
pascal@19515
|
552 jz image_done
|
pascal@19515
|
553 jmp @@loop
|
pascal@19515
|
554
|
pascal@19515
|
555 endp _read_image
|
pascal@19515
|
556
|
pascal@19515
|
557
|
pascal@19515
|
558 ;***************************************************************
|
pascal@19515
|
559 ;unsigned long strtol(const char *s);
|
pascal@19515
|
560 ;***************************************************************
|
pascal@19515
|
561 global _strtol:near
|
pascal@19515
|
562 proc _strtol near
|
pascal@19515
|
563
|
pascal@19515
|
564 ;TODO NO386
|
pascal@19515
|
565 ifndef NO386
|
pascal@19515
|
566 pop ax ;caller return address
|
pascal@19515
|
567 pop cx ; s
|
pascal@19515
|
568 push cx
|
pascal@19515
|
569 push ax
|
pascal@19515
|
570 xor ebx,ebx
|
pascal@19515
|
571 jcxz @@end
|
pascal@19515
|
572 push si
|
pascal@19515
|
573 mov si,cx
|
pascal@19515
|
574 xor ecx,ecx
|
pascal@19515
|
575 xor eax,eax
|
pascal@19515
|
576 mov cl,10 ; radix
|
pascal@19515
|
577 lodsb
|
pascal@19515
|
578 cmp al,'+'
|
pascal@19515
|
579 je @@radixskip
|
pascal@19515
|
580 cmp al,'-'
|
pascal@19515
|
581 clc
|
pascal@19515
|
582 jne @@radixkeep
|
pascal@19515
|
583 stc
|
pascal@19515
|
584 @@radixskip:
|
pascal@19515
|
585 lodsb
|
pascal@19515
|
586 @@radixkeep:
|
pascal@19515
|
587 pushf
|
pascal@19515
|
588 cmp al,'0'
|
pascal@19515
|
589 jne @@radixok
|
pascal@19515
|
590 mov cl,8
|
pascal@19515
|
591 lodsb
|
pascal@19515
|
592 mov dl,20h
|
pascal@19515
|
593 or dl,al
|
pascal@19515
|
594 cmp dl,'x'
|
pascal@19515
|
595 jne @@radixok
|
pascal@19515
|
596 mov cl,16
|
pascal@19515
|
597 @@strtollp:
|
pascal@19515
|
598 lodsb
|
pascal@19515
|
599 @@radixok:
|
pascal@19515
|
600 sub al,'0'
|
pascal@19515
|
601 jb @@endstrtol
|
pascal@19515
|
602 cmp al,9
|
pascal@19515
|
603 jbe @@digitok
|
pascal@19515
|
604 or al,20h
|
pascal@19515
|
605 cmp al,'a'-'0'
|
pascal@19515
|
606 jb @@endstrtol
|
pascal@19515
|
607 sub al,'a'-'0'-10
|
pascal@19515
|
608 @@digitok:
|
pascal@19515
|
609 cmp al,cl
|
pascal@19515
|
610 jae @@endstrtol
|
pascal@19515
|
611 xchg eax,ebx
|
pascal@19515
|
612 mul ecx
|
pascal@19515
|
613 add eax,ebx
|
pascal@19515
|
614 xchg eax,ebx
|
pascal@19515
|
615 jmp @@strtollp
|
pascal@19515
|
616 @@endstrtol:
|
pascal@19515
|
617 mov cl,10
|
pascal@19515
|
618 cmp al,'k'-'a'+10
|
pascal@19515
|
619 je @@shift
|
pascal@19515
|
620 mov cl,20
|
pascal@19515
|
621 cmp al,'m'-'a'+10
|
pascal@19515
|
622 je @@shift
|
pascal@19515
|
623 mov cl,30
|
pascal@19515
|
624 cmp al,'g'-'a'+10
|
pascal@19515
|
625 jne @@noshift
|
pascal@19515
|
626 @@shift:
|
pascal@19515
|
627 shl ebx,cl
|
pascal@19515
|
628 @@noshift:
|
pascal@19515
|
629 popf
|
pascal@19515
|
630 jnc @@end
|
pascal@19515
|
631 neg ebx
|
pascal@19515
|
632 @@end:
|
pascal@19515
|
633 push ebx
|
pascal@19515
|
634 pop ax
|
pascal@19515
|
635 pop dx
|
pascal@19515
|
636 popsiret:
|
pascal@19515
|
637 pop si
|
pascal@19515
|
638 else
|
pascal@19515
|
639 pop ax ;caller return address
|
pascal@19515
|
640 pop cx ; s
|
pascal@19515
|
641 push cx
|
pascal@19515
|
642 push ax
|
pascal@19515
|
643 push si
|
pascal@19515
|
644 push di
|
pascal@19515
|
645 xor ax,ax
|
pascal@19515
|
646 cwd
|
pascal@19515
|
647 xchg ax,di
|
pascal@19515
|
648 jcxz @@end
|
pascal@19515
|
649 mov si,cx
|
pascal@19515
|
650 mov cx,10 ; radix
|
pascal@19515
|
651 lodsb
|
pascal@19515
|
652 cmp al,'+'
|
pascal@19515
|
653 je @@radixskip
|
pascal@19515
|
654 cmp al,'-'
|
pascal@19515
|
655 clc
|
pascal@19515
|
656 jne @@radixkeep
|
pascal@19515
|
657 stc
|
pascal@19515
|
658 @@radixskip:
|
pascal@19515
|
659 lodsb
|
pascal@19515
|
660 @@radixkeep:
|
pascal@19515
|
661 pushf
|
pascal@19515
|
662 cmp al,'0'
|
pascal@19515
|
663 jne @@radixok
|
pascal@19515
|
664 mov cl,8
|
pascal@19515
|
665 lodsb
|
pascal@19515
|
666 mov ah,20h
|
pascal@19515
|
667 or ah,al
|
pascal@19515
|
668 cmp ah,'x'
|
pascal@19515
|
669 jne @@radixok
|
pascal@19515
|
670 mov cl,16
|
pascal@19515
|
671 @@strtollp:
|
pascal@19515
|
672 lodsb
|
pascal@19515
|
673 @@radixok:
|
pascal@19515
|
674 sub al,'0'
|
pascal@19515
|
675 jb @@endstrtol
|
pascal@19515
|
676 cmp al,9
|
pascal@19515
|
677 jbe @@digitok
|
pascal@19515
|
678 or al,20h
|
pascal@19515
|
679 cmp al,'a'-'0'
|
pascal@19515
|
680 jb @@endstrtol
|
pascal@19515
|
681 sub al,'a'-'0'-10
|
pascal@19515
|
682 @@digitok:
|
pascal@19515
|
683 cmp al,cl
|
pascal@19515
|
684 jae @@endstrtol
|
pascal@19515
|
685
|
pascal@19515
|
686 push ax
|
pascal@19515
|
687 push si
|
pascal@19515
|
688 push dx
|
pascal@19515
|
689 xchg ax,di
|
pascal@19515
|
690 mul cx
|
pascal@19515
|
691 xchg ax,di
|
pascal@19515
|
692 xchg ax,dx
|
pascal@19515
|
693 xchg ax,si
|
pascal@19515
|
694 pop ax
|
pascal@19515
|
695 mul cx
|
pascal@19515
|
696 add ax,si
|
pascal@19515
|
697 pop si
|
pascal@19515
|
698 xchg ax,dx
|
pascal@19515
|
699 pop ax
|
pascal@19515
|
700 mov ah,0
|
pascal@19515
|
701 add di,ax
|
pascal@19515
|
702 adc dx,0
|
pascal@19515
|
703
|
pascal@19515
|
704 jmp @@strtollp
|
pascal@19515
|
705 @@endstrtol:
|
pascal@19515
|
706 mov cl,10
|
pascal@19515
|
707 cmp al,'k'-'a'+10
|
pascal@19515
|
708 je @@shift
|
pascal@19515
|
709 mov cl,20
|
pascal@19515
|
710 cmp al,'m'-'a'+10
|
pascal@19515
|
711 je @@shift
|
pascal@19515
|
712 mov cl,30
|
pascal@19515
|
713 cmp al,'g'-'a'+10
|
pascal@19515
|
714 jne @@noshift
|
pascal@19515
|
715 @@shift:
|
pascal@19515
|
716 rcl di,1
|
pascal@19515
|
717 shl dx,1
|
pascal@19515
|
718 loop @@shift
|
pascal@19515
|
719 @@noshift:
|
pascal@19515
|
720 popf
|
pascal@19515
|
721 jnc @@end
|
pascal@19515
|
722 not dx
|
pascal@19515
|
723 neg di
|
pascal@19515
|
724 jne @@end
|
pascal@19515
|
725 inc dx
|
pascal@19515
|
726 @@end:
|
pascal@19515
|
727 xchg ax,di
|
pascal@19515
|
728 pop di
|
pascal@19515
|
729 popsiret:
|
pascal@19515
|
730 pop si
|
pascal@19515
|
731 endif
|
pascal@19515
|
732 ret
|
pascal@19515
|
733
|
pascal@19515
|
734 endp _strtol
|
pascal@19515
|
735
|
pascal@19515
|
736
|
pascal@19515
|
737 ;***************************************************************
|
pascal@19515
|
738 ;>void sort(unsigned long *base:BX!, size_t nel:CX)
|
pascal@19515
|
739 ;NO386 safe: only used by VCPI
|
pascal@19515
|
740 ;***************************************************************
|
pascal@19515
|
741 global _sort:near
|
pascal@19515
|
742 proc _sort near
|
pascal@19515
|
743
|
pascal@19515
|
744 pop ax ;caller return address
|
pascal@19515
|
745 pop bx ; base
|
pascal@19515
|
746 pop cx ; nel
|
pascal@19515
|
747 push cx
|
pascal@19515
|
748 push bx
|
pascal@19515
|
749 push ax
|
pascal@19515
|
750 global sort:near
|
pascal@19515
|
751 sort:
|
pascal@19515
|
752 ifndef fastsort
|
pascal@19515
|
753 ; bubble sort
|
pascal@19515
|
754 push si
|
pascal@19515
|
755 cmp cx,2
|
pascal@19515
|
756 jl popsiret
|
pascal@19515
|
757 shl cx,2
|
pascal@19515
|
758 @@loop:
|
pascal@19515
|
759 xor ax,ax
|
pascal@19515
|
760 jcxz popsiret
|
pascal@19515
|
761 mov si,4
|
pascal@19515
|
762 @@next:
|
pascal@19515
|
763 mov edx,[bx+si-4]
|
pascal@19515
|
764 cmp edx,[bx+si]
|
pascal@19515
|
765 jbe @@ok
|
pascal@19515
|
766 xchg edx,[bx+si]
|
pascal@19515
|
767 mov [bx+si-4],edx
|
pascal@19515
|
768 mov ax,si
|
pascal@19515
|
769 @@ok:
|
pascal@19515
|
770 add si,4
|
pascal@19515
|
771 cmp si,cx
|
pascal@19515
|
772 jb @@next
|
pascal@19515
|
773 xchg ax,cx
|
pascal@19515
|
774 jmp @@loop
|
pascal@19515
|
775 else
|
pascal@19515
|
776 ; shell sort (c) uclibc GPL
|
pascal@19515
|
777 push si di
|
pascal@19515
|
778 ; {
|
pascal@19515
|
779 ;> size_t wgap:SI;
|
pascal@19515
|
780 ;
|
pascal@19515
|
781 ; if (nel > 1) {
|
pascal@19515
|
782 cmp cx,1
|
pascal@19515
|
783 jbe @@end
|
pascal@19515
|
784 ; wgap = 0;
|
pascal@19515
|
785 xor ax,ax
|
pascal@19515
|
786 ; do {
|
pascal@19515
|
787 @@wgaplp:
|
pascal@19515
|
788 mov si,ax
|
pascal@19515
|
789 ; wgap = 3 * wgap + 1;
|
pascal@19515
|
790 mov dx,3
|
pascal@19515
|
791 mul dx
|
pascal@19515
|
792 inc ax
|
pascal@19515
|
793 ; } while (wgap < (nel-1)/3);
|
pascal@19515
|
794 cmp ax,cx
|
pascal@19515
|
795 jb @@wgaplp
|
pascal@19515
|
796 ; /* From the above, we know that either wgap == 1 < nel or */
|
pascal@19515
|
797 ; /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
|
pascal@19515
|
798 ; wgap *= 4; /* So this can not overflow if wnel doesn't. */
|
pascal@19515
|
799 shl si,2
|
pascal@19515
|
800 ; nel *= 4; /* Convert nel to 'wnel' */
|
pascal@19515
|
801 shl cx,2
|
pascal@19515
|
802 ; do {
|
pascal@19515
|
803 @@lp1:
|
pascal@19515
|
804 ;> size_t i:DI;
|
pascal@19515
|
805 ; i = wgap;
|
pascal@19515
|
806 mov di,si
|
pascal@19515
|
807 ; do {
|
pascal@19515
|
808 @@lp2:
|
pascal@19515
|
809 ;> size_t j:DX;
|
pascal@19515
|
810 ; j = i;
|
pascal@19515
|
811 mov dx,di
|
pascal@19515
|
812 ; do {
|
pascal@19515
|
813 @@lp3:
|
pascal@19515
|
814 ;> register char *a:BX!;
|
pascal@19515
|
815 ;
|
pascal@19515
|
816 ; j -= wgap;
|
pascal@19515
|
817 sub dx,si
|
pascal@19515
|
818 ; a = j + ((char *)base);
|
pascal@19515
|
819 push bx
|
pascal@19515
|
820 add bx,dx
|
pascal@19515
|
821 ; if (cmp(a, a + wgap) <= 0) {
|
pascal@19515
|
822 mov eax,[bx]
|
pascal@19515
|
823 cmp eax,[bx+si]
|
pascal@19515
|
824 jbe @@brk3
|
pascal@19515
|
825 ; break;
|
pascal@19515
|
826 ; }
|
pascal@19515
|
827 xchg eax,[bx+si]
|
pascal@19515
|
828 mov [bx],eax
|
pascal@19515
|
829 ; swap(a, a + wgap);
|
pascal@19515
|
830 pop bx
|
pascal@19515
|
831 ; } while (j >= wgap);
|
pascal@19515
|
832 cmp dx,si
|
pascal@19515
|
833 jae @@lp3
|
pascal@19515
|
834 push bx
|
pascal@19515
|
835 @@brk3:
|
pascal@19515
|
836 pop bx
|
pascal@19515
|
837 ; i += 4;
|
pascal@19515
|
838 add di,4
|
pascal@19515
|
839 ; } while (i < nel);
|
pascal@19515
|
840 cmp di,cx
|
pascal@19515
|
841 jb @@lp2
|
pascal@19515
|
842 ; wgap = (wgap - 4)/3;
|
pascal@19515
|
843 sub si,4
|
pascal@19515
|
844 xchg ax,si
|
pascal@19515
|
845 cwd
|
pascal@19515
|
846 mov si,3
|
pascal@19515
|
847 div si ; kill dx
|
pascal@19515
|
848 xchg ax,si
|
pascal@19515
|
849 ; } while (wgap);
|
pascal@19515
|
850 or si,si
|
pascal@19515
|
851 jnz @@lp1
|
pascal@19515
|
852 @@end:
|
pascal@19515
|
853 ; }
|
pascal@19515
|
854 ;}
|
pascal@19515
|
855 pop di si
|
pascal@19515
|
856 ret
|
pascal@19515
|
857 endif
|
pascal@19515
|
858
|
pascal@19515
|
859 endp _sort
|
pascal@19515
|
860
|
pascal@19515
|
861
|
pascal@19515
|
862 ;***************************************************************
|
pascal@19515
|
863 ;void* malloc(unsigned sz);
|
pascal@19515
|
864 ;***************************************************************
|
pascal@19515
|
865 global _malloc:near
|
pascal@19515
|
866 proc _malloc near
|
pascal@19515
|
867
|
pascal@19515
|
868 pop ax ;caller return address
|
pascal@19515
|
869 pop cx ; sz
|
pascal@19515
|
870 push cx
|
pascal@19515
|
871 push ax
|
pascal@19515
|
872 global malloc:near ; malloc(cx)
|
pascal@19515
|
873 malloc:
|
pascal@19515
|
874 mov ax,[_heap_top]
|
pascal@19515
|
875 mov bx,sp
|
pascal@19515
|
876 sub bh,14h ; MIN_STACK=_1k+PAGE_SIZE
|
pascal@19515
|
877 sub bx,cx
|
pascal@19515
|
878 jb @@outofmem
|
pascal@19515
|
879 cmp bx,ax
|
pascal@19515
|
880 jb @@outofmem
|
pascal@19515
|
881 add [_heap_top],cx ; _BEG has zero'd heap
|
pascal@19515
|
882 ;mov bx,ax
|
pascal@19515
|
883 @@zalloc:
|
pascal@19515
|
884 ;mov [byte bx],0
|
pascal@19515
|
885 ;inc bx ; ZF=0
|
pascal@19515
|
886 ;loop @@zalloc
|
pascal@19515
|
887 ret
|
pascal@19515
|
888 @@outofmem:
|
pascal@19515
|
889 mov bx,offset msg_malloc
|
pascal@19515
|
890 call puts
|
pascal@19515
|
891 xor ax,ax ; ZF=1
|
pascal@19515
|
892 ret
|
pascal@19515
|
893
|
pascal@19515
|
894 endp _malloc
|
pascal@19515
|
895
|
pascal@19515
|
896
|
pascal@19515
|
897 ifdef NO386
|
pascal@19515
|
898 ;***************************************************************
|
pascal@19515
|
899 ;u16 topseg();
|
pascal@19515
|
900 ;***************************************************************
|
pascal@19515
|
901 global _topseg:near
|
pascal@19515
|
902 proc _topseg near
|
pascal@19515
|
903
|
pascal@19515
|
904 int 12h
|
pascal@19515
|
905 jnc @@max640k
|
pascal@19515
|
906 mov ax,640 ; 9000
|
pascal@19515
|
907 @@max640k:
|
pascal@19515
|
908 sub al,040h
|
pascal@19515
|
909 and al,0C0h
|
pascal@19515
|
910 mov cl,6
|
pascal@19515
|
911 shl ax,cl
|
pascal@19515
|
912 ret
|
pascal@19515
|
913
|
pascal@19515
|
914 endp _topseg
|
pascal@19515
|
915 endif
|
pascal@19515
|
916
|
pascal@19515
|
917
|
pascal@19515
|
918 ends _TEXT
|
pascal@19515
|
919
|
pascal@19515
|
920 end
|
pascal@19515
|
921
|
pascal@19515
|
922 ;###### END OF FILE ############################################
|