home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
BDOS
/
DOSPLSOR.ARK
/
DOSRELOC.MAC
< prev
next >
Wrap
Text File
|
1986-12-07
|
14KB
|
589 lines
title 'DOSRELOC - make/replace MOVCPM (86/12/07)'
; ***********************************************
; * Allows creation of MOVDOS or MOVCPM system *
; * where custom bioses, CCPs, BDOS patches, *
; * etc. have been installed. *
; * *
; * Copyright (C) 1980, 1982, 1984, 1986 *
; * by C.B. Falconer (203) 281-1438 *
; * 680 Hartford Tpk., *
; * Hamden, Conn 06517 *
; * *
; * All rights reserved *
; ***********************************************
; * 86/12/07 No change, altered DOS+ ver. *
; ***********************************************
; * 1.2 86/11/13 - Added OsborneI configuration *
; * Now require 'G' 2nd parameter for any *
; * immediate execution. Fewer accidents. *
; * Added "save" size customization *
; ***********************************************
; * 85/11/19 - Intel mnemnonics, no change *
; ***********************************************
; * 1.1 10 Mar. 1984. Added Kaypro installation *
; * constants. Specify aseg for m80. cbf *
; ***********************************************
;
; *** WARNING *** special values installed in "reloc"
; for KAYPRO sign-on. Very klugy
;
; ***********************************************
; Generate a relocation image for CP/M 2.2 & variants
; Assumes that:
; 1. zero based image located at 0980h-22ffh
; 2. running system exists @(6)-0806h up
; Generates a relocation bit map at 05c0 thru 08ffh where each byte
; specifies relocation for 8 object bytes. The ms bit of the bit
; vector corresponds to the lower of the 8 object bytes. Note that
; the bootstrap image at 900h thru 97fh will be read in from the
; system disk. If the assemble time constant "boot" is false suitable
; boot images are assumed to exist and any existing relocation bits
; are preserved.
;
; Algorithm: Wherever the two systems differ by exactly the load
; address hi byte of the running system a relocation bit is generated,
; else we assume some random data value, and generate 0.
;
; As far as possible this code is dependant on the various assembly
; time constants below. This should ease adaptation to other DOS+ or
; CPM versions or other systems. This is organized to simplify the
; conditional assembly areas to ease adaptation to other assemblers.
;
; The zero based image is available, 80h bytes higher, in the standard
; "MOVCPM" program. The user will have to add a suitable bios and
; optional boot image. For DOS+ the distributed MOVDOS+ program
; contains all images in the correct locations and is based on this.
;
; Since DDT or DDTZ replaces ccp in operation, and modifies the sysfnc
; entry in addition, the bit vector generator will not run under DDTZ.
; In addition, since the data is modified when relocating, the program
; can not be run again without reloading a fresh image. The system
; self modifies to become, in turn:
; bit vector generator
; "movcpm" program
; error program
;
;
true equ -1
false equ not true
boot set true; false leaves the boot reloc bits
ver equ 12; program version
;
; CPM version. Set only one value "true"
cpm14 equ false
cpm22 equ false
dos24 equ true
;
; Host machine. Set only one value "true".
; This suffices for the configured machines.
; For others various customization equates must be modified.
sssd equ false
yale equ false
kp83 equ true; early Kaypro II/4 only
oz1 equ false; Osborne I, dd
;
if NOT (sssd OR yale OR kp83 or oz1)
+++ Error - set at least one system true +++
endif
;
; DOS+/CPM values
cout equ 2; write char.
tstr equ 9; write string
reboot equ 0
sysfnc equ reboot+5
defcb equ reboot+05ch
parm1 equ defcb+1
altfcb equ reboot+06ch
parm2 equ altfcb+1
;
; define minimum size to run DDTZ and MOVDOS+
if yale or sssd or oz1
minsiz equ 16*4
endif
if kp83; allow for bank switch, bios above it
minsiz equ 17*4+2
@sgnon equ 01dch; offset for cbf (f4) bios sign-on msg.
endif; VERY klugy patch arrangement.
;
; cpmsiz cannot exceed 01a00h on SSSD systems. Others vary.
; Smaller values can be used where the bios allocation is less
; than the maximum storable on 51 sectors (tks 0 & 1) (SSSD)
; For standard systems this means biosiz must not exceed 0380h
; Note that the system may use further uninitialized memory.
;
; Anomalous to avoid nested ifs. Ease portability
if kp83
biosiz equ 200h
btsect equ 0; Kaypros native numbering scheme
endif
if yale
biosiz equ 080h
btsect equ 1; Uses standard sector numbering
endif
if sssd
biosiz equ 0380h; Standard allocation
btsect equ 1;
endif
if oz1
biosiz equ 0880h
btsect equ 0; Actually unused
boot set false
endif
;
if cpm22 or dos24; use the following
syssiz equ 28; pages, ver 2.2 bios allowance
ccpsiz equ 0800h; size of the ccp segment
bdosiz equ 0e00h; size of bdos segment
endif
if cpm22
cpmver equ 22; cpmversion no.
endif
if dos24
cpmver equ 25
endif
if cpm14; use the following
syssiz equ 23; 23 pages, ver 1.4 bios allowance
ccpsiz equ 0800h; size of the ccp segment
bdosiz equ 0d00h; size of bdos segment
cpmver equ 14; cpmversion no.
endif
btsize equ 080h; size of any boot image
cpmsiz equ btsize+ccpsiz+bdosiz+biosiz; Total system size
imgloc equ 0900h; location of the zero based image
;
if sssd AND (cpmsiz gt 01a00h)
+++ ERROR - can't handle this size bios +++
endif
;
pages equ (imgloc+cpmsiz-1)/256
;
; offset controls the default /n parameter when the system sets itself
; to the max. memory available. This moves DOS+ or CPM up the spec-
; ified number of 256 byte pages, where less than the normal alloca-
; tion for bios is required. 0 is equivalent to the original movcpm.
; Offsets that are non-divisible by 4 will report a /n size parameter.
; Similarly negative values can be used to reserve space at the top of
; memory for other uses
if kp83 or sssd
offset equ 0; in "pages"
endif
if yale
offset equ 4; All bios except vector/dskparms in ROM
endif
if oz1
offset equ -5; in "pages", reserve 1.25 k at top.
endif
;
; ******** END customization equates **********
;
; control chars
cr equ 0dh
lf equ 0ah
;
aseg; Absolute segment
org 0100h
;
nop; handy for debug
begin: jmp start; to patch for reverse operation
;
; *************************************************
; generate the relocation bit map and construct a revised version of
; "movdos+" or "movcpm" program. The new "movdos+" can generate the
; owners bios, ccp and bootstrap
start: lxi sp,stack
lxi d,signon
mvi c,tstr
call sysfnc; sign-on
call ldboot; in case image needed
if not boot; bypass booter area
lxi h,bitv+btsize/16
endif
if boot; include booter area
lxi h,bitv
endif
shld bitvec
lhld sysfnc+1
lxi d,-(ccpsiz+6)
dad d; point to start of ccp
mov a,h
sta delta
if boot; include booter area
lxi d,-btsize
endif
if not boot; leave patch space
lxi d,0
endif
dad d
xchg
if not boot; count and zero base ptr for no boot
lxi h,cpmbas+btsize; bypass booter
lxi b,(cpmsiz+7-btsize)/8; ensure full bytes
endif
if boot; count & zero base to include booter
lxi h,cpmbas
lxi b,(cpmsiz+7)/8
endif
call vect; make relocation vector
lxi h,mvcpm
shld begin+1; convert entry
lxi d,dunmsg
jmp exit
;
; make bit vector
; at entry, (hl)=^current zero based image byte
; (de)=^current running system byte
; (bc)=(bytes to examine)/8
; (delta)=critical difference to signal relocation
; (bitvec)=^storage for generated bit vector
; a,f,b,c,d,e,h,l,bitvec,bitvec^
vect: push b
lxi b,8; b:=0;c:=bit ctr.
vect2: lda delta
xchg
sub m
xchg
add m
cma
adi 1; cy if result was 0
mov a,b
adc a; 2*a+cy
mov b,a
inx d
inx h
dcr c
jnz vect2; same vector byte
push h
lhld bitvec
mov m,b
inx h
shld bitvec
pop h
pop b
dcx b; count generated bytes
mov a,b
ora c
jnz vect; do next byte
ret
;
; load track 0 sector 1 (the bootstrap) just below ccp
; this is the booter that works with the current system
; a,f,b,c,d,e,h,l
ldboot: if NOT oz1; which has no boot sector
mvi c,0
mvi a,9; select drive
call biosf
lhld sysfnc+1
lxi d,-(ccpsiz+6)-128
dad d; find base of ccp-128
mov b,h
mov c,l
mvi a,12; set dma
call biosf
mvi c,btsect
mvi a,11; set sector
call biosf
mvi c,0
mvi a,10; set track
call biosf
mvi a,13; read sector
call biosf
ora a
lxi d,msg7
jnz exit; bad read
ret
;
; transfer to bios function #(a)
; a,f+bios
biosf: push h
lhld reboot+1
mov l,a
add a
add l
mov l,a
xthl; restore hl, stack xfr adr
endif; so plenty of room for bit map on Osborne
ret
;
; *************************************************
; replacement section for "movdos+" or "movcpm" to use the above
; generated bit map. Uses "movcpm" protocol, except that the size
; specification (e.g. "48") can be qualified by /1,/2, or /3 (e.g.
; "48/1") to move the final system up by 1, 2, or 3 256 byte
; increments. Thus the system can be relocated on any page boundary.
;
; interrogate system for top of contiguous (to 0) memory
; returns (hl)=^last functional location (+256*offset)
; a,f,h,l
qmem: lxi h,0ffh; assumes 0..100h exists
qmem1: inr h
jz qmem2; full memory.
mov a,m
cma
mov m,a; *** This are must not
cmp m; *** end up on page location 0ffh
cma; *** else it will self destruct.
mov m,a; restore it
jz qmem1
qmem2: dcr h; point to last location functional
mov a,h
adi offset
mov h,a
ret
;
; a replacement "movcpm" program
mvcpm: lxi sp,stack
lxi h,reboot
shld begin+1; prevent a 2nd call
lxi d,signon
mvi c,tstr
call sysfnc; sign-on
lxi d,parm1
ldax d
cpi ' '
jz mvcpm5; use max available
cpi '?'
jz mvcpm5; use max available
lxi h,0; will hold mem address
mvcpm1: ldax d
inx d
call qnum
jc mvcpm2; not digit
sui '0'
mov c,l
mov b,h
dad h; 2*
dad h; 4*
dad b; 5*
dad h; 10*
mov c,a
mvi b,0
dad b; incorporate value
jmp mvcpm1
mvcpm2: dad h
dad h; 4*, in pages
cpi '/'; check for increment
jnz mvcpm3; none
ldax d
inx d
call qnum
jc errer; bad input
sui '0'
cpi 4
jnc errer; bad input
add l
mov l,a; result in pages
mvcpm3: mov a,h
dcr a
jm mvcpm4; less than 64k
jnz errer; more than 64k
ora l
jnz errer; 64/n k, error
mvcpm4: mov h,l
mvi l,0; *256, form top address
dcx h; form top available address
jmp mvcpm6
mvcpm5: call qmem; find top available
mvcpm6: lxi d,-syssiz*256;
dad d; final loadpoint in (hl)
inx h; to actual loadpoint
mov a,h
sta delta; hi byte of relocation point
cpi minsiz-syssiz
jc errer; specification too small
mvi c,tstr
lxi d,msg1
call sysfnc; advise
call tdelt
lxi d,msg1a
mvi c,tstr
call sysfnc
call reloc; relocate data in place
lda parm2
cpi 'G'
jz exec; put in place and execute
mvi c,tstr
lxi d,msg2
call sysfnc
call tdelt
lxi d,msg3
jmp exit
;
; put the relocated image in place and execute it
exec: mvi c,tstr
lxi d,msg6
call sysfnc
lxi d,cpmbas+btsize; ignore the booter area
lda delta
mov h,a
mvi l,0
lxi b,cpmsiz-btsize; count to transfer
push h; save for control xfr
exec1: ldax d
mov m,a
inx h
inx d
dcx b
mov a,b
ora c
jnz exec1; more to move
pop h
lxi d,ccpsiz+bdosiz
dad d; form entry to bios cold start
pchl
;
; output "delta" as nn[/n] size id
; a,f
tdelt: push b
push d
push h
lda delta
adi syssiz; correct for top of memory
mov b,a
ani 3
mov c,a
mov a,b
rar
rar
ani 03fh
mvi e,'0'-1
jnz tdelt1; not 64k
mvi e,'6'
mvi a,'4'
jmp tdelt2
tdelt1: inr e
sui 10
jp tdelt1; extract ms digit
adi '0'+10
tdelt2: push b
push psw
mvi c,cout
call sysfnc
pop psw
mov e,a
mvi c,cout
call sysfnc
pop b
mov a,c
ora a
jz tdelt9; no extra portion
adi '0'
push psw
mvi c,cout
mvi e,'/'
call sysfnc
pop psw
mov e,a
mvi c,cout
call sysfnc
tdelt9: pop h
pop d
pop b
ret
;
; relocate the data image in place, using the
; global variable "delta" as the relocation amount
; a,f,b,c,d,e,h,l
reloc: lxi h,bitv
lxi d,cpmbas
lxi b,(cpmsiz+7)/8
reloc1: push b; save byte counter
lxi b,8
mov b,m; get reloc bits
xchg
reloc2: mov a,b
add a
mov b,a
jnc reloc3; dont relocate this
lda delta
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 b
dcx b
mov a,b
ora c
jnz reloc1; not done
; ********************************************
if kp83; ** special considerations for sign-on
lda parm1
cpi ' '
rz; 64k max, leave native sign-on
lxi d,parm1
lxi h,cpmbas+btsize+ccpsiz+bdosiz+@sgnon; SPECIAL VALUE
mov a,m; for cbf bios --^ ONLY
cpi '6'
rnz; This is not the right version
ldax d; Appears to be the right bios,
mov m,a; go ahead and patch the sign-on
inx d
inx h
ldax d
mov m,a; crude 2 digits for now
endif
; ********************************************
ret
;
; check (a) for ascii numeric char, carry if not
; f
qnum: cpi '0'
rc
cpi '9'+1
cmc
ret
;
; error exit
errer: lxi d,msg5
; " "
exit: mvi c,tstr
call sysfnc
jmp reboot
;
msg1: db 'Constructing $'
msg1A: db 'k DOS+ System V. '
db cpmver/10+'0','.',cpmver MOD 10 + '0', ' for '
if sssd
db 'SSSD std. system'
endif
if kp83
db 'Kaypro 2/4 (83)'
endif
if yale
db 'Yale'
endif
if oz1
db 'Osborne I'
endif
db '$'
msg2: db cr,lf,'Ready for "SYSGEN" or "SAVE '
db pages/10 + '0', pages MOD 10 +'0'
db ' DOS$'
msg3: db 'K.SYS"$'
msg5: db 'Invalid system size$'
msg6: db cr,lf,'Running new system$'
msg7: db cr,lf,'Error reading bootstrap image$'
dunmsg: db 'Now "SAVE '
db pages/10 + '0', pages MOD 10 +'0'
db ' MOVDOS+.COM"$'
signon: db cr,lf,'DOS+ Mover Ver. '
db ver/10+'0','.',ver mod 10+'0',cr,lf,'$'
;
; storage
bitvec: ds 2
delta: ds 1
ds 64; run time stack
stack: ds 0
;
; the data base area
org imgloc-(cpmsiz+7)/8
if $ lt stack
+++ ERROR bios too large +++
endif
bitv: ds (cpmsiz+7)/8; resultant bit vector
cpmbas: ds cpmsiz; image of cpm system
;
end
α¬