title 'CCPLUS/DDT INSTALLER - load and lock in CCPLUS' ; *************************************** ; * Copyright (C) 1986 86/01/06 * ; * * ; * by C.B. Falconer (203) 281-1438 * ; * 680 Hartford Tpk. * ; * Hamden, Conn. 06517 * ; * * ; * All rights reserved * ; *************************************** ; ; Modified from RELOCCP (RSX12 package) for quick CCPLUS installation ; **** SEE CCPLOCK.MAC for instructions **** ; ; 86/1/26 Revised to handle the non-std Osborne I system. ; ; Relocate a program, by pages, to reside below BDOS. The program to ; be relocated is at 0200h up, assembled as if it begins at location ; 0. Following the program code proper is a relocation bit map. Each ; byte specifies relocation for 8 bytes of the program, with the ms ; bit of the relocation byte corresponding to the lower of the 8 ; object bytes. ; The 0 based image at location 0200h is: ; jmp somewhere; the entry point. ; dw codesize; to be moved/relocated ; db pages; of memory required, total ; ; The bit image is formed by comparing the code image with another ; assembled for org 100. See "makeprl" and "vect" below for details. ; ; The first execution of this system forms the relocation bit vector ; from the two images, and self-modifies to become a loader on the ; next execution. ; aseg; For M80 ; true equ -1 false equ not true ; ; Set this true to create a loader for non-standard systems, such ; as the Osborne I, which do not supply the necessary 12 stack bytes. ; The system then can no longer "ret" to CCP, which is not needed ; for a CCP or equivalent loader anyhow. badccp equ true ; ; cp/m values cout equ 2 tstr equ 9 reboot equ 0 bdos equ 5 @bdos equ bdos+1 ; org 0100h ; if badccp; RET to CCP not available. lxi sp,@prgimg endif lxi h,@prgimg+3 mov c,m ! inx h ! mov b,m; get size inx h ! mov a,m; pages lxi h,@prgimg mov d,h ! mov e,l; save pointer to start dad b; ^ to 1st relocation byte ; " " ; (a) is pages, (bc) is size, (de) is start, (hl) is reloc bits ; " " ; The following location, after forming the relocation bits, ; is automatically patched to be "jmp relocup". patch: jmp makeprl; on 1st execution only ; " " fall through as noted above ; do relocation, move and execute ; (a) is pages, (bc) is size, (de) is start, (hl) is reloc bits relocup: push h lxi h,reboot shld patch+1; prevent re-execution lhld @bdos; form origin for relocated cma; code on page boundary add h; Truncate bdos ptr downward adi 1; can allow for extra space pop h; ^ relocation bits ; " " ; relocate the image (de)^, length (bc), in place, by (a) pages, ; using the bit vector at (hl). At completion the image is ready to ; be moved into place at location (a) [entry] * 256. ; h,l reloc: push b; save length push d; & pointer to image push psw; & relocation amount call vlength; form bit vector length reloc1: pop psw push b; save byte counter push psw; relocation amount mvi c,8 mov b,m; get reloc bits xchg reloc2: mov a,b ! add a ! mov b,a jnc reloc3; dont relocate this pop psw; relocation amount push psw add m ! mov m,a reloc3: inx h; next obj byte dcr c ! jnz reloc2; more bits to scan xchg inx h; next reloc bit vector pop psw pop b push psw dcx b ! mov a,b ! ora c jnz reloc1; more pop h; h := pushed a mov l,b; 0, form origin pop d; ^image pop b; restore length ; " " relocation done push h; save as execution point, move exit ; " " ; move (bc) bytes from (de)^ to (hl)^. (bc) <> 0 on entry. ; a,f,b,c,d,e,h,l move: ldax d ! mov m,a; move relocated code inx d ! inx h ! dcx b mov a,b ! ora c jnz move ret; execute relocated code ; ; form length of relocation bit vector = ((bc)+7) DIV 8) ; a,f,b,c vlength: push h; round size up to multiple of 8 lxi h,7 ! dad b mov c,l ! mov b,h pop h ; " " ; shift (bc) right 3 places, 0s in ; a,f,b,c bcrz3: call bcrz ; " " ; shift (bc) right 2 places, 0s in ; a,f,b,c bcrz2: call bcrz ; " " ; shift (bc) right, inserting zero bit ; a,f,b,c bcrz: ora a; clear any cy mov a,b ! rar ! mov b,a mov a,c ! rar ! mov c,a ret ; ; make relocatable code file from double image at 0200h up ; A 2nd image is located immediately above the zero based ; image, assembled for origin at 0100h. makeprl: push h lxi h,relocup shld patch+1; next execution moves pop h ; " " ; make bit vector. At entry: ; (bc) = bytes to examine ; (de) = ^0 based image ; (hl) = ^0100h based image, and to start of bit ; vector storage area. ; At exit (hl) points to free byte above computed relocation vector. ; a,f,b,c,d,e,h,l vect: call vlength; form bit vector length push b; save vector byte counter push h; save vector storage ptr. vect1: lxi b,8; bit count and zero reloc byte vect2: ldax d sub m adi 1; carry if difference was 1 mov a,b adc a; 2*a+cy mov b,a inx d ! inx h dcr c ! jnz vect2; same vector byte pop b; ^vector storage stax b; save vector byte inx b xthl; save ^1 based, dcx h; get & decrement ctr mov a,h ! ora l xthl; restack counter push b; and vector pointer jnz vect1; more bytes to generate pop h; point to next free byte pop b; purge stack ; " " push h lxi d,pgmsg mvi c,tstr call bdos pop h ! dcx h; ^last used byte push h ! mov a,h call tadzs; signal pages to save pop h mov a,l ! ora a jm reboot; last 1/2 page used mov a,h dcr a push psw mvi a,'(' call couta; signal usage for "SAVE nn+" pop psw; available in CCPLUS call tadzs mvi a,'+' call couta mvi a,')' call couta jmp reboot ; ; output (a) in dec. to console, no leading zeroes ; a,f,b,c,d,e,h,l tadzs: mov l,a ! mvi h,0 ; " " ; output (hl) in dec. to console. Suppress leading zeros. ; a,f,b,c,d,e,h,l tdzs: lxi b,0f00ah; c=divisor=1 , b=iter cnt=-16 xra a; clear tdzs1: dad h; m := (hl)/10; rdr to (a) ral; shift off into (a) cmp c; test jc tdzs2; no bit sub c; bit = 1 inx h tdzs2: inr b ! jm tdzs1; not done push psw; save output digit mov a,h ! ora l cnz tdzs; not left digit, recursive pop psw; last unlisted digit adi '0' ; " " ; output (a) to console ; a,f,b,c,d,e,h,l couta: mov e,a; output (a) to console mvi c,cout jmp bdos; and exit ; pgmsg: if NOT badccp db 'Now ' endif db 'SAVE $' ; ; Where the zero based program image belongs. @prgimg equ ($+0ffh) AND 0ff00h ; end