title 'RELOCCP 1.2 - load programs below CCP (84/07/28)' ; *********************************************** ; * Copyright (C) 1982,1984 * ; * * ; * by C.B. Falconer (203) 785-2447 * ; * Room 6016C (203) 281-1438 * ; * Yale School of Medicine * ; * 789 Howard Avenue * ; * New Haven, Conn 06504 * ; * * ; * 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 ; ============= ; 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. ; .z80 true equ -1 false equ not true overlay equ false; Handy for creating overlays clist; List the conditional areas ; 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. ld hl,@prgimg+3 ld c,(hl); inc hl ld b,(hl); get size inc hl ld a,(hl); get pages ld hl,@prgimg ld d,h ld e,l; save pointer to start add hl,bc; ^ 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 jp 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 hl ld hl,reboot ld (patch+1),hl; prevent another execution ld hl,(@bdos); form origin for relocated cpl; code on page boundary add h; This trucates bdos ptr downward sub ccpsiz-1; allow for ccp retention pop hl; ^ 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 bc; save length push de; save pointer to image push af; save relocation amount call vlength; form bit vector length reloc1: pop af push bc; save byte counter push af; relocation amount ld c,8 ld b,(hl); get reloc bits ex de,hl reloc2: ld a,b add a,a ld b,a jp nc,reloc3; dont relocate this pop af; relocation amount push af add a,(hl) ld (hl),a reloc3: inc hl; next object byte dec c jp nz,reloc2; more bits to scan ex de,hl inc hl; next reloc bit vector pop af pop bc push af dec bc ld a,b or c jp nz,reloc1; not done pop hl; h := pushed a ld l,b; zero, form origin pop de; ^image pop bc; restore length ; " " relocation done push hl; 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: ld a,(de); move relocated image ld (hl),a inc de inc hl dec bc ld a,b or c jp nz,move ret; execute relocated image ; ; form length of relocation bit vector ; = ((bc)+7) DIV 8) ; a,f,b,c vlength: push hl; round size up to ld hl,7 add hl,bc; multiple of 8 ld c,l ld b,h pop hl ; " " ; 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: or a; clear any carry ld a,b rra ld b,a ld a,c rra ld c,a ret ; ; *************************************************************** ; * After initial execution to form the relocation bit vector * ; * 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 above * ; * 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 af push hl ld a,(reboot+2); Page for bios system ld hl,sysfnc+2 sub (hl) pop hl sub bdosiz; If this is not exact, assume jp nz,adjust1; that ccp is already saved pop af ret adjust1: pop af; Dont need this space reserved sub 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 hl ld hl,relocup ld (patch+1),hl; next execution moves pop hl ; " " ; 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 bc; save vector byte counter push hl; save vector storage ptr. vect1: ld bc,8; bit count and zero reloc byte vect2: ld a,(de) sub (hl) add a,1; carry if difference was 1 ld a,b adc a,a; 2*a+cy ld b,a inc de inc hl dec c jp nz,vect2; same vector byte pop bc; ^ vector storage ld (bc),a; save vector byte inc bc ex (sp),hl; save ^ 1 based, dec hl; get & decrement counter ld a,h or l ex (sp),hl; restack counter push bc; and vector pointer jp nz,vect1; more bytes to generate pop hl; point to next free byte pop bc; purge stack ; " " push hl ld de,pgmsg ld c,tstr call sysfnc pop hl dec hl; ^ last used byte push hl ld a,h call tadzs; signal pages to save pop hl ld a,l or a jp m,reboot; last 1/2 page used ld a,h dec a push af ld a,'(' call couta; signal usage for "SAVE nn+" pop af; available in CCPLUS call tadzs ld a,'+' call couta ld a,')' call couta jp reboot; cp/m exit ; ; output (a) in decimal to console, no leading zeroes ; a,f,b,c,d,e,h,l tadzs: ld l,a ld h,0 ; " " ; output (hl) in decimal to console. ; suppress leading zeros. ; a,f,b,c,d,e,h,l tdzs: ld bc,0f00ah; c=divisor=1 , b=iter cnt=-16 xor a; clear tdzs1: add hl,hl; (hl) := (hl)/10; rdr to (a) rla; shift off into (a) cp c; test jp c,tdzs2; no bit sub c; bit = 1 inc hl tdzs2: inc b jp m,tdzs1; not done push af; save output digit ld a,h or l call nz,tdzs; not left digit, recursive pop af; last unlisted digit add a,'0' ; " " ; output (a) to console ; a,f,b,c,d,e,h,l couta: ld e,a; output (a) to console ld c,cout jp sysfnc; and exit ; pgmsg: db 'Now SAVE $' endif; Not overlay ; ; Where the zero based program image belongs. @prgimg equ ($+0ffh) AND 0ff00h end