title 'RELOCCP 1.2 - load programs below CCP (84/07/28)' ; *********************************************** ; * Copyright (C) 1982,1984 * ; * * ; * by C.B. Falconer (203) 281-1438 * ; * 680 Hartford Tpk. * ; * Hamden, Conn. 06517 * ; * * ; * All rights reserved * ; *********************************************** ; ; Relocate a program, by pages, to reside below BDOS. The program ; is loaded below CCP, assumed present. The program to be relocated ; is at 0200h up, and is 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. See revision 1.2 below for format of program size ; and space requirement data. ; ; The bit image is formed by comparing the code image with another ; assembled for org 0. 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. ; ; Note that any data areas to be reserved for the relocated program ; must be reserved by the pages value at 205h. ; ; If the program image extends beyond the relocated origin, this ; system will fail. It relocates first, then moves, and thus would ; self destroy its upper portion. ; ; Revisions etc ; ============= ; 85/11/09 No changes. Converted to Intel mnemnonics cbf. ; 84/07/28 Ver 1.2 C.B. Falconer ; Converted for standard code unit size data. ; 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 ; added the overlay conditional to modify application load ; ; 84/06/02 Ver 1.1 C.B. Falconer ; converted to Zilog mnemnonic set. Added prompt for ; CCPLUS 1/2 page save ability. ; aseg; For M80 compatibility ; true equ -1 false equ not true overlay equ false; Handy for creating overlays ; if overlay subttl 'Overlay system, load/execute only' else subttl 'Create relocation bits and load/execute' endif ; ; cp/m values cout equ 2 tstr equ 9 reboot equ 0 sysfnc equ 5 @bdos equ sysfnc+1 ; ; This governs the code below BDOS retained. 0 to discard CCP ccpsiz equ 8; 256 byte pages, preserve this bdosiz equ 14; pages, normal bios/bdos relation ; org 0100h; cp/m compatible ; ; Use the CCP stack so that moved/executed systems can "ret" ; This stack is limited. CCPLUS supplies adequate room. lxi h,@prgimg+3 mov c,m; inx h mov b,m; get size inx h mov a,m; get 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". However it ; may be patched to a "call" instruction for system verification, ; which will then fall through to "reloc" below. The overlaid ; verification/adjustment code may use the space from "makeprl" ; below through the end of the page. For example the overlay ; may query the operator as to whether the CCP is to be retained, ; and if not subtract 8 from (a). Such a system may also detect ; that CCP is already retained by the bios/bdos jump relationship, ; and automatically remove the CCP retention bias. patch: if overlay; Setup for creating an overlay call adjust; call the overlay code else jmp makeprl; on 1st execution only endif; overlay ; " " 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 another execution lhld @bdos; form origin for relocated cma; code on page boundary add h; This trucates bdos ptr downward sui ccpsiz-1; allow for ccp retention pop h; ^ relocation bits ; " " ; relocate the image (de)^, length (bc), in place ; using the bit vector at (hl); ; relocate by (a) pages. ; 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; save pointer to image push psw; save 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 object 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; not done pop h; h := pushed a mov l,b; zero, form origin pop d; ^image pop b; restore length ; " " relocation done push h; save as execution point, move exit ; " " Note that CCP return is under this ; " " ; move (bc) bytes from (de)^ to (hl)^ ; (bc) <> 0 on entry. ; a,f,b,c,d,e,h,l move: ldax d; move relocated image mov m,a inx d inx h dcx b mov a,b ora c jnz move ret; execute relocated image ; ; form length of relocation bit vector ; = ((bc)+7) DIV 8) ; a,f,b,c vlength: push h; round size up to lxi h,7 dad b; multiple of 8 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 carry mov a,b rar mov b,a mov a,c rar mov c,a ret ; ; *************************************************************** ; * After initial execution to form the relocation bit vectori * ; * the code from here up may be overlaid by load-time code to * ; * verify system validity, modify parameters, etc. Caution: * ; * the CCP stack is in use. Typical overlay code would be: * ; * org patch * ; * call whatzis; with regs as at patch * ; * org makeprl * ; * whatzis: ....; preserving stack levels * ; * ret; reg. state governs relocation * ; *************************************************************** ; if overlay; insert the overlay code here ; ; Check if the CCP has already been retained, and if so adjust ; the relocation values so as not to retain the space twice adjust: push psw push h lda reboot+2; Page for bios system lxi h,sysfnc+2 sub m pop h sui bdosiz; If this is not exact, assume jnz adjust1; that ccp is already saved pop psw ret adjust1: pop psw; Dont need this space reserved sui ccpsiz; ret else; form the relocation bits ; make relocatable code file from double image at 0200h up ; A second 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 ; the 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 counter 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 sysfnc 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; cp/m exit ; ; output (a) in decimal to console, no leading zeroes ; a,f,b,c,d,e,h,l tadzs: mov l,a mvi h,0 ; " " ; output (hl) in decimal 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 sysfnc; and exit ; pgmsg: db 'Now SAVE $' endif; Not overlay ; ; Where the zero based program image belongs. @prgimg equ ($+0ffh) AND 0ff00h end