cseg segment para public 'code' org 100h ; This program is used to load an EXE file faster than DOS. ; To use it, enter 'RUN prog', where prog is a valid EXE program. ; The file may be any size, but for programs less than 64K, ; making a COM file using EXETOCOM.BIN as a header works faster. recct equ 504 ; max recs per read run proc far assume cs:cseg,ds:cseg,ss:nothing,es:nothing mov sp,offset estak ; point to internal stack call p100 ; initialize call p200 ; open file jmp p300 ; copy this prog to hi memory p010: call p400 ; read exe file to lo memory jmp p600 ; relocate and execute prog p050: mov ah,9 ; print error message int 21h mov ax,oseg push ax xor ax,ax push ax ret 0 ; terminate p100 proc near ; initialize mov dx,offset copyr mov ah,9 ; print copyright message int 21h mov ax,ds mov oseg,ax ; save original seg add ax,10h mov nseg,ax ; save new prog seg mov si,2 mov bx,[si] ; get top of memory from psp mov topmem,bx mov ax,offset endprog add ax,15 and ax,0fff0h mov eprog,ax ; point to end of prog mov cl,4 shr ax,cl mov bx,ds add ax,bx mov dtads,ax ; point to start dta mov si,5ch ; point to 1st fcb mov di,offset fcb ; & work fcb mov cx,37 rep movsb ; copy it mov di,offset fcb+9 ; make sure extension is 'EXE' mov si,offset exe mov cx,3 repnz movsb ; copy 'EXE' to extension ; juggle fcbs in psp mov si,81h ; point to command line in psp mov di,5ch ; point to first fcb in psp mov ax,2901h int 21h ; parse first file name (prog to execute) ; rearrange command line mov di,81h ; point to start of command line mov bx,80h mov ch,0 mov cl,[bx] ; get length of command line add cx,di sub cx,si ; new command line length mov [bx],cl ; save it inc cl ; copy carriage return too! repnz movsb ; move command line down mov si,offset fcbfill ; fill fcbs with blanks mov di,offset 5ch mov cx,16 rep movsb ; clear first fcb mov si,offset fcbfill mov di,offset 6ch mov cx,16 rep movsb ; clear second fcb mov si,81h ; get command line back mov di,5ch ; point to first fcb mov ax,2901h mov bx,offset drives int 21h ; parse first parm cmp al,1 ; error? jbe p110 ; no mov [bx],al ; set error in lo byte p110: mov di,6ch mov ax,2901h int 21h ; parse second parm cmp al,1 ; error? jbe p120 ; no mov [bx+1],al ; set error in hi byte p120: ret p100 endp p200 proc near ; open file mov dx,offset fcb mov ah,0fh int 21h and al,0ffh ; error? jz p210 ; no mov dx,offset errmsg1 jmp p050 p210: mov si,offset fcb+16 ; get file size mov ax,[si] ; lower part mov cl,7 shr ax,cl ; divide by 128 mov bx,ax ; hold in bx mov ax,[si+2] ; upper part of file size mov cl,9 sal ax,cl ; divide by 128 add ax,bx ; total file size divided by 128 mov norecs,ax ; save as norecs mov ax,128 mov si,offset fcb+14 ; set recsize = 128 mov [si],ax mov al,0 ; zero 5 bytes in fcb mov di,offset fcb+32 mov cx,5 repnz stosb ; clear fcb bytes 32 - 36 mov ax,norecs mov cl,3 sal ax,cl ; # of pghs for prog add ax,dtads ; top of prog (pghs) mov bx,topmem ; top of memory cmp bx,ax ; is there room? jae p220 ; yes mov dx,offset errmsg4 jmp p050 p220: ret p200 endp p300: ; read exe header mov cx,4 call p500 ; read 4 recs mov si,eprog mov ax,[si] ; get EXE signature cmp ax,5a4dh ; valid exe file? jz p310 ; yes mov dx,offset errmsg2 jmp p050 p310: ; check stack placement mov ax,[si+10h] ; get value for sp mov cl,4 shr ax,cl ; convert to pghs add ax,nseg ; add base seg add ax,[si+0eh] ; and sp offset mov bx,topmem ; get top of memory cmp bx,ax ; is there room for the stack? jae p315 ; yes mov dx,offset errmsg4 jmp p050 p315: mov ax,[si+8] ; get header size (pghs) mov cl,3 shr ax,cl ; divide by 8 to get 128-byte recs sub ax,4 ; already read mov cx,ax jcxz p320 ; no more header call p500 ; read rest of header p320: mov ax,norecs ; recs left mov cl,3 sal ax,cl ; convert to pghs add ax,nseg ; plus start point gives copy destination mov bx,dtads ; end of header cmp ax,bx ; is start point above header? jae p325 ; yes mov ax,bx ; no - change copy destination p325: mov es,ax ; copy prog here sub bx,oseg ; minus psp gives pghs to copy mov cl,3 sal bx,cl ; words to copy mov cx,bx xor di,di xor si,si rep movsw ; copy it mov di,offset p330 push es push di ret 0 ; jump to new copy p330: push es pop ds ; set ds=es=new cs mov ax,es mov ss,ax ; set ss=es jmp p010 p400 proc near ; read file mov ax,nseg mov dtads,ax p410: mov cx,norecs ; # of recs left sub cx,recct ; 63K worth? ja p420 ; yes add cx,recct ; no - read remainder jmp p430 p420: mov cx,recct ; read 63K p430: call p500 ; read file p440: mov cx,norecs ; any more to read? jcxz p450 ; no jmp p410 ; read next block p450: ret p400 endp p500 proc near ; read file - cx contains recs to read push ds mov bx,dtads mov ds,bx ; new ds mov dx,0 mov ah,1ah int 21h ; set dta pop ds mov dx,offset fcb mov ah,27h int 21h ; random block read and al,0ffh ; error? jz p510 ; no mov dx,offset errmsg3 jmp p050 p510: mov ax,cx ; adjust dta for next read sub norecs,ax mov cl,3 sal ax,cl ; 8 pghs/rec add dtads,ax ret p500 endp p600: mov ax,nseg ; relocate and execute it mov si,eprog mov bx,si add bx,[si+18h] ; first relocation item mov cx,[si+6] ; # of items jcxz p620 ; none p610: mov dx,[bx+2] ; get code seg add dx,ax ; add start seg mov es,dx ; in es mov di,[bx] ; set instruction in es add es:[di],ax ; add start seg add bx,4 ; do another loop p610 ; done? p620: ; pass control to exe prog mov ax,nseg ; new prog seg add ax,[si+0eh] ; plus ss offset gives new ss cli mov ss,ax mov sp,[si+10h] sti mov ax,nseg ; new prog seg add ax,[si+16h] ; plus cs offset gives new cs mov bx,[si+14h] ; new ip push ax push bx mov bx,drives ; get drive status mov ax,oseg ; set up ds & es mov ds,ax mov es,ax mov ah,1ah ; reset dta mov dx,80h int 21h mov ax,bx ; drive status in ax ret 0 ; far return to exe prog copyr db 'RUN - Copyright 1983 Data Base Decisions',10,13,'$' errmsg1 db 'Program not found',7,10,13,'$' errmsg2 db 'Header not found ',7,10,13,'$' errmsg3 db 'Unable to load program',7,10,13,'$' errmsg4 db 'Not enough memory',7,10,13,'$' oseg dw 0 ; original data seg nseg dw 0 ; start of new prog topmem dw 0 ; top of memory norecs dw 0 ; # of 128 byte recs in file dtads dw 0 ; dta data seg drives dw 0 ; drive status for fcbs exe db 'EXE' ; file extension fcb db 37 dup(0) ; work fcb eprog dw 0 ; end of this prog stak db 16 dup('stack ') ; temp stack estak db 0 fcbfill db 0,11 dup(' '),4 dup(0) ; fcb filler endprog equ this word run endp cseg ends end run