wok annotate linld/stuff/src/CRTL.ASM @ rev 19538

linld: add 'linld <kernel> <cmdline>' syntax
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Dec 02 12:37:59 2016 +0100 (2016-12-02)
parents bb42796dcd3b
children 31c5cbbd9380
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@19538 16 vcpi_alloc_err db "vcpi "
pascal@19515 17 msg_malloc db "malloc() failure",0
pascal@19515 18 msg_crlf db 13,10,0
pascal@19515 19
pascal@19515 20 ends _DATA
pascal@19515 21
pascal@19515 22 segment _BSS byte public use16 'BSS'
pascal@19515 23
pascal@19515 24 global _heap_top:word
pascal@19515 25 _heap_top dw ?
pascal@19515 26 global _no_exit:byte
pascal@19515 27 _no_exit db ?
pascal@19515 28 filecnt db ? ; in fact 0 minus file count...
pascal@19515 29 nextfilename dw ?
pascal@19515 30
pascal@19515 31 ends _BSS
pascal@19515 32
pascal@19515 33 segment _TEXT byte public use16 'CODE'
pascal@19515 34
pascal@19515 35 ;***************************************************************
pascal@19538 36 ;char* strcpy(const char* a, const char* b);
pascal@19538 37 ;***************************************************************
pascal@19538 38 global _strcpy:near
pascal@19538 39 proc _strcpy near
pascal@19538 40
pascal@19538 41 mov dl,0
pascal@19538 42 cat:
pascal@19538 43 pop ax ;caller return address
pascal@19538 44 pop cx ; a
pascal@19538 45 pop bx ; b
pascal@19538 46 push bx
pascal@19538 47 push cx
pascal@19538 48 push ax
pascal@19538 49 push si
pascal@19538 50 mov si,cx
pascal@19538 51 shr dl,1
pascal@19538 52 jnc @@nocat
pascal@19538 53 @@catlp:
pascal@19538 54 lodsb
pascal@19538 55 cmp al,0
pascal@19538 56 jne @@catlp
pascal@19538 57 dec si
pascal@19538 58 shr dl,1
pascal@19538 59 jnc @@nocat
pascal@19538 60 cmp cx,si
pascal@19538 61 jz @@nocat
pascal@19538 62 mov [word si],20h
pascal@19538 63 inc si
pascal@19538 64 @@nocat:
pascal@19538 65 sub bx,si
pascal@19538 66 @@cpylp:
pascal@19538 67 mov al,[bx+si]
pascal@19538 68 mov [si],al
pascal@19538 69 inc si
pascal@19538 70 cmp al,0
pascal@19538 71 jne @@cpylp
pascal@19538 72 mov ax,cx
pascal@19538 73 pop si
pascal@19538 74 ret
pascal@19538 75
pascal@19538 76 endp _strcpy
pascal@19538 77
pascal@19538 78
pascal@19538 79 ;***************************************************************
pascal@19538 80 ;char* strcat(const char* a,const char* b);
pascal@19538 81 ;***************************************************************
pascal@19538 82 global _strcat:near
pascal@19538 83 proc _strcat near
pascal@19538 84
pascal@19538 85 mov dl,1
pascal@19538 86 jmp cat
pascal@19538 87
pascal@19538 88 endp _strcat
pascal@19538 89
pascal@19538 90
pascal@19538 91 ;***************************************************************
pascal@19538 92 ;char* strcatb(const char* a,const char* b);
pascal@19538 93 ;***************************************************************
pascal@19538 94 global _strcatb:near
pascal@19538 95 proc _strcatb near
pascal@19538 96
pascal@19538 97 mov dl,3
pascal@19538 98 jmp cat
pascal@19538 99
pascal@19538 100 endp _strcatb
pascal@19538 101
pascal@19538 102
pascal@19538 103 ;***************************************************************
pascal@19538 104 ;void* malloc(unsigned sz);
pascal@19538 105 ;***************************************************************
pascal@19538 106 global _malloc:near
pascal@19538 107 proc _malloc near
pascal@19538 108
pascal@19538 109 pop ax ;caller return address
pascal@19538 110 pop cx ; sz
pascal@19538 111 push cx
pascal@19538 112 push ax
pascal@19538 113 global malloc:near ; malloc(cx)
pascal@19538 114 malloc:
pascal@19538 115 mov ax,[_heap_top]
pascal@19538 116 mov bx,offset msg_malloc
pascal@19538 117 mov dx,-1400h ; MIN_STACK=_1k+PAGE_SIZE
pascal@19538 118 add dx,sp
pascal@19538 119 sub dx,ax ; can't overflow
pascal@19538 120 cmp dx,cx
pascal@19538 121 jb puts
pascal@19538 122 add [_heap_top],cx ; _BEG has zero'd heap
pascal@19538 123 ;mov bx,ax
pascal@19538 124 @@zalloc:
pascal@19538 125 ;mov [byte bx],0
pascal@19538 126 ;inc bx ; ZF=0
pascal@19538 127 ;loop @@zalloc
pascal@19538 128 ret
pascal@19538 129
pascal@19538 130 endp _malloc
pascal@19538 131
pascal@19538 132
pascal@19538 133 ;***************************************************************
pascal@19515 134 ;void puts(const char* s):
pascal@19515 135 ;void putsz(const char* s):
pascal@19515 136 ;***************************************************************
pascal@19515 137 global _puts:near
pascal@19515 138 proc _puts near
pascal@19515 139
pascal@19515 140 pop ax ;caller return address
pascal@19515 141 pop bx ; s
pascal@19515 142 push bx
pascal@19515 143 push ax
pascal@19515 144 global puts:near ; puts(bx)
pascal@19515 145 puts:
pascal@19515 146 call putsz
pascal@19515 147 mov bx,offset msg_crlf
pascal@19515 148 jmp putsz
pascal@19515 149
pascal@19515 150 global _putsz:near
pascal@19515 151 _putsz:
pascal@19515 152 pop ax ;caller return address
pascal@19515 153 pop bx ; s
pascal@19515 154 push bx
pascal@19515 155 push ax
pascal@19515 156 global putsz:near ; putsz(bx)
pascal@19515 157 putsz:
pascal@19515 158 push bx
pascal@19515 159 call strlen
pascal@19515 160 pop dx
pascal@19515 161 xchg ax,cx
pascal@19515 162 mov bx,1
pascal@19515 163 mov ah,40h
pascal@19538 164 int 21h
pascal@19538 165 xor ax,ax ; ZF=1 (for malloc failure)
pascal@19538 166 ret
pascal@19515 167
pascal@19515 168 endp _puts
pascal@19515 169
pascal@19515 170
pascal@19515 171 ;***************************************************************
pascal@19538 172 ;int fileattr(const char* name);
pascal@19538 173 ;***************************************************************
pascal@19538 174 global _fileattr:near
pascal@19538 175 proc _fileattr near
pascal@19538 176
pascal@19538 177 pop ax ;caller return address
pascal@19538 178 pop dx ; name
pascal@19538 179 push dx
pascal@19538 180 push ax
pascal@19538 181 mov ax,4300h
pascal@19538 182 int 21h
pascal@19538 183 xchg ax,cx
pascal@19538 184 jmp chkc
pascal@19538 185
pascal@19538 186 endp _fileattr
pascal@19538 187
pascal@19538 188
pascal@19538 189 ;***************************************************************
pascal@19515 190 ;int open(const char* name, int flags);
pascal@19515 191 ;***************************************************************
pascal@19515 192 global _open:near
pascal@19515 193 proc _open near
pascal@19515 194
pascal@19515 195 pop cx ;caller return address
pascal@19515 196 pop bx ; name
pascal@19515 197 pop ax ; flags
pascal@19515 198 push ax
pascal@19515 199 push bx
pascal@19515 200 push cx
pascal@19515 201 global open:near ; open(bx,al)
pascal@19515 202 open:
pascal@19515 203 mov dx,bx
pascal@19515 204 mov ah,3dh
pascal@19515 205 dos:
pascal@19515 206 int 21h
pascal@19538 207 chkc:
pascal@19515 208 jnc doret
pascal@19515 209 fail:
pascal@19515 210 sbb ax,ax ; ax=-1 CF
pascal@19515 211 cwd
pascal@19515 212 doret:
pascal@19515 213 ifndef NO386
pascal@19538 214 push dx ; see next_chunk:lseek
pascal@19538 215 push ax
pascal@19538 216 pop eax
pascal@19515 217 endif
pascal@19515 218 ret
pascal@19515 219
pascal@19515 220 endp _open
pascal@19515 221
pascal@19515 222
pascal@19515 223 ;***************************************************************
pascal@19515 224 ;int close(int fd);
pascal@19515 225 ;***************************************************************
pascal@19515 226 global _close:near
pascal@19515 227 proc _close near
pascal@19515 228
pascal@19515 229 pop ax ;caller return address
pascal@19515 230 pop bx ; fd
pascal@19515 231 push bx
pascal@19515 232 push ax
pascal@19515 233 global close:near ; close(bx)
pascal@19515 234 close:
pascal@19515 235 mov ah,3Eh
pascal@19515 236 or bx,bx
pascal@19515 237 jnz dos
pascal@19515 238 ret
pascal@19515 239
pascal@19515 240 endp _close
pascal@19515 241
pascal@19515 242
pascal@19515 243 ;***************************************************************
pascal@19515 244 ;int read(int fd, void* data, int sz);
pascal@19515 245 ;***************************************************************
pascal@19515 246 global _read:near
pascal@19515 247 proc _read near
pascal@19515 248
pascal@19515 249 mov ah,3fh
pascal@19515 250 rwio:
pascal@19515 251 ifndef NO386
pascal@19515 252 pop dx ;caller return address
pascal@19515 253 pop ebx ; fd & data
pascal@19515 254 pop cx ; sz
pascal@19515 255 push cx
pascal@19515 256 push ebx
pascal@19515 257 push dx
pascal@19515 258 else
pascal@19515 259 mov bx,sp
pascal@19515 260 mov cx,[bx+6]
pascal@19515 261 mov dx,[bx+4]
pascal@19515 262 mov bx,[bx+2]
pascal@19515 263 endif
pascal@19515 264 clc
pascal@19515 265 jcxz fail
pascal@19515 266 rwioz:
pascal@19515 267 ifndef NO386
pascal@19515 268 push ebx
pascal@19515 269 pop bx
pascal@19515 270 pop dx
pascal@19515 271 endif
pascal@19515 272 jmp dos
pascal@19515 273
pascal@19515 274 endp _read
pascal@19515 275
pascal@19515 276
pascal@19515 277 ;***************************************************************
pascal@19515 278 ;int write(int fd, const void* data, int sz);
pascal@19515 279 ;***************************************************************
pascal@19515 280 global _write:near
pascal@19515 281 proc _write near
pascal@19515 282
pascal@19515 283 mov ah,40h
pascal@19515 284 jmp rwio
pascal@19515 285
pascal@19515 286 endp _write
pascal@19515 287
pascal@19515 288
pascal@19515 289 ;***************************************************************
pascal@19515 290 ;long lseek(int fd, long sz, int dir);
pascal@19515 291 ;***************************************************************
pascal@19515 292 global _lseek:near
pascal@19515 293 proc _lseek near
pascal@19515 294
pascal@19515 295 ifndef NO386
pascal@19515 296 pop ax ;caller return address
pascal@19515 297 pop bx ; fd
pascal@19515 298 pop ecx ; sz
pascal@19515 299 pop dx ; dir
pascal@19515 300 push dx
pascal@19515 301 push ecx
pascal@19515 302 push bx
pascal@19515 303 push ax
pascal@19515 304 else
pascal@19515 305 mov bx,sp
pascal@19515 306 mov dx,[bx+8]
pascal@19515 307 mov cx,[bx+6]
pascal@19515 308 mov ax,[bx+4]
pascal@19515 309 mov bx,[bx+2]
pascal@19515 310 endif
pascal@19515 311 lseek:
pascal@19515 312 xchg ax,dx ; dir
pascal@19515 313 mov ah,42h
pascal@19515 314 ifndef NO386
pascal@19515 315 push ecx
pascal@19515 316 pop dx
pascal@19515 317 pop cx
pascal@19515 318 endif
pascal@19515 319 jmp dos
pascal@19515 320
pascal@19515 321 endp _lseek
pascal@19515 322
pascal@19515 323
pascal@19515 324 ;***************************************************************
pascal@19515 325 ;int strlen(const char* s);
pascal@19515 326 ;***************************************************************
pascal@19515 327 global _strlen:near
pascal@19515 328 proc _strlen near
pascal@19515 329
pascal@19515 330 pop ax ;caller return address
pascal@19515 331 pop bx ; s
pascal@19515 332 push bx
pascal@19515 333 push ax
pascal@19515 334 global strlen:near ; strlen(bx)
pascal@19515 335 strlen:
pascal@19515 336 mov cx,bx
pascal@19515 337 jcxz @@end
pascal@19515 338 dec bx
pascal@19515 339 @@lenlp:
pascal@19515 340 inc bx
pascal@19515 341 cmp [byte bx],0
pascal@19515 342 jne @@lenlp
pascal@19515 343 sub bx,cx
pascal@19515 344 @@end:
pascal@19515 345 xchg ax,bx
pascal@19515 346 ret
pascal@19515 347
pascal@19515 348 endp _strlen
pascal@19515 349
pascal@19515 350
pascal@19515 351 ;***************************************************************
pascal@19515 352 ;int strhead(const char* a,const char* b);
pascal@19515 353 ;***************************************************************
pascal@19515 354 global _strhead:near
pascal@19515 355 proc _strhead near
pascal@19515 356
pascal@19515 357 pop cx ;caller return address
pascal@19515 358 pop ax ; a
pascal@19515 359 pop bx ; b
pascal@19515 360 push bx
pascal@19515 361 push ax
pascal@19515 362 push cx
pascal@19515 363 @@loop:
pascal@19515 364 mov cl,[bx] ; cl = *b++
pascal@19515 365 inc bx
pascal@19515 366 or cl,cl ; clear C
pascal@19515 367 jz fail ; return 0
pascal@19515 368 xchg ax,bx
pascal@19515 369 xor cl,[bx] ; cl -= *a++
pascal@19515 370 and cl,0dfh ; case insensitive
pascal@19515 371 stc
pascal@19515 372 jnz fail ; return -1
pascal@19515 373 inc bx
pascal@19515 374 xchg ax,bx
pascal@19515 375 jmp @@loop
pascal@19515 376
pascal@19515 377 endp _strhead
pascal@19515 378
pascal@19515 379
pascal@19515 380 ;***************************************************************
pascal@19515 381 ;char* malloc_or_die(unsigned size);
pascal@19515 382 ;***************************************************************
pascal@19515 383 global _malloc_or_die:near
pascal@19515 384 proc _malloc_or_die near
pascal@19515 385
pascal@19515 386 pop ax ;caller return address
pascal@19515 387 pop cx ; size
pascal@19515 388 push cx
pascal@19515 389 push ax
pascal@19515 390 global malloc_or_die:near ; malloc_or_die(cx)
pascal@19515 391 malloc_or_die:
pascal@19515 392 call malloc
pascal@19538 393 jz _exit
pascal@19515 394 ret
pascal@19515 395
pascal@19515 396 endp _malloc_or_die
pascal@19515 397
pascal@19515 398
pascal@19515 399 ;***************************************************************
pascal@19515 400 ;int die(const char* msg);
pascal@19538 401 ;int exit();
pascal@19515 402 ;int abort();
pascal@19515 403 ;***************************************************************
pascal@19515 404 global _die:near
pascal@19515 405 proc _die near
pascal@19515 406
pascal@19515 407 pop ax ;caller return address
pascal@19515 408 pop bx ; s
pascal@19515 409 push bx
pascal@19515 410 push ax
pascal@19515 411 global die:near ; die(bx)
pascal@19515 412 die:
pascal@19515 413 call puts
pascal@19538 414 global _exit:near
pascal@19538 415 _exit:
pascal@19515 416 mov al,[_no_exit]
pascal@19515 417 cmp al,0
pascal@19515 418 jne @@hang
pascal@19515 419 extrn exit:near
pascal@19515 420 inc ax
pascal@19515 421 jmp near exit
pascal@19515 422 @@hang:
pascal@19515 423 mov bx, offset msg_hang
pascal@19515 424 call puts
pascal@19515 425 global _abort:near
pascal@19515 426 _abort:
pascal@19515 427 cli
pascal@19515 428 @@stop:
pascal@19515 429 hlt
pascal@19515 430 jmp @@stop
pascal@19515 431
pascal@19515 432 endp _die
pascal@19515 433
pascal@19515 434
pascal@19515 435 ;***************************************************************
pascal@19538 436 ;u32* malloc_bufv_or_die(struct image_himem *m);
pascal@19538 437 ;***************************************************************
pascal@19538 438 global _malloc_bufv_or_die:near
pascal@19538 439 proc _malloc_bufv_or_die near
pascal@19538 440
pascal@19538 441 pop bx ;caller return address
pascal@19538 442 pop ax
pascal@19538 443 push ax
pascal@19538 444 push bx
pascal@19538 445 push si
pascal@19538 446 xchg ax,si
pascal@19538 447 mov ecx,[si+6] ; m->size
pascal@19538 448 dec ecx
pascal@19538 449 shr ecx,12
pascal@19538 450 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
pascal@19538 451 push cx
pascal@19538 452 inc cx ; cnt+1
pascal@19538 453 shl cx,2 ; bufv => vcpi => vm86
pascal@19538 454 ; our malloc zeroes allocated mem: bufv[cnt]=0;
pascal@19538 455 ; Allocate pages, storing addrs in addrbuf
pascal@19538 456 call malloc_or_die
pascal@19538 457 pop cx
pascal@19538 458 push cx ; _sort:nel
pascal@19538 459 push ax ; _sort:base
pascal@19538 460 mov [si+18],ax ; m->bufv
pascal@19538 461 xchg ax,bx
pascal@19538 462 @@vcpi_alloc:
pascal@19538 463 xor edx,edx
pascal@19538 464 mov ax,0DE04h
pascal@19538 465 int 67h
pascal@19538 466 or ah,ah
pascal@19538 467 jz @@ok
pascal@19538 468 mov bx,offset vcpi_alloc_err
pascal@19538 469 jmp die
pascal@19538 470 @@ok:
pascal@19538 471 mov [bx],edx
pascal@19538 472 add bx,4
pascal@19538 473 loop @@vcpi_alloc
pascal@19538 474 @@again:
pascal@19538 475 call _sort
pascal@19538 476 extrn _initrd
pascal@19538 477 cmp si,offset _initrd
pascal@19538 478 jne @@quit
pascal@19538 479 pop ax
pascal@19538 480 pop cx
pascal@19538 481 push cx ; _sort:nel
pascal@19538 482 push ax ; _sort:base = m->bufv
pascal@19538 483 ;again:
pascal@19538 484 ; for (i = cnt-1; i >= 0; i--) {
pascal@19538 485 @@chkloop:
pascal@19538 486 mov bx,cx
pascal@19538 487 dec bx
pascal@19538 488 ; if (m->bufv[i] > m->fallback+i*_4k && m->bufv[i] < m->fallback+m->size) {
pascal@19538 489 shl bx,2
pascal@19538 490 add bx,ax ; m->bufv
pascal@19538 491 mov edx,[bx] ; m->bufv[i]
pascal@19538 492 sub edx,[si+2] ; m->fallback
pascal@19538 493 cmp edx,[si+6] ; m->size
pascal@19538 494 jae @@chknext
pascal@19538 495 shr edx,12
pascal@19538 496 cmp dx,cx
pascal@19538 497 jb @@chknext
pascal@19538 498 ; m->bufv[i] = vcpi_alloc_or_die();
pascal@19538 499 ; sort(m->bufv,cnt);
pascal@19538 500 ; goto again;
pascal@19538 501 mov cx,1
pascal@19538 502 jmp @@vcpi_alloc
pascal@19538 503 ; }
pascal@19538 504 ; }
pascal@19538 505 @@chknext:
pascal@19538 506 loop @@chkloop
pascal@19538 507 @@quit:
pascal@19538 508 pop ax
pascal@19538 509 pop cx
pascal@19538 510 pop si
pascal@19538 511 ret
pascal@19538 512
pascal@19538 513 endp _malloc_bufv_or_die
pascal@19538 514
pascal@19538 515
pascal@19538 516 ;***************************************************************
pascal@19515 517 ;void next_chunk(struct image_himem *m);
pascal@19515 518 ;***************************************************************
pascal@19515 519 proc _next_chunk near
pascal@19515 520
pascal@19515 521 pop bx
pascal@19515 522 pop ax
pascal@19515 523 push ax
pascal@19515 524 push bx
pascal@19538 525 push si di
pascal@19515 526 xchg ax,di
pascal@19515 527 mov bx,[di] ; m->fd
pascal@19515 528 call close
pascal@19515 529 ifndef NO386
pascal@19515 530 xor eax,eax
pascal@19515 531 else
pascal@19515 532 xor ax,ax
pascal@19515 533 endif
pascal@19515 534 cwd
pascal@19515 535 mov [di],ax ; m->fd
pascal@19515 536 mov bx,[di+28] ; m->state
pascal@19515 537 cmp al,[bx] ; ""
pascal@19515 538 jz @@end
pascal@19515 539 mov si,bx
pascal@19515 540 @@scan:
pascal@19515 541 lodsb
pascal@19515 542 mov cx,si
pascal@19515 543 cmp al,','
pascal@19515 544 jz @@eos
pascal@19515 545 cmp al,0
pascal@19515 546 jnz @@scan
pascal@19515 547 dec cx
pascal@19515 548 @@eos:
pascal@19515 549 mov [di+28],cx ; m->state
pascal@19515 550 dec si
pascal@19515 551 push [word si]
pascal@19515 552 mov [byte si],dl ; set temp eos
pascal@19515 553 xchg ax,dx ; O_RDONLY
pascal@19515 554 call open
pascal@19515 555 pop [word si] ; restore string
pascal@19515 556 jc @@die
pascal@19515 557 mov [di],ax ; m->fd
pascal@19538 558 mov [di+30],ax ; m->fd2close
pascal@19515 559 mov dx,2 ; SEEK_END
pascal@19515 560 xchg ax,bx
pascal@19515 561 ifndef NO386
pascal@19515 562 xor ecx,ecx
pascal@19515 563 else
pascal@19515 564 xor ax,ax
pascal@19515 565 xor cx,cx
pascal@19515 566 endif
pascal@19515 567 call lseek
pascal@19515 568 @@die:
pascal@19515 569 mov bx,[di+20] ; m->errmsg
pascal@19515 570 jc die
pascal@19515 571 mov bx,[di] ; m->fd
pascal@19515 572 ifndef NO386
pascal@19515 573 push eax
pascal@19538 574 xor ecx,ecx
pascal@19538 575 xor dx,dx
pascal@19538 576 call lseek ; rewind
pascal@19515 577 pop eax
pascal@19515 578 @@end:
pascal@19515 579 mov [di+22],eax ; m->chunk_size
pascal@19515 580 else
pascal@19515 581 push ax
pascal@19515 582 push dx
pascal@19538 583 xor ax,ax
pascal@19538 584 xor cx,cx
pascal@19538 585 cwd
pascal@19538 586 call lseek ; rewind
pascal@19515 587 pop dx
pascal@19515 588 pop ax
pascal@19515 589 @@end:
pascal@19515 590 mov [di+22],ax ; m->chunk_size
pascal@19515 591 mov [di+24],dx
pascal@19515 592 endif
pascal@19538 593 pop di si
pascal@19515 594 ret
pascal@19515 595
pascal@19515 596 endp _next_chunk
pascal@19515 597
pascal@19515 598
pascal@19515 599 ;***************************************************************
pascal@19515 600 ;void open_image(const char *name, struct image_himem *m);
pascal@19515 601 ;struct image_himem {
pascal@19515 602 ; 0 int fd;
pascal@19515 603 ; 2 u32 fallback;
pascal@19515 604 ; 6 u32 size;
pascal@19515 605 ;10 u32 remaining;
pascal@19515 606 ;14 u32 buf;
pascal@19515 607 ;18 u32 *bufv;
pascal@19515 608 ;20 char *errmsg;
pascal@19515 609 ;22 u32 chunk_size;
pascal@19515 610 ;26 void (*next_chunk)(struct image_himem *);
pascal@19515 611 ;28 u16 state;
pascal@19538 612 ;30 u16 fd2close;
pascal@19515 613 ;};
pascal@19515 614 ;***************************************************************
pascal@19515 615 global _open_image:near
pascal@19515 616 proc _open_image near
pascal@19515 617
pascal@19515 618 arg fname :word, \
pascal@19515 619 m :word = PARAM_SIZE
pascal@19515 620
pascal@19515 621 push bp
pascal@19515 622 mov bp,sp
pascal@19515 623 push si di
pascal@19515 624 ifndef NO386
pascal@19515 625 xor eax,eax ; 1st loop flag + eos
pascal@19515 626 else
pascal@19515 627 xor ax,ax ; 1st loop flag + eos
pascal@19515 628 endif
pascal@19515 629 mov di,[m]
pascal@19515 630 cmp [di],ax ; m->fd
pascal@19515 631 jnz @@alreadydone
pascal@19515 632 ifndef NO386
pascal@19515 633 mov [di+6],eax ; m->size = 0L
pascal@19515 634 else
pascal@19515 635 mov [di+6],ax ; m->size = 0L
pascal@19515 636 mov [di+8],ax
pascal@19515 637 endif
pascal@19515 638 mov [word di+26],offset _next_chunk
pascal@19515 639 mov si,[fname]
pascal@19515 640 mov [di+28],si ; m->state
pascal@19515 641 @@next:
pascal@19515 642 push di
pascal@19515 643 call [word di+26] ; m->next_chunk()
pascal@19515 644 pop di
pascal@19515 645 ifndef NO386
pascal@19515 646 add eax,3
pascal@19515 647 and al,0FCh
pascal@19515 648 add [di+6],eax ; m->size += m->chunk_size
pascal@19515 649 or eax,eax
pascal@19515 650 jnz @@next
pascal@19515 651 else
pascal@19515 652 mov cx,ax
pascal@19515 653 or cx,dx
pascal@19515 654 add ax,3
pascal@19515 655 adc dx,0
pascal@19515 656 and al,0FCh
pascal@19515 657 add [di+6],ax ; m->size += m->chunk_size
pascal@19515 658 adc [di+8],dx
pascal@19538 659 inc cx ; jcxnz
pascal@19515 660 loop @@next
pascal@19515 661 endif
pascal@19515 662 mov [di+28],si ; m->state
pascal@19515 663 push di
pascal@19515 664 call [word di+26] ; m->next_chunk()
pascal@19515 665 pop di
pascal@19515 666 @@alreadydone:
pascal@19515 667 push ax
pascal@19515 668 image_done:
pascal@19515 669 pop ax
pascal@19515 670 pop di si bp
pascal@19515 671 ret
pascal@19515 672
pascal@19515 673 endp _open_image
pascal@19515 674
pascal@19515 675
pascal@19515 676 ;***************************************************************
pascal@19515 677 ;int read_image(struct image_himem *m, void* data, int sz);
pascal@19515 678 ;***************************************************************
pascal@19515 679 global _read_image:near
pascal@19515 680 proc _read_image near
pascal@19515 681
pascal@19515 682 arg m :word, \
pascal@19515 683 data :word, \
pascal@19515 684 sz :word = PARAM_SIZE
pascal@19515 685
pascal@19515 686 push bp
pascal@19515 687 mov bp,sp
pascal@19515 688 push si di
pascal@19515 689 ifndef NO386
pascal@19515 690 push 0 ; return value
pascal@19515 691 else
pascal@19515 692 xor ax,ax
pascal@19515 693 push ax
pascal@19515 694 endif
pascal@19515 695 mov di,[m]
pascal@19515 696 @@loop:
pascal@19538 697 ifndef NO386
pascal@19538 698 xor ecx,ecx
pascal@19538 699 mov cx,[word sz]
pascal@19538 700 @@chksz:
pascal@19538 701 mov eax,[di+22] ; m->chunk_size
pascal@19538 702 cmp ecx,eax
pascal@19538 703 jb @@szok
pascal@19538 704 xchg eax,ecx
pascal@19538 705 else
pascal@19538 706 mov cx,[word sz]
pascal@19538 707 @@chksz:
pascal@19538 708 mov ax,[di+22] ; lo m->chunk_size
pascal@19538 709 cmp cx,ax
pascal@19515 710 jb @@szok
pascal@19515 711 cmp [word di+24],0 ; hi m->chunk_size
pascal@19515 712 jne @@szok
pascal@19515 713 xchg ax,cx
pascal@19538 714 endif
pascal@19515 715 @@szok:
pascal@19538 716 jcxz image_done
pascal@19538 717 push cx
pascal@19515 718 push [word data]
pascal@19515 719 push [word di]
pascal@19515 720 call _read
pascal@19538 721 pop dx
pascal@19515 722 pop bx
pascal@19538 723 pop dx
pascal@19538 724 jc image_done
pascal@19515 725 add bx,ax
pascal@19515 726 xor cx,cx
pascal@19538 727 ifndef NO386
pascal@19538 728 cwde ; ax < 8000h
pascal@19538 729 cwd
pascal@19538 730 sub [di+22],eax
pascal@19538 731 else
pascal@19538 732 cwd ; ax < 8000h
pascal@19515 733 sub [di+22],ax
pascal@19538 734 sbb [di+24],dx
pascal@19538 735 jnz @@fill
pascal@19538 736 cmp [di+22],dx
pascal@19538 737 endif
pascal@19538 738 jnz @@fill
pascal@19538 739 dec cx
pascal@19515 740 @@fill:
pascal@19515 741 test al,3
pascal@19515 742 je @@filled
pascal@19538 743 mov [bx],dl
pascal@19515 744 inc bx
pascal@19515 745 inc ax
pascal@19515 746 jmp @@fill
pascal@19515 747 @@filled:
pascal@19538 748 ifndef NO386
pascal@19538 749 sub [di+10],eax ; m->remaining
pascal@19538 750 else
pascal@19538 751 sub [di+10],ax ; m->remaining
pascal@19538 752 sbb [di+12],dx
pascal@19538 753 endif
pascal@19515 754 add [bp-4-2],ax
pascal@19515 755 add [word data],ax
pascal@19515 756 sub [word sz],ax
pascal@19538 757 pushf
pascal@19538 758 and cx,[di+26] ; m->next_chunk
pascal@19538 759 jz @@same_chunk
pascal@19515 760 push di
pascal@19515 761 call cx ; m->next_chunk()
pascal@19515 762 pop di
pascal@19538 763 @@same_chunk:
pascal@19538 764 popf
pascal@19538 765 jnz @@loop
pascal@19538 766 jmp image_done
pascal@19515 767
pascal@19515 768 endp _read_image
pascal@19515 769
pascal@19515 770
pascal@19515 771 ;***************************************************************
pascal@19515 772 ;unsigned long strtol(const char *s);
pascal@19515 773 ;***************************************************************
pascal@19515 774 global _strtol:near
pascal@19515 775 proc _strtol near
pascal@19515 776
pascal@19515 777 ifndef NO386
pascal@19515 778 pop ax ;caller return address
pascal@19515 779 pop cx ; s
pascal@19515 780 push cx
pascal@19515 781 push ax
pascal@19515 782 xor ebx,ebx
pascal@19538 783 jcxz @@jncend
pascal@19515 784 push si
pascal@19515 785 mov si,cx
pascal@19515 786 xor ecx,ecx
pascal@19515 787 xor eax,eax
pascal@19515 788 lodsb
pascal@19538 789 mov dl,20h
pascal@19538 790 or dl,al
pascal@19538 791 cmp dl,'n' ; vga=normal
pascal@19538 792 je @@vga
pascal@19538 793 dec cx
pascal@19538 794 cmp dl,'e' ; vga=extended
pascal@19538 795 je @@vga
pascal@19538 796 dec cx
pascal@19538 797 cmp dl,'a' ; vga=ask
pascal@19538 798 jne @@notvga
pascal@19538 799 @@vga:
pascal@19538 800 dec cx
pascal@19538 801 xchg ax,cx
pascal@19538 802 cwd
pascal@19538 803 jmp popsiret
pascal@19538 804 @@notvga:
pascal@19538 805 mov cx,10 ; radix
pascal@19515 806 cmp al,'+'
pascal@19515 807 je @@radixskip
pascal@19515 808 cmp al,'-'
pascal@19515 809 clc
pascal@19515 810 jne @@radixkeep
pascal@19515 811 stc
pascal@19515 812 @@radixskip:
pascal@19515 813 lodsb
pascal@19515 814 @@radixkeep:
pascal@19515 815 pushf
pascal@19515 816 cmp al,'0'
pascal@19515 817 jne @@radixok
pascal@19515 818 mov cl,8
pascal@19515 819 lodsb
pascal@19515 820 mov dl,20h
pascal@19515 821 or dl,al
pascal@19515 822 cmp dl,'x'
pascal@19515 823 jne @@radixok
pascal@19515 824 mov cl,16
pascal@19515 825 @@strtollp:
pascal@19515 826 lodsb
pascal@19515 827 @@radixok:
pascal@19515 828 sub al,'0'
pascal@19515 829 jb @@endstrtol
pascal@19515 830 cmp al,9
pascal@19515 831 jbe @@digitok
pascal@19515 832 or al,20h
pascal@19515 833 cmp al,'a'-'0'
pascal@19515 834 jb @@endstrtol
pascal@19515 835 sub al,'a'-'0'-10
pascal@19515 836 @@digitok:
pascal@19515 837 cmp al,cl
pascal@19515 838 jae @@endstrtol
pascal@19515 839 xchg eax,ebx
pascal@19515 840 mul ecx
pascal@19515 841 add eax,ebx
pascal@19515 842 xchg eax,ebx
pascal@19515 843 jmp @@strtollp
pascal@19515 844 @@endstrtol:
pascal@19515 845 mov cl,10
pascal@19515 846 cmp al,'k'-'a'+10
pascal@19515 847 je @@shift
pascal@19515 848 mov cl,20
pascal@19515 849 cmp al,'m'-'a'+10
pascal@19515 850 je @@shift
pascal@19515 851 mov cl,30
pascal@19515 852 cmp al,'g'-'a'+10
pascal@19515 853 jne @@noshift
pascal@19515 854 @@shift:
pascal@19515 855 shl ebx,cl
pascal@19515 856 @@noshift:
pascal@19515 857 popf
pascal@19538 858 @@jncend:
pascal@19515 859 jnc @@end
pascal@19515 860 neg ebx
pascal@19515 861 @@end:
pascal@19515 862 push ebx
pascal@19515 863 pop ax
pascal@19515 864 pop dx
pascal@19515 865 popsiret:
pascal@19515 866 pop si
pascal@19515 867 else
pascal@19515 868 pop ax ;caller return address
pascal@19515 869 pop cx ; s
pascal@19515 870 push cx
pascal@19515 871 push ax
pascal@19515 872 push si
pascal@19515 873 push di
pascal@19515 874 xor ax,ax
pascal@19515 875 cwd
pascal@19515 876 xchg ax,di
pascal@19538 877 jcxz @@goend
pascal@19515 878 mov si,cx
pascal@19538 879 lodsb
pascal@19538 880 mov dl,20h
pascal@19538 881 or dl,al
pascal@19538 882 mov cx,-1
pascal@19538 883 cmp dl,'n' ; vga=normal
pascal@19538 884 je @@vga
pascal@19538 885 dec cx
pascal@19538 886 cmp dl,'e' ; vga=extended
pascal@19538 887 je @@vga
pascal@19538 888 dec cx
pascal@19538 889 cmp dl,'a' ; vga=ask
pascal@19538 890 jne @@notvga
pascal@19538 891 @@vga:
pascal@19538 892 xchg ax,cx
pascal@19538 893 cwd
pascal@19538 894 jmp popsiret
pascal@19538 895 @@goend:
pascal@19538 896 jmp @@end
pascal@19538 897 @@notvga:
pascal@19515 898 mov cx,10 ; radix
pascal@19515 899 cmp al,'+'
pascal@19515 900 je @@radixskip
pascal@19515 901 cmp al,'-'
pascal@19515 902 clc
pascal@19515 903 jne @@radixkeep
pascal@19515 904 stc
pascal@19515 905 @@radixskip:
pascal@19515 906 lodsb
pascal@19515 907 @@radixkeep:
pascal@19515 908 pushf
pascal@19515 909 cmp al,'0'
pascal@19515 910 jne @@radixok
pascal@19515 911 mov cl,8
pascal@19515 912 lodsb
pascal@19515 913 mov ah,20h
pascal@19515 914 or ah,al
pascal@19515 915 cmp ah,'x'
pascal@19515 916 jne @@radixok
pascal@19515 917 mov cl,16
pascal@19515 918 @@strtollp:
pascal@19515 919 lodsb
pascal@19515 920 @@radixok:
pascal@19515 921 sub al,'0'
pascal@19515 922 jb @@endstrtol
pascal@19515 923 cmp al,9
pascal@19515 924 jbe @@digitok
pascal@19515 925 or al,20h
pascal@19515 926 cmp al,'a'-'0'
pascal@19515 927 jb @@endstrtol
pascal@19515 928 sub al,'a'-'0'-10
pascal@19515 929 @@digitok:
pascal@19515 930 cmp al,cl
pascal@19515 931 jae @@endstrtol
pascal@19515 932
pascal@19515 933 push ax
pascal@19515 934 push si
pascal@19515 935 push dx
pascal@19515 936 xchg ax,di
pascal@19515 937 mul cx
pascal@19515 938 xchg ax,di
pascal@19515 939 xchg ax,dx
pascal@19515 940 xchg ax,si
pascal@19515 941 pop ax
pascal@19515 942 mul cx
pascal@19515 943 add ax,si
pascal@19515 944 pop si
pascal@19515 945 xchg ax,dx
pascal@19515 946 pop ax
pascal@19515 947 mov ah,0
pascal@19515 948 add di,ax
pascal@19515 949 adc dx,0
pascal@19515 950
pascal@19515 951 jmp @@strtollp
pascal@19515 952 @@endstrtol:
pascal@19515 953 mov cl,10
pascal@19515 954 cmp al,'k'-'a'+10
pascal@19515 955 je @@shift
pascal@19515 956 mov cl,20
pascal@19515 957 cmp al,'m'-'a'+10
pascal@19515 958 je @@shift
pascal@19515 959 mov cl,30
pascal@19515 960 cmp al,'g'-'a'+10
pascal@19515 961 jne @@noshift
pascal@19515 962 @@shift:
pascal@19515 963 rcl di,1
pascal@19515 964 shl dx,1
pascal@19515 965 loop @@shift
pascal@19515 966 @@noshift:
pascal@19515 967 popf
pascal@19515 968 jnc @@end
pascal@19515 969 not dx
pascal@19515 970 neg di
pascal@19515 971 jne @@end
pascal@19515 972 inc dx
pascal@19515 973 @@end:
pascal@19515 974 xchg ax,di
pascal@19515 975 pop di
pascal@19515 976 popsiret:
pascal@19515 977 pop si
pascal@19515 978 endif
pascal@19515 979 ret
pascal@19515 980
pascal@19515 981 endp _strtol
pascal@19515 982
pascal@19515 983
pascal@19515 984 ;***************************************************************
pascal@19515 985 ;>void sort(unsigned long *base:BX!, size_t nel:CX)
pascal@19515 986 ;NO386 safe: only used by VCPI
pascal@19515 987 ;***************************************************************
pascal@19515 988 global _sort:near
pascal@19515 989 proc _sort near
pascal@19515 990
pascal@19515 991 pop ax ;caller return address
pascal@19515 992 pop bx ; base
pascal@19515 993 pop cx ; nel
pascal@19515 994 push cx
pascal@19515 995 push bx
pascal@19515 996 push ax
pascal@19515 997 global sort:near
pascal@19515 998 sort:
pascal@19515 999 ifndef fastsort
pascal@19515 1000 ; bubble sort
pascal@19515 1001 push si
pascal@19515 1002 shl cx,2
pascal@19515 1003 @@loop:
pascal@19515 1004 xor ax,ax
pascal@19515 1005 mov si,4
pascal@19538 1006 cmp cx,si
pascal@19538 1007 jbe popsiret
pascal@19515 1008 @@next:
pascal@19515 1009 mov edx,[bx+si-4]
pascal@19515 1010 cmp edx,[bx+si]
pascal@19515 1011 jbe @@ok
pascal@19515 1012 xchg edx,[bx+si]
pascal@19515 1013 mov [bx+si-4],edx
pascal@19515 1014 mov ax,si
pascal@19515 1015 @@ok:
pascal@19515 1016 add si,4
pascal@19515 1017 cmp si,cx
pascal@19515 1018 jb @@next
pascal@19515 1019 xchg ax,cx
pascal@19515 1020 jmp @@loop
pascal@19515 1021 else
pascal@19515 1022 ; shell sort (c) uclibc GPL
pascal@19515 1023 push si di
pascal@19515 1024 ; {
pascal@19515 1025 ;> size_t wgap:SI;
pascal@19515 1026 ;
pascal@19515 1027 ; if (nel > 1) {
pascal@19515 1028 cmp cx,1
pascal@19515 1029 jbe @@end
pascal@19515 1030 ; wgap = 0;
pascal@19515 1031 xor ax,ax
pascal@19515 1032 ; do {
pascal@19515 1033 @@wgaplp:
pascal@19515 1034 mov si,ax
pascal@19515 1035 ; wgap = 3 * wgap + 1;
pascal@19515 1036 mov dx,3
pascal@19515 1037 mul dx
pascal@19515 1038 inc ax
pascal@19515 1039 ; } while (wgap < (nel-1)/3);
pascal@19515 1040 cmp ax,cx
pascal@19515 1041 jb @@wgaplp
pascal@19515 1042 ; /* From the above, we know that either wgap == 1 < nel or */
pascal@19515 1043 ; /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
pascal@19515 1044 ; wgap *= 4; /* So this can not overflow if wnel doesn't. */
pascal@19515 1045 shl si,2
pascal@19515 1046 ; nel *= 4; /* Convert nel to 'wnel' */
pascal@19515 1047 shl cx,2
pascal@19515 1048 ; do {
pascal@19515 1049 @@lp1:
pascal@19515 1050 ;> size_t i:DI;
pascal@19515 1051 ; i = wgap;
pascal@19515 1052 mov di,si
pascal@19515 1053 ; do {
pascal@19515 1054 @@lp2:
pascal@19515 1055 ;> size_t j:DX;
pascal@19515 1056 ; j = i;
pascal@19515 1057 mov dx,di
pascal@19515 1058 ; do {
pascal@19515 1059 @@lp3:
pascal@19515 1060 ;> register char *a:BX!;
pascal@19515 1061 ;
pascal@19515 1062 ; j -= wgap;
pascal@19515 1063 sub dx,si
pascal@19515 1064 ; a = j + ((char *)base);
pascal@19515 1065 push bx
pascal@19515 1066 add bx,dx
pascal@19515 1067 ; if (cmp(a, a + wgap) <= 0) {
pascal@19515 1068 mov eax,[bx]
pascal@19515 1069 cmp eax,[bx+si]
pascal@19515 1070 jbe @@brk3
pascal@19515 1071 ; break;
pascal@19515 1072 ; }
pascal@19515 1073 xchg eax,[bx+si]
pascal@19515 1074 mov [bx],eax
pascal@19515 1075 ; swap(a, a + wgap);
pascal@19515 1076 pop bx
pascal@19515 1077 ; } while (j >= wgap);
pascal@19515 1078 cmp dx,si
pascal@19515 1079 jae @@lp3
pascal@19515 1080 push bx
pascal@19515 1081 @@brk3:
pascal@19515 1082 pop bx
pascal@19515 1083 ; i += 4;
pascal@19515 1084 add di,4
pascal@19515 1085 ; } while (i < nel);
pascal@19515 1086 cmp di,cx
pascal@19515 1087 jb @@lp2
pascal@19515 1088 ; wgap = (wgap - 4)/3;
pascal@19515 1089 sub si,4
pascal@19515 1090 xchg ax,si
pascal@19515 1091 cwd
pascal@19515 1092 mov si,3
pascal@19515 1093 div si ; kill dx
pascal@19515 1094 xchg ax,si
pascal@19515 1095 ; } while (wgap);
pascal@19515 1096 or si,si
pascal@19515 1097 jnz @@lp1
pascal@19515 1098 @@end:
pascal@19515 1099 ; }
pascal@19515 1100 ;}
pascal@19515 1101 pop di si
pascal@19515 1102 ret
pascal@19515 1103 endif
pascal@19515 1104
pascal@19515 1105 endp _sort
pascal@19515 1106
pascal@19515 1107
pascal@19515 1108 ifdef NO386
pascal@19515 1109 ;***************************************************************
pascal@19515 1110 ;u16 topseg();
pascal@19515 1111 ;***************************************************************
pascal@19515 1112 global _topseg:near
pascal@19515 1113 proc _topseg near
pascal@19515 1114
pascal@19515 1115 int 12h
pascal@19515 1116 jnc @@max640k
pascal@19515 1117 mov ax,640 ; 9000
pascal@19515 1118 @@max640k:
pascal@19538 1119 sub ax,028h
pascal@19515 1120 and al,0C0h
pascal@19515 1121 mov cl,6
pascal@19515 1122 shl ax,cl
pascal@19515 1123 ret
pascal@19515 1124
pascal@19515 1125 endp _topseg
pascal@19515 1126 endif
pascal@19515 1127
pascal@19538 1128 ;***************************************************************
pascal@19538 1129 ;void rmcpy(void* rmbuf, u16 rmsize);
pascal@19538 1130 ;***************************************************************
pascal@19538 1131 global _rmcpy:near
pascal@19538 1132 proc _rmcpy near
pascal@19538 1133
pascal@19538 1134 pop bx ;caller return address
pascal@19538 1135 pop ax ; rmbuf
pascal@19538 1136 pop cx ; rmsize
pascal@19538 1137 push cx
pascal@19538 1138 push ax
pascal@19538 1139 push bx
pascal@19538 1140 push si di es
pascal@19538 1141 xchg ax,si
pascal@19538 1142 xor di,di
pascal@19538 1143 ifdef NO386
pascal@19538 1144 call _topseg
pascal@19538 1145 mov es,ax
pascal@19538 1146 else
pascal@19538 1147 push 9000h
pascal@19538 1148 pop es
pascal@19538 1149 endif
pascal@19538 1150 cld
pascal@19538 1151 rep
pascal@19538 1152 movsb
pascal@19538 1153 extrn _cmdline:word
pascal@19538 1154 mov si,[_cmdline]
pascal@19538 1155 mov di,8000h
pascal@19538 1156 mov ch,10h ; 4k
pascal@19538 1157 rep
pascal@19538 1158 movsb
pascal@19538 1159 pop es di si
pascal@19538 1160 ret
pascal@19538 1161
pascal@19538 1162 endp _rmcpy
pascal@19515 1163
pascal@19515 1164 ends _TEXT
pascal@19515 1165
pascal@19515 1166 end
pascal@19515 1167
pascal@19515 1168 ;###### END OF FILE ############################################