home *** CD-ROM | disk | FTP | other *** search
- 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
- U