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

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