IMD 1.16: 28/05/2007 16:33:22 -FOG/UTL011         DIF RNO DIF2 COMs SSED2 COMQ OZCPR COMOZCPR DOCREAD ME ZCPR DOC !"#$%ZCPR DOCY&'()*+-FOG/UTL011DISK DOC ,.in 8 .rm 72 .ce 99 Reducing the Swelling of the Phone Bill with DIF and SSED November 17, 1981 Chuck Forsberg Computer Development Inc Beaverton OR .ce 0 Lately (if not sooner) it has become obvious that there must b bette an cheape wa t distribut softwar update t changing programs than to transmit all of the new files in their totality, even though only a few lines in each have been changed. For some years the Unix differential file print program diff(1) (the (1) re  fers to the section of the Unix Programmers Manual in which it is described) has had a -e flag which provides a set of ed commands suitable for transforming the first file to the second. With these tools, only an update file need be transmitted, heck, compare the two files with dif. Unix folks with 14 character file names and modification times stored by the filesystem have little trouble keeping the files synchronized. (If the antecedent files are different, there's no telling what th provided, of course, that both the sender and the receiver had copies of the same antecdent file. I have written a "new" diff called dif.c which manages to operate in the primitive CP/M environment. The editing commands output in response to thee output file will look like!) For us poor CP/M folks (verrry) patiently awaiting something like Unix to appear magically on out desktops, I propose that the revision or revision date of the antecedent file be placed in the new file adjacent to the n -e option refrence sequential lines in the source files, so they (the commands) can be executed by a stream editor. (The Unix diff(1) creates difference files with non-forward- sequential commands.) To generate a difference file, the command is ew revision or date, preferably on the same line. This way the user may easily verify that he has the correct antecedent. Dif Versions 1.10 and later place hash indices of the RETAINED lines of the antecedent file in the difference output. This all  dif -e oldfile newfile >file.dif The >file.dif redirects the standard output to the file. A + may be susbtituted for > if simultaneous console output is desired. The receiver then invokes:  ssed oldfile newfileows ssed 1.10 or later to verify correctness of the antecedent file. The new .dif files are compatible with the old ssed, but, alas, not with Unix ed or sed. The array sizes in dif.c may have to be shrunk somewhat to run on a 48k system. For  Which will result in newfile being created identical to the original newfile. Well, not precisely identical, but identical up to and including the EOF (^Z) character. The dribble after that may change, so CRCK may say they are different. To ctesting, give:  dif -e filea fileb |ssed filea >filec  dif fileb filec (fileb and filec should be identical) It ought to work if you said:  dif -e filea fileb |ssed filea |dif fileb and it does, with version 2.0.    Version 2.0 of dif.c adds a -u flag which will unsqueeze filea before comparing it to fileb. Thus you can say:  sq filea  dif -eu filea.qqq fileb |ssed filea |dif fileb Or you can say:  dif -eu filea.qqq fileb7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o |ssed -u filea.qqq |dif fileb to test dif and ssed. (Be sure dif and ssed are exactly where you say they are, or else pipes will be broken.) Restriction: Since the BDS Standard I/O library and the Directed I/O package are somewhat confused abo#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2rut translation between CP/M's cr/lf terminated lines and **nixs' \n terminated lines, dif was written to strip cr's from the input in order that only one cr appear on the output. As a result, lines terminated by cr/lf, lf, and lf/cr all come out t+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77he same! This would munge files where lf/cr has a special meaning (MBASIC continuation lines) or where embedded cr's are used (RTTY art). Unix is a trademark of WECO, CP/M of Digital Research. !a{   `OE!y6$ -7rBo&))T])))!y:=b#:=#:$=2#v+:<"(">6͋5:&=͋5#*&=|"M1Ϳ5#>6͋5:&=͋5>#͋5>6͋5:'=͋5#*&="<(#>͋5:&=͋5>s͋*K͞+@O:'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z5>@2=#R1Ϳ5#(,#:==2=)(@#>s͋5#͘(Y#X1:>͋5:&=͋5c1Ϳ5#f1Ϳ52=#(—#>͋5:&=͋5>{͋5c1Ϳ5#(#:$=µ#>}͋5c1Ú#:$=;-͘(#>&͋5͋5f2Ú#:$=$v+è":=  $,v+2#:$=>$$>͋5v+>͋5>@2$=2#*="<1Ϳ5:=2="<|s$}d$[2Ϳ5z$g$[3Ϳ5>G>)͋5$#͞*D)͏,Ͷ,v++4ʱ$̓)c"s Æ v(Ù î(]6(&!û+)ú)`6&!9DM!"9P! ~#fo! s#r! ~#fo! sͰ*9P|* *9P*9P!d !Ͱ!9dif.c 2.00 (dif 2.0) 11-17-81Usage: dif [-dev] filea {fileb,outfile] -d display lines that match -e generate Editor script -u Unsqueeze filea -v Verbose Can't open %sCan't open %sS#r! ^#Vr+szP! ^#Vr+s~#fon}>=! ~#fo~#fon}+M! ~#fo~#fo#"9P! ~#fo! ͡{2`P{2bP{2cP{2aP{2_P*"jP*"lP! ^#Vr+sz6 ! ^#Vr+s~#fo! s#rn}-6 ! ^#Vr+sn}3 ! ~#fon&ͪ>d> >e> >u> >vtandard Inputbottom[%d]=%x top=%x %s$a %u . Files are different No differences encountered '%s' Unlinked y )*5Pv Ì )*7P͉ ß l!9DM*}T *}T+"}T*T͜ `is#r! `i~#fo"T*T#| !0u"}T*T͜ "}T|  >& - !bP40 !aP40 *"jP!cP40 !`P40 X öÅ! ~#foX ! ~#foҮ !6 !Ͱ!T !Ͱ! !Ͱ! !Ͱ! !Ͱ! !Ͱ!ͳ!)H! ~#fo~#fo"?PͶ#| ! ~#fo~#fo! !Ͱ!ͳ )H"5P! ~#!*}T++"}T*T!96%*î(]6)!9DM$'*5P*vo*?P!}!-!0*5P*! ! s#r! ~#fo*5P3s! ^#Vr+sn}ƒ! *?P!!-*5P*! s#r! ~#fo|! ~#fo *?P!!-fo++|\ !/L! ~#fo##~#fo"APͶ#|R ! ~#fo##~#fo! !Ͱ!ͳY /L"7Ph *"lP! "AP*cP}y *"jPͼ!"=P";P"dP{2iP{2hPd"CP"pP"TP"GP"EP"\P"IP*`P} `i6`in& `in&)GP~#fo`in&)CP~#fo`in&! !Ͱ`i!0!"yP!"{P`iw#w`i~#fo! ~#fot`i~#fo))yP*5P*s#r`i~#fo))yP##*5P*s#r`i^#Vr+s!9%s Not Squeezed (%s -> %s) %s has invalid decode tree size ,"1+î(n++!9DM! n&);P! s#r! n&)jP~#fo"nP! 4ü !"fP!"MP"KP!OP!Ϳ*CP"KP!WP!Ϳ*EP"MP*KP###~#foͣ*MP###~#fo|g}o| *MP*KP|ʌ  *dP*KP~#fo"dP*bP}ʵ *KP!$ *KP"KP*MP"MP9 *aP} *dP!* *_P} !3 !Ͱ* !H !n&)GP~#fo"rP*rP"rP! n})*MP,*KP"tP*tP"vP! ~#fo~#fo"pP*pP|}! ~#fo"pP*pP! ~#fo "pP*`P}ʼ*pP*vP*tP*rP! ~#fo~#fo! n&!!!!9! n&hPn}E!I!*pP! ~#fo~#fo! ~#fo~#fo!   ~#fo! ~#fo~#fo! n&!e!!9!! ~#fo*pP*rPҋ! n&)CP~#fo"pP*`P}ʀ*pP!!*tP|‹ç*pP*tPڿ*pP*vPڿ*`P}ʼ!!*pP`is#r`i~#fo##! ns`i~#fo"pP>2xP!xP5n}*pP#"pP+*n*T s#rz! 6k`i^#Vr+s~#fo"T! ^#Vr+s!L! 6*T###~#foh! 6k! n}! ~#fo! s#r! ^#Vr+sz`i~#fo*T s#rz·! 6`i^#Vr+s~#fo"T! ^#Vr+s!! 6*T###~#fo! 6P!!9~#fos{++  *`P}W! ~#fo~#fo! n&!!! n&hP6`i~#fo6#6`i~#fo`i~#fos#r`i~#fo###6#6!`i~#fo! ~#fo`i~#fos#r! ~#fo^#Vr+s*pP+"pP! ~#fo~#fo!!*pP6*pÅ*`P}A! n&! n&! n&! ~#fo!a! *`P& ! w#w! ~#fo! ~#fo ! ~#fo)T~#fo~#fo! ~#fo)T~#fo###~#fo! ~#fo)T~#fo~#fo! ~#fo)T~#fo##n&! ~#fo)T~#fo! ~#fo!! !9! P`i~#fo! s#rzK`i~#fo!! ~#fo`i~#fo;s#rU`i~#fow#w`i~#fo###! ~#fo~#fos#r! ~#fo`i~#fos#r*`P&*pP! ~#fo`i~#fo~#fo`i~#fo! ~#fo~#fo! n&!!!9!`i~#fo`i~#fo! s#r! ^#Vr+sW*!! ~#fo!T! ~#fo|;C! ~#fo! ~#fos#rñ*MP###~#fo*KP###~#fo!! *`P};! w#w! ~#fo! ~#fo;! ~#fo)T~#fo! ~#fo)T~#fo###~#fo! ~#fo)T~#fo~#fo! ~#fo)T~#fo##n& ~#fow#w*pP#"pPE!9File %d line %d q=%x qq=%x qqq=%x p=%x Getline called after E-O-F %d %3d fp=%x hash=%04x next=%x p=%x Wrapped: p=%x Buffer Filled EOF on file %d at line %d **EOF** Line %d is too long %d %3d gp=%x hash=%04x len=%3d ! ~#fo)T~#fo! ~#fo!! !9! ^#Vr+sÌ!! 9Difference at %d:%d Dodiff Quantity=%d k't=%d w'a=%d w'b=%d HTBL %3d:addr=%x f=%d h=%4x l=%3d nxt=%x Can't find match at a:line %d b:line %d HTBL %d:addr=%x f=%d h=%4x l=%3d p=%x î( ,.û]6!9DM>2_P*`P}U*MP###~#fo*KP###~#fo!L! ! s! sT`is#r`i^#Vr+s*KP"Ts#r`i^#Vr+s*MP"Ts#r! 6#6! 6#6! 6! n}W! n}! n}W! n}k! ~#fo! s#r! ^#Vr+szk`i~#fo%.30s û!9DM! ~#fo~#fo|<! ~#fo~#fo! ~#fo! ~#fo##n& ! ~#fo~#for)!"T*yT#"yT*5Po"{T#|Ÿ!!"yT*T))yP*{T|g}o)~#fo"T*T))yP*{T"{T|g}o)~#fo"T*T|y*T#  "T*T!*T!"}T!c"yT!9DM! ~#fo~#fo~#fo! ~#fo~#fo~#foc!! ~#fo~#fo~#fo! ~#fo~#fo~#foҐ!! ~#fo~#fo##n! ~#fo~#fo##nѯgW+)î(n+ú)Ï'Á-!9DM! s#r! s#r! ~#fo)T! s#!! *dP!!! ~#fo###~#fo! ~#fob ! ~#fo! ~#fo! s#r !!*fP! ~#fo"fPË *dP!!p!*?P*KP###~#fo!!*KP! s#r! ~#fo###~#fo! ~#fo ! ~#fo!"! ~#fo! s#rò *rT! s#r! ~#fo! ~#foG! ~#fo~#fo##n}:8! ~#fo##! s#r! ~#fo! ~#fo8! ~#fo~#fo##n}{)! ~#fo~#fo~#fo! ~#fo~#fo~#foʦ)! ~#fo~#fo###~#fo! ~#fo! ~#fo~#fo###~#fo! ~#fo)! ~#fo~#fo~AP*MP###~#fo!"*MP! s#r! ~#fo###~#fo! ~#fop!! ~#fo!("! ~#fo! s#r#!`i~#fo"KP! ~#fo"MP!Ê!!9Found match at %d:%d Fudge=%d skipa=%d skipb=%d %d%d%da %u c %u . d %u -------- Line %4d of '%s' ----#fo|!! ~#fo~#fo~#fo|$)! ~#fo~#fo~#fo~#fo! ~#fo~#fo~#fo~#fo_)! ~#fo~#fo! ~#fo~#fo;|ʎ)! ~#fo~#fo~#fo! ~#fo~#fo~#fo;|)! ~#fo~#fo###~#fo! s#r! ~#fo~#fo###~#fo!  ---%s++++++++ Line %4d of '%s' ++++ +%s7*N#"*|)yoO"|g}o"*+"|0"*x"(î(]6+)`6ó-!9DM*##s*#s*s! ~#fo͐ ~#fo)*s#r! 6#6`i6#6͐͐ ~#foҭ%w}"í%! ~#fo͐)~#fon}<#s#r! ~#fo~#fo`is#r! ~#fo~#fo! s#r! ^#Vr+sL! ^#Vr+s ! ~#fo^!Ê!*`P}ʱ! ~#fo! ~#fo!!!!`i~#fo!! ~#fo*aP}ʎ ! ~#fo*KP###~#fo! s#r! ~#fo*MP! s#r###~#fo! s|ʾ#+7$>K$Ö%! ~#fo͐)~#fo#n}0#f$* ! ~#fo͐)~#fo#f"#|€#! ~#fo͐)~#fo#!%!i"l"*6!%! ~#fo͐)~#foo"|»#*n&|g}os$*##4! ~#fo͐)~#fo#*###s#r! ~#fo͐)~#fo#n}4$!#r*`P}0! ~#fo! ~#fo*fP!!!! ~#fo|*fP*KP###~#fo!!! ~#fo+|ʯ!,! ~#fo‰!$ï*fP*KP###~#fo! ~#fo+!!*fP! ~#fo"fP! ~#fo|~ ! ~#fo|*KP###~#fo *dP*MP###~#fo+ ~#fo͐)!%s#r! ~#fo͐)*s#rK$*#n&|g}os! ~#fo͐)~#fo#n}v$!%!i"l"! ~#fo͐)~#fo#r"*! ~#fo͐)~#fo#u"#|$! ~#fo͐)~#fo#!%!i"l"*#4w}m%͐! s#r͐   ~#foG%! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s$͐ ^#Vr+s`i^#Vr+s*^#Vr+sÓ%͐ ͐s#r! ~#fo͐ ~#fo)w#wá%! ^#Vr+s`i^#Vr+s"!9Can't open %s <8~# x«8 ><8~+ x8|}8):7:,*8:*9  }|2q 29(9:qw#9! {w7*!9& 6C#6O#6Ms9*|‰9!\&Û9!\&*|›9!!l&!~#fo9> +9#~¸9##ì9a{ !p9!*w#9:**9*!ѷ! , FNxg>GoyM:$\&Û9!\&*|›9!!l&!~#fo9> +9#~¸9##ì9a{ !p9!*w#9:**9*!*K͞+@k)_Q'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o  #z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r ^#Vr+s~#fo`is#rn}-l`i^#Vr+sn}i͐n&ͧ>uF>U>vR>\c!PM4f!OM4fv͐+|! !ͪ! !ͪ! !ͪ! !ͪ! !ͪ! !ͪ!ͭ!)H! ~#fo~#fo"1LͰ#| *1L! !ͪ!+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77ͭ )H"/L*PM} *"SMͶ!"3L!"L}aS >i2>L*5L#"5L*3L*5L{ *5L*3L!, !ͪ; *3L*5Lҗ *RM}— ͼ{ *9L} *:L*L}i *7L+"7L#*3L *RM}!a{   `OE!y6$ -7rBo&))T])))!y:=b#:=#:$=2#v+:<"(">6͋5:&=͋5#*&=|"M1Ϳ5#>6͋5:&=͋5>#͋5>6͋5:'=͋5#*&="<(#>͋5:&=͋5>s͋ Ϳ *>L}c *>L}i P *>L}dP !?L! !ͪ! !ͪ!ͭ6 *RM}a ͼS ! !ͪ!ͭ!9ssed.c 2.0 11-4-81 Usage: ssed [-v] infile [outfile] Editing commands on stdin Edited output on stdout -u U5>@2=#R1Ϳ5#(,#:==2=)(@#>s͋5#͘(Y#X1:>͋5:&=͋5c1Ϳ5#f1Ϳ52=#(—#>͋5:&=͋5>{͋5c1Ϳ5#(#:$=µ#>}͋5c1Ú#:$=;-͘(#>&͋5͋5f2Ú#:$=$v+è":=nsqueeze infile -v Verbose Can't open %sAt line %d: Can't back up to %d CRC error on Antecedent File %u should be %u '%s' is not the correct Antecedent Illegal command %sDifference file garbled or not made by dif -e Ssed finished */L $,v+2#:$=>$$>͋5v+>͋5>@2$=2#*="<1Ϳ5:=2="<|s$}d$[2Ϳ5z$g$[3Ϳ5>G>)͋5$#͞*D)͏,Ͷ,v++4ʱ$̓)) <ty%ë É +C!9DM͐! ͡*"SM{2PM{2OM! ^#Vr+szl! !9DM*YQ- *YQ+"YQ*[QÀ À  `is#r!^ ͐"[Q*[Q#|U !0u"YQ*[QÀ À  "YQ|r !À À *YQ++"YQ*[QÀ !9Þ Ùâty%!9DM͌ ͏ */L͒ v *1L! !͕ !͘ */L͒ ! ! s#r͐*/L͛ s! ^  #Vr+sn} */L͒ ! s#r͐|4 ͐N *1L! !͕ !͘ !"UM!"WM`iw#w͐͐Ү ͐))UM*/L͒ s#r͐))UM##*/L͒ s#r`i^#Vr+s` !9%s Not Squeezed %s has invalid decode tree size të÷k<:>>H_!b! ^#Vr+s͐s! ^#Vr+s6͐͐b! ^#Vr+s͐s_ÿ!9q,!9DM`iw#w*MMn}.–*MM#"MM*3L*MMn}$­*MM#"MM!}*MMn&n|͐ ?*MM#"MM+n&`is#rí͐!97*N#"*29L*OM}$!":L*3L!! *QM}>* !?L |X*OM}S!! !?L"MM "7L"5L*MMn},*MM#"MM "7L*MM#"MM+n& }2>L*MM#"MM+n} ²>29L*MM ":L*OM}*:L*3L*>L&*7L*5L!?L!! !9!%d:EOF on stdin %|)yo|g}o"*+"|*>ëty%[|%!9DM*##s*#s*s! ~#fo͐ ~#fo)*s#r! 6#6`i6#6͐͐ ~#fosw}ʫs! ~#fo͐)~#fon}<|ʄ+>\! ~#fo͐)~#fo#n},* ! sop1=%d op2=%d cmd=0%o linno=%d cmdcrc=%u =ëty%!9DM*SM!L1`is#rzz>2RM*OM}w!!4!L7#|!!4!:*3L#"3L`i^#Vr+s!*2RMEOF on old file Uë÷ty%*J!LF||!!L>2QM*L}.•*L& ڕ!LO#|¸!!L!R*3L#"3LVUnexpected EOF on stdin Write Error!"]Q*UQ#"UQ#n&|g}os! ~#fo͐)~#fo#n}<!!/2! ~#fo͐)~#fo#8*! ~#fo͐)~#fo#;#|¦! ~#fo͐)~#fo#!!/2*#4w}3͐! s#r͐͐ ~#fo ! ~#fo͐)! ~#fo͐#)~#fos#r!E*/L"WQ#|!!"UQ*]Q))UM*WQ|g}o)~#fo"]Qn*]Q))UM*WQ"WQ|g}o)~#fo"]Q*]Q|*]Q#"]Q*]Q’!Õ*]Q!"YQ!c"UQ!9DM͐! s#r͐ !!9~#fo`is#r> > >>>>>  ^#Vr+s͐ ^#Vr+s`i^#Vr+s*^#Vr+sY͐ ͐s#r! ~#fo͐ ~#fo)w#wg! ^#Vr+s`i^#Vr+sË!9Can't open %s <'~# x' ><'~+ x'|}'E)7:"͐! ^#Vr+sns{,#! ^#Vr+s#! n}]#! ^#Vr+s!]#! ^#Vr+s6 6#s#! ^#Vr+s`insÉ#! ^#Vr+s`insj ͐6!9á#s!9DM! ^#Vr+sn`is{#`in} #͐! ͞#͐`in&͞##|#!#é#!#!,*':*(}|2q N(D(:qw?(! {w7*!9& 6C#6O#6M(*|¥(!\&÷(!\&*|·(!!l&!~#fo(> +(#~(##(a{ !p)!*w#9 $$!9DM͐͐ [$͐^#Vr+s͐ H$͐0P$͐7s!&æ$͐ ͐͐ ͉͐$`is͐ ͐͐ )͐$`in&#&æ$!9õ$,!9DM`iw#w͐~#fon&Ͳ$}%͐ ?͐^#Vr+snѯg`is#r(:**)*!ѷ! , FNxg>Goyi)$#(*|¥(!\&÷(!\&*|·(!!l&!~#fo(> +(#~(##(a{ !p)!*w#$͐ %!9%J%!9DM! n&%|?%! n&D%! n&!9DM! n&aͯu%! n&zͯ  !\&!7*!%&*!%&%!, !\&!TELk7%`(ty%7*  ZVP ?COM$$$ SUBDIR LISTlTYPEpUSERDFU GO ERA ESAVE REN GET JUMP> > _>a{_>( R~~#  2j:=:з2:_ѯ2<!~6z>_ ENo FilЇ!ж>2:ҷ(Ez͢(;:=2< /!P!6#5zͩ(>>!Rg͸Ï͸>> !F#~w6!"Y >*[~!8#Jп͸Ï 8=_.:;<>[Y o$! ~+ H(+!~ (#0 0Wy8 88Oyx! ~ (-H()08 80#OzW{_W{_}͏: !Ҷx921wy_j2y2(͖z>/İ/2:Ϸ )1w_Aз( 8 >10Qc_2xB:ҷn~#fo!Ϳ~>=!о!ϯ2ͲS[  ( @G:(:wx2p2C. C`#6SY:Ϸ͕(#* >?w?f͕#6 :<2!  # ### >ͅ!~ =Ͳ(A(S SYS(Wx2ͭ(i=`O> բ L{ _ J |xdocumentation Instruction fo installatio o a Osborn ar included. OZCPҠ require Osborn leve 1.3 I ha no bee teste o versio 1.2 I definitel wil no wor o Re A. DIFFERENCE BETWEE OZCP AN ZCP (1.0).   >  (> x 0 >.g ʹ 6?# EAllYoЯG>2#xͲ2("Y͛ͅ>2!6!~8 9 =w4!Ϳ~ ( ( ( !! > !x g(=Ë!5 6>P( - Th director displa ha bee modifie t fi o th 5 characte display. - dis rese i performe automaticall befor deletin files savin files o executin program. - OZCP wil ruBo&[ͤ(:2ͲS()SY|(+!f> ͩ< cxoͭEDelete FileYB[:!Ͳ= (#"Y G!~(p p2ͤËr_Er28: :ҷE=2͖E properl o a Osborn 1. INSTALLATION. Th installatio instruction assum tha th use i familia wit us o DDT. 1. Usin DDT chec th byt a locatio 018b o setup.com I shoul b 0c0h Chang i t 0c9h : x!w!͛!"y͏!~2!~2ϯ2\!!!~( (#~(#x2cj~c͖Ï͏x ͤ"22͛ͅ >( 2_!ү‡6!>μ8f< =EFul>c Thi chang wil no affec th operatio o setu unde th standar ccp I thi chang i no made yo wil no b abl t us setu unde OZCPR. 2. Cop OZCPR.COM DDT.COM an SYSGEN.CO t blan diskette.h OZCP -- ZCP (1.0 fo Osborn 1. Page # .po 0 .op 11 Apr 82 Michael M Rubenstein ABSTRACT. Thi documen describe th difference betwee OZCPҠ an ZCPR I i mean t b use i conjunctio wit蠠 th堠 ZCPҠ  Thi diskett shoul hav bee SYSGENe䠠 wit th standar CP/͠ operatin syste an configure wit setu a desire fo th majorit o you diskettes. 3 Wit thi diskett i driv A type dd ozcpr.com Th  e mov OZCP t hig memor with m100,8ff,8000 .cp 4 Loa sysge with isysgen.com r Clear the default dcb name with f5d,67,20 Star sysge with g100,27f Sysge wil as fo initia system. EN O DOCUMENT a i wil b necessar t us setu t reconfigur an disk whic d no us th configuratio o yo th sourc drive Respon A Sysge wil the rea th operatin syste an brea t ddt. Mov OZCP t 4000 with m8000,87ff,4000 Typ an sysge wil as fo th destinatio drive Respon A Sysge wil cop th ne syste t A Whe sysge ask fo anothe destination jus respon retur t exit. 4. Pres rese an retur t restar th syste wit th ne ccp. 5. Moun dis o driv an tes th variou feature o OZCPR Pa especia attentio t th director command I ther i an proble becaus o chang i th Osborne i i likel tha th mos visibl effec wil b i th di command I ther i an proble here D NO CONTINUE. 6. Us SYSGE t mov th operatin syste t you othe diskettes Remembe tha i wil b necessar t us setu t reconfigur an disk whic d no us th configuratio o yo   .MB0 OZCPR OZCP require Osborn leve 1.3 I ha no bee teste o versio 1. an i definitel wil no wor o RE A. Thi i modificatio o th CP/ Built-i command a the wer originall she pag t read Wit "P optio th comman fun ction a i doe today scrollin thr th entir file. 4 SAVE-Allow yo t specif th numbe o "pages yo wan save i HE o i sectors Als i th fil tha yo ar tryin te u fo us I expand th usabilit o command DIR ERA TYPE SAVE REN an USE an add command LIST DFU JUMP GO an GET Th modification ar extremel eas t instal an hav trie th ne an change function an SAV alread exists messag "Delet file? i returned 5 REN-I th ne fil nam alread exists messag "Delet File? i returned. 6 USER-Use numbe ma b specifie i HEX Als USE i USE 0. Th ne  se som improvement tha coul hel al o us Afte th modification ar installed al o th thing tha yo coul d i th pas ca stil b done thi jus add t you syste comman power Als th familia A promp tha w acommands are: 1 LIST-Type fil o th lis devic (printer withou paging. 2 DFU-Allow temporar chang i defaul use numbe fro th customar 0. 3 JUMP-Allow th use t "call th progra o "sub-r accus- ome to change no whe yo ar usin use numbe othe tha 0 Fo instance i yo ente th comman USE 10 th promp wil no rea A10>. Briefl summarize ar change commands: 1 DIR-List i thre column i routine tha i currentl loade i memor a th specifie address 4 GO-Sam a jum excep n addres i specifie an th instructio perform jum t 100h Ha th effec o re- executin whateve yo di las withounstea o two. 2 ERA-List th file tha hav bee delete whe i finishe i action 3 TYPE-Withou specifyin a optio th fil typin i stoppe a soo a you scree i filled Yo the hi ke an ge anot an intervenin commands. 5 GET-Allow th use t loa fil int memor startin a specifie address Additiona Modification I logge i t driv B: th OZCP wil searc driv A fo comman progra tha y  o ar tryin t ru i i can' fin i o B: I won' g fro t whe yo ar logge i o however. I logge i o anothe Use number th OZCP wil searc th defaul Use numbe (usuall 0 fo comman progra i i  can' fin i i you use number I logge i o B an use numbe othe tha th defaul number i wil searc i th followin sequence: 1 Th Driv an you use number 2 Th Driv an defaul use number 3 Th Replacement for the CP/M CCP ZCPR is a Group Project By the CCP-GROUP: RLC - Richard Conn FJW - Frank Wancho KBP - Keith Peterson RGF - Ron Fowler ZCPR Documentation By RL Driv an defaul use number  i th followin sequence: 1 Th Driv an you use number 2 Th Driv an defaul use number 3 ThC Table of Contents ----- -- -------- Introduction 2 Part A: Installation Instructions 4 ZCPR Integration Example  5 Setting the ZCPR Inline Options 8 REL, BASE, CPRLOC, RAS, SUBA, CLEVEL3 8 Customization Symbols 8 NLINES, WIDE, PGDFLT  8 PGDFLG, MAXUSR, SYSFLG, SOFLG, SUPRES, DEFUSR, SPRMPT, CPRMPT, NUMBASE, 9 SECTFLG, FENCE 10 Patching SUBMIT.COM 10 Part   B: Usage Instructions and Explanation of Commands 11 The ZCPR Command Hierarchy Search 11 The ZCPR-Resident Commands 14 DIR, ERA is available which sends its output to the CP/M LST: Device and does NOT page . The DIR command has been extended to allow the dis- play of the system files or all files . The ERA command now prints out the names of the  14 LIST, TYPE, SAVE 15 REN, USER, DFU 16 JUMP, GO, GET 17 ZCPR Error Messages files it is erasing . The current user number may be included as part of the command prompt; if the user is under a number other than 0, the prompt is of the form 'du>' (like 'A2>' or 'B10>'), and, if the user is under  18 Part C: ZCPR Command Levels and How to Use Them 19 Page 1 ZCPR - A Z80 Replacement for the CP/M CCP Documentation on ZCPR - A Z80 Replacement for the CP/M CCP 0, the prompt may be 'd>' or 'd0>' as per his choice . The SUBMIT facility has been changed in two basic ways: - the prompt changes to 'du$' or 'd$' when the SUBMIT command is printed -  ZCPR is a replacement for the CP/M Console Command Processor (CCP) which is designed to run as part of CP/M on Z80-based microcomputers. In most cases it is upward-compatible with the original CP/M Version 2.2 CCP. ZCPRthe $$$.SUB is executed from drive A: (note that the original SUBMIT problem now exists, but the new SUB.COM facility corrects it); the CCP-GROUP definition of an Indirect Command File now applies, and this definition is that a, however, provides many extensions to the CP/M CCP. Included in these extensions are the following features: . The TYPE function can be made to page or not page its output at the user's discretion . A LIST function ny sequence of commands which may be issued from the console is also a valid sequence of commands for execution from an Indirect Command File; hence, the sequence: DIR B:    DIR A: may be issued from either the console or an Indirect Command File, and the results of the execution of this sequence are the same. Basically, this says that Indirect Command Files are upward-compe COM file is loaded and executed if found or an error message (COMMAND?, when COMMAND was the user's command name) is printed . The numeric argument for the SAVE command can be specified in hexadecimal so that the user may atible to the console input (but not necessarily that the contents of an Indirect Command File may be issued at the console without modification). Page 2 ZCPR - A Z80 Replacement femploy the values presented by tools such as DDT exactly as they are given . A GET command which loads a file at a specified memory address and a JUMP command which "calls" the subroutine at a specified memory address have or the CP/M CCP . A command-search hierarchy is now implemented which is executed roughly as follows: - the user's command is checked against the CPR- resident commands and executed immediately if a match is found been added; a GO command which "calls" the subroutine at 100H (subset of the JUMP capabidity) has also been added This document provides the user of ZCPR with the following information: Part A: Installation Instruct - failing that, the current user number on the current disk is scanned for the COM file; the COM file is loaded and executed if found - failing that, a default user number (initially 0 but can be reset ions Part B: Usage Instructions and Explanation of Commands Part C: ZCPR Command Levels and How to Use Them Page 3 ZCPR - A Z80 Replacement for the CP/M CCP with the DFU CPR-resident command) on the cur- rent disk is scanned for the COM file; the COM file is loaded and executed if found - finally, failing that, the default user number on disk A: is scanned for the COM file; th Part A Installation Instructions In order to install ZCPR on a target microcomputer (must be currently running CP/M 2.2), the user must know two basic things: 1) Where his CCP is cur  rently running in memory 2) Where his CCP is located in the SYSGEN image, or, for systems which don't support SYSGEN (such as P&T CP/M 2.2 for the TRS-80 Model II), where his CCP is located on disk and how to place the new ZCPR done by obtaining a SYSGEN image of your system, scanning it via a debugger such as DDT to find the offset for the CCP, reading the new CPR in on top of the old one, and finally running SYSGEN again to place the resultant system on  on top of it The first question is answered relatively easily. A pro- gram, known as either BDOSLOC or BDLOC (for BDOS Locator), is provided with ZCPR. You should assemble this program for your particular computer (change t disk. If you DO NOT have SYSGEN capability, a Disk Utility program is required to locate the CCP on disk and then write the new ZCPR on top of the old one. The net result of this integration is the placement of the new Zhe base ORG if you are running non- ORG-0 CP/M) and execute it. Upon execution, it will provide you with the base address of (1) the BDOS and (2) the CCP for your particular system. BDOSLOC has worked correctly for all systems tested CPR onto disk in the proper place so that it will be loaded with the rest of CP/M on cold boot and executed properly. To find the original CCP, you typically have to locate it by its appearance. It is probably stored contiguously so far, but there is always a chance that it may NOT work for some non-tested system. For the time being, assume that it works correctly and record the starting base page address of your CCP. The second question is not answered neaon disk, so, once it is found, a sequential overwrite is all that is required. Probability is extremely high that it is stored contiguously in the SYSGEN image. The CCP starts with two (2) and ONLY TWO jump instructions followed by arly so easily. If you have the ability to SYSGEN your system, it is much easier (commonly) than if you do not. You must, after assembling the ZCPR properly, integrate it into the sysgen (or disk) image of CP/M. This can be buffer area (possibly containing an initial command and/or the Digital Research copyright notice). The Digital Research manuals show the CCP to reside at address 980H in the SYSGEN image, but this may vary with system. To fin  d this image, use DDT or some other such debugger, load the SYSGEN image you can get via SYSGEN, and examine memory starting at around 900H for the two (and ONLY two) jumps described above. If you find an area with more than two jumps (ant). This assembler is required because of the MACROs used. Only the resultant HEX file is required. 3. Assuming that you can use SYSGEN, obtain a SYSGEN image of your current CP/M system and save it on disk.  group of them), you are probably looking at the BIOS and should go lower for the CCP. The CCP will probably start on an even page or half-page address (like 900H, 980H, 1100H, etc). Page 4 4. Load the SYSGEN image into memory with DDT (or equivalent). Once loaded, verify that the original CCP is at the IMAGE address found above and compute the integration offset using the DDT H command: H, The second number displayed gives you the OFFSET value required for step 5. 5. Integrate ZCPR into your SYSGEN image via DDT's I and ROFFSET commands. Use IZCPR.HEX (or the name of your version of ZCPR) toeps using the information of the page address of the CCP (obtained from BDOSLOC and called CPRLOC within ZCPR) and the SYSGEN image address of the CCP (called IMAGE for reference in this document). 1. Edit ZCPR and set load the FCB and ROFFSET (where OFFSET was computed in step 4) to load the ZCPR.HEX file into memory at the proper location. Check to see that ZCPR is indeed properly loaded by examining the SYSGEN IMAGE area. 6. Place t the CPRLOC equate to the value obtained from above. Also set any flags and values as you desire (see the section on ZCPR Customization below). When satisfied, end the edit session. 2. Assemble ZCPR with MAC (or equivalehe new system on disk by running SYSGEN and NOT loading the system from disk (use the memory image). For further clarification of the above process, the following is a sample terminal session which outlines the steps taken.    ZCPR Integration Example B>; Sample terminal session for integrating ZCPR B>sysgen SYSGEN VER 2.2 SOURCE DRIVE NAME (OR RETURN TO SKIP)b SOURCE ON B, THEN TYPE RETURN <-- I hit the RETURN key here FUNCTION COMPLETE CCP's address The Base Page Address of this system's BDOS is C5 The Base Page Address of this system's CCP is BD <-- This is it B>ddt cpm56.com <-- Now to find the CCP in the SYSGEN image DDT VERS 2.0 NEXT PC 2D00 0100 -d900,90f  / DESTINATION DRIVE NAME (OR RETURN TO REBOOT) <-- and here B>save 44 cpm56.com <-- We now have a SYSGEN image of CP/M to work with  <-- Start looking around here 0900 31 80 E7 3E 06 3C 3C FE 1B CA 00 C2 DA 11 E7 D6 1..>.<<......... -da00,a0f 0A00 31 00 01 01 01 0C C5 CD 0F E4 21 00 BE 11 00 04 1.........!..... -db00,b0f 0B00 31 00 01 01 01 11 C5 CD 0F E4 21 00 C0 11 Page 5 ZCPR - A Z80 Replacement for the CP/M CCP B>xdir XDIR Version 2.6 User Number: 0, Double Density File Attributes: Non-System Filename.Typ Size K Filename.Typ Size K Filename.Typ Size K -------- --- ------  00 02 1.........!..... -db80,b8f 0B80 31 00 01 01 09 01 CD A8 00 21 00 D2 11 00 C2 0E 1........!...... -- Detail Left Out -- -d1100 <-- I found it at 1100H; note the 2 JMP's 1100 C3 FF BD C3 FB BD 50 10 20 20 20 20 20 20 20  -------- --- ------ -------- --- ------ !TEXTWRK.-12 0 CPR .DOC 8 EE687 .TXT 4 CPR .AQM 34 TFS .HLP 6 EE687PRE.TXT 4 CPR .ASM 50 CONTENTS.T01 6 SW1 .TXT 10 CPR .20 ......P. 1110 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 ........ 1120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ -- Detail Left Out -- -^C <-- Return to CP/M; I know that CPRLOC BAK 4 CONTENTS.T02 4 SW2 .TXT 2 CPM56 .COM 12 CONTENTS.T03 4 B: 30 Entries & 22 Files -- 338K Bytes Remaining File Data: 14 Files -- 154K Bytes Displayed B>bdosloc <-- Now to locate the will be BD00H and the IMAGE offset is 1100H B>ed cpr.asm {edit ZCPR here and place CPRLOC=BD00H}# -- Detail Left Out -- B>mac cpr $pz sz <-- Now to assemble the CPR CP/M MACRO ASSEM 2.0 C4F0    <-- Note that CPR MUST end before BDOS begins! 014H USE FACTOR END OF ASSEMBLY Page 6 ZCPR - A Z80 Replacement for the CP/M CCP B>ddt cpm56.PRLOC (CPRLOC equ 0) for integration via MOVCPM rather than the DDT/SYSGEN technique outlined above; set to TRUE for MOVCPM integra- tion or FALSE for DDT/SYSGEN integration BASE Base addrecom <-- Now to integrate! DDT VERS 2.0 NEXT PC 2D00 0100 -h1100,bd00 <-- Compute offset for new CPR CE00 5400 <-- Offset is 5400H -icpr.hex <-- Init FCB -r5400 <-- ss of your CP/M system; standard CP/M has a base of 0, but some CP/M systems (such as for the TRS-80 Model I and Heath/Zenith H89/Z89) start physical RAM memory at a higher address; eqRead in new CPR with offset NEXT PC 2D00 0000 -^C <-- Done! B>sysgen <-- Now to SYSGEN onto disk SYSGEN VER 2.2 SOURCE DRIVE NAME (OR RETURN TO SKIP) <-- Use memory image DESTINATION DRIVE NAME (uate BASE to the starting RAM memory address of your system CPRLOC This is the starting address of ZCPR; set the second CPRLOC equate to the address you obtain from BDOSLOC RAS OR RETURN TO REBOOT)b <-- onto B: DESTINATION ON B, THEN TYPE RETURN FUNCTION COMPLETE DESTINATION DRIVE NAME (OR RETURN TO REBOOT) <-- Done for now B> Page 7 ZCPR - A Z80 ReplaThis is an equate which masks out selected ZCPR command functions for security purposes on Remote Access Systems such as Bulletin Boards; the masked out functions currently include SAVcement for the CP/M CCP Setting the ZCPR Inline Options The following are the four basic options available to the user under ZCPR for customization of his package. Option Name Function REL Configures CE, ERA, REN, JUMP, GO, and GET; set RAS to TRUE to mask these out or FALSE to leave them in SUBA This is an equate which determines the drive onto which ZCPR will look for an executing Indi  rect Command File. If the basic philosophy of the Indirect Command File described above is to be maintained, this symbol should be set to TRUE (look on drive A: for the $$$.SUB file); if  Page 8 ZCPR - A Z80 Replacement for the CP/M CCP Customization Symbols The following symbols are provided for further customization of ZCPR to a user's particular tastes an not, this symbol should be set to FALSE (look on the default drive from the $$$.SUB file). To review, the basic philosophy of the Indirect Command File is that any sequence of commands d hardware facilities. Option Name Function NLINES Number of lines on the user's CRT for paging WIDE This equate is used to select a narrow or wide display under the DIR command; if WIDE is equated  which may be issued from the console (within reason, which means NOT to erase a $$$.SUB file) may also be issued from within an Indirect Command File, and the resultant execution should  to TRUE, each file name is separated by two spaces, a FENCE, and two more spaces; if WIDE is equated to FALSE, each file name is separated by one space, a FENCE, and one more space PGDFLT  be identical (same functions performed). CLEVEL3 This equate enables or disables extended Command Level 3 Processing. If set to TRUE, extended Command Level 3 Processing is enabled and the user  This is the Paging Default flag for the TYPE command; if PGDFLT is set to TRUE, the TYPE command will page its output by default and the P option on the TYPE command (see below) w command line is automatically capitalized, the terminating zero is placed at the end of the buffer, and the internal CIBPTR is set correctly (see later for more information). ill prohibit paging; if PGDFLT is set to FALSE, the TYPE command will NOT page its output by default and the P option will enable paging PGDFLG This sets the option character in the command l  ine for the TYPE command (the 'P' mentioned above); if the user wishes to change this option character, he need only change this equate MAXUSR This is the largest user number recognized by thr on B: in user 0 sees 'B>' as the prompt, but with SUPRES set to FALSE, a user on B: in user 0 sees 'B0>' as the prompt Page 9 ZCPR - A Z80 Replacement for e USER command; if the user wishes to protect the higher user areas, he may set this symbol to the highest area normally accessable; 15 is the largest permitted value for MAXUSR SYSFLG This ithe CP/M CCP DEFUSR This is the CPR-default user number which is searched in the command hierarchy for the COM files (distributed as 0); the DFU changes this temporarily until a Warm Boot or s the option character for the DIR command line which is used to specify that DIR search All Files (both $SYS and $DIR) for its display; the distributed default for this is 'A' SOFLG This isCold Boot is done, at which time the search reverts to this value SPRMPT This is the CPR prompt character which indicates that a SUBMIT file is in execution; by default it i the option character for the DIR command line which is used to specify that DIR search ONLY the $SYS files for its display; the distri- buted default for this is 'S' SUPRES Set SUPRES to TRUs set to '$', so prompts like 'A$' appear during SUBMIT file execution CPRMPT This is the CPR prompt character which indicates that the CPR is awaiting a user console command; by default it iE to suppress printing the user number when the user is under User Number 0 or set SUPRES to FALSE to ALWAYS display the User Number with the CPR prompt; with SUPRES set to TRUE, a uses set to '>', so prompts like 'A>' appear during user input to the CPR NUMBASE This is the escape character used by those commands which require a DECIMAL number as an argument; placing this c  haracter after the number argument switches the base to HEXADECIMAL; for example, 'SAVE 15 MYFILE' can be expressed as 'SAVE FH MYFILE' if NUMBASE is set to 'H' (the default) SEC1A 1A 1A 1A 1A 1A SUB......... -^C <-- Done A>save 5 newsubmt.com <-- Save new SUBMIT.COM file Page 10 ZCPR - A Z80 Replacement for the CP/M CCP TFLG This character constant is the suffix option for the SAVE command which specifies that sectors, as opposed to pages, are to be saved; the default value is 'S' FENCE This is the char Part B Usage Instructions and Explanation of Commands The following instructions are written with the assumption that the reader is quite familiar with how to use CP/M 2.2 and its CCP. ZCPR is written as a logicalacter printed to separate entries in a directory listing; it's default value is '|' Patching SUBMIT.COM SUBMIT.COM may be patched to run with ZCPR by the following procedure (this is recommended  extension of the CP/M 2.2 CCP philosophy and should be addressed as such. The ZCPR Command Hierarchy Search The first, and most basic thing, to learn about ZCPR is the order in which is searches for a COM file for execuif the user does not have SUB.COM). This patch simply makes it always place the $$$.SUB file on Drive A:. Illustrative terminal session follows: A>ddt b:submit.com DDT VERS 2.0 NEXT PC 0600 0100 -s5bb <-- Patch ition or a file specified by the GET command. Under the CP/M 2.2 CCP, if the specified COM file command was not found on the current drive in the current user area, the CCP aborted with an error message. ZCPR, however, continuess at 5BB Hex 05BB 00 1 <-- Change 0 (default drive) to 1 (drive A:) 05BC 24 . <-- That's it! -d5b0 5cf <-- See change 05B0 00 00 00 00 00 00 30 30 31 20 24 01 24 24 24 20 ......001 $.$$$ 05C0 20 20 20 20 53 55 42 00 00 00  searching from this point a maximum of two more levels. This command hierarchy search was outlined above and is described here in further detail. 1. If the command is of the form 'COMMAND' and NOT 'd:COMMAND', the CPR  -resident command list is searched for a match. If the match is found, the CPR-resident command is immediately processed. If the match is not found or the command is of the form 'd:COMMAND', the next step is taken. Note that  the current Default User Number, ZCPR temporarily logs him into it and searches the directory. If COMMAND.COM is found, it is loaded as described above and executed. If not, ZCPR proceeds to the next step.  the 'd:COMMAND' form is good for executing a command COM file which has the same name as a CPR-resident command (such as SAVE or DIR). 2. If the command is of the form 'd:COMMAND', disk drive 'd:' is temporarily log Page 11 ZCPR - A Z80 Replacement for the CP/M CCP 5. The user is now in the Default User Number, and at this point, ZCPR checks to see if the user is on disk drive A:. If not, it temporariged in for the purpose of the command search. Otherwise, the currently logged-in drive is used. 3. Now the file named COMMAND.COM is searched for. If found, it is loaded into memory starting at 100H and executed. ly logs into A: and searches the default user number of A: for COMMAND.COM. If found, it is loaded as described above and executed. If not, ZCPR prints the command name as an error message and returns to command input mode,  If not, proceed to step 4. 4. Now that the first search for COMMAND.COM has failed, the CPR checks to see if the user is under the current Default User Number. The Default User Number may be that set by the DEFUSR eq aborting the SUBMIT file if COMMAND came from it. In all cases of the search above, if COMMAND.COM is found, after it is loaded into memory, ZCPR resets the user to his original disk drive and user number. Hence, the files refeuate in the CPR or that set by the user via the DFU command. DEFUSR is in effect if DFU has not been issued since the last Warm or Cold Boot, and DFU is in effect if it was issued since the last Warm or Cold Boot. If the user is NOT underrenced by the user by default are obtained from this environment. To illustrate this command hierarchy search, consider the following examples: Example 1: DEFUSR equ 0 {default user number is 0} B10> <-- User is on Drive   B:, User Number 10 B10>ASM TEST.BBZ <-- User wishes to assemble TEST.ASM in Drive B:, User 10 <-- At this point, ZCPR looks on B:/10 for ASM.COM, fails, looks on B:/0, fails, and finally looks on A:/0 12 ZCPR - A Z80 Replacement for the CP/M CCP Another Example: For example, if the user is logged into Drive B: in User Area 10, the Default User Number is 0, and the following COM files are present as indicated --; it finds ASM.COM here and goes back to B:/10 for the file Example 2: DEFUSR equ 0 and DFU issued B10> <-- User is on Drive B:, User Number 10 B10>DFU 5 <-- User Selects User 5 as default B10>ASM TEST.BBZ <-- As WM.COM on Drive A: in User 0 MBASIC.COM on Drive A: in User 0 and on Drive B: in User 0 TEST.COM on Drive B: in User 10 and Drive B: in User 0 then the above <-- At this point, ZCPR looks on B:/10 for ASM.COM, fails, look on B:/5, fails, and finally looks on A:/5; it fails here also and prints ASM? as an error message Example 3: DEFUSR equ 0 B> <-- Use following happens when the following commands are issued from the console (or Indirect Command File): B10>WM TEST2.TXT \ \ \__ File to be edited \ \__ Invoke the WM.COM file (Word Master editor) \__ User is on Drive B: ir is on Drive B:, User Number 0 B>ASM TEST.BBZ <-- As above <-- At this point, ZCPR looks on B:/0 for ASM.COM, fails, looks on A:/0, fails, and prints error message Example 4: DEFUSR equ 0 A10> <-- User is on Dn User Area 10 Results: ZCPR searches B: User 10, B: User 0, and A: User 0 for WM.COM; it finds WM.COM in A: User 0, loads it, logs the user back into B: User 10, and executes it. B10>MBASIC \ \__ Invoke the MBASrive A:, User Number 10 A10>ASM TEST.AAZ <-- As above, but file on A: <-- At this point, ZCPR looks on A:/10 for ASM.COM, fails, looks on A:/0, fails, and prints error message PageIC.COM file (MBASIC Interpreter) \__ User is on Drive B: in User Area 10 Results: ZCPR searches B: User 10 and B: User 0 for MBASIC.COM; it finds MBASIC.COM in B: User 0, so it doesn't bother to look on A: User 0. MBAS  IC.COM is then loaded and executed as described in the previous example. B10>TEST \ \__ Invoke the TEST.COM file (TEST program) \__ User is on Drive B: in User Area 10 Results: ZCPR searches B: User 10 for TESthe names of the files on disk Forms: DIR <-- Displays $DIR files DIR S <-- Displays $SYS files DIR A <-- Displays both $DIR and $SYS files Customization Variables: WIDE T.COM; it finds TEST.COM in B: User 0, so it doesn't bother to look further (if it had, it would have found TEST.COM in B: User 0). TEST.COM is then loaded and executed as described above. B10>TEST2 \ \__ Invoke the TEST2.COM f SYSFLG SOFLG FENCE Examples: DIR *.ASM <-- All $DIR .ASM files DIR *.COM S <-- All $SYS .COM files DIR *.COM A <-- All .COM files Notes: If a file is scanned for and no such name exiile (TEST2 program) \__ User is on Drive B: in User Area 10 Results: ZCPR searches B: User 10, B: User 0, and A: User 0 for TEST2.COM; it doesn't find it, so it issues the error message 'TEST2?', which says it couldnsts on disk, the 'No Files' message will appear. However, if a file is scanned for and the name exists as a $SYS file and $DIR files are being scanned for, no file name is displayed but the 'No Files' message does NOT appear. Fo't find TEST2.COM. Page 13 ZCPR - A Z80 Replacement for the CP/M CCP The ZCPR-Resident Commands The following pages describe the ZCPR-Resident Commands. Tr example, if TEST.COM is a $SYS file and 'DIR TEST.COM' is issued, no message appears. If 'DIR TEXT.COM' is issued and TEXT.COM does not exist on disk, the 'No Files' message is displayed. Command: ERA Function: To Erase the sphese are commands located within ZCPR itself which are executed from within ZCPR. The phrases and refer to ambiguous file name and unambigous file name as per the CP/M convention. Command: DIR Function: To Display a listing of ecified $R/W files from disk Forms: ERA <-- Erase both $DIR and $SYS files Customization Variables: WIDE FENCE Examples: ERA *.ASM <-- Erase all .ASM files ERA *.* <-- Eras!  e all files Notes: If a $R/O file is encountered, a BDOS error message will be displayed and the procedure is stopped. The user is unsure at this time as to which files have been erased and which have not and should check. Sos: When the display pauses during paging, type any char to continue or ^C to abort. ^S also works. Command: SAVE Function: To Copy the TPA starting at 100H to disk Forms: SAVE <-- in DEC SAVE H <-- in HEX SAVE S <-- Number of sectors SAVE H S <-- Number of sectors Customization Variables: NUMBASE RAS : LIST Function: To Print the specified file on the CP/M LST: device Forms: LIST <-- Print the file (no paging) Customization Variables: -None- Examples: LIST TEST.TXT <-- Print TEST.TXT on LST:  Examples: SAVE 15 MYFILE.TXT <-- 15 pages saved SAVE FH MYFILE.TXT <-- 15 pages saved SAVE 10H MYFILE.TXT S <-- 16 sectors (8 pages) saved Notes: If the file name to be saved already exists, then SAVENotes: If the file has a $SYS attribute, it will be found as well as those with $DIR attributes. Command: TYPE Function: To Print the specified file on the CP/M CON: device Forms: TYPE <-- Print the file with  will exit with the message 'Delete File?'; if the user REALLY wants to save under this name, he may then type Y or y and the current file will be deleted and then recreated containing the specified part of the TPA. the paging deflt TYPE P <-- Print the file with the paging deflt negated Customization Variables: NLINES PGDFLT PGDFLG Examples: TYPE TEST.TXT TYPE TEST.TXT P Note Page 15 ZCPR - A Z80 Replacement for the CP/M CCP Command: REN Function: To Change the name of a disk file Forms: REN = Customization Variables: RAS Examples: "   REN NEWFILE.TXT=OLDFILE.TXT Notes: If already exists, the message 'Delete File?' will be printed and the user may respond with Y or y to delete the current and then rename to . Command: ress> in HEX Customization Variables: NUMBASE RAS Examples: JUMP E000 or JUMP E000H <-- Jump to E000H JUMP <-- Jump to 000H JUMP 0 <-- Jump to 000H Notes: JUMP perforUSER Function: To Change the current user number Forms: USER <-- in DEC USER H <-- in HEX Customization Variables: -None- Examples: USER 15 ms a subroutine "call", so the called routine may return to the ZCPR by either a RET or a Warm Boot. Command: GO Function: To "call" the subroutine starting at 100H Forms: GO <-- Execute reentrant at 100H Cust USER FH USER 0 USER <-- Same as USER 0 Notes: -None- Command: DFU Function: To Temporarily Change the default user number for the command hierarchy search Forms: DFU <-- omization Variables: RAS Examples: GO *.ASM <-- Assuming XDIR is loaded, gives directory of *.ASM Notes: This command is identical in function to JUMP 100H; JUMP, ho in DEC DFU H <-- in HEX Customization Variables: -None- Examples: DFU 15 DFU FH DFU 0 DFU <-- Same as DFU 0 Notes: See above for explanatiwever, leaves the address as the first entry in CP/M BASE + 80H (the input line buffer), while GO has no such address. Command: GET Function: To load a file from disk into memory starting at the specified page Forms: GETon. Page 16 ZCPR - A Z80 Replacement for the CP/M CCP Command: JUMP Function: To "call" the subroutine at the specified page address Forms: JUMP
<-- <--
in HEX Customization Variables: NUMBASE RAS Examples: GET 8000 TEST.80 <-- Load TEST.80 starting at 8000H GET 100 TEST.80 or GET 100H TEST.80 <-- Load TEST.80 #   starting at 100H GET 0 TEST.80 <-- Load TEST.80 starting at 000H Notes: GET searches for the specified file according to the same command hierarchy search employed by the ZCPR command scanner. space on disk From GET or command load by CPR, means that there is not enough space in memory Delete File? From REN or SAVE, means that the file specified already exists on disk and Hence, if the user is on B:/10 and the file is on A:/0 with the current default user number at 0, GET will search from B:/10 to B:/0 to A:/0 in looking for the file. Page 17 ZC the user may type Y or y to delete it and proceed with the REN or SAVE function Page 18 ZCPR - A Z80 Replacement for the CP/M CCP Part C PR - A Z80 Replacement for the CP/M CCP ZCPR Error Messages The following are the error messages issued by ZCPR and their meanings. Message Meaning ? Printed after a command or an argument means th ZCPR Command Levels and How to Use Them ZCPR Version 1.0 and beyond supports three distinct command levels in its implementation. Each level constitutes a different way to issue a command for ZCPR to process. Command Leveat such was invalid No File From DIR, this means that DIR did not locate any files Also from ERA with the same meaning All? Issued in response ERA *.*, asks the user is he really wants to erase all thls 1 and 2 are common to all implementations of CP/M and CP/ZM from CP/M Version 1.4. Command Level 1 is that command level in which the command is issued by the user from his console terminal. The prompt 'd>' or 'du>' appears on te files. Unlike under the original CP/M 2.2 CCP, single character input is required (Y or y for yes and anything else for no) with NO to end the line Full From SAVE, means that there is not enough he terminal, and the user is allowed to enter the command with editing from the terminal. Command Level 2 is that command level in which the command is entered from an executing $$$.SUB file. In both cases, the command is store$  d in the internal ZCPR buffer called CIBUFF (Command Input BUFFer). Under both Command Levels 1 and 2, the command is placed into this buffer, the characters of the command line are capitalized, a character count which indicates tng: 1. Locate the ZCPR. Since the ZCPR is ALWAYS 2K bytes in size and located directly under the BDOS, the transient can locate the ZCPR by examining the BDOS entry page address at location 7 and subtracting 8 from thhe number of characters in the command line is stored in CBUFF (the byte before CIBUFF), an ending binary 0 is placed after the last character in the command line, and the internal pointer CIBPTR (Command Input Buffer PoinTeR) is set tis number (8 pages = 2K bytes). The resulting number is the base page address of ZCPR. 2. Store the command line in CIBUFF and the character count in CBUFF. Knowing the base page address of ZCPR, the following informato point to CIBUFF (the first character of the command line). Command Level 3 is an extended concept to Command Levels 1 and 2 which is specifically supported by ZCPR Version 1.0 and beyond. This command level allows a transient pion is useful in doing this: Page 19 ZCPR - A Z80 Replacement for the CP/M CCP ORG CPRLOC ;Base Address of ZCPR JMP CPR ;Enter ZCPR and Execute Derogram to place a command line into CIBUFF and the character count into CBUFF and have this command line executed by ZCPR. Once control is trans- ferred to ZCPR to execute the command line, the transient program which placed the commanfault Cmd JMP CPR1 ;Enter ZCPR and Don't Execute MBUFF: DB BUFLEN ;Size of CIBUFF in bytes CBUFF: DS 1 ;Number of Bytes in Command Line CIBUFF: DS BUFLEN ;Buffer for Command Line d line loses control and the command is executed exactly as though it had been typed by the user at his console terminal. In order for a transient program to utilize the Command Level 3 facility, this program MUST do the followi CBUFF: DS 1 ;Number of Bytes in Command Line CIBUFF: DS BUFLEN ;Buffer for Command Lin DS 1 ;Buffer for Ending 0 (set by ZCPR) CIBPTR: DS 2 ;Address of CIBUFF (set by ZCPR) %   3. Obtain the User/Disk Flag. Location 4 contains this number, but the user may select a flag of his choice. This flag is one byte long, and the high-order nybble (4 bits) contains the user number and the low-order n mov a,h ;High-Order Address in A sui 8 ;A=High-Order Address of CPR mov h,a ;HL=Address of CPR mvi l,0 shld cpr ;Save address in buffer lxi d,6 ;Poinybble contains the disk number to process the command from. The User/Disk Flag is to be passed to ZCPR in the C Register. 4. When ready, transfer control to ZCPR to process the command by JMPing to the base address of ZCPR. t to command line buffer dad d ;HL points to command line buffer xchg ;DE points to command line buffer mvi c,10 ;READLN into this buffer call bdos lhld cpr ;Get A The first JMP in the JMP Table given above is at this address. At this time, ZCPR will log in the user and disk in the User/Disk Flag and process the Command Level 3 Command Line. Page 20 ddress of CPR lda udflag ;Get User/Disk Flag mov c,a ; ... in C pchl ;Run Command Line cpr: ds 2 ;CPR Address buffer prmpt: db 'User Command? $' Enjoy using ZCPR!  ZCPR - A Z80 Replacement for the CP/M CCP The following is a sample program which illustrates the steps outlined above: ; ; Demonstration of Command Level 3 Facility by RLC ; udflag equ 4 ;Address of User -- RLC Page 21 SIG/Access: Enjoy using ZCPR!un Command Line cpr: ds 2 ;CPR Address buffer prmpt: db 'User Command? $' Enjoy using ZCPR! /Disk Flag bdos equ 5 ;Address of BDOS Entry Point org 100h lxi d,prmpt ;Print User Prompt mvi c,9 ;PRINT function call bdos lhld bdos+1 ;Get address of BDOS &  lt-in functions to CP/M. Dennis McFerran of FOG reviewed this program and verified proper operation. He supplied the READ.ME file, which briefly explains features of ZCPR. More detailed documentation is contained in ZCPR.DOC and OZCPR.DOC.  Jim Woolley FOG Disk Librarian October, 1982 ME file, which briefly explains features of ZCPR. More detailed documentation is contained in ZCPR.DOC and OZCPR.DOC.  DISK.DOC -FOG/UTL.011 First Osborne Group (FOG) Utility Disk This disk contains DIF2 and SSED2, which were submitted by Jim Crowell of FOG. DIF2 permits identification of differences between two files. It can feed information regarding the differences to SSED2, which will edit the differences into a copy of the original file. For a brief description of the use of these programs, place the .COM files in drive A. At the A> prompt, type DIF2 or type SSED2 More complete instructions are contained in DIF.RNO. OZCPR was received from the Osborne Users Group (OUG) of the Washington D.C. area. It replaces your Console Command Processor (CCP) and adds several new bui'