wok-current diff linld/stuff/src/CRTL.ASM @ rev 19571
linld: large image support with VCPI
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Dec 22 21:06:17 2016 +0100 (2016-12-22) |
parents | 31c5cbbd9380 |
children | 23fc786c04e8 |
line diff
1.1 --- a/linld/stuff/src/CRTL.ASM Tue Dec 06 18:49:44 2016 +0100 1.2 +++ b/linld/stuff/src/CRTL.ASM Thu Dec 22 21:06:17 2016 +0100 1.3 @@ -18,7 +18,7 @@ 1.4 msg_hang db "High mem corrupted - not exiting to DOS" 1.5 msg_crlf db 13,10,0 1.6 vcpi_alloc_err db "vcpi " 1.7 -msg_malloc db "malloc() failure",0 1.8 +msg_malloc db "malloc failure",0 1.9 1.10 ends _DATA 1.11 1.12 @@ -28,6 +28,9 @@ 1.13 _no_exit db ? 1.14 filecnt db ? ; in fact 0 minus file count... 1.15 nextfilename dw ? 1.16 + ifdef LARGE_IMAGES 1.17 +curdata dw ? 1.18 + endif 1.19 1.20 ends _BSS 1.21 1.22 @@ -112,13 +115,13 @@ 1.23 push cx 1.24 push ax 1.25 global malloc:near ; malloc(cx) 1.26 -malloc: 1.27 +malloc: ; keep CX, use AX,BX 1.28 mov ax,[_heap_top] 1.29 + mov bx,-1400h ; MIN_STACK=_1k+PAGE_SIZE 1.30 + add bx,sp 1.31 + sub bx,ax ; can't overflow 1.32 + cmp bx,cx 1.33 mov bx,offset msg_malloc 1.34 - mov dx,-1400h ; MIN_STACK=_1k+PAGE_SIZE 1.35 - add dx,sp 1.36 - sub dx,ax ; can't overflow 1.37 - cmp dx,cx 1.38 jb puts 1.39 add [_heap_top],cx ; _BEG has zero'd heap 1.40 ;mov bx,ax 1.41 @@ -286,38 +289,32 @@ 1.42 1.43 1.44 ;*************************************************************** 1.45 -;long lseek(int fd, long sz, int dir); 1.46 +;long lseekset(int fd, long sz); 1.47 ;*************************************************************** 1.48 - global _lseek:near 1.49 - proc _lseek near 1.50 + global _lseekset:near 1.51 + proc _lseekset near 1.52 1.53 - ifndef NO386 1.54 pop ax ;caller return address 1.55 pop bx ; fd 1.56 - pop ecx ; sz 1.57 - pop dx ; dir 1.58 + pop dx ; sz lo 1.59 + pop cx ; sz hi 1.60 + push cx 1.61 push dx 1.62 - push ecx 1.63 push bx 1.64 push ax 1.65 - else 1.66 - mov bx,sp 1.67 - mov dx,[bx+8] 1.68 - mov cx,[bx+6] 1.69 - mov ax,[bx+4] 1.70 - mov bx,[bx+2] 1.71 - endif 1.72 -lseek: 1.73 - xchg ax,dx ; dir 1.74 - mov ah,42h 1.75 - ifndef NO386 1.76 - push ecx 1.77 - pop dx 1.78 - pop cx 1.79 - endif 1.80 + global lseekset:near 1.81 +lseekset: 1.82 + clc 1.83 + global rewind:near 1.84 +rewind: ; rewind(bx,C=1) 1.85 + mov ax,4200h 1.86 + jnc dos 1.87 +lseek0: ; lseek0(bx,ax=dir) 1.88 + cwd 1.89 + xor cx,cx 1.90 jmp dos 1.91 1.92 - endp _lseek 1.93 + endp _lseekset 1.94 1.95 1.96 ;*************************************************************** 1.97 @@ -444,6 +441,16 @@ 1.98 fd2close dw ? ;30 u16 fd2close; 1.99 ends ;}; 1.100 1.101 + ifdef LARGE_IMAGES 1.102 +struc data_himem ;struct data_himem { 1.103 +first dd ? ; 0 u32 first; 1.104 +cacheidx dw ? ; 4 int cacheidx; 1.105 +pageidx dw ? ; 6 int pageidx; 1.106 +cache dd 1024 dup(?) ; 8 int cache; 1.107 +page dd 1024 dup(?) ;4104 int page; 1.108 +ends ;}; // size=8200 1.109 + endif 1.110 + 1.111 ;*************************************************************** 1.112 ;u32* malloc_bufv_or_die(struct image_himem *m); 1.113 ;*************************************************************** 1.114 @@ -456,6 +463,16 @@ 1.115 push bx 1.116 push si 1.117 xchg ax,si 1.118 + ifdef LARGE_IMAGES 1.119 + mov cx,[word ((image_himem si).size) + 2] 1.120 + shr cx,4 ; pages index size = size >> 20 1.121 + add cx,8+4096+8 1.122 + call malloc_or_die 1.123 + mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE; 1.124 + add ecx,[(image_himem si).size] 1.125 + shr ecx,12 1.126 + mov [curdata],ax 1.127 + else 1.128 mov ecx,[(image_himem si).size] 1.129 dec ecx 1.130 shr ecx,12 1.131 @@ -466,59 +483,88 @@ 1.132 ; our malloc zeroes allocated mem: bufv[cnt]=0; 1.133 ; Allocate pages, storing addrs in addrbuf 1.134 call malloc_or_die 1.135 - pop cx 1.136 - push cx ; _sort:nel 1.137 - push ax ; _sort:base 1.138 + pop cx 1.139 + push ax 1.140 + endif 1.141 mov [(image_himem si).bufv],ax 1.142 - xchg ax,bx 1.143 + xchg ax,si 1.144 @@vcpi_alloc: 1.145 xor edx,edx 1.146 mov ax,0DE04h 1.147 int 67h 1.148 or ah,ah 1.149 - jz @@ok 1.150 mov bx,offset vcpi_alloc_err 1.151 - jmp die 1.152 -@@ok: 1.153 - mov [bx],edx 1.154 - add bx,4 1.155 + jnz die 1.156 +; for (i = cnt-1; i >= 0; i--) 1.157 + ifdef LARGE_IMAGES 1.158 + mov eax,ecx 1.159 + dec eax 1.160 + else 1.161 + mov ax,cx 1.162 + dec ax 1.163 + cwde 1.164 + endif 1.165 + shl eax,12 ; i*_4k 1.166 +; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again 1.167 + extrn _pm 1.168 + mov bx,offset _pm+2 1.169 + push eax 1.170 + add eax,[bx-2+2] 1.171 + cmp eax,edx ; pm.fallback+i*_4k <= edx ? 1.172 + pop eax ; i*_4k 1.173 + jbe @@pmok 1.174 + cmp edx,[bx-2+2] ; edx >= pm.fallback ? 1.175 + jae @@vcpi_alloc 1.176 +@@pmok: 1.177 +; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again 1.178 + extrn _initrd 1.179 + mov bx,offset _initrd+2 1.180 + add eax,[bx-2+2] ; +initrd.fallback 1.181 + cmp eax,edx ; initrd.fallback+i*_4k > edx ? 1.182 + ja @@initrdok 1.183 + mov eax,[bx-2+6] ; initrd.size 1.184 + add eax,[bx-2+2] ; +initrd.fallback 1.185 + cmp eax,edx ; initrd.fallback+initrd.size > edx ? 1.186 +@@jnc_vcpi_alloc: 1.187 + ja @@vcpi_alloc 1.188 +@@initrdok: 1.189 + ifdef LARGE_IMAGES 1.190 + cmp [(data_himem si).first],0 1.191 + jne @@notfirst 1.192 + mov [(data_himem si).first],edx 1.193 +@@notfirst: 1.194 + mov bx,[(data_himem si).cacheidx] 1.195 + cmp bh,4 1.196 + jae @@nextpage 1.197 + shl bx,2 1.198 + inc [(data_himem si).cacheidx] 1.199 + mov [(data_himem bx+si).cache],edx 1.200 + loopd @@vcpi_alloc 1.201 + mov [(data_himem bx+si).cache],ecx ; last is 0 1.202 +@@nextpage: 1.203 + and [(data_himem si).cacheidx],0 1.204 + mov bx,[(data_himem si).pageidx] 1.205 + mov [(data_himem bx+si).page],edx 1.206 + add [(data_himem si).pageidx],4 1.207 + push cx 1.208 + lea cx,[(data_himem si).cache] 1.209 + ifdef NO386 1.210 + push edx 1.211 + pop dx 1.212 + pop ax 1.213 + endif 1.214 + call storepage ; storepage(edx,cx) 1.215 + pop cx 1.216 + or ecx,ecx ; clear C 1.217 + jnz @@jnc_vcpi_alloc 1.218 + mov [dword (data_himem si).cacheidx],ecx 1.219 + xchg ax,si 1.220 + else 1.221 + mov [si],edx 1.222 + lodsd ; si=+4 1.223 loop @@vcpi_alloc 1.224 -@@again: 1.225 - call _sort 1.226 - extrn _initrd 1.227 - cmp si,offset _initrd 1.228 - jne @@quit 1.229 pop ax 1.230 - pop cx 1.231 - push cx ; _sort:nel 1.232 - push ax ; _sort:base = m->bufv 1.233 -;again: 1.234 -; for (i = cnt-1; i >= 0; i--) { 1.235 -@@chkloop: 1.236 - mov bx,cx 1.237 - dec bx 1.238 -; if (m->bufv[i] > m->fallback+i*_4k && m->bufv[i] < m->fallback+m->size) { 1.239 - shl bx,2 1.240 - add bx,ax ; m->bufv 1.241 - mov edx,[bx] ; m->bufv[i] 1.242 - sub edx,[(image_himem si).fallback] 1.243 - cmp edx,[(image_himem si).size] 1.244 - jae @@chknext 1.245 - shr edx,12 1.246 - cmp dx,cx 1.247 - jb @@chknext 1.248 -; m->bufv[i] = vcpi_alloc_or_die(); 1.249 -; sort(m->bufv,cnt); 1.250 -; goto again; 1.251 - mov cx,1 1.252 - jmp @@vcpi_alloc 1.253 -; } 1.254 -; } 1.255 -@@chknext: 1.256 - loop @@chkloop 1.257 -@@quit: 1.258 - pop ax 1.259 - pop cx 1.260 + endif 1.261 pop si 1.262 ret 1.263 1.264 @@ -526,16 +572,189 @@ 1.265 1.266 1.267 ;*************************************************************** 1.268 -;void next_chunk(struct image_himem *m); 1.269 +; void memcpy_image(struct image_himem *m); 1.270 ;*************************************************************** 1.271 - proc _next_chunk near 1.272 + global _memcpy_image:near 1.273 + proc _memcpy_image near 1.274 1.275 + pop ax ;caller return address 1.276 pop bx 1.277 + push bx 1.278 + push ax 1.279 + ifndef NO386 1.280 + mov edx,[(image_himem bx).fallback] 1.281 + mov eax,[(image_himem bx).buf] 1.282 + cmp eax,edx ; if (m->fallback != m->buf) 1.283 + jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size) 1.284 + ifdef LARGE_IMAGES 1.285 + mov ecx,[(image_himem bx).size] 1.286 +memcpy_imagez: 1.287 + push ecx 1.288 + else 1.289 + push [(image_himem bx).size] 1.290 + endif 1.291 + push eax 1.292 + push 0 1.293 +call_memcpy32: 1.294 + push edx 1.295 + else 1.296 + mov ax,[word ((image_himem bx).fallback)] 1.297 + mov dx,[word ((image_himem bx).fallback)+2] 1.298 + mov cx,[word ((image_himem bx).buf)] 1.299 + cmp ax,cx ; if (m->fallback != m->buf) 1.300 + jnz @@do 1.301 + cmp dx,[word ((image_himem bx).buf)+2] 1.302 + jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size) 1.303 +@@do: 1.304 + push [word ((image_himem bx).size)+2] 1.305 + push [word ((image_himem bx).size)] 1.306 + push [word ((image_himem bx).buf)+2] 1.307 + push cx 1.308 + xor cx,cx 1.309 + push cx 1.310 +call_memcpy32: 1.311 + push dx 1.312 + push ax 1.313 + ifdef LARGE_IMAGES 1.314 + jmp @@memcpy 1.315 +memcpy_imagez: 1.316 + push ecx 1.317 + push eax 1.318 + push 0 1.319 + push edx 1.320 + endif 1.321 + endif 1.322 +@@memcpy: 1.323 + extrn _memcpy32:near 1.324 + call near _memcpy32 1.325 + add sp,14 1.326 +@@skip: 1.327 + ret 1.328 + 1.329 + endp _memcpy_image 1.330 + 1.331 +;*************************************************************** 1.332 +;void storepage(u32 *dst, u16 src); 1.333 +;*************************************************************** 1.334 + global _storepage:near 1.335 + proc _storepage near 1.336 + 1.337 + pop ax ;caller return address 1.338 + pop bx 1.339 + pop cx 1.340 + push cx 1.341 + push bx 1.342 + push ax 1.343 + ifndef NO386 1.344 + mov edx,[bx] 1.345 + else 1.346 + mov ax,[bx] 1.347 + mov dx,[bx+2] 1.348 + endif 1.349 +storepage: 1.350 + ifndef NO386 1.351 + push 0 1.352 + push 4096 1.353 + push 0 1.354 + else 1.355 + xor bx,bx 1.356 + push bx 1.357 + mov bh,4096/256 1.358 + push bx 1.359 + xor bx,bx 1.360 + push bx 1.361 + endif 1.362 + push cx 1.363 + push ds 1.364 + jmp call_memcpy32 1.365 + 1.366 + endp _storepage 1.367 + 1.368 + 1.369 + ifdef LARGE_IMAGES 1.370 +;*************************************************************** 1.371 +;void reset_bufv(u32 *p); 1.372 +;*************************************************************** 1.373 + global _reset_bufv:near 1.374 + proc _reset_bufv near 1.375 + 1.376 + pop bx ;caller return address 1.377 pop ax 1.378 push ax 1.379 push bx 1.380 - push si di 1.381 - xchg ax,di 1.382 + mov [curdata],ax 1.383 + xchg ax,bx 1.384 + and [dword (data_himem bx).cacheidx],0 1.385 + ret 1.386 + 1.387 + endp _reset_bufv 1.388 + 1.389 +;*************************************************************** 1.390 +;u32* prev_bufv(); 1.391 +;u32* prev_bufv(); 1.392 +;*************************************************************** 1.393 + global _prev_bufv:near 1.394 + global _next_bufv:near 1.395 + proc _prev_bufv near 1.396 + 1.397 + stc 1.398 + db 73h ; jnc 1.399 +_next_bufv: 1.400 + clc 1.401 + sbb ax,ax 1.402 + stc 1.403 + rcl ax,1 ; -1/+1 1.404 + xor ecx,ecx 1.405 + push si 1.406 + mov si,[curdata] 1.407 + add ax,[(data_himem si).cacheidx] 1.408 + test ax,0fc00h 1.409 + jz @@gotpage 1.410 + push ax ; FFFF / 0400 1.411 + sar ax,8 ; FFFC / 0004 1.412 + and al,0fch 1.413 + add [(data_himem si).pageidx],ax 1.414 + mov bx,[(data_himem si).pageidx] 1.415 + lea bx,[(data_himem bx+si).page] 1.416 + mov edx,ds 1.417 + shl edx,4 1.418 + lea cx,[(data_himem si).cache] 1.419 + add edx,ecx 1.420 + mov eax,[bx] 1.421 + or eax,eax 1.422 + jnz @@pageok 1.423 + pop ax 1.424 + xchg ax,bx 1.425 + pop si 1.426 + ret 1.427 +@@pageok: 1.428 + mov cx,4096 1.429 + call memcpy_imagez ; get page 1.430 + pop ax ; FFFF / 0400 1.431 + cbw 1.432 + shr ax,6 ; 03FF / 0000 1.433 +@@gotpage: 1.434 + mov [(data_himem si).cacheidx],ax 1.435 + shl ax,2 1.436 + xchg ax,bx 1.437 + lea ax,[(data_himem bx+si).cache] 1.438 + or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx 1.439 + jnz @@notfirst2 1.440 + xchg ax,si ; &first 1.441 +@@notfirst2: 1.442 + pop si 1.443 + ret 1.444 + 1.445 + endp _prev_bufv 1.446 + endif 1.447 + 1.448 + 1.449 +;*************************************************************** 1.450 +;void next_chunk(struct image_himem *m); 1.451 +;*************************************************************** 1.452 + proc next_chunk near 1.453 + 1.454 + push si 1.455 mov bx,[(image_himem di).fd] 1.456 call close 1.457 ifndef NO386 1.458 @@ -567,44 +786,35 @@ 1.459 jc @@die 1.460 mov [(image_himem di).fd],ax 1.461 mov [(image_himem di).fd2close],ax 1.462 - mov dx,2 ; SEEK_END 1.463 xchg ax,bx 1.464 - ifndef NO386 1.465 - xor ecx,ecx 1.466 - else 1.467 - xor ax,ax 1.468 - xor cx,cx 1.469 - endif 1.470 - call lseek 1.471 + mov ax,4202h ; SEEK_END 1.472 + call lseek0 1.473 @@die: 1.474 mov bx,[(image_himem di).errmsg] 1.475 jc die 1.476 mov bx,[(image_himem di).fd] 1.477 ifndef NO386 1.478 push eax 1.479 - xor ecx,ecx 1.480 - xor dx,dx 1.481 - call lseek ; rewind 1.482 + stc 1.483 + call rewind 1.484 pop eax 1.485 @@end: 1.486 mov [(image_himem di).chunk_size],eax 1.487 else 1.488 push ax 1.489 push dx 1.490 - xor ax,ax 1.491 - xor cx,cx 1.492 - cwd 1.493 - call lseek ; rewind 1.494 + stc 1.495 + call rewind 1.496 pop dx 1.497 pop ax 1.498 @@end: 1.499 mov [word (image_himem di).chunk_size],ax 1.500 mov [word ((image_himem di).chunk_size)+2],dx 1.501 endif 1.502 - pop di si 1.503 + pop si 1.504 ret 1.505 1.506 - endp _next_chunk 1.507 + endp next_chunk 1.508 1.509 1.510 ;*************************************************************** 1.511 @@ -633,7 +843,7 @@ 1.512 mov [word (image_himem di).size],ax ; m->size = 0L 1.513 mov [word ((image_himem di).size)+2],ax 1.514 endif 1.515 - mov [(image_himem di).next_chunk],offset _next_chunk 1.516 + mov [(image_himem di).next_chunk],offset next_chunk 1.517 mov si,[fname] 1.518 mov [(image_himem di).state],si 1.519 @@next: 1.520 @@ -979,130 +1189,6 @@ 1.521 endp _strtol 1.522 1.523 1.524 -;*************************************************************** 1.525 -;>void sort(unsigned long *base:BX!, size_t nel:CX) 1.526 -;NO386 safe: only used by VCPI 1.527 -;*************************************************************** 1.528 - global _sort:near 1.529 - proc _sort near 1.530 - 1.531 - pop ax ;caller return address 1.532 - pop bx ; base 1.533 - pop cx ; nel 1.534 - push cx 1.535 - push bx 1.536 - push ax 1.537 - global sort:near 1.538 -sort: 1.539 - ifndef fastsort 1.540 -; bubble sort 1.541 - push si 1.542 - shl cx,2 1.543 -@@loop: 1.544 - xor ax,ax 1.545 - mov si,4 1.546 - cmp cx,si 1.547 - jbe popsiret 1.548 -@@next: 1.549 - mov edx,[bx+si-4] 1.550 - cmp edx,[bx+si] 1.551 - jbe @@ok 1.552 - xchg edx,[bx+si] 1.553 - mov [bx+si-4],edx 1.554 - mov ax,si 1.555 -@@ok: 1.556 - add si,4 1.557 - cmp si,cx 1.558 - jb @@next 1.559 - xchg ax,cx 1.560 - jmp @@loop 1.561 - else 1.562 -; shell sort (c) uclibc GPL 1.563 - push si di 1.564 -; { 1.565 -;> size_t wgap:SI; 1.566 -; 1.567 -; if (nel > 1) { 1.568 - cmp cx,1 1.569 - jbe @@end 1.570 -; wgap = 0; 1.571 - xor ax,ax 1.572 -; do { 1.573 -@@wgaplp: 1.574 - mov si,ax 1.575 -; wgap = 3 * wgap + 1; 1.576 - mov dx,3 1.577 - mul dx 1.578 - inc ax 1.579 -; } while (wgap < (nel-1)/3); 1.580 - cmp ax,cx 1.581 - jb @@wgaplp 1.582 -; /* From the above, we know that either wgap == 1 < nel or */ 1.583 -; /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */ 1.584 -; wgap *= 4; /* So this can not overflow if wnel doesn't. */ 1.585 - shl si,2 1.586 -; nel *= 4; /* Convert nel to 'wnel' */ 1.587 - shl cx,2 1.588 -; do { 1.589 -@@lp1: 1.590 -;> size_t i:DI; 1.591 -; i = wgap; 1.592 - mov di,si 1.593 -; do { 1.594 -@@lp2: 1.595 -;> size_t j:DX; 1.596 -; j = i; 1.597 - mov dx,di 1.598 -; do { 1.599 -@@lp3: 1.600 -;> register char *a:BX!; 1.601 -; 1.602 -; j -= wgap; 1.603 - sub dx,si 1.604 -; a = j + ((char *)base); 1.605 - push bx 1.606 - add bx,dx 1.607 -; if (cmp(a, a + wgap) <= 0) { 1.608 - mov eax,[bx] 1.609 - cmp eax,[bx+si] 1.610 - jbe @@brk3 1.611 -; break; 1.612 -; } 1.613 - xchg eax,[bx+si] 1.614 - mov [bx],eax 1.615 -; swap(a, a + wgap); 1.616 - pop bx 1.617 -; } while (j >= wgap); 1.618 - cmp dx,si 1.619 - jae @@lp3 1.620 - push bx 1.621 -@@brk3: 1.622 - pop bx 1.623 -; i += 4; 1.624 - add di,4 1.625 -; } while (i < nel); 1.626 - cmp di,cx 1.627 - jb @@lp2 1.628 -; wgap = (wgap - 4)/3; 1.629 - sub si,4 1.630 - xchg ax,si 1.631 - cwd 1.632 - mov si,3 1.633 - div si ; kill dx 1.634 - xchg ax,si 1.635 -; } while (wgap); 1.636 - or si,si 1.637 - jnz @@lp1 1.638 -@@end: 1.639 -; } 1.640 -;} 1.641 - pop di si 1.642 - ret 1.643 -endif 1.644 - 1.645 - endp _sort 1.646 - 1.647 - 1.648 ifdef NO386 1.649 ;*************************************************************** 1.650 ;u16 topseg(); 1.651 @@ -1123,42 +1209,6 @@ 1.652 endp _topseg 1.653 endif 1.654 1.655 -;*************************************************************** 1.656 -;void rmcpy(void* rmbuf, u16 rmsize); 1.657 -;*************************************************************** 1.658 - global _rmcpy:near 1.659 - proc _rmcpy near 1.660 - 1.661 - pop bx ;caller return address 1.662 - pop ax ; rmbuf 1.663 - pop cx ; rmsize 1.664 - push cx 1.665 - push ax 1.666 - push bx 1.667 - push si di es 1.668 - xchg ax,si 1.669 - xor di,di 1.670 - ifdef NO386 1.671 - call _topseg 1.672 - mov es,ax 1.673 - else 1.674 - push 9000h 1.675 - pop es 1.676 - endif 1.677 - cld 1.678 - rep 1.679 - movsb 1.680 - extrn _cmdline:word 1.681 - mov si,[_cmdline] 1.682 - mov di,8000h 1.683 - mov ch,10h ; 4k 1.684 - rep 1.685 - movsb 1.686 - pop es di si 1.687 - ret 1.688 - 1.689 - endp _rmcpy 1.690 - 1.691 ends _TEXT 1.692 1.693 end