IMD 1.16: 1/06/2007 9:55:20 FOGCPM.163 --FOGCPM163CCP COM BDOSRSX ASM BDOSRSX RSX CCP EXT] CCP102 UPD CCP102A NOTCCP103 NOT!CCP104 NOT CCP105 NOT$ !"#$CCP3 DOC;%&'()*+,CCP3MAKESUB -.CCP3STRTASM/0CCPEXT C 1CCPHDR MAC,234567CCPHDR SUB8CMDRUN COM9:;CODE C <CODE COM^=>?@ABCDEFGHCODECLR C ICODECLR COM8JKLMNOPDIRNAME COMQDIRNAME MACRDIRRSX MACSEXT SUBTFILES DOC UVGETCCP C WXHISTORY DOC5YZ[\]^_LOADER MACj`abcdefghijklmLRUNHDR MACnopLRUNHDR SUBqMAKECCP SUBrMAKEFILEDATsPUTCCP C tuRELHEX COMLvwxyz{|}~ROOT DIRSCANAS ASM"SCANAS RSXSCANCZIIASM"SCANCZIIRSXSCANLISTDOCSCANLN ASM'SCANLN RSXSETDIR COM SETDIR MAC'SUBMOD DOCSUBMOD1 ASM SUBMOD1 SUB-03-00 87 -CPM163 DOCThis is the disk name. 5LOADER y; s1*"| 7!~(Rz= :  * ""{og{%|}D t-#N#F:(#4( ^#V{ : 3K!*. >k s#rr+6.""1-*D`.45. F.~(. ^#Vx>`. s#rz%~( n#f$"6 n!f"%$~L:="@8>@W%~(*OB0:!" <_18(=X1`[%v{~bk#N#Fk$Zcx( { ~#o0/!8 !":= ڎ*ڎW~fsf-*-"~%(=_~`2s`~%(:w`6%- Load Error$<bH!D$@$$ $    "@ @CMDRUN COM1!1."~z2~2:ݖ K$ck!*k  'b-6S$6f6g6O6P~+2v4n -3N3-2~`~03v w` >3~/V# "3~(!.yq5N /w,w-5>2 -!=6#6#6!PROFILE.S  $ve$1! Y2:(( $~(3*|(&! (: #:(+>:! L # >> (4% İ w%2~$w$4v ~IwH B : H!~##~ J*|(! ( ͟ !~<2#~~4((h͗h͗!R[ W !~=::( ~%G~$w$w%~4( .>: Ϳ !~  !` ^#VCOM SUB wGy!W  !"*%.2P# !4*+" 2 "Qx2Sl "Tx2V:V:V:w`ݶZ2N*og$2|wOwwww3~ ~, ~-< w,w-3;_- -!-6 -!.~# 6     -_-=w`! 6Qpg-6g, *|(& s ( ( -:VN,0Password: $Disk I/O Error$Invalid drive$"?" in command$  (#!6 !(;;( w#;()!( w#(G!w#xw< !-ͥ (w#6 # :><: (-!:==8:?=#: s ! (# Password Error $- !/+ ;!(: ~,<<(~-<#"~ͥ w!> # *""~ ( #]T! 6*%.#w! 6 6 #w.6#6 #t#6.w. _*~1~2s1r2r.NEXTCMNDa{   C V2(^1f..5.~w1#~w2w.\( ""-|F# !3 | !3 [ x. +"!   ~!G( *~;# կ( *~:( ( ( (#ѯ* *~08:0ͥ  x<A8Q0 ~@#~: #ͱ :><:?8 #:=<+ Invalid Drive/User $*jT+~#wy#4444*h~> > <-&o 8B|+ {0~ȹ #( !546* L t  command not found.$( *"~08:0ͥ "x~0 xG#G8& & % > Ʌo$!8  > #  x> # ~0:.:/ : &: 2 22!/~ #~ !! !1 >2  #~8! ͒: W{=?8 W>A~ !".!^L  >2n  >2 x*0)#!00+  >2 × ! .n!/~hc#~!c2<2 : '?G*x~l2ww-+~ͳ_+~0ͳ 80 ?#F#~0_~!8ͥ Gͥ #(!|0?:G ~( #x8p!Hx y -2!`Q (A! !.`|ɯCCP EXTHISTORY DAT Substitution not foundHISTORY DAT:  (User 0)$AB;>>2o!"#͍}ʔ==”͍""2mNl :; ; ; This RSX displays a history trace of of bdos calls. ; ; (C) 1986 by Michael D. Kersenbrock Aloha, Oregon ; serial: db 0,0,0,0,0,0 start: jmp trace next: jmp $-$ prev: dw 0 remove: db 0ffh ; remove with next load nonbank: db 0 ; both banked and non-banked are OK thename: db 'BDOSTRSX' ; BDOS tracing RSX name loader: db 0 ; load for banked AND non-banked systems db 0,0 ; system use junque trace: push psw ; save all at entry push d push h push b mvi a,'<' ; get leading output indicator call putchar ; put to console screen pop b ; get bdos function number push b mov a,c rrc!rrc!rrc!rrc ; put msn into lsn call trascii ; translate msn to ascii call putchar ; send it to console screen pop b ; get function number again push b mov a,c call trascii ; translate lsn to ascii call putchar ; send it to console screen mvi a,'>' ; get output string terminator call putchar ; put it to screen pop b ; return all registers back pop h pop d pop psw jmp next ; and let it continue with its business trascii: ani 0fh ; make lsn "clean" adi '0' ; assume it is numeric at first cpi '9'+1 ; numeric? rc ; yup adi 'A'-'0'-0ah ; nope, must be A-F ret putchar: mvi c,06h ; direct console i/o bdos call mov e,a ; put character into place jmp next ; put character to the screen, then return to ; trace routine above (that called putchar). w ; save all at entry push d push h push b mvi a,'<' ; get leading output indicator call putchar ; put to console screen pop b ; get bdos function number push b mov a,c rrc!rrc!rrc!rrc ; put msn into lsn call trascii ; translate msn to ascii call putchar ; send it to console screen pop b ; get function number again push b mov a,c call trascii ; translate lsn to ascii call putchar ; send it to console screen mvi a,'>' ; get output string terminator call putchar ; put it to screen pop b ; return all rVBDOSTRSX>>P 0:_ B `I`I`! 9^#V#!%`Pb! Command line: %s |g}o|/g}/o^#V#DM!99`iH`|z2`:Xa}a}}’`|ʡ`!}¡`|ʒ`!}|`}|?>o&zo&|`}|>o&|o&z2`:Xa||`/g}/o#za/W{/_aDM!>2))a#}o|g1a :=2a}:=2a}DM!>))Pa =Ha}}/o|/g#}|ʡ`Ò`|g}o{_ʙa|b|7g}oa{_ʙa)”a}}o|gN#F# N#F#zڽa{a##^#VBK^#Vza#ya###a#xa#~#fo}|>?o&}|>o&{_ʙa|g}ob|g}o!9~#9b!Fb|7I`!(" !9!9^#V!bIgI`! 9^#V" !9!9^#V!bIgI`* !9^#V4cI`! 9N#F`i~b!(`i#DM+^4c͈`b!þb!(! 4cI`! 9N#F`i~0c!9^#V`i#DM+^4c͈`-c!c!I`! 9N#F!9^#V!PY8`DM`i ͈`wc! c͈`wc!cI`!3!9^#VcI`! 9N#F!9^#Vc`ʿc!!9^#V`i bc`c!`iI`!9N#F! ^#V`i^#Vad! 9^#V!8`e! 9^#V`i~#fo#s#r+s!8`I`!!9^#VeI`!DM`ia}d`i DM~d]dI`!9N#F!!9s#r`i~ e! ^!8`d!e!9s#r! ^~!9~#fojas#r! ^!8` e*! ^#Vs#r! ^#V"!! s!9^#VI`! 9N#F! ^!8`ʇe! ^#V`i^#V͜a! ^#V! ^͈`ʇe!`in&jas!!9^#V!͈`e!`in&8`s!`is#r! s#r!`i~#edf! ^#V!͈` f!!9! ^͈`ne!9^#V! ^#V`is#r! ^#V! ^#V! s#r!`in&jas!9^#V`i~#fo#s#r+s!8`I`!9N#F! ^#V!͈`ʏf`i! s#r*|ʯf*!9s#r*^#V"f! ^#Vͮz!9s#rzf!! s#rÀf!`in&jas!9^#V! s#rI`! 9^#V""!9!9^#V!+gIg!*"sI`! 9^#V*"#""+s!8`I`!N9N#F!P9^#V#+^z[l%͈`Pl!!9s!!D9s#r! !B9s#r!!@9s#rn&-͈`g!!D9s#r#+^0͈`g!0!B9s#r!!>9s#r#+^!0ͧ`8h9ͨ`8h!>9^#V! @a!>9s#rg.͈`ʓh!!@9s#r#+^!0ͧ`ʓh9ͨ`ʓh!@9^#V! @a!@9s#rOhl͈`h#+^!:9!T9~#fos#r͋͞rid͈`i!:9!T9~#fo##s#r++^#V͞rie͈`)if͈`)ig͈`Oi!9!T9~#fos#rri!:9!T9~#fo##s#r++^#V͞k!9!!>9͋ͱ;l!9!49s#rCk!:9͋vÉi!9! !>9͋ͱ\l!9!49s#r!-!69~#fo+s#rsj!9! !>9͋ͱ\l!9!49s#rCk!9! !>9͋ͱ;l!9!49s#rCk!9!!>9͋ͱ;l!9!49s#rCk!:9͋!49s#r-!89s#r[ke͈`ʗj!Új!!B9^#V!͈`ʱj!ùj!B9^#V!9! 9!9! 9!49s#r-!89s#r!!@9s#r[k!:9͋!9!69s#rsCkaoxidiujx=jscjejfjcjk!9!49~#fo͜a!89s#r!89^#V!@9~#fo`~k!@9^#V!89s#r!D9~#ʹk!>9~#fo+s#r#!89~#fo`ʹk!B9^#V`iH`Èk!!69s#rk!69~#fo#s#r!49^#V~l!69^#V!@9~#fo`l!49~#fo#s#r+^`iH`k!D9~#Ml!>9~#fo+s#r#!89~#fo`Ml! `iH` lXl`iH`_gI`!9N#F!9^#V`iͱ!9͋Ɇq$^+s! 9`i݆͋7͞rlI`!9N#F!9^#V! 9͋vÉtm! 9͋8`! 9!9͋vvs͞`iraͱ!9͋Ɇq)$^+s! 9`ira݆͋7͞!9͋ͱ\l!9*͉nÓm)bͧm)b*DM*o&)bmo&)b**+++*DM*!9N#F#^#Vkb6#> 6 #=m>6#=m : >,n Afn[n@)nafn{fn`w# .Gn`n/nmnw#0n{o|g `nmnw#Qn!!|a{ $PIPE.IN$PIPE.OUTI`!!!5͓!:o&8`5s!}2!q"5!5!"*`ʟqn& ͈`nn& ͈`o#nn&|oßqn&|͈`;o!"#"*!DMpn&>͈`Qo!DMdon&<͈`ʋp!DM#^! ͈`…on& ͈`ʈodo#~on& ͈`¶on& ͈`o!#+soÎoxp͔yp!*)5;v͈`p*)5^#V~xGp!W}DM`i)))^#V!ƀ͈`Dp!`i @a&s#rTp!w}DM`i͈`}p!qss!qs! q*|ʈpßqÜqn&"͈`p#*#"+)5s#r~pn&"͗`p#+òpn&|p!#+sÜqn&2͈`qn&>͈`q#+!DMdo͔yKq!*͜a+*)5;v*"`q*#"+)5s#r#~ʜqn& ͈`ˆqn& ͈`ʙq!#+sÜq`qn!5*`qCan't open file for redirection: <> I`Sd*m! 9~#q!rm*|ʿr***^! ͈`.r*^! ͈`9r*#"+r*DM`i~jr`i^! ͗`jr`i^! ͗`jr`i#DM+>r`i~}r!`i#DM+s!*!r* s! 9!rs*s!rs!rm!sm͓mA:$$$.SUB<Couldn't open file at end of pipe: .COMA:$$$.SUB$$$.SUBI`! 9^#V!!s!s!\!7t!\!ͤm8`͈`Zs!!!9ts##++~#sasnfDMés`i#DM+^#+s`i~sasÕs! #+sjs!u}2z.COMI`! 9^#V~t! 9~#fo#s#r+^!ͤmsI`!"!I`!I`!$!9^#VBKZt!`i#DM+s+ͧ`ntNt! 9^#V~t! 9^#V#^!:͈`t! 9^#V^J!9^#Vs!! 9~#fos#r! 9^#V!9^#VtI`! 9~#fo#s#rBK! !9s!9n&+s!ͧ`.u!9^#V~u! "u!?`i#DM+st! 9^#V!DM! 9^#V! !9^#V~:v!9^#V^! ͗`:v!9^#V^!*͈`u! 9^#V`iaʹu! 9^#V`iaʶu!?!9~#fo#s#r+sÍuu! 9^#Vau!?!9~#fo#s#r+sùu&v!9^#V^!.͈`v`i! 9s#r&v!9^#V^!9~#fo#s#r+s!9~#fo#s#r+IuI`!!9s#r!9^#V!9s#r!\!9^#V7t!\!ͤm8`!9s#r!͗`w!ͮz!9s#rBKzµv!xs!q!9^#V)))))!9^#V#^!:͈`v!9^#V^`i#DM+s!:`i#DM+s!w#+ ͨ`~wn&8` ͗`Gw#+^`i#DM+sOw#+͈`{wn&8` ͈`~w!.`i#DM+sw!`is!9^#V!9~#fo#s#r+)!9~#fos#r!\!ͤm8`!9s#r!9^#V!͗`w!9^#V!9~#fo`Žv!!9s#r x!9~#fo#s#r+!9^#V!9~#foax!9^#V6x#+!9~#fo`x)!9~#fo^#V! 9^#V)!9~#fo^#Vyx!9^#V)!9~#fo^#VBK)!9~#fo^#V! 9^#V)!9~#fos#r`i)!9~#fos#r.xw!9^#VNot enough memory to expand wildcardI`!DM`i`ʓy!9^#V^!9^#V^`;y!!9^#V^!9^#V^`]y!! 9~#fo#s#r+!9~#fo#s#r+! 9^#V~y! yI`! 9~#fo#s#r+^BK`i*͈`y`i?͈`y!xy`i ͗`™y!ѷPY!y!1w#z\*I`! 9^#VͮzI`!9^#V!9~#fo@a!9s#r!9^#Vͮz!9s#rzyz!!!9^#V! 9^#Vͳ!9^#VI`! 9^#V{I`! 9^#V### b#*|z!""!"nfDMz`i`i^#VBK! ^#Vag{! ^#V͈`+{`i^#VsrZ{`i##~#fo͜as#r! ^#V))PYDM! s#r"`i`i*͈`ʄ{͈{DM|„{!zI`! 9^#V))|DM͈`ʫ{!`i! 9^#Vsr{*I`! 9^#V!DM*{nf`ia|nf`ia@|nfa=|`ia@|nf`ia@|{nf! ^#V))PY͈`ʈ|nf##^#V`i##~#fos#rnf^#V`is#rÔ|nf`is#rnf))PY͈`|! ^#V##~#fos#r`i^#Vsr|`iut"!|#|+!9^#V*}*Ë9}|}*"|ɯ=go!9~#f/o|/g#"Ëcon:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR:I`!9^#V!!9^#Vw}I`!!!9s#ré}!9~#fo#s#r!9^#V! `}nft͈`}Ð}!"!!DM}`iDM`i~#~!9^#V`i^#Vτ~}! ^#V!9^#V!8`#!9s#r!9^#V!8`M~n&u|M~!"!!9^#V!8`t~n&u|t~!"!! ^#Vsrn&un&u!ut!9^#V!9^#V!9^#VnfH`! 9!`~!tut!!9^#VI`! 9^#V!`! 9^#V! `!"!! 9^#V)))DM! ^#V! ^#VH`! 9s#r!! s! s! s`is!t! s#r! 9^#VI`!ŋDM~`i&DM`iaʙ!% ^zʣv!"!!9^#Vmʾ!"!!9^#V!8`!ͤm!ͤm͈`!9^#V!8`!ͤm͈`!"!;!9^#V!8`͈`;!"!!!! s#r!# s!$ s`i!9^#V!s#r!9^#V!8`#!% s!8`ʕ!ƀ!9^#V!s#rè!!9^#V!s#r!I`!!9^#V!%s!I`! 9N#F!ͤm!!% s!I`!I`! 9^#V!`! 9^#V! `!!"!! 9^#V)))DM!9^#V!9^#V! ^#V! ^)^#VH`I`!DM!9^#V$~n$&!͜aDM!9~#foaʪ!9^#VBK!9^#Vy!!9^#V`i͜a b!9s#rz'!9^#V!9^#V`ĩ!9s#rz'!9^#V!9~#fo͜a͌aPY!9^#V!͌aPYDM`i!9~#foap!9^#V`i͜a!9^#V`iyp`i!9^#VI`! 9N#F!!ͤm!!ͤm"͈`´*͈`ς!"!!!ͳۂ*|ۂ!!9^#V!9^#V!$ ^!͓!"ͤm"|!!$ ^!9~#fo8`!$ szE`i!~#fo#s#r!I`!9N#F!e#!9~#fo``i#DM+^!9s#r!9^#V! ͈`ʨ! !9^#Vͤm!9^#V!9^#Vͤm^)b!у)b"*!"* *!4#4*+"}҃o&"*I`!9!L9^#Vm!9!ͤm!9!J9^#Vm!9!L9^#Vm!9!ͤmI`!9!29^#Vm!9!ͤm! 9F+N+V+^+~+ngxʱw# ä!9^#V#N#F#nẍ́s# „!9^#V#~#fox# ߄!!}!}!9^#V#~#fox*~*# !9~#foB#9}!9^#V#^#V#N#F߄!9^#V#^#V#N#F!9^#V#~#fox*~ʔ# Å!9^#V#^#V#N#FÅ!9^#V#n~Džͅ#ú!|!9^#V#n#xDž +~ͅ!9~   3!9~A3[3!}!9~a3{!!9~03:3!9~a[{[ o&!9~Aq[q o&!*Ï!*w#w#w#w*~#~#~#~"*V+^+V+^*"*s#r#s#r***""*>w#*~½#ò=ɯ<**###04+6**#R**#h**#}**#’**#§*~/w#·*~?G*^#V#~#fo))܇#ԇDM*s#r#q#p*~?W*###~~w+7~w+~#(O* %y2*%:2ͤ *w#`:* %y2*%ͤ *w#“:! w#ª> 2! ~w#»O !#Јy! 4!5µ!5! ~w#O !# y߈ !#&*~#9* ~#I! w#W> 2! ~w#hғ !#|ғ‡!5b* w#¢ʽ!ʲ!<òʽòýʲý*s#r#6#6*s#r#z6#6*^#V0123456789abcdefRtbIIvnn.t.t.ttttttttt%}D*}D/}4}9}>}C}H}M}R}LiRCCP+ version 1.02 update notes. 09/10/85 Jim Lopushinsky 1. The CCP is now no larger than the one supplied with CP/M Plus. This has been possible by removing some unnessary code, and converting it to Zilog mnemonics and optimizing the code to use Z80 instructions wherever possible. MACRO-80 is now required to assemble the CCP and LOADER. The Loader is now 1 page smaller than previous versions. As a result of all this, CCP+ will now only run on the Z80. 2. A library command processor has been added which loads CP/M Plus .COM, .SUB and .PRL files from a library called COMMAND.LBR. CMDRUN.COM is invoked by the CCP whenever it cannot find the required command. CCP+ version 1.01 update notes. 02/20/85 Jim Lopushinsky 1. The comparison of the ZCPR variable MAXDRV is now properly adjusted. Previous versions assumed 1=A, 2=B, etc. It has now been corrected so that 0=A, 1=B. 2. On cold boot, the ZCPR variables are initialized as follows: MAXDRV = 15 (Drive P:) MAXUSR = 16 (User 15) WHEEL = 0FFH (enabled) . This has been possible by removing some unnessary code, and converting it to Zilog mnemonics and optimizing the code to use Z80 instructions wherever possible. MACRO-80 is now required to assemble the CCP and LOADER. The Loader is now 1 page smaller than previous versions. As a result of all this, CCP+ will now only run on the Z80. 2. A library command processor has been added which loads CP/M Plus .COM, .SUB and .PRL files from a library called COMMAND.LBR. CMDRUN.COM is invoked by the CCP whenever it cannot find the required command. CCP+ version 1.01 update notes. 02/20/85 Jim Lopushinsky 1. The comparison of the ZCPR variable MAXDRV is now properly adjusted. Previous versions assumed 1=A, 2=B, etc. It has now been corrected so that 0=A, 1=B. 2. On cold boot, the ZCPR variables are initialized as follows: MAXDRV = 15 (Drive P:) Oct 3, 1985 Jim Lopushinsky CCP102 has 2 bugs relating to loading of .SUB files from a Command library. These have been corrected in version 1.02A 1. If the .SUB file is passed a command tail with a string longer than 8 characters, it is terminated with "command not found." 2. When using LD in write-protect mode, the CCP will go into an endless loop trying to erase $$$.SUB from within the write-protected library. Note that if using LD, use SETDEF to set the Temporary file drive to the same drive as the drive/user that LD does not allow for Libraries. Also, the *NEW* patch to SUBMIT.COM must be installed by running SUBMOD1.SUB. This patch will always force SUBMIT to build its SYSINxx.$$$ file in user 0 of the temporary file drive. This will safely allow execution of .SUB files from within Libraries when using LD in write-protect mode, and will prevent libraries from growing in size when using LD in read/write mode. November 06 1985 Version 1.03 Many thanks to Stuart Rose for his modifications to CCP+, most of which are included in version 1.03 (some slightly modified). -Jim Lopushinsky ------------------------------------------- November 04 1985 This "B" release of the version 1.02 CCP CP/M+ replacement both fixes a couple of bugs related to drive/user validation, and allows a more customizable CCP at assembly time with the additon of several equates. Bugs: The DRVSPEC routine had a bug in which a partial drive/user parse would return with the correct flags set, but it would also set either the user byte or drive byte of the command FCB to a no-zero value, indicating a successful parse later on. This has been fixed. The CCP was also a little sloppy in checking for a valid drive/user when requesting a COMfile, SUBfile, or PRLfile to be run. This allowed unprotected executable programs in protected directories to be run by non-privileged users. If a drive/user spec is given, it is now always checked against MAXDRV and MAXUSR (unless, of course, if the WHEEL byte is set). New Equates and Flag Options: All new equates live in CCPHDR.MAC for easy configuration at assembly time. As a result the accompanying version must be used for a successful assembly of the new CCP source: Flags Mnemonics: The "flags" byte was originally set using a decimal (or hexadecimal) value. To make things a little less cryptic, all bits of the flag byte are given mnemonics: time = 01H - display time in CCP prompt byechk = 02H - check for a BYE RSX noxoff = 04H - disable flow control XON/XOFF (^Q/^S) yesprl = 08H - allow PRLfiles yeslbr = 10H - allow a library command processor whllbr = 20H - test WHEEL byte before invoking CMDRUN expand = 40H - expand user's "universe" Under original conditions, the "flags" byte was set as: flags db time + byechk + yeslbr + expand EXPAND: If the user, through the WHEEL byte, or directory names enters a user-area outside those boundaries specified by MAXDRV and MAXUSR, then these new values are normally written back to MAXDRV and MAXUSR. This effectively expands the "universe" for the current user. By removing this option from the flag byte, these new "expanded" values for the maximum drive and user are NOT written back into the MAXDRV and MAXUSR bytes. If you prefer the original CCP configuration, include this option with the flag byte. WHLLBR: If the "yeslbr" bit is set in the "flags" bytes, then a library command processor is invoked if the current command cannot be located. If this option is included, then the library command processor will only be invoked if the WHEEL byte is set to 0FFH (super-user). If you prefer the original configuration, remove this option from the flag byte. Note that this option has no affect if the "yeslbr" bit is not set. MAXDRV, WHEEL, and MAXUSR bootup values: CCP102 was sent out with MAXDRV = 15, WHEEL = 0FFH, and MAXUSR = 16. If you wished different values you had to locate the appropriate place in in CCP102 source and change. They may now be set in the header source: mydrv = 'n' + drvoff - sets your maximum drive to "n:" mywhl = n - sets your initial wheel byte value to n myusr = n + usroff - sets your maximum user to n Note: It should not be necessary to modify the initial ZCPR values, as I cannot think of a reason why the system needs help from the CCP in restricting drive/user access during a Cold start. These values should be set by a utility included in PROFILE.SUB for non-remote access or by the BYE program for remote access. -JEL Many thanks to Jim Lopushinsky for the original CCP source and support programs. An added mention to Jim Dunn of the Sparrow RPC/M+ for his comments and suggestions. Stuart Rose Mississauga RCP/M+ System Mississauga, Ontario (416)-624-4935 300/1200 baud ---------------------------------------------- Edited and incorporated into version 1.03: Jim Lopushinsky Meadowlark RCP/M Edmonton, Alberta 403-435-6579 300/1200 baud e to "n:" mywhl = n - sets your initial wheel byte value to n myusr = n + usroff - sets your maximum user to n Note: It should not be necessary to modify the initial ZCPR values, as I cannot think of a reason why the system needs help from the CCP in restricting drive/user access during a Cold start. These values should be set by a utility included in PROFILE.SUB for non-remote access or by the BYE program for remote access. -JEL Many thanks to Jim Lopushinsky for the original CCP source and support programs. An added mention to Jim Dunn of the Sparrow RPC/M+ for his comments and suggestions. Stuart Rose Mississauga RCP/M+ System Mississauga, Ontario (416)-624-4935 300/1200 baud ---------------------------------------------- Edited and incorporated into version 1.03: Jim Lopushinsky Meadowlark RCP/M Edmonton, Alberta 403-435-6579 300/1 Jim Lopushinsky July 14, 1986 Edmonton Alberta, Canada Version 1.04 incorporates the following features: 1. EXDRV and EXUSR variables added to CMDRUN library processor. These set the excluded drive/user combination to exclude the search for COMMAND.LBR. It is now safe to allow the use of the library processor in an RCPM environment. Set these variables to the UPLOAD area of your system. It prevents callers from uploading a COMMAND.LBR of their own, and executing .COM files from within it via your library processor. 2. Fixed a problem with command chaining. The chain function now properly works within submit files. 3. Added the option of displaying caller's connect time instead of the current time at the prompt. Routines courtesy of Stuart Rose. 4. Changed the FLAGS byte to equates. This allowes the CCP to stay within the 25 sectors size of the original CCP from DRI. If all of the options are selected, however, the CCP may still be larger than 25 sectors, and you may have to modify your BIOS, or use a special loader to install the CCP. One such loader for the Osborne by George Peace is included in this library. The disadvantage with equates instead of a flags byte is that the source has to be assembled each time an option is changed. 5. Included a name for the multi-line RSX produced by the CCP (NEXTCMND). AD area of your system. It prevents callers from uploading a COMMAND.LBR of their own, and executing .COM files from within it via your library processor. 2. Fixed a problem with command chaining. The chain function now properly works within submit files. 3. Added the option of displaying caller's connect time instead of the current time at the prompt. Routines courtesy of Stuart Rose. 4. Changed the FLAGS byte to equates. This allowes the CCP to stay within the 25 sectors size of the original CCP from DRI. If all of the options are selected, however, the CCP may still be larger than 25 sectors, and you Mike Kersenbrock Sept 1986 Aloha, Oregon USENET: tektronix!copper!michaelk Version 1.05 incorporates the following features (over and above 1.04): 1. Provides a built-in history mechanism similar to that in Berkeley-Unix's CSH ("sea-shell"). Included is a built-in command "h" that diplays the history. See beginning of "history.doc" for more details. This mechanism does not store command lines that start with either a leading ":" or a leading space (" "). Submit files can be edited to have leading spaces in each line if it is desired that submit-file internals not be individually saved in the history. The history database is saved on the "temporary disk" as set by setdef. A separate history is used for each user-space. Use with my RAMDISK results in no visible operational delay. Delay is quite noticeable with a floppy, but may be acceptable (esp. with fast and/or cached floppies). This mechanism is totally within the CCP and the temporary disk, and therefore, does NOT reduce the available TPA memory space (as an RSX might do). 2. Provided detached enhancement ability. An additional routine can be executed just before the history routine. If a file named "CCP.EXT" exists on the "temporary disk" (set by setdef), then for each command line processed by CCP, that routine is loaded to address 6000 (hex) and "called". See History.doc and/or code for more details. If register HL is returned NOT-ZERO, then the history mechanism is turned off for "this" command. The intended purpose of this "hook" is to allow a HLL or MLL routine to be written for easy enhancements. The language in mind is "C", and an example test case has been provided in the distribution ("CCPEXT.C"). My temp disk is a 720K RAMDISK, and with that, there is no noticeable delay caused by the loading of this enhancement file "each time". The author intends to purchase an AMIGA later this year, so these enhancements may not come to pass (then why did he do any of these enhancements? -- good question -- probably habit). 3. Provided a conditional assembly flag that will "fix" CP/M Plus's handling of lines that start with a colon. "With" the fix, the "return code" is NOT reset with every command line executed, but IS reset upon cold boot. The purpose of this is to allow this author's port of the "Aussie Make" to properly terminate make-execution upon an step-wise error. My MAKE "works" by creating a submit file, then chaining to it (the submit file's last command deletes itself). In my USENET distributed version, the "-i" option puts a colon in front of each command (my current private-version inverts the sense of "-i" back to "normal", and puts spaces in front of each command to keep them out of the history, don't know if it is worthwhile distributing this again for these changes). Using this "fixed" CCP, MAKE works like this: a) Just before the chaining, MAKE resets the CP/M return status to zero. b) The ch ained-to command file executes commands as required to bring the files up to date. c) If an error happens, then the return status is "set", and all the rest of the submit-file commands are not executed (because of the leading colon). The difference with the non-fixed version, is that only the NEXT submit file command would be skipped, rather than ALL of them as in the "fixed version". For this to work, one's compilers, linkers, assemblers, etc need to set the return-status upon error. I have included in my distribution, several RSX examples -- the ones I use on several of my software tools -- that cause my software to set the return-status. They should be easy to modify for "your" tools. 4. I reinstituted the conditional-assembly flag that when used, makes the user NOT be in the prompt when the user number is ZERO. This author doesn't use non-0 user spaces, and likes a "non-busy" prompt. Set the other way, the original code is reinstituted, so there shouldn't be a problem with other people's builds. 5. With these features, the CCP remains less than 4K (albeit, getting close). 6. Quite a few auxillary files are included into the distribution for development use. Some may be useable "asis", and some should be useable as templates that can be modified for other systems. A list of what's what is in the file "files.doc". the "fixed version". For this to work, one's compilers, linkers, assemblers, etc need to set the return-status upon error. I have included in my distribution, several RSX examples -- the ones I use on several of my software tools -- that cause my software to set the return-status. They should be easy to modify for "your" tools. 4. I reinstituted the conditional-assembly flag that when used, makes the user NOT be in the prompt when the user number is ZERO. This author doesn't use non-0 user spaces, and likes a "non-busy" prompt. Set the other way, the original code is reinstituted, so ther CCP+ is a CP/M Plus CCP replacement. It is a result of dissasembling the CCP supplied with CP/M Version 3.0 and modifying the resultant source code for use in an RCP/M system. Because most of the code is copyright by Digital Research, only registered users of CP/M Plus may use this CCP replacement. This CCP includes the following changes: 1. All built-in commands have been removed. None are needed since Digital Research supplies the equivalent transient commands with CP/M 3. The user number is changed by entering u: at the system prompt, where u is the new user number. 2. It is not necessary for .COM and .SUB files to have the SYS attribute to be accessable from other user areas. The CCP searches user 0 (if the current user number is non-zero) after the current user number is searched for each drive in the command search path. 3. Commands of the form du:command or ud:command or u:command are allowed. 4. The display of the user/drive in the system prompt has been reversed to be consistent with ZCPR. 5. If the command or submit file to be executed is password protected and the correct password is not supplied or the default password does not match, a "Password:" prompt appears and the user is given one chance to enter the correct password. 6. The time (in the format [HH:MM]) is displayed at the system prompt. This can optionally be turned off. Also, for RCP/M systems, the caller's connect time instead of the current time can optionally be displayed at the system prompt. 7. The CCP checks for the presence of a BYE RSX, and if BYE is active, stop/start scroll support is turned off. All RCPM listing utilities monitor ^S input, so the BDOS should not monitor console input during console output in an RCPM system. The CCP uses function 60 (RSX function 4) to test for BYE active. My version of BYE returns 0 in register A. If this function reaches the BDOS, 0FFH is returned. Checking for BYE active can optionally be turned off. 8. The CCP uses offset +9 in the System Control Block to pass the user number of the file to load in conjunction with function 59. The value passed is user number+1, with 0 = current user number. The Loader resets this value to 0. Transient programs can set SCB+9 to load files from different user numbers. 9. If a .COM or .SUB file cannot be found, the message "command not found" is displayed. 10. Named directories are implemented (similar to ZCPR). If directory names were loaded via SETDIR, the name of the drive/user is displayed. The CCP also calls any active LBR RSX's to display their Library names. The display of directory names can be turned on  or off by using the DIRNAME utility. The directory name file (ROOT.DIR) can be created using your favorite editor. Use the sample supplied for syntax. The CCP supports password protected directories. To log into a named directory, simply enter its name as a command with an optional password, and if it is password protected, and the correct password was not supplied, a password will be prompted. 11. Full support of the ZCPR wheel byte is implemented including MAXDRIVE, MAXUSER, and WHEEL. If the wheel byte is set, access is allowed to any named directory without regard to password protection or the settings of max drive and user. If the wheel byte is zero, access is denied to out-of-bounds drive and user areas as determined by MAXDRIVE and MAXUSER. To log into an out-of-bounds area when the wheel byte is zero, you must enter the name of the target directory, then  if it is password protected, supply the correct password. If this is successfull, the MAXDRIVE and MAXUSER locations are modified to reflect the extended access. 12. A Cmdrun facility similar to the ZCPR LRUN command, which executes commands from a library has been implemented. CMDRUN can load any CP/M+ command file from COMMAND.LBR including .COM, .SUB and .PRL files. CMDRUN is invoked automatically if the CCP cannot find the required command, and CMDRUN in turn, searches for COMMAND.LBR using the drive search chain, and follows the filetype search order as set by SETDEF for selecting members once COMMAND.LBR has been found. Note that the cmdrun facility can be optionally selected. The following options can be selected by using setting them to YES in the file CCPHDR.MAC: YESLBR EQU NO Yes, to allow library command processor to be loaded and run if the command cannot be found. WHLLBR EQU NO Yes, to check Wheel byte before running library command processor. No effect unless YESLBR is YES. If yes, the library command processor will only be run if the wheel byte is 0FFH. EXPAND EQU NO Yes, to expand the users universe if the Wheel byte is zero and the user enters the name of an out of bounds directory and is successfully taken there. This will cause the MAXDRV and MAXUSER bytes to be updated to the expanded access. BYECHK EQU NO Yes, to check for presence of BYE, and if BYE is active, to disable flow-control checking (XON/XOFF). For this to be effective, BYE509 or newer must be present and CCPPLUS set to YES in BYE. NOXOFF EQU NO Yes, to always disable flow-control (XON/XOFF). Should be left NO, except with an older version of BYE. If set yes, then there is no way to pause output from most non-RCPM utilities. TIME EQU NO Yes, to display current time at the system prompt in the form [HH:MM]. But see TIMEON below. TIMEON EQU NO Yes, to display caller's connect time instead of current time at the system prompt. Both TIME and TIMEON must be set yes. Only effective with BYE509 or newer. Reverts to display current time if BYE is not active. YESPRL EQU NO Yes, to allow loading of MP/M PRL (page relocatable) files. Leave this NO unless you have MP/M specific programs. You can use SID or EDFILE to modify the following locations in CCP.COM: 3E0H: FCB for locating and loading the library command processor as follows: 3E0H: User number+1. 0 = use default user number. 3E1H: Drive code+1. 0 = use drive search chain. 3E2H: File name (must be exactly 11 bytes). The current file name is 'CMDRUN COM' (CMDRUN.COM). I have been using the CCP in the Meadowlark RCPM for over 3 years. It offers ZCPR-like capabilities which most callers are used to, and also allows the Sysop and privaleged users to easily use password protected commands. If you make use of CCP+, and have any comments or suggestions, call the above RCPM at 403-435-6579 @ 300/1200 baud, or voice at 403-437-2591. Jul 14, 1986 Jim Lopushinsky Edmonton, Alberta, Canada MP/M PRL (page relocatable) files. Leave this NO unless you have MP/M specific programs. You can use SID or EDFILE to modify the following locations in CCP.COM: 3E0H: FCB for locating and loading the library command processor as follows: 3E0H: User number+1. 0 = use default user number. 3E1H: Drive code+1. 0 = use drive search chain. 3E2H: File name (must be exactly 11 bytes). The current file name is 'CMDRUN COM' (CMDRUN.COM). I have been using the CCP in the Meadowlark RCPM for over 3 years. It offers ZCPR-like capabilities which most call type ccp+make.sub --------- TYPELZ v2.0 (CCP+MAKE.SUB) [^X = abort = next line = next page] --------- ; CCP+MAKE.SUB 18-Oct-86 ; Jerry Levy ; (215) 657-0898 ; ; Submit file to create CCP.COM and CMDRUN.COM for CCP104+ if you ; have Z80ASM assembler and LINK80 and don't have MicroSoft's M80 and L80. ; ; 1. Change filespec from .MAC to .Z80 for CCPHDR.MAC, LOADER.MAC ; and LRUNHDR.MAC. Leave CCP104+.MAC as CCP104+.MAC ; 2. Edit CCPHDR.Z80 and LRUNHDR.Z80 to select options ; 3. do SUBMIT CCP+MAKE ; ; Assumes CCPHDR.Z80, LRUNHDR.Z80, LOADER.Z80, CCP104.MAC are on disk B: ; ; NOTE: Always set CCP EQU YES in CCPHDR.Z80 ; ; set CCP EQU YES in LRUNHDR.Z80 if making CMDRUN.COM ; set CCP EQU NO if not making/using CMDRUN.COM b: [more] era ccp.com z80asm loader.bbz/m link loader[op $$sz] z80asm ccphdr.bbz/h sid loader.prl eral purpose file copy utility with several command line ohave Z80ASM assembler and LINK80 and don't have MicroSoft's M80 and L80. ; ; 1. Change filespec from .MAC to .Z80 for CCPHDR.MAC, LOADER.MAC ; and LRUNHDR.MAC. Leave CCP104+.MAC as CCP104+.MAC ; 2. Edit CCPHDR.Z80 and LRUNHDR.Z80 to select options ; 3. do SUBMIT CCP+MAKE ; ; Assumes CCPHDR.Z80, LRUNHDR.Z80, LOADER.Z80, CCP104.MAC are on disk B: ; ; NOTE: Always set CCP EQU YES in CCPHDR.Z80 ; ; set CCP EQU YES in LRUNHDR.Z80 if making CMDRUN.COM ; set CCP EQU NO if not making/using CMDRUN.COM b: [more] era ccp.com z80asm loader.bbz/m link load; EXECST.ASM for the Osborne Executive George Peace - 2/85 ; This program should be placed on the "A" drive in user zero if the ; expanded CP/M Plus CCP (CCP+) is on the boot diskette. ; This program (or at least the code presented) must be executed prior to ; the first execution of the CCP on the first warm boot. Osborne - in its ; usual short-sighted wisdom - forgot to count the number of sectors ; available on the boot disk for the CCP.COM file. There are 4 physical ; sectors of 1024 bytes available (32 sectors) on the disk. The cold boot ; code loads all 32 to bank 0, address 0. The warm boot transfers only the ; first 25 from bank zero to bank 1. This never appeared as a problem ; until someone decided to expand the CCP beyond 25 sectors (i.e. CCP+). ; This code takes advantage of the first-pass warm boot logic in the ; Executive to allow BIOS modification immediately prior to first transfer ; of the CCP to the TPA. It simply changes a 0Ch to 0Fh to allow a greater ; number of bytes to be transferred from bank 0 to bank 1. ; ORG 100H START: LHLD 1 ;get warm boot vector address INX H ;move up to routine start address MOV A,M ;get low order byte of address ADI 41H ;add offset into WBOOT routine MOV E,A ;save low order byte INX H ;increment to high order byte MOV D,M ;save high order byte XCHG ;move the computed address to from DE to HL MOV A,M ;get the high order byte of the CCPLEN value CPI 0CH ;is it 0Ch? JNZ 0 ;nope - take no chances MVI A,0FH ;yup - load up register A with 0Fh MOV M,A ;and replace the byte in BIOS JP 0 ;now do a warm boot and (hopefully) load CCP END  up register A with 0Fh MOV M,A ;and replace the byte in BIOS JP 0 ;now do a warm boot and (hopefully) load (i.e. CCP+). ; This code takes advantage of the first-pass warm boot logic in the ; Executive to allow BIOS modification immediately prior to first transfer ; of the CCP to the TPA. It simply changes a 0Ch to 0Fh to allow a greater ; number of bytes /* * C C P E X T . C * * This is a test file for doing a ccp extension. This routine * is called as :ccp.ext, and is loaded to * address 0x6000. * * This is written in Manx Aztec C II version 1.05g * * * Written 9/1986 by Michael D. Kersenbrock */ main() { /* dummy */ } ccpext(cmdline,hbuffer) char *cmdline; /* points to command line (at the byte count) */ char *hbuffer; /* simple defn for now, make a struct pointer later */ { printf("\nCommand line: %s\n",cmdline+1); return(0); /* zero should keep history mechanism active */ } dress push hl ; save it ex de,hl ;  ; Modified CCP for CP/M version 3.1 ; ; This CCP is intended to overcome some of the shortfalls of the CCP supplied ; with CP/M Plus. It is especially useful in an RCP/M environment. See the ; accompanying CCP+.DOC DOCfile for more details. ; ; This is the modified dissasembled version of the CCP. ; ; Jim Lopushinsky, Edmonton, Alberta, Canada ; (403) 435-6579 @ 300/1200 bps ; ;Feb 3/85 Released to public domain ;Feb 8/85 Incorporated DRI CCP patch #2 ;Feb 20/85 Fixed ZCPR maxdrv compare variable ;Feb 20/85 Init MAXDRV,MAXUSR, and WHEEL bytes on cold boot. ;May 21/85 Converted Select drive to BDOS calls ;Sep 8/85 Added Library Command run facility (Thanks to Richard Saeks) ;Nov 4/85 Added EXPAND equate for expanding universe, flag bit mnemonic ; equates, WHLLBR equate which will only allow running of the ; library processor (ie: CMDRUN.COM) if the wheel byte is set, ; boot equates for MAXDRV, WHEEL and MAXUSR, and PRINT0 equate ; for printing user number in prompt if the user number is zero. ; - Stuart Rose ;Nov 6/85 Removed PRINT0 equate. User number is always displayed if ; user 0. Changed WHLLBR and EXPAND as option bits to eliminate ; the need for reassembly to change options. ; ;Sep 1986 Put in print0 equate so that I can optionally not display ; the user number when it is zero. Put in makecolon flag ; to modify program return code to be useable with a ; "make" program. Added ccphistory flag that will add a ; Unix (tm of AT&T) -style "history" mechanism. ; - Mike Kersenbrock ; ; ; .z80 aseg no equ 0 yes equ 0ffffh drvoff equ 'A' ; drive offset usroff equ 1 ; user offset ;------------------------------------------------------------------------------ ;The following equate determines whether the CCP or CMDRUN library processor ;is assembled. ccp equ yes ;yes=CCP, no=CMDRUN ;------------------------------------------------------------------------------ ;The following equate determines whether the CCP has UNIX (tm of AT&T) csh-like ;history handling enabled. ccphistory equ yes ;yes=history, no=plain-jane ccp ;------------------------------------------------------------------------------ ;When enabled, this option will make colon'd commands NOT execute when the ;return code is ff00-ffff. Also, the code will NOT be reset unless it is ;a cold boot. makecolon equ yes ;yes="make" will work, no=orig version ;------------------------------------------------------------------------------ ;When yes, the user number is ALWAYS printed in a prompt. When no, user number ;is not printed when it is zero. print0 equ no ;yes=always print user nr ;------------------------------------------------------------------------------ ; The following option determines whether or not the library command processor ; should be invoked when a command is not found, depending on the status of ; the WHEEL byte. By including with the flag byte, the CCP will check the ; WHEEL byte and only invoke the library command processor if set. If not set ; then the WHEEL byte is ingored and only the "yeslbr" bit is checked (Note: ; for this equate to have any affect, you must set the "yeslbr" bit in the ; "flags" byte). whllbr equ NO ; Yes, check wheel byte before running ; library command processor ;------------------------------------------------------------------------------ ; The following option determines whether or not your user-area universe ; should expand. Generally, your universe is set by the MAXDRV and MAXUSR ; bytes in the system page (page 0). However, if you are a wheel user (the ; WHEEL byte set), you may be able to gain access to user-areas outside this ; universe. If this occurs, your universe can be expanded to include these ; new user-areas (these new values are written back to MAXDRV and MAXUSR). expand equ NO ; Yes, change MAXDRV & MAXUSR ;------------------------------------------------------------------------------ ; The following are the value that MAXDRV, WHEEL and MAXUSR are set to upon a ; bootstrap. mydrv equ 'P' - drvoff ; maximum drive mywhl equ 0ffh ; 0=NO WHEEL, 0FFH=WHEEL myusr equ 15 + usroff ; maximun user number ;------------------------------------------------------------------------------ ; These are mnemonic for the flag byte time equ NO ; Yes, display time in prompt byechk equ NO ; Yes, check for BYE RSX noxoff equ NO ; Yes, disable flow control XON/XOFF (^Q/^S) yesprl equ NO ; Yes, allow PRL files yeslbr equ YES ; Yes, allow library command processor timeon equ NO ; Yes, display time-on-system instead of ; current time if BYE active. ;------------------------------------------------------------------------------ tpa equ 0100H ; transient program area starts here ccporg equ 03E0H ; start of ccp ;------------------------------------------------------------------------------ if not ccp ccphistory equ no endif ;------------------------------------------------------------------------------ org tpa ; start at tpa jp start ;go past loader ; db 0 ;Dummy byte loadlen: ds 2 ;Length of Loader module ;....... ; ;Library command processor FCB. The FCB can be modified using SID or EDFILE ;(starting at CCPORG) org ccporg ;Room for loader module crname: db 0 ;User number + 1 (0 = Default) CCPORG db 0 ;Drive + 1 (0 = use drive search chain) CCPORG+1 db 'CMDRUN COM' ;Library processor file name CCPORG+2 ; ^^^^^^^^^^^ Must be 11 bytes long include CCP105.MAC end ry command processor timeon equ NO ; Yes, display time-on-system instead of ; current time if BYE active. ;------------------------------------------------------------------------------ tpa equ 0100H ; transient program area starts here ccporg equ 03E0H ; start of ccp ;------------------------------------------------------------------------------ if not ccp ccphistory equ no endif ;------------------------------------------------------------------------------ org tpa ; start at tpa jp m80 =loader link loader[op m80 =ccphdr relhex ccphdr sid loader.prl yw%4v ~IwH=: > 2~lw+2H*"-"b!"]:U 16kwfv Wba(iCannot read SUB member6(&iOut of disk space writing $$$.SUB6(iCannot close $$$.SUB6fT$:H(@>:!1*+E/$$$.Sw`Ha:Tw`$$$ SUB!* t-2aeO ( "K]*_2a yQ$( |-'n ,$:T(Яw`'n:Tw` >C]"_w%! ^#VCOM SUB +x:>:  :U > ~ȹ#R!546*W iO command not found.$R*"W~08:0"x~0 xG#G8IɅo$!8  > # ;x> # ~0: COMMAND LBR"Wa|F# !| !xx. +"! ; ;~!G( *W~;# կR*~:( ( ( (#ѯ**~08:0 x<A8Q0 ~@#~: #+~#wy#*h~> > ~ȹ#R!546*W iO command not found.$R*"W~08:0"x~0 xG#G8IɅo$!8  > # #include "c:stdio.h" main() { int code; code = bdoshl(0x6c,0xffff); printf("\nProgram Return Code is: %x\n",code); printf("\nProgram Return Code is: %d\n",code); } YQ!5JYPY[rQ=4V9|vQ!5JYJ4r]GY4| \ ?CCP104 NOT CCP105 NOT$ !"#$CCP3 DOC;%&'()*+,CCP3MAKESUB -.CCP3STRTASM/0CCPEXT C 1CCPHDR MAC,234567CCPHDR SUB8CMDRUN COM9:;CODE $$$͋!!l!9s#r!9^#V!@͒!9^#V!]͒ Program Return Code is: %x Program Return Code is: %d |g}o|/g}/o^#V#DM!99`i͊|z2[+/:[+}H}}|!}|!}|}|?>o&zo&|}|>o&|o&z2[+/:[+||:/g}/o#zH/W{/_HDM!>2Z+))[#}o|gs :Z+=2Z+S}:Z+=2Z+S}DM!>))Ғ =Š}}/o|/g#}||g}o{_|S|7g}o{_)}}o|gN#F# N#F#z{##^#VBK^#Vz)#y#####x#~#fo}|>?o&}|>o&{_|g}oS|g}o!9\+~#{!|7͋!b."b+!9!9^#V!͋͋! 9^#V"b+!9!9^#V!͋͋*b+!9^#Vv͋! 9N#F`i~*!b.`i#DM+^v'!!b.! v͋! 9N#F`i~r!9^#V`i#DM+^vo!D!͋! 9N#F!9^#V!PYzDM`i ʹ! )ʹ!)͋!m.!9^#V)͋! 9N#F!9^#V)!!9^#V`iK)&!`i͋!9N#F! ^#V`i^#V0^! 9^#V!z_! 9^#V`i~#fo#s#r+s!z͋!!9^#V_͋!W.DM`i.>ʿ`i DMß͋!9N#F!!9s#r`i~M! ^!z!_!9s#r! ^% !9~#foͬs#r! ^!zM*.! ^#Vs#r! ^#V".!! s!9^#V͋! 9N#F! ^!z! ^#V`i^#V! ^#V! ^4"!`in&ͬs!!9^#V!!`in&zs!`is#r! s#r!`i~#ͦ! ^#V!L!!9! ^4"°!9^#V! ^#V`is#r! ^#V! ^#V! s#r!`in&ͬs!9^#V`i~#fo#s#r+s!z͋!9N#F! ^#V!`i! s#r*.|*.!9s#r*.^#V".! ^#V!9s#rz!! s#r!`in&ͬs!9^#V! s#r͋! 9^#V"d+!9!9^#V!m͋!*d+s͋! 9^#V*d+#"d++s!z͋!N9N#F!P9^#V#+^zʝ %ʒ !!9s!!D9s#r! !B9s#r!!@9s#rn&- !!D9s#r#+^0+ !0!B9s#r!!>9s#r#+^!0z 9z !>9^#V! ͂!>9s#r6 . !!@9s#r#+^!0 9 !@9^#V! ͂!@9s#rÑ l #+^!:9!T9~#fos#r''ô dG !:9!T9~#fo##s#r++^#V=+'ô ek fk gʑ !9!T9~#fos#rX+X+ô !:9!T9~#fo##s#r++^#V/+'^ !9!!>9''!9!49s#rÅ !:9'͸'+3 !9! !>9'.('͞ !9!49s#r!-!69~#fo+s#rsV !9! !>9''͞ !9!49s#rÅ !9! !>9''!9!49s#rÅ !9!!>9''!9!49s#rÅ !:9'P+!49s#ro&!89s#rÝ e ! !!B9^#V! ! !B9^#V!9! 9X+X+X+!9! 9!49s#ro&!89s#r!!@9s#rÝ !:9'P+!9!69s#rsÅ o d uY x s e f c; H !9!49~#fo!89s#r!89^#V!@9~#fo !@9^#V!89s#r!D9~# !>9~#fo+s#r#!89~#fo !B9^#V`i͊ !!69s#r !69~#fo#s#r!49^#V~X !69^#V!@9~#foX !49~#fo#s#r+^`i͊ !D9~# !>9~#fo+s#r#!89~#foʏ ! `i͊b Ú `i͊á͋!9N#F!9^#V`i=+'!9' (ͳ)P+f+^+s! 9`i=+('y)'>(´ ͋!9N#F!9^#V! 9'͸'+ʶ! 9'P+z! 9!9'͸'0)͸'͵('`iʹ=+'!9' (ͳ)P+)f+^+s! 9`iʹ=+('y)'!9''͞ !9*kk*\+DM*^+o&ko&k*\+*+++*^+DM*`+!9N#F#^#Vkb6#> 6 #=2>6#=; : >n Aڨ[_@kaڨ{Ҩ`w# .ʉʢqͯw#r{o|g ʢͯw#“!!|a{ $PIPE.IN$PIPE.OUT͋!!!w,%!:o&zw,s!}2!"w+!w,!",*,n& :n& D#n&|Qn&|}!",#",*.!DMFn&>ʓ!DMæn&<!DM#^! n& æ#~ n& n&  !#+s xFF!*,)w+}F*,)w+^#V% xʉ!͙DM`i))).^#V!"ʆ!`i ͂`.s#rÖ!͹DM`iʿ!--!-! *,|n&"0#*,#",+)w+s#r~n&"#+n&|-!#+sn&2\n&>\#+!DMæʍ!*,+*,)w+}*,",â*,#",+)w+s#r#~n& n& !#+sâ!w+*,Can't open file for redirection: <> ͕͋*.ͯ%! 9~#=!ͯ%*,|*.*.W%*,^! p*,^! {*,#",+R*,DM`i~ʬ`i^! ʬ`i^! ʬ`i#DM+À`i~ʿ!`i#DM+s!*.!*,L! 9!-*,-!5-!:ͯ%!Dͯ%A:$$$.SUB<Couldn't open file at end of pipe: .COMA:$$$.SUB$$$.SUB͋! 9^#V!J&!(!͵&!\!y!\!zʜ!!!9ö##++~#>nfDM`i#DM+^#+s`i~>! #+sì!u}2P.COM͋! 9^#V~`! 9~#fo#s#r+^!2͋!"B/!͋!͋!$!9^#VBKÜ!`i#DM+s+ʰÐ! 9^#V~! 9^#V#^!:! 9^#V^͌'!9^#Vs!! 9~#fos#r! 9^#V!9^#V͋! 9~#fo#s#rBK! !9s!9n&+s!p!9^#V~a! d!?`i#DM+s9! 9^#V!DM! 9^#V! !9^#V~|!9^#V^! |!9^#V^!*(! 9^#V`i>! 9^#V`i>!?!9~#fo#s#r+s%! 9^#V1%!?!9~#fo#s#r+sh!9^#V^!.I`i! 9s#rh!9^#V^!9~#fo#s#r+s!9~#fo#s#r+Ë͋!!9s#r!9^#V!9s#r!\!9^#Vy!\!z!9s#r!/!!9s#rBKz! -!!9^#V)))))!9^#V#^!:@!9^#V^`i#DM+s!:`i#DM+s!Q#+ n&z ʉ#+^`i#DM+sÑ#+ʽn&z !.`i#DM+sI!`is!9^#V!9~#fo#s#r+)!9~#fos#r!\!z!9s#r!9^#V!/!9^#V!9~#fo!!9s#rN!9~#fo#s#r+!9^#V!9~#fo>!9^#Vx#+!9~#fo)!9~#fo^#V! 9^#V)!9~#fo^#VE!9^#V)!9~#fo^#VBK)!9~#fo^#V! 9^#V)!9~#fos#r`i)!9~#fos#rp=!9^#VNot enough memory to expand wildcard͋!DM`i!9^#V^!9^#V^}!!9^#V^!9^#V^ʟ!! 9~#fo#s#r+!9~#fo#s#r+! 9^#V~!O͋! 9~#fo#s#r+^BK`i*`i? !x`i !ѷPY!!1w#X\*͋! 9^#V͋!9^#V!9~#fo͂!9s#r!9^#V!9s#rz»!!!9^#V! 9^#V%!9^#V͋! 9^#V͋! 9^#V###K#*-|(!,"-",!",nfDM?`i`i^#VBK! ^#V0ʩ! ^#Vm`i^#VsrÜ`i##~#fos#r! ^#V))PYDM! s#r"-`i`i*-DM|!3͋! 9^#V)),DM!`i! 9^#Vsr*-͋! 9^#V!DM*-3nf`i?Pnf`i>‚nf0`i?‚nf`i>‚*nf! ^#V))PYnf##^#V`i##~#fos#rnf^#V`is#rnf`is#rnf))PY! ^#V##~#fos#r`i^#Vsr`iut"-!/#|+!9^#V*-Q*-9}|Q*-"-|ɯ=go!9~#f/o|/g#"-con:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR:͋!9^#V!!9^#V͹͋!.!!9s#r!9~#fo#s#r!9^#V!  nfa!"B/!!D/DM'`iDM`i~#H!9^#V`i^#V&H! ^#V!9^#V!z#!9s#r!9^#V!zʏn&u|!"B/!!9^#V!zʶn&u|¶!"B/!! ^#Vsrn&un&u!+"ut!9^#V!9^#V!9^#Vnf͊! 9! !aut!!9^#V͋! 9^#V!J ! 9^#V! T !"B/!! 9^#V))).DM! ^#V! ^#V͊! 9s#r!! s! s! s`is!a! s#r! 9^#V͋!-DM `i&DM`i7.> !% ^z ø !"B/!!9^#V!!"B/!!9^#V!z!!!]!!9^#V!zP!!Z!!"B/!}!!9^#V!z}!!"B/!!!! s#r!# s!$ s`i!9^#V!s#r!9^#V!z#!% s!z!!"!9^#V!s#r!!!!9^#V!s#r!͋!!9^#V!%s!͋! 9N#F!!!% s!͋!͋! 9^#V!Y"! 9^#V! c"!"B/!! 9^#V))).DM!9^#V!9^#V! ^#V! ^)7.^#V͊͋!DM!9^#V$~#n$&!DM!9~#fo?"!9^#VBK!9^#Vͻ##!!9^#V`iK!9s#rzi#!9^#V!9^#V`i%!9s#rzi#!9^#V!9~#foPY!9^#V!PYDM`i!9~#fo>ʲ#!9^#V`i!9^#V`iͻ#ʲ#`i!9^#V͋! 9N#F!!!!"B/#*B/$!"B/!!!%$*B/|$!!9^#V!9^#V!$ ^!%!""B/|U$!!$ ^!9~#foz!$ sz‡$`i!~#fo#s#r!͋!9N#F!ç$#!9~#fo%`i#DM+^!9s#r!9^#V! $! !9^#V!9^#V!9^#V$k!%k"*^+!"^+*\+L%*\+!4>%#4*`++"`+}%o&"B/*`+͋!9!L9^#V!9!!9!J9^#V!9!L9^#V!9!͋!9!29^#V!9!! 9F+N+V+^+~+ngx%w# %!9^#V#N#F#nx&s# &!9^#V#~#fox5&:&5&# !&!D&!}!}!9^#V#~#foxl&~l&# [&!9~#foʄ&#{&}!9^#V#^#V#N#F!&!9^#V#^#V#N#F[&!9^#V#~#foxl&~&# &[&!9^#V#^#V#N#F&!9^#V#n~ ''#&!|!9^#V#n+'#"'x ' +~+''!9~ `' `' `'u'!9~Au'[u'!}!9~au'{`'!!9~0u':u'`'!9~aڝ'{ҝ' o&!9~Aڳ'[ҳ' o&!*.'!*.w#w#w#w*.~#~#~#~"?.*.V+^+V+^*?."?.*.s#r#s#r*?.*.*.".".*.>w#4(*.~*#C(*=ɯ<*.*.###r(T(v(P(P(T(+x(*.*.#”(*.*.#ª(*.*.#¿(*.*.#(*.*.#(*.~/w#(*.~?G*.^#V#~#fo)))#)DM*.s#r#q#p*.~?W*.###~U)~w+G)C)7~w+Y)U)~#j)O1(*.K.g)y2I.*.S.g):I.2I.)K.*.w#¢):I..(*.K.g)y2I.*.S.g))O.*.w#):I..(!O.w#)> 2J.!K.~w#)OO.!S.#*y-*!K.4!J.5)!J.5_*!K.~w#:*OO.!S.#M*y-*!*O.!S.#h**.S.~#{**.O.~#‹*!K.w#™*> 2J.!K.~w#ª**K.!S.#¾***!J.5¤**.K.w#*X(*!X(*!?@ABCDEFGHCODECLR $$$.'!!l>|g}o|/g}/o^#V#DM!99`i&|z2:6}}}p|!}|p!}|}|?>o&zo&|}|>o&|o&z2:6||/g}/o#z/W{/_DM!>2))#}o|g :=2}:=2}DM!>)). =&}}/o|/g#}|p|g}o{_w||7g}o]{_w)r}}o|gN#F# N#F#zڛ{ҟ##^#VBK^#Vz#yʿ###í#xº#~#fo}|>?o&}|>o&{_w|g}o|g}o!9~#!$|7*+5I*DM*o&go&**+++*DM*!9N#F#^#Vkb6#> 6 #=’>6#=› : > A[ҿ@a{`w# .w#{o|g w#!!|a{ $PIPE.IN$PIPE.OUT'!!!!:o&s!}2!T"!!"*͠An& fšn& fʤ#~n&|±An&|f!"#"*A!DMæn&>f!DMn&<f-!DM#^! f'n& f*#~ln& fXn& fi!#+sl0x¦6ʦ!*) fʦ*)^#Vͅx!DM`i)))^#V!hf!`i s#r!DM`if!U͍ ͍ !x͍ ! {*|*A>n&"fʐ#*#"+)s#r~un&"uu#+Tn&|ʍ!#+s>n&2fʼn&>fʼ#+!DM6!*z+*) *"*#"+)s#r#~>n& f*n& f;!#+s>q!*{Can't open file for redirection: <> '*?! 9~#ʝ!e*|a*?*A͔*^! f*^! f*#"+ò*DM`i~ `i^! u `i^! u `i#DM+`i~!`i#DM+s!*?!o*ͬ! 9!q͍ *͍ !͍ !!5A:$$$.SUB<Couldn't open file at end of pipe: .COMA:$$$.SUB$$$.SUB'! 9^#V!͇! !!\! !\!Ff!!!9 ##++~#s s nfDMK `i#DM+^#+s`i~b b 7 ! #+s !u}2Ͱ.COM'! 9^#V~ ! 9~#fo#s#r+^!FÒ '!"O!'!'!$!9^#VBK !`i#DM+s+ͅ ! 9^#V~d ! 9^#V#^!:fd ! 9^#V^!9^#Vs!! 9~#fos#r! 9^#V!9^#Vz '! 9~#fo#s#rBK! !9s!9n&+s!ͅ !9^#V~ ! !?`i#DM+sÙ ! 9^#V!DM! 9^#V! !9^#V~ !9^#V^! u !9^#V^!*fʈ ! 9^#V`i[ ! 9^#V`iX !?!9~#fo#s#r+s/ Å ! 9^#Vʅ !?!9~#fo#s#r+s[ !9^#V^!.fʩ `i! 9s#r !9^#V^!9~#fo#s#r+s!9~#fo#s#r+ '!!9s#r!9^#V!9s#r!\!9^#V !\!F!9s#r!uʏ !P!9s#rBKzW !͍ !{!9^#V)))))!9^#V#^!:fʠ !9^#V^`i#DM+s!:`i#DM+s!ñ #+ ͆ n& u #+^`i#DM+s #+f n& f !.`i#DM+sé !`is!9^#V!9~#fo#s#r+)!9~#fos#r!\!F!9s#r!9^#V!uʏ !9^#V!9~#fo͠0 !!9s#rî !9~#fo#s#r+!9^#V!9~#fow!9^#V #+!9~#fo͠t)!9~#fo^#V! 9^#V)!9~#fo^#Vͥq!9^#V)!9~#fo^#VBK)!9~#fo^#V! 9^#V)!9~#fos#r`i)!9~#fos#r Ý !9^#VNot enough memory to expand wildcard'!DM`i͠5!9^#V^!9^#V^͡!!9^#V^!9^#V^͠!! 9~#fo#s#r+!9~#fo#s#r+! 9^#V~2!ï'! 9~#fo#s#r+^BK`i*fg`i?fk!x{`i u;!ѷPY!!1w#¸\*'! 9^#VP'!9^#V!9~#fo!9s#r!9^#VP!9s#rz!!!9^#V! 9^#V2!9^#V'! 9^#Vo'! 9^#V####*|ˆ!""!"nfDMß`i`i^#VBK! ^#V ! ^#Vf`i^#Vsr`i##~#fozs#r! ^#V))PYDM! s#r"`i`i*f&*DM|&!Ó'! 9^#V))͌DMfM!`i! 9^#Vsro*'! 9^#V!DM*Ónf`iʰnf`inf`inf`iÊnf! ^#V))PYf*nf##^#V`i##~#fos#rnf^#V`is#r6nf`is#rnf))PYfq! ^#V##~#fos#r`i^#Vsry`iut"!͏#|+!9^#V*ڱ*9}|ڱ*"|ɯ=go!9~#f/o|/g#"con:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR:'!9^#V!!9^#V'!!!9s#rK!9~#fo#s#r!9^#V! ͠mnf fw2!"O!!QDMÇ`iDM`i~#ʨ!9^#V`i^#VNʨ! ^#V!9^#V!#!9s#r!9^#V!n&u|!"O!!9^#V!n&u|!"O!! ^#Vsrn&un&u!ut!9^#V!9^#V!9^#Vnf&! 9!͠|! ut!!9^#V'! 9^#V!͠ª! 9^#V! ͡ʴ!"O!! 9^#V)))DM! ^#V! ^#V&! 9s#r!! s! s! s`is! ! s#r! 9^#V'!DM `i&DM`i;!% ^zE!"O!!9^#V`!"O!!9^#V!z!F!Ffʽ!9^#V!ʰ!Ffʺ!"O!!9^#V!f!"O!!!! s#r!# s!$ s`i!9^#V!s#r!9^#V!#!% s!7!h!9^#V!s#rJ!N!9^#V!s#r!'!!9^#V!%s!'! 9N#F!F!!% s!'!'!9!L9^#V!9!F!9!J9^#V!9!L9^#V!9!F'!9!29^#V!9!F! 9F+N+V+^+~+ngx0w# #!9^#V#N#F#nxLs# A!9^#V#~#foxrwr# ^!ځ!}!}!9^#V#~#foxʩ~ʩ# Ø!9~#fo#ø}!9^#V#^#V#N#F^!9^#V#^#V#N#FØ!9^#V#~#foxʩ~# Ø!9^#V#^#V#N#F!9^#V#n~FL#9!|!9^#V#nh#_xF +~hL!9~ ʝ ʝ ʝò!9~Aڲ[Ҳ!}!9~aڲ{ڝ!!9~0ڲ:ҲÝ!9~a{ o&!9~A[ o&!CCCCCCII     :B1":]OʇͣUse: DIRNAME OFF to disable directory name display DIRNAME ON to enable directory name display *.:^NʞF~w~w~#_ãdisable directory name display DIRNAME ON to enable directory name dispCCP104 NOT CCP105 NOT$ !"#$CCP3 DOC;%&'()*+,CCP3MAKESUB -.CCP3STRTASM/0CCPEXT C 1CCPHDR MAC,234567CCPHDR SUB8CMDRUN COM9:;CODE C <CODE COM^=>?@ABCDEFGHCODECLR C ICODECLR COM8JKLMNOPDIRNAME $$$ .z80 ;Utility to enable or disable directory name display by the CCP ; ;Copyright (c) 1984 - Jim Lopushinsky ; tbuff equ 80h fcb equ 5ch bdos equ 5 dirname: ld de,scbpb ld c,49 call bdos ld (scbadr),hl ld a,(fcb+1) cp 'O' jp z,onoff help: call ilprt db 'Use: DIRNAME OFF to disable directory name display',13,10 db ' DIRNAME ON to enable directory name display',13,10,0 rst 0 onoff: ld hl,(scbadr) ld l,0a4h ld a,(fcb+2) cp 'N' jp z,diron cp 'F' jp nz,help ld a,(hl) and 7fh ld (hl),a rst 0 diron: ld a,(hl) or 80h ld (hl),a rst 0 ilprt: pop hl ld a,(hl) inc hl push hl or a ret z ld e,a ld c,2 call bdos jp ilprt dseg db 'DIRNAME Copyright (c) 1984 - Jim Lopushinsky' scbpb: db 3ah,0 scbadr: ds 2 rsx66: db 66 end dirname  .z80 ;DIR RSX used in conjuction with SETDIR. The Directory names ;are loaded into this RSX. The only function that this RSX performs ;is to return the address of the Directory table for the CCP ; ;Copyright (c) 1984 - Jim Lopushinsky ; ;RSX prefex follows: ; dw 0,0,0 jp ftest next: jp 0 dw 0,0 db 'DIR ' db 0,0,0 init: db 0 ftest: ld a,(init) or a jp z,next ld a,c cp 60 jp nz,next ld a,(de) cp 66 jp nz,next xor a ld hl,dirtbl ret dirtbl: db 0 ds 256 ;to give 2 pages for the RSX and lots ;of room for directory names db 0 end CODECLR COM8JKLMNOPDIRNAME COMQDIRNAME MACRDIRRSX $$$z8e ccp.ext ccp.sym ?@ABCDEFGHCODECLR C ICODECLR COM8JKLMNOPDIRNAME COMQDIRNAME MACRDIRRSX MACSEXT $$$Michael D. Kersenbrock Sept 1986 Aloha, Oregon NEW FILES ADDED TO DISTRIBUTION FOR VERSION 1.05 BDOSRSX ASM 2k Gives BDOS call trace (RSX source) Use w/scan RSXes BDOSRSX RSX 2k Gives BDOS call trace CCP COM 4k MDK-system's version of CCP assembled CCP EXT 12k Test file for HLL extensions (put on temp disk) CCP105 MAC 82k New assembly source replacing CCP104.MAC CCP105 NOT 4k Quick description of the 1.05 enhancements CCPEXT C 2k Source of testfile CCP.EXT CODE C 2k Development utility to display CCP's current status-code CODE COM 12k Binary to above CODECLR C 2k Development utility to reset CCP's current status-code CODECLR COM 8k Binary to above EXT SUB 2k Used by makefile.dat in generating CCP.EXT FILES DOC 0k This file GETCCP C 2k Utility to get current CCP from system track for MDKsystem HISTORY DOC 8k Description and code-header for history mechanism MAKEFILE DAT 2k Make's makefile for all this "junque". PUTCCP C 2k Utility to install CCP into system track for MDK's system SCANAS ASM 6k - SCANAS RSX 2k | SCANCZII ASM 6k | - Source and RSX's for MDK's C-compiler tools. SCANCZII RSX 2k | Attachment of these, make the associated tools SCANLN ASM 6k | post errors to the CPM Plus status-code. SCANLN RSX 2k - SCANLIST DOC 2k List of the above group 5 enhancements CCPEXT C 2k Source of testfile CCP.EXT CODE C 2k Development utility to display CCP's current status-code CODE COM 12k Binary to above CODECLR C 2k Development utility to reset CCP's current status-code CODECLR COM 8k Binary to above EXT SUB 2k Used by makefile.dat in generating CCP.EXT FILES DOC 0k This file GETCCP C 2k Utility to get current CCP from system track for MDKsystem HISTORY DOC 8k Description and code-header for history mechanism MAKEFILE/* * This program gets the CCP off of a MDK-Format Double Density * disk, and puts it into the declared filename. * * The CCP is located in sectors 9-16 (inclusive) of track-1. * * Sectors are 0.5K each. * * Written 9/1986 by Michael D. Kersenbrock */ #include "c:stdio.h" FILE *Outfile; char Buffer[5000]; struct block { char funct; char areg; int bcreg; int dereg; int hlreg; } Biospb; main(argc,argv) int argc; char *argv[]; { register int sector; if (argc != 2) { Usage(); exit(1); } if ((Outfile=fopen(argv[1],"w")) == NULL ) { fprintf(stderr,"\nCan't open file: %s\n",argv[1]); Usage(); exit(2); } fclose(Outfile); for (sector = 9 ; sector <= 16 ; sector++) { /* * Set track number */ bioscall(10,1,0); /* * Set sector number */ bioscall(11,sector,0); /* * Set dma bank to 1 */ bioscall(28,0,1); /* * Set dma address */ bioscall(12,&Buffer[(sector-9)*512],0); /*  * Read sector */ bioscall(13,0x8000,0); } Outfile=fopen(argv[1],"w"); for (sector = 0 ; sector < 4096 ; sector++) { putc(Buffer[sector],Outfile); } fclose(Outfile); } bioscall(number,bc,a) int number; int bc; int a; { Biospb.funct = number; Biospb.bcreg = bc; Biospb.areg = a; return(bdos(0x32,&Biospb)); } Usage() { fprintf(stderr,"\nUsage: getccp \n"); } ,argv) int argc; char *argv[]; { register int sector; if (argc != 2) { Usage(); exit(1); } if ((Outfile=fopen(argv[1],"w")) == NULL ) { fprintf(stderr,"\nCan't open file: %s\n",argv[1]); Usage(); exit(2); } fclose(Outfile); for (sector = 9 ; sector <= 16 ; sector++) { /* * Set track number */ bioscall(10,1,0); /* * Set sector number */ bioscall(11,sector,0); /* * Set dma bank to 1 */ bioscall(28,0,1); /* * Set dma address */ bioscall(12,&Buffer[(sector-9)*512],0); /* ; ; >>>>>>-- COMMAND LINE HISTORY PROCESSING FOR CP/M PLUS --<<<<<< ; ; (C) Copyright 1986 by Michael D. Kersenbrock, 18625 S.W. Hennig ; Court, Aloha, Oregon 97006 All rights Reserved. ; ; Personal non-commercial use and distribution of this software ; is permitted so long as the above Copyright notice is maintained ; with this and subsequent copies. ; ; History (no pun intended, but noted): ; ; Version 1.0 - September 1986 Original release ; ; ; This was written first in psuedo HLL code, then hand coded into assembly ; language. That psuedo-HLL code is included below as comment lines. ; ;Note: No matter how efficiently written, this isn't really practical without ; a ramdisk or a fast hard disk. No strong effort is done to minimize ; the file size (and thus disk speed) because it isn't likely to ; acceptably fast with a floppy (regardless). I use a FAST 720K ramdisk. ; Actually, I have tried it with my floppy, and it isn't too bad at all ; but then, the floppy IS cache'd. I did my own cacheing over and above ; CP/M 3.0's (didn't like theirs), so I don't know how it works with ; DRI's version of cache. I have 178K of floppy-file cacheing. ; ; This history implements "!!", "!pattern", "!number" for command ; substitution, and implements the command 'h' to give a list of ; previous commands and their numbers. ; ; These examples use '!' as the history command character, this is ; the same as Berkeley-UNIX's (tm of AT&T) CSH shell. This CP/M ; implementation uses '|' interchangeably. The functions implemented ; are: ; ; !! Repeat last command, similar to ^W ; ; ! Repeat last command that starts with ; the given pattern. ; ; ! Repeat command numbered ; ; EACH OF THE ABOVE THREE: append the rest of ; "this line" to the substituted line. Example: ; ; If command #40 were: "COMPILE -O -C", then ; "!40 ROUTINE.C" would result in: ; "COMPILE -O -C ROUTINE.C" ; ; h Command that gives numbered command history ; list to be used with the above command. ; ; When a history-substitution is made for a command, the new ; command line is presented to the console for editing in a ; similar fashion to the banked-^W command (unlike csh). ; ; With the substitutions, the rest of the calling command line ; (if any) is added onto the substitution-replacement line. ; ; If you don't want submit files to store their internal-commands ; into the history record, put a space in front of those commands. ; ; If the file ": CCP.EXT" exists, then that program is ; loaded into memory at address 6000H, then executed with HBUFFER ; and CMDLINE address-pointers passed on the stack "above" the ; return address. CMDLINE's pointer is "just" above the return address. ; ; ; Data structure "buffer" has 42 CMDSIZE-byte records numbered 0-41. ; ; defns: when file is read in, ; record 1: contains the last command number ; record 2: contains the last command ; then... ; record 0: is where last command nr is moved to ; record 1: is where "translated" current command ; is built. ; ; ;History file format: ; ; One command line per RECSIZE byte logical record. ; ; First sector contains the current command number (1-byte) ; ; Second sector contains the last command ; Third sector contains the command before last ; (etc.) ; ; If the first byte of a sector is a null, we have ; "reached the end" of the history (null-commands are ; not stored). ; ; The file saves the last 40 command lines. ; ; A "command-line" has the first byte being the byte count, ; and a null-terminator just after the last "real" byte. ; ; If a substituted command line is modified by the line ; editor (when given the opportunity), then this new changed ; version will be put into the history along with the one ; "fetched" from history. ; ; Pattern: String of non-space and non-control characters ; ; ; ; This history routine is called with a newly gotten command in the ; CMDLINE buffer. This routine will play games with the buffer (possibly ; modifying its contents), then return. ; ; if (Command length == 0 || cmd starts w/' ' or ':') { ; return(); ; } ; buffer is cleared to nulls ; Check to see if "temp:Historyx.dat" exists ; ; if (exists) { ; readfile into data buffer starting at record-1 point ; } ; ; read command number from record-1, and write it to record-0 ; reset substitution and error flags; ; if (first-char == '!') { ; if (2nd char == '!') { ; copy line at record-2 to record-1; ; copy rest of cmdline onto end of the record-1 line; ; set substitution flag; ; } ; else if (rest up to a terminator is numeric) { ; translate number to binary; ; if ( command number wanted is NOT in our list ) { ; clear cmd line ; print "not found" ; set errorflag; ; break out from first level 'if' ; } ; else { ; copy record[(cmdnr-number+1)] to record-1; ; copy rest of cmdline onto end of the record-1 line; ; set substitution flag; ; } ; } ; else { ; search (bottom-up) for a string match (no white space) ; if (found) { ; copy that line to record-1; ; copy rest of cmd line onto end of record-1 line ; set substitution flag; ; } ; else { ; clear cmd line ; print "not found" ; set errorflag; ; break out from first level 'if' ; } ; } ; copy record-1 to cmdline; ; ; } ; else if (1st char == 'h' && 2rd char == terminator) { ; reset substitution flag, and set err flag ; print cmd lines w/numbers to screen ; } ; else { ; copy cmdline to record-1 ; } ; if (not ERRORFLAG) { ; increment command number at 0 ; ; if (first-char-of-cmd is printable, and not ' ' or ':') { ; write buffer starting at record0 (bumps last one out) ; } ; } ; else { ; reset command line; ; } ; ; if (substitution flag set) { ; calculate checksum of cmdline; ; set DMA address to cmdline; ; set DE to zero and call function 10 (edit substitution line); ; if (new checksum != old checksum) { ; go through self again; ; } ; } ; ; command line now contains command line, ready for "normal" processing. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; END OF HISTORY MODULE ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set substitution flag, and set err flag ; print cmd lines w/numbers to screen ; } ; else { ; copy cmdline to record-1 ; } ; if (not ERRORFLAG) { ; increment command number at 0 ; ; if (first-char-of-cmd is printable, and not ' ' or ':') { ; write buffer starting at record0 (bumps last one out) ; } ; } ; else { ; reset command line; ; } ; ; if (substitution flag set) { ; calculate checksum of cmdline; ; set DMA address to cmdline; .Z80 ;Modified LOADER for CP/M version 3.1 ; ;This Loader is to be combined with the modified CCP before installing ;the CCP. It is especially useful in an RCPM ;environment. See CCP+.DOC for more details. ; ;This is the modified dissasembled version of the LOADER. ; ;Jim Lopushinsky, Edmonton, Alberta, Canada ;484-5981 @ 300/1200 bps bdos EQU 5 ;............. ; ;RSX header for the loader. ; ; begin: ds 4 ; 100H dw end-begin ;Length of loader module 104H JP LOADER ;Loader entry point NEXT: JP 6 ;modified to JMP BDOS PREV: DEFW 7 ;modified to point to prev RSX DEFB 0 ;remove flag DEFB 0 ;non-banked flag DEFB 'LOADER ' ;The name of this RSX DEFB 0FFH ;Loader flag DEFB 0,0 ;reserved ;......... ; ;End of RSX header ; scbbase: ;Address of Base of System Control Block DEFW 0 ; 11BH membase: ;Address of Base of Common memory DEFB 0 ; 11DH ;........... ; ;Jump table for service routines that the CCP uses in the non-relocated ;version of the loader ; JP chkrsx ;Remove inactive RSXs 11EH JP reloc ;Relocate RSX 121H JP setload ;compute relocate address 124H JP setnext ;set up next RSX pointer 127H JP setrsx ;set up RSX chains 12AH ; ;save IX and call BDOS 12DH ; xbdos: push ix call bdos pop ix ret ;............ ; ;Loader entry point. All BDOS calls are intercepted here. We only ;need to intercept function 59, Load overlay ; LOADER: LD A,C ;Get BDOS function CP 59 ;is it Load overlay? jr NZ,NEXT ;on to BDOS if not POP BC ;GET RETURN ADDRESS IN [BC] PUSH BC LD (STKSAVE),sp LD SP,LDRSTACK PUSH BC ;Save return address on stack ld ix,(scbbase) ;SCB in IX EX DE,HL LD (LFCBADDR),HL ;Save Load FCB address LD A,H ;Test for load address of 0 OR L PUSH AF ;save flags CALL Z,CHKRSX ;Delete inactive RSXs if 0 POP AF ;restore flags CALL NZ,LOAD ;if load address non-zero, load the program POP DE ;Get return address LD HL,100H ;point to start of .COM file LD A,(HL) ;Get first byte CP 0C9H ;Is it a return inst? jr Z,DORSX ;RSXs attached. Go relocate them LD A,D ;Test for return address of 100H DEC A OR E jr NZ,NOT100H ;Jump if not loading a .COM or .PRL file LD A,(PREV+1) ;Get High byte prev address OR A ;is it 0? jr NZ,NOT100H ;Nope LD HL,(NEXT+1) ;Get next RSX address LD (BDOS+1),HL ;Save in JMP BDOS in page 0 LD (BDOSJMP),HL ;And save it for us CALL SETTPA ;Set Top of TPA address in SCB NOT100H: LD sp,(STKSAVE) ;Restore callers stack XOR A ;flag no error LD L,A LD H,A RET ;............... ; ;HERE IF BAD LOAD ADDRESS ; BADADDR: LD DE,0FEH ;init error code ERRRET: LD sp,(STKSAVE) ;restore callers stack POP HL ;get return address PUSH HL DEC H ;test for return to 100H (called from CCP) LD A,H OR L EX DE,HL ;error code in HL LD A,L ;propagate error code to A and B LD B,H RET NZ ;return if called by user program (not CCP) BADADRA: LD C,9 ;print string function LD DE,LOADMSG ;point to load error message CALL xbdos ;print the error message RST 0 ;and warm boot. ;................. ; ;RELOCATE THE RSX ; MOVERSX: INC HL LD C,(HL) ;Get length of RSX into BC INC HL LD B,(HL) LD A,(MEMBASE) ;Get common memory base OR A ;Test for banked system jr Z,NONBNK ;Jump if non-banked system INC HL INC (HL) ;Test for non-banked only load jr Z,LNOLOAD ;jump if non-banked only RSX NONBNK: PUSH DE ;Save RSX start address CALL SETLOAD ;Set up relocation address POP HL ;RSX start address in HL CALL RELOC ;Relocate the RSX CALL SETRSX ;Set up the RSX pointers LNOLOAD: POP HL ;restore COM header table location ;............... ; ;LOAD RSX'S AND ADJUST COM FILE ; DORSX: LD DE,16 ;offset in COM file header to start of ;RSX length table ADD HL,DE ;form address PUSH HL ;save on stack LD E,(HL) ;Get start address of RSX in DE INC HL LD D,(HL) LD A,E ;Test for end of RSX table OR D jr NZ,MOVERSX ;Go do it if not at end CALL 0103H ;Call init routine in COM file RSX header LD A,(200H) ;Get first byte of .COM file CP 0C9H ;Is it return inst? jr NZ,NO2NDHDR ;Jump if no second header page set 1,(ix+33h) ;Set RSX flag ;........... ; ;Here to move the COM file down one page ; NO2NDHDR: LD bc,(0101H) ;Get length of COM file into bc LD HL,200H ;source LD DE,100H ;destination LDIR ;Move COM file down one page jr NOT100H ;and process next header ;............ ; ;SET UP RSX HEADERS. DE = base of RSX ; SETRSX: LD HL,(BDOS+1) ;get top of TPA LD L,0 ;align on page boundary LD BC,6 ;length of move LDIR ;move Serial number into place xor a LD E,18H ;point to loader flag LD (DE),A ;zero the loader flag LD E,0DH ;High byte of prev address LD (DE),A ;zero prev high byte DEC DE ;low byte of prev LD A,7 LD (DE),A ;prev = 0007H LD L,E ;point to prev in next RSX LD E,0BH ;next field in this RSX LD (HL),E ;set prev field of next RSX INC HL ;to point to this RSX LD (HL),D ;.............. ; ;SET UP NEXT FIELD IN RSX HEADER ;HL = base of next RSX, DE= next field in this RSX ; SETNEXT: EX DE,HL ;HL=next field, DE=next RSX LD (HL),D ;save page number DEC HL ;point to low byte LD (HL),6 ;always 6 STNEXTA: LD L,6 ;adjust LD (BDOS+1),HL ;alter JMP BDOS LD (BDOSJMP),HL ;and save it for us ;............. ; ;SET TOP OF TPA IN SCB ; SETTPA: LD DE,LSCBPB ;point to SCB paramater block ;............. ; ;GET/SET SCB AT [DE] ; LGSSCB: LD C,49 ;get/set SCB jp xbdos ;Set the Top TPA address in SCB ;............. ; ;DELETE ANY INACTIVE RSX'S ; CHKRSX: LD HL,(BDOS+1) ;get top of TPA LD B,H ;top of TPA page in B RSXRMLOOP: LD H,B ;get RSX base page LD L,18H ;offset to loader flag INC (HL) ;test loader flag DEC (HL) RET NZ ;return if at loader LD L,0BH ;offset to high byte of next field LD B,(HL) ;get next RSX page into B LD L,0EH ;point to remove flag LD A,(HL) ;get remove flag OR A ;test remove flag jr Z,RSXRMLOOP ;jump if not to remove this RSX LD L,0CH ;point to prev field LD E,(HL) ;get prev address into DE INC HL LD D,(HL) LD A,B ;get next RSX page LD (DE),A ;set prev RSX to bypass this RSX DEC DE LD A,6 ;always 6 LD (DE),A INC DE ;back to high byte of prev field LD H,B ;form address of next RSX LD L,0CH ;offset to prev field in next RSX LD (HL),E ;set prev address in next RSX INC HL ;to bypass this RSX LD (HL),D LD A,D ;test for page zero prev pointer OR A PUSH BC ;save RSX page CALL Z,STNEXTA ;alter location 6 if we just removed ;lowest RSX POP BC ;restore RSX page jr RSXRMLOOP ;and loop for more RSXs ;............ ; ;LOAD THE PROGRAM ; LOAD: PUSH HL ;save FCB address LD DE,DMASCB ;point to SCB param block for get DMA CALL LGSSCB ;Get current DMA address EX DE,HL ;DMA into DE ex (sp),iy ;restore FCB address, save IY bit 7,(ix+25h) ;test library member load jr z,notlbr ld l,(iy+23h) ld h,(iy+24h) ;get member length into HL ld (memlen),hl ;save member length jr load1 notlbr: ld (iy+20h),0 ;zero record count load1: ld l,(iy+21h) ld h,(iy+22h) ;get load address into HL ex (sp),iy ;restore IY, save FCB address DEC H ;test for load address < 100H INC H jp Z,BADADDR ;jump if attempt to load below 100H PUSH HL ;save load address PUSH DE ;save old DMA address PUSH HL ;save load address again CALL setusr ;set up multi-sector count, user number POP HL ;restore load address PUSH AF ;save old mult-sector count on stack MOREREAD: LD A,(BDOS+2) ;get base page of top of TPA DEC A ;less one SUB H ;compare with load address jp C,TOHIGH ;jump if too high jp Z,tohigh LD (nextaddr),HL ;save current sector address CP 64 jr C,ok64 LD a,64 ok64: PUSH HL LD d,a ADD A,a bit 7,(ix+25h) ;test library flag jr z,load3 ld hl,(memlen) ;get member length left ld c,a ;sector count in c ld b,0 sbc hl,bc ;calculate new length left jr nc,load2 ;jump if no overflow ld a,(memlen) ;get length left ld hl,0 load2: ld (memlen),hl ;save new length left or a ;at end of member? jr nz,load3 pop hl ;restore stack inc a ;A = 1 jr readend load3: LD e,a CALL setmce LD e,0 POP HL PUSH HL PUSH DE CALL LREAD ;read a sector POP DE ;restore block length POP HL ;restore sector address ADD HL,DE ;bump sector address jr Z,MOREREAD ;jump if no read errors READEND: POP BC ;get old multi-sector count DEC A ;if EOF, A = zero LD E,B ;old multi-sector count in E CALL SETMCE ;restore old multi-sector count LD C,26 ;set DMA function POP DE ;restore old DMA address PUSH AF ;save read EOF status CALL setous ;set DMA to old value, restore old user number POP AF ;restore read EOF status LD de,(ERRCODE) ;get read error flags jp NZ,ERRRET ;jump if read error (not EOF) POP DE ;restore load address into DE POP HL ;restore FCB address into HL ;............. ; ;CHECK FOR PRL FILE (PAGE RELOCATABLE) ; bit 6,(ix+25h) ;is it PRL? ret z ;............. ; ;here if .PRL file loaded ; LD A,E OR A ;must be on even page boundary jp NZ,BADADDR ;jump if not on page boundary LD H,D ;load address into HL LD L,E INC HL ;point to code length in PRL header LD C,(HL) ;get code length into BC INC HL LD B,(HL) LD L,E ;L = 0 ;............... ; ;RELOCATE THE LOADED MODULE ; RELOC: INC H ;point to start of code PUSH DE ;save load address PUSH BC ;save length LDIR ;move the module to target location ;[HL] NOW POINTS TO START OF BIT MAP POP BC ;restore length POP DE ;restore target address PUSH DE LD E,D ;target page into E DEC E ;adjust relocation offset PUSH HL ;save bit map address LD H,E ;relocation offset in H LD E,0 ;init bit offset RELOCLP: LD A,B ;test for end OR C jr Z,RELOCDN ;Jump if done DEC BC ;Decrement length left LD A,E ;get number of bits left AND 7 jr NZ,NOBUMP ;jump ok EX (SP),HL ;get bit map address LD A,(HL) ;get next byte from bit map INC HL ;bump EX (SP),HL ;back to stack LD L,A ;bits in L NOBUMP: RL l ;shift into carry jr NC,NOADJUST ;jump if no need to adjust LD A,(DE) ;get a byte ADD A,H ;adjust it LD (DE),A ;put it back NOADJUST: INC DE ;bump pointer jr RELOCLP ;and loop for more RELOCDN: ;relocation complete POP DE ;adjust stack POP DE RET ;................ ; ;HERE IF LOAD ADDRESS IS TOO HIGH ; TOHIGH: CALL SETMSC ;restore things LD HL,80H ;point to TBUFF CALL LREAD ;read one more sector into TBUFF jr NZ,READEND ;jump if read error LD HL,0FEH ;set error code LD (ERRCODE),HL jr READEND ;and jump to read return ;.............. ; ;SET UP THE LOAD PARAMETERS ; SETLOAD: LD A,(BDOS+2) ;get top of TPA page DEC A ;less one DEC BC ;decrement load length SUB B ;compute target page INC BC ;correct load length CP 0FH ;load must start at page 15 or higher jp C,BADADRA ;jump if too low LD HL,(NEXTADDR) ;get target address CP H ;compare with load page jp C,BADADRA ;jump if target address > load address LD D,A ;relocation address into DE LD E,0 RET ;.............. ; ;RETURN MULTI-SECTOR COUNT IN [A] AND SET IT TO 1 ; SETMSC: LD E,1 ;set multi-sector count to 1 ;............... ; ;RETURN MULTI-SECTOR COUNT IN [A] AND SET IT TO [E] ; SETMCE: LD A,(ix+66H) ;get the old multi-sector count LD (ix+66H),E ;set the new multi-sector count RET ;.............. ; ;SET DMA ADDRESS AND READ a sector ; LREAD: EX DE,HL ;DMA address in DE LD C,26 ;Set DMA function CALL xbdos ;set the DMA address LD C,20 ;Read sequential function LD HL,(LFCBADDR) ;point to FCB EX DE,HL ; into DE CALL xbdos ;read a sector LD (ERRCODE),HL ;save return code OR A ;set read return flag RET ;............ ; ;set up load user number ; SETUSR: LD A,(ix+25H) ;get load user number and 1fh ;default user number jr Z,setmsc ;go and set multi-sector count if default DEC A ;adjust to true user number LD E,A ;into E for BDOS LD A,(ix+60H) ;get old user number LD (curusr),A ;save it LD (ix+60H),E ;set new user number jr setmsc ;and on to set multi-sector count ;................ ; ;restore old user number ; setous: LD A,(ix+25H) ;get load user number and 1fh ;default? Jr Z,setous1 ;on to restore old DMA if default LD A,(curusr) ;get old user number LD (ix+60H),A ;restore it setous1: LD (ix+25H),0 ;set load user to default jp xbdos ;.............. ; ;LOAD ERROR MESSAGE ; LOADMSG: DEFB 0DH,0AH DEFB 'Load Error$' ;............ ; ;SCB FOR GET DMA ADDRESS ; DMASCB: DEFB 3ch ;offset to DMA address DEFB 0 ;return value from SCB ;........... ; ;SCB PARAMETER BLOCK TO SET OFFSET 62H (TOP OF TPA) ; LSCBPB: DEFB 62h ;offset to top of TPA address DEFB 0FEH ;set word in SCB end equ $ BDOSJMP equ $ ;Top of TPA address NEXTADDR equ $+2 ;next load sector address LFCBADDR equ $+4 ;load FCB address STKSAVE equ $+6 ;user stack save ERRCODE equ $+8 ;read error return code ;local stack space LDRSTACK EQU $+45 curusr equ $+10 ;old user number memlen equ $+11 ;library member length END er number and 1fh ;default? Jr Z,setous1 ;on to restore old DMA if default LD A,(curusr) ;get old user number LD (ix+60H),A ;restore it setous1: LD (ix+25H),0 ;set load user to default jp xbdos ;.............. ; ;LOAD ERROR MESSAGE ; LOADMSG: DEFB 0DH,0AH DEFB 'Load Error$' ;............ ; ;SCB FOR GET DMA ADDRESS ; DMASCB: DEFB 3ch ;offset to DMA address DEFB 0 ;return value from SCB ;........... ; ;SCB PARAMETER BLOCK TO SET OFFSET 62H (TOP OF TPA) ; LSCBPB: DEFB 62h ;offset to top of TPA address DEFB 0FEH ;set word in SCB end equ $ BDOSJMP equ $ ;Top of TPA address NEXTADDR equ $+2 ;next load sector address LFCBADDR equ $+4 ;load FCB address STKSAVE equ $+6 ;user stack save ERRCODE equ $+8 ;rea .z80 aseg ;Modified CCP for CP/M version 3.1 ; ;This CCP is intended to overcome some of the shortfalls of the ;CCP supplied with CP/M Plus. It is especially useful in an RCPM ;environment. See CCP+.DOC for more details. ; ;This is the modified dissasembled version of the CCP. ; ;Jim Lopushinsky, Edmonton, Alberta, Canada ;403-435-6579 @ 300/1200 bps ; ;Feb 3/85 Released to public domain ;Feb 8/85 Incorporated DRI CCP patch #2 ;Feb 20/85 Fixed ZCPR maxdrv compare variable ;Feb 20/85 Init MAXDRV,MAXUSR, and WHEEL bytes on cold boot. ;May 21/85 Converted Select drive to BDOS calls ;Sep 8/85 Added Library Command run facility (Thanks to Richard Saeks) no equ 0 yes equ 0ffffh ;----------------------------------------------------------------- ;The following equate determines weather the CCP or CMDRUN ;library processor is assembled. ccp equ no ;yes=CCP, no=CMDRUN ;------------------------------------------------------------------------------ ;The following equate determines whether the CCP has UNIX (tm of AT&T) csh-like ;history handling enabled. ccphistory equ no ;yes=history, no=lrun-loader ;----------------------------------------------------------------- TPA EQU 100H ;Tpa programs get loaded here org tpa ;start at tpa jp start ;jump over variables ;---------------------------------------------------------------- ;The EXDRV and EXUSR values determine which drive/user area is ;excluded when searching for COMMAND.LBR. The purpose of these ;values is to prevent callers from uploading a COMMAND.LBR and ;invoking CMDRUN to execute .COM files from it. These 2 values ;should be the UPLOAD area of your system. If you do not wish ;to exclude any drive/user, use 0 for EXDRV. EXDRV: db 1 ;Exclude drive. A=1, B=2, etc ;0 = do not exclude any drive/user EXUSR: db 4 ;Exclude user number. ;---------------------------------------------------------------- ;Do not modify the following equates. WHLLBR EQU NO EXPAND EQU NO TIME EQU NO BYECHK EQU NO NOXOFF EQU NO YESPRL EQU NO YESLBR EQU NO TIMEON EQU NO include CCP105.MAC ry, no=lrun-loader ;----------------------------------------------------------------- TPA EQU 100H ;Tpa programs get loaded here org tpa ;start at tpa jp start ;jump over variables ;---------------------------------------------------------------- ;The EXDRV and EXUSR values determine which drive/user area is ;excluded when searching for COMMAND.LBR. The purpose of these ;values is to prevent callers from uploading a COMMAND.LBR and ;invoking CMDRUN to execute .COM files from it. These 2 values ;should be the UPLOAD area of your system. If you do not wish ;to exclude any drive/user, use 0 for EXDRV. EXDRV: db 1 ;Exclude drive. A=1, B=2, etc ;0 = do not exclude any drive/user EXUSR: db 4 ;Exclude user number. ;---------------------------------------------------------------- ;Do not modify the following equates. WHLLBR EQU NO EXPAND EQU NO TIMEm80 =lrunhdr l80 lrunhdr,cmdrun/n/e gencom cmdrun [loader CCP EXT] CCP102 UPD CCP102A NOTCCP103 NOT!CCP104 NOT CCP105 NOT$ !"#$CCP3 DOC;%&'()*+,CCP3MAKESUB -.CCP3STRTASM/0CCPEXT C 1CCPHDR MAC,234567CCPHDR SUB8CMDRUN COM9:;CODE C <CODE COM^=>?@ABCDEFGHCODECLR C ICODECLR COM8JKLMNOPDIRNAME COMQDIRNAME MACRDIRRSX MACSEXT SUBTFILES DOC UVGETCCP C WXHISTORY DOC5YZ[\]^_LOADER MACj`abcdefghijklmLRUNHDR MACnopLRUNHDR $$$sid loader.prl ?@ABCDEFGHCODECLR C ICODECLR COM8JKLMNOPDIRNAME COMQDIRNAME MACRDIRRSX MACSEXT SUBTFILES DOC UVGETCCP C WXHISTORY DOC5YZ[\]^_LOADER MACj`abcdefghijklmLRUNHDR MACnopLRUNHDR SUBqMAKECCP $$$all: ccp.com cmdrun.com ccp.ext scanczii.rsx scanas.rsx scanln.rsx ccp.ext: ccpext.c cc-c ccpext linkc -o ccp.ext ccpext.o -c 6003 -b 6000 submit ext.sub ccp.com: loader.prl ccphdr.hex submit makeccp.sub loader.prl: loader.mac m80 =loader link loader[op] ccphdr.hex: ccphdr.mac ccp105.mac m80 =ccphdr relhex ccphdr cmdrun.com: lrunhdr.mac ccp105.mac m80 =lrunhdr l80 lrunhdr,cmdrun/n/e gencom cmdrun [loader] scanczii.rsx: scanczii.asm rmac scanczii link scanczii [OP] erase scanczii.rsx rename scanczii.rsx=scanczii.prl scanln.rsx: scanln.asm rmac scanln link scanln [OP] erase scanln.rsx rename scanln.rsx=scanln.prl scanas.rsx: scanas.asm rmac scanas link scanas [OP] erase scanas.rsx rename scanas.rsx=scanas.prl "a!"Rd9^#V"`*a))"b*as"c!">d9^#V*as!"d9^#V!/* * This program installs a CCP onto a MDK-Format Double Density * disk, geting the data from the declared filename. * The file's data is transferred directly, not taking into account * the 100H "load-offset". * * The CCP is located in sectors 9-16 (inclusive) of track-1 (4K). * * Sectors are 0.5K each. * * Written 9/1986 by Michael D. Kersenbrock */ #include "c:stdio.h" FILE *Infile; char Buffer[5000]; struct block { char funct; char areg; int bcreg; int dereg; int hlreg; } Biospb; main(argc,argv) int argc; char *argv[]; { register int sector; register int temp; if (argc != 2) { Usage(); exit(1); } if ((Infile=fopen(argv[1],"r")) == NULL ) { fprintf(stderr,"\nCan't open file: %s\n",argv[1]); Usage(); exit(2); } for (sector = 0 ; sector < 4096 ; sector++) { if ((temp= getc(Infile)) == EOF) break; Buffer[sector] = temp; } fclose(Infile); for (sector = 9 ; sector <= 16 ; sector++) { /* * Set track number */ bioscall(10,1,0); /* * Set sector number */ bioscall(11,sector,0); /* * Set the dma bank to '1' */ bioscall(28,0,1); /* * Set dma address */ bioscall(12,&Buffer[(sector-9)*512],0); /* * Write sector */ bioscall(14,1,0); } } bioscall(number,bc,a) int number; int bc; int a; { Biospb.funct = number; Biospb.bcreg = bc; Biospb.areg = a; return(bdos(0x32,&Biospb)); } Usage() { fprintf(stderr,"\nUsage: putccp \n"); } t argc; char *argv[]; { register int sector; register int temp; if (argc != 2) { Usage(); exit(1); } if ((Infile=fopen(argv[1],"r")) == NULL ) { fprintf(stderr,"\nCan't open file: %s\n",argv[1]); Usage(); exit(2); } for (sector = 0 ; sector < 4096 ; sector++) { if ((temp= getc(Infile)) == EOF) break; Buffer[sector] = temp; } fclose(Infile); for (sector = 9 ; sector <= 16 ; sector++) { /* * Set traT !9"t#! #>G3! !!"͵!#>G3!P!!!͵!C#6!"b#> 2d#l"F#2E#2H#2I#:C#R!f#Ͷ:D#ƒ!h#ͶeO!j#Ͷ!D#D!l#Ͷ:D#ª!C#6O:D#og |:D#2e#!n#Ͷ͚:e#og |D:e# *Z#!F#s#r:e# D:e#> 2d#O:D#og |,DO:D#2e#!p#Ͷ!r#:e#og++|ODc!"F#!!R >> !"j!##>!E#~n!F#^#Vq!H#~n!I#~nl!^#V"v#2D#<2y#*v#~2#:#og:y#og\d!d#4:d#og |8*b# |!" !z#s !"b#*b##"b#>2d#!y#*b#~2x#:D#!D#2D#!#:d#og~:x#]!D#4!y#4:E#og |x!E#4:D#!I#:E#ogw:I#!D#2I#:D#2#!D#D!#Ͷ!D#~2#!$Ͷ!D#~2#:#!#ng"Z#:#2D#:E#og+|:I#!E#2I#!F#^#V"$*$|!$w:I#!$2I#*$}!$w:I#!$2I#:I#/<2I#!!R >> !"j!##>!E#~n!F#^#Vq!H#~n>2$:E#2$:$og:$og\!I#:$og~n!$4y!!R !#j!I#~n*F#:E#og"F#2E#2I#^#V"$!\#$#>=>2$*$~2 $: $og:$og\C! $Ͷ:D#3>!\#:$_>G#!$4*t#ʹRg >> !%#>@ l!^ ^#Vʙ‰n#Fғ#N#r+s#^#V++r+s~n5n5^ q#pnO4~ _ s#r#s#r#q!r/" Format Overflow*1"-&'"! $G N'BZ!9F=~# ->  =&9nx2y ]2"*x2=cA AҐG:=cx2"!F6!~#ʴx=>E +-/2:0 4 !.QQBe[Ež+kt-tcGҒxGGGšGyOʭ cÞ:ҿðy2~#z0 0_!~4_!sc;:G:!c2G:<2=(c:c>2^ !5-:!<_!>w w>+P!~5>.͖G:x0}:> !~ʐ5!4!5-2x!^4{ү!~0>0G "$4 =<4 <_!9z  +60<x< Axc  =>   B C~0#3 W% : 0  *$n ` x=Z G G ‡ :Y"p ځ !H"xG ځ G G › G >  Í ­ x§ > G ¸ G x >G =  x!F" :W" :F">  >2$!$G :W"# !F"# > + > + + 2$!$ !$rg O:x"yd !9G` ~#'Q Q yg O:p"v ÷   {‡ j& *W"*F"\#\> > > {=>' !9 =~#' {>' ý {=>' {>b *F"++|2$!$ ɯ > >2$"$"$`i"$!9"$!$+ 5% ~# 0 *5%~ *5%~t !/%>G3!!!y"͵!y""C%!A%fÜ !/%>G3!R.!!"͵!""G%!E%fñ *7%"I%!I%f!K%*;%^#V!O"s#r*=%^#V!Q"s#r*9%^#Vͧ|*_"ͧ|G !O%Y *9%^#V}*_"}G !Q%Y :t"= *9%^#V}*_"}G= !S%Y :w"X *9%^#V}X !U%Y ^#V"W%!/""]%*W%"a%!Y%r"c%"g%!c%À k%~# … :p"  " + !o%^#V}*k%w!B""x%*k%"z%*m%"v%!r% + !"o%" *o%#"o%:q%*k%*o%w*o%*m%^#V+\| :q%   2q%:q%!/""%!"%!|%r2%!%G ^#V"%:p"V :r" *% *%5!%6:% | ͯ n ] î !% *% *%5!N"6!% :N"ʫ *%6È 2%:% !/""%!"%!%r!F"6#6!%6 ^#V"%!B""%*%"%!%ͽ!/""%!"%!%rô:p"*%~ -*F"#"F"ô*%~ A!F"6#6ô:x"*%~ c*J"#"J"!H"6#6ô*%~ ´*H"#"H"!H"#!H"6#6*H"*Y"#\|´!/""%!"%!%r!N"6"%!9"%!%! 9^%~# *%^#V|*%*% ͭ*% nb#*% !%>9=!%>*%!%#*%~#V*%6P#6*%~#*%^#V))|*%6#6Ð*%6<#6*%6#6*%6#6*%6#6*% 6*%^#V}͍}2%*%^#V}!%44*%^#V}>2%*%^#V}(*%~#(*%6#6*%"%*%"%*%"%!%͚*%^#V|e*%"%!"%!%r^#V^#V' :1"ڃ!r21"O!'"’6× +~#w!2" s#r!1"4ɰ/" I/O Stack Overflow:x"!% :N"!B""%!%ͪ!%6:N"2%!N"6:% *F"#"F":% !F"6#6:%""*^#V#"^#V.:":"|?|~.:yaoA =.:;<>[]$y *a ͎Úa$͎a1ڼ o&))))\xH  #w ͎͔*#AG͎a:  6p4͎+ͦ7#aC#*/6?3w͎aJ͎7#6 C.ƒ͎ ͦwaʃ#*o6?sw͎^aʊ͎w#6 ƒ%#6Œ*##^ ~?£# œxCON CON RDR PUN LST M! ~͔$;͎a1\l;$;!~ ;͎!a" 0͎#x=G ͎>ɯ*+=^#VE#{#z=6#6E r+s!%F#~ڜ!%6P  =  = !%^r+s6 #6 !%4^N*|}=¹lO>~>N*|Y=y= >~=>q2*/"Lq{VE**#:OZE#s#rc_L3VEr+s{‚!4*+>|ʑ+}o$.~2."?:ҠG:Ҡ*p4#6ÁZ:͋*++"}+͑}|2"Z͋"1|ʠ##"6*s#r { *:w>6a*"Á*w#wÁ$?ʁͦ.qÁ$?ʁ.NÁ*~" 4#4#4$?ʁ~4ͽʁV>CÁ$?ʁ~V>Cʁ*~+>Á4Á*!*~!/2*|X(^#VZZ{zkz2zʚ:ŽͦqÕN#u*|*~=!:wì>$?ʁ|}ʁ~> ҁ<Á$?ʁ|*w=Á* *^#V6+6++ʹÁ$Qʁ>ҁ"N#F#~.q#p#w>Á$Qʁ>*~Z!p=b>!*" s#r#w=Á* }!X&6 4>2W&*T&!4#4#4~#N#F#y#x#:W&*T&!!:V&ҹ:X&~G~#~O?9#~9! p! y! q<=<͹ɯ~#N#F#w#q#pͰ͠~g#!!?! 6?<ʢ= _!xږœFNuwxG>O>G!$q#p#6"Q&"T&2S&x2V&͠2W&Ͱ!S&~5h =5:V&5*T&< W&5*Q&:V&O*T&:X&&y OA:V&¹*Q&w# ;:W&[*T&![?*Q&"Q&:W&/g.x}03|g}o txg.>Gx|g}oÔȇá)çyw# í~#~#WWObk++ ~+y~#/!/"{#z*O"*Q"xyx;_!s^#V͒5>(7yn>)7|*|$*͒ͤl!>,75> _=  =  = 0:77EE5|S}S ~dԀ ̀ڋÂxEN #~7Ô!e͒*&!9{_z{ 5>#7*&>=^#V#_>: >?7!]͒͒>=7^#V|/}&.))Ò#F>A> #J~ >.~ =;^#V# File: Traceback: ERROR FIXED OVERFLOW OVERFLOW UNDERFLOW ZERO DIVIDE END OF FILE UNDEFINED FILE KEYNULCONCONRDRPUNLSTBADG!"~& Ç! Condition Stack Overflow$4Ox![& w#s#r#s#r!9!" s#r!"N![& +++++_#{x#z}++~_++!"5!~# ŒÈ!"N![& +++++§#~#+{#z++~ç#^#V=!1"~' 5:1"_!2"^#V"/"B".~# *_")))))p" )|  *B"|}*""F":1"*/"B"w# 4 !"{ M N 64!"&"&"&2"21"!&!}|u ڞ "&q#p##}o"&*}o|Ҥ !Ç!+w+w+r+s4w#w#s#r++*&s#r"&*&#"&*&DM!&x~d!#~+d!+F+Nq#p*&+"&_!b!=!!+~O~#~G!>w!/x=!yZ! 6# 4! (!=ɯ ~#fo !&~#ʄ!*& l!!Ç!!  Insufficient Memory$ Invalid I/O List End of Execution$!n nn HEXFILRELFILSYSINSYSPRINT@ $1.REL$1.HEX: File contains relocatable code#####!#D####$$$$/"$$ Invalid Format Item$$$$$$ Stream/Record Sequen/Direct Input/Output Keyed Access P< $conC%G%B"#%$$%%3%4%a%g%x%z%i%j%%% %%%%%%%%%%%%.dat%%%%%%% %%%@ $1.REL$1.HEX: File contains relocatable code#####!#D####$$$$/"$$ Invalid Format Item$$$$$$ Stream/Record SequenSYSTEM; A0 System commands HELPF; A1 Help files MISC; A2 Miscellaneous CPM+; A3 CP/M Plus UPLOAD; A4 Latest uploads BASIC; A5 Basic programs ADV; A6 Adventure OTHRSYS; B0 Other BBS systems DIRU; B1 Directory and cataloge utilities RCPM; B2 Bulletin board utilities LANG; B3 Languages MODEM; B4 Communication software UTIL; B5 Utilities MODULES; B6 Modules and syslib DISKUTL; C0 Disk maintenance utilities IBMPC; C1 IBM Personal computer CPM86; C2 CP/M-86 software TXTUTL; C3 Text and word processing C; C4 C language software ZCPR; C5 ZCPR3 software SQUSQ; C6 Squeeze and unsqueeze utilites PCSIG; D0 IBM PC/SIG volumes SIGM; E0 SIG/M volumes SPEC1;XYZ A7 SPEC2;XYZ B7 SPEC3;XYZ C7 SYS1;ABC A8 SYS2;ABC B8 SYS3;ABC C8 PRIV;QQZ A9 SYSLOG;CCXY A15 ; ; S C A N A S . A S M ; ; This RSX scans the console stream for particular patterns, if one ; of the patterns are found, the SCB error flag is set. ; ; This, being for AS.COM, looks for "ERROR" and "Cannot", setting the ; error flag if found. ; ; The purpose of this RSX is to make "MAKE" work more fully under CP/M plus. ; ; CCP105.ASM with makecolon turned "on" allows the "-i" function in "make" ; to be functional (stopping the make sequence upon a stepwise error) for ; those programs (typically compilers, linkers,assemblers) which set the SCB ; error code upon errors. Since most (of my) programs don't even know about ; that error flag, something needs to be done: this RSX. This RSX is to be ; attached to the appropriate compilers (etc), and the patterns set ; appropriately. The patterns needed are those put out by the compiler (etc) ; when it detects an error. My C-compiler, for instance, puts out ; an "errors" count with compile-time errors, and "failure" with command-line ; errors. Thus, I would look for those two words in the output stream. ; I had used the "BDOSRSX" RSX to determine that my compiler uses bdos call ; 02 (console output) to stream its error message(s). ; ; The particular version of CP/M "Make" being referred to is my port ; of the "Aussie Make" -- which I posted to Usenet's net.micro.cpm . ; ; (C) Copyright 1986 by Michael D. Kersenbrock Aloha, Oregon ; serial: db 0,0,0,0,0,0 start: jmp scan next: jmp $-$ prev: dw 0 remove: db 0ffh ; remove with next load nonbank: db 0 ; both banked and non-banked are OK thename: db 'SCANAS ' ; Scan console output RSX for AS.COM loader: db 0 ; load for banked & non-banked systems db 0,0 ; system use junque scan: ; note: no BDOS call has input in 'a' mov a,c ; get bdos call number cpi 2 ; console output stream? jnz next ; no, so quickly bypass this RSX ; yep, so .... push psw ; save all at entry push h push b push d ; ; The general scheme is to maintain a window into the stream ; equal to the maximum width of the longest search string. When ; a character is sent to the console, it is added to the "window", ; and then that window is compared with all the strings. If ; a match is made (at any time), then the SCB error flag is set. ; The specific error flag set is: ; FF12 == MAKE ERROR ; ; Note that comparisons (etc) are sort of done tail-end first ; (the "current" character that just came in is the "tail-end" ; of something). ; Insert new character into window lxi h,window+winsize-2 ; source pointer to end-1 of window lxi d,window+winsize-1 ; destination pointer to end of window lxi b,winsize-1 ; want to move all but last character db 0edh,0b8h ; Z80 LDDR reverse block move pop d ; get new character push d mov a,e sta window ; insert the new character into window lxi d,str1 ; point to first string call compare ; compare string to window contents cz seterror ; set SCB error if error found lxi d,str2 ; point to second string call compare ; compare strin to window contents cz seterror ; set SCB error if error found exit: pop d ; return all registers back pop b pop h pop psw jmp next ; and let it continue with its business window: db ' ' ; length >= longest of below strings winsize equ 6 ; the above length ; NOTE: the strings should be ; spelt backwards. str1: db 'RORRE',0 ; first string to look for str2: db 'tonnaC',0 ; second string to look for ; Compare strings at window and at (DE). Return ; with ZERO FLAG RESET FOR NOMATCH and SET for MATCH. ; Note that the comparison strings terminate with a null. compare: lxi h,window ; *HL -> window, *DE -> compareString cmploop: ldax d ; get fixed-string character ora a ; end of string? rz ; yep, so return with MATCH indicated cmp m ; strings matching? rnz ; nope, so quit now & tell the caller inx h ; point to next char in each string inx d jmp cmploop ; and compare next character seterror: mvi c,6ch ; BDOS function for set-return code lxi d,0ff12h ; load MAKE ERROR CODE jmp next ; go set code, then return to whomever ; called seterror it continue with its business window: db ' ' ; length >= longest of below strings winsize equ 6 ; the above length ; NOTE: the strings should be ; spelt backwards. str1: db 'RORRE',0 ; first string to look for str2: db 'tonnaC',0 ; second string to look for ; Compare strings at window and at (DE). Return ; with ZERO FLAG RESET FOR NOMATCH and SET for MATCH. ; Note that the comparison strings terminate with a null. compare: lxi h,window ; *HL -> window, *DE -> compareString cmploop: ldax d ; get fixed-string character ora a ; end of string? rz ; yep, so return with MATCH indicated cmp m ; strings matching? rnz ; nope, so quit now & tell the caller inx h ; point to next char in eawSCANAS y !ST{2OUbo[bo  RORREtonnaC!OȾ#el  I; ; S C A N C Z I I . A S M ; ; This RSX scans the console stream for particular patterns, if one ; of the patterns are found, the SCB error flag is set. ; ; This, being for CZII.COM, looks for "error" and "failure", setting the ; error flag if found. ; ; The purpose of this RSX is to make "MAKE" work more fully under CP/M plus. ; ; CCP105.ASM with makecolon turned "on" allows the "-i" function in "make" ; to be functional (stopping the make sequence upon a stepwise error) for ; those programs (typically compilers, linkers,assemblers) which set the SCB ; error code upon errors. Since most (of my) programs don't even know about ; that error flag, something needs to be done: this RSX. This RSX is to be ; attached to the appropriate compilers (etc), and the patterns set ; appropriately. The patterns needed are those put out by the compiler (etc) ; when it detects an error. My C-compiler, for instance, puts out ; an "errors" count with compile-time errors, and "failure" with command-line ; errors. Thus, I would look for those two words in the output stream. ; I had used the "BDOSRSX" RSX to determine that my compiler uses bdos call ; 02 (console output) to stream its error message(s). ; ; The particular version of CP/M "Make" being referred to is my port ; of the "Aussie Make" -- which I posted to Usenet's net.micro.cpm . ; ; (C) Copyright 1986 by Michael D. Kersenbrock Aloha, Oregon ; serial: db 0,0,0,0,0,0 start: jmp scan next: jmp $-$ prev: dw 0 remove: db 0ffh ; remove with next load nonbank: db 0 ; both banked and non-banked are OK thename: db 'SCANCZII' ; Scan console output RSX for czii loader: db 0 ; load for banked & non-banked systems db 0,0 ; system use junque scan: ; note: no BDOS call has input in 'a' mov a,c ; get bdos call number cpi 2 ; console output stream? jnz next ; no, so quickly bypass this RSX ; yep, so .... push psw ; save all at entry push h push b push d ; ; The general scheme is to maintain a window into the stream ; equal to the maximum width of the longest search string. When ; a character is sent to the console, it is added to the "window", ; and then that window is compared with all the strings. If ; a match is made (at any time), then the SCB error flag is set. ; The specific error flag set is: ; FF12 == MAKE ERROR ; ; Note that comparisons (etc) are sort of done tail-end first ; (the "current" character that just came in is the "tail-end" ; of something). ; Insert new character into window lxi h,window+winsize-2 ; source pointer to end-1 of window lxi d,window+winsize-1 ; destination pointer to end of window lxi b,winsize-1 ; want to move all but last character db 0edh,0b8h ; Z80 LDDR reverse block move pop d ; get new character push d mov a,e sta window ; insert the new character into window lxi d,str1 ; point to first string call compare ; compare string to window contents cz seterror ; set SCB error if error found lxi d,str2 ; point to second string call compare ; compare strin to window contents cz seterror ; set SCB error if error found exit: pop d ; return all registers back pop b pop h pop psw jmp next ; and let it continue with its business window: db ' ' ; length >= longest of below strings winsize equ 7 ; the above length ; NOTE: the strings should be ; spelt backwards. str1: db 'rorre',0 ; first string to look for str2: db 'eruliaf',0 ; second string to look for ; Compare strings at window and at (DE). Return ; with ZERO FLAG RESET FOR NOMATCH and SET for MATCH. ; Note that the comparison strings terminate with a null. compare: lxi h,window ; *HL -> window, *DE -> compareString cmploop: ldax d ; get fixed-string character ora a ; end of string? rz ; yep, so return with MATCH indicated cmp m ; strings matching? rnz ; nope, so quit now & tell the caller inx h ; point to next char in each string inx d jmp cmploop ; and compare next character seterror: mvi c,6ch ; BDOS function for set-return code lxi d,0ff12h ; load MAKE ERROR CODE jmp next ; go set code, then return to whomever ; called seterror  continue with its business window: db ' ' ; length >= longest of below strings winsize equ 7 ; the above length ; NOTE: the strings should be ; spelt backwards. str1: db 'rorre',0 ; first string to look for str2: db 'eruliaf',0 ; second string to look for ; Compare strings at window and at (DE). Return ; with ZERO FLAG RESET FOR NOMATCH and SET for MATCH. ; Note that the comparison strings terminate with a null. compare: lxi h,window ; *HL -> window, *DE -> compareString cmploop: ldax d ; get fixed-string character ora a ; end of string? rz ; yep, so return with MATCH indicated cmp m ; strings matching? rnz ; nope, so quit now & tell the caller inx h ; point to next chaySCANCZIIy !TU{2OVdq\dq  rorreeruliaf!OȾ#gl  I There is an RSX for each program used by MAKE in its doings. A particular RSX may be used for more than one program if appropriate. This file is a list of which are which with which (eh?). The YYYY.RSX's are attached to the associated XXXX.COM file by: gencom XXXX YYYY ----------------------------- SCANCZII.RSX - Is used with the czii "C" compiler SCANAS.RSX - Is used with "as", the "C" compiler's assembler SCANLN.RSX - Is used with "ln", the "C" compiler's linker lpresl; ; S C A N L N . A S M ; ; This RSX scans the console stream for a particular pattern, if ; this pattern is not found, the SCB error flag is set. ; ; This, being for LN.COM, looks for the pattern "1.07Base:". ; if it is found before/when "Base:" is found, then NO error messages ; were found. This is looking for error messages between the ...1.07 signon ; message, and the statistics line. Obviously, this is depending upon the ; version number of the linker. ; ; The purpose of this RSX is to make "MAKE" work more fully under CP/M plus. ; ; CCP105.ASM with makecolon turned "on" allows the "-i" function in "make" ; to be functional (stopping the make sequence upon a stepwise error) for ; those programs (typically compilers, linkers,assemblers) which set the SCB ; error code upon errors. Since most (of my) programs don't even know about ; that error flag, something needs to be done: this RSX. This RSX is to be ; attached to the appropriate compilers (etc), and the patterns set  ; appropriately. The patterns needed are those put out by the compiler (etc) ; when it detects an error. My C-compiler, for instance, puts out ; an "errors" count with compile-time errors, and "failure" with command-line ; errors. Thus, I would look for those two words in the output stream. ; I had used the "BDOSRSX" RSX to determine that my compiler uses bdos call ; 02 (console output) to stream its error message(s). ; ; The particular version of CP/M "Make" being referred to is my port ; of the "Aussie Make" -- which I posted to Usenet's net.micro.cpm . ; ; (C) Copyright 1986 by Michael D. Kersenbrock Aloha, Oregon ; serial: db 0,0,0,0,0,0 start: jmp scan next: jmp $-$ prev: dw 0 remove: db 0ffh ; remove with next load nonbank: db 0 ; both banked and non-banked are OK thename: db 'SCANLN ' ; Scan console output RSX for ln loader: db 0 ; load for banked & non-banked systems db 0,0 ; system use junque okflag db 0 ; flag == 0 if the str1 string hasn't ; been found yet scan: ; note: no BDOS call has input in 'a' mov a,c ; get bdos call number cpi 2 ; console output stream? jnz next ; no, so quickly bypass this RSX ; yep, so .... push psw ; save all at entry push h push b push d ; ; The general scheme is to maintain a window into the stream ; equal to the maximum width of the longest search string. When ; a character is sent to the console, it is added to the "window", ; and then that window is compared with all the strings. If ; a match is made (at any time), then the SCB error flag is set. ; The specific error flag set is: ; FF12 == MAKE ERROR ; ; Note that comparisons (etc) are sort of done tail-end first ; (the "current" character that just came in is the "tail-end" ; of something). ; Insert new character into window lxi h,window+winsize-2 ; source pointer to end-1 of window lxi d,window+winsize-1 ; destination pointer to end of window lxi b,winsize-1 ; want to  move all but last character db 0edh,0b8h ; Z80 LDDR reverse block move pop d ; get new character push d mov a,e sta window ; insert the new character into window lxi d,str1 ; point to first string call compare ; compare string to window contents jnz scan2 ; go look for error if OK not found mvi a,1 ; get a non-zero sta okflag ; indicate the "goodstring" is found scan2: lda okflag ; already found the "goodstring"? ora a jnz exit ; yep, so skip further comparisons lxi d,str2 ; point to second string call compare ; compare strin to window contents cz seterror ; set SCB error if error found exit: pop d ; return all registers back pop b pop h pop psw jmp next ; and let it continue with its business window: db ' ' ; length >= longest of below strings winsize equ 12 ; the above length ; NOTE: the strings should be ; spelt backwards. str1: db ':esaB',0ah,0dh,0dh,'70.1',0 ; first string to look for  str2: db ':esaB',0 ; second string to look for ; Compare strings at window and at (DE). Return ; with ZERO FLAG RESET FOR NOMATCH and SET for MATCH. ; Note that the comparison strings terminate with a null. compare: lxi h,window ; *HL -> window, *DE -> compareString cmploop: ldax d ; get fixed-string character ora a ; end of string? rz ; yep, so return with MATCH indicated cmp m ; strings matching? rnz ; nope, so quit now & tell the caller inx h ; point to next char in each string inx d jmp cmploop ; and compare next character seterror: mvi c,6ch ; BDOS function for set-return code lxi d,0ff12h ; load MAKE ERROR CODE jmp next ; go set code, then return to whomever ; called seterror iness window: db ' ' ; length >= longest of below strings winsize equ 12 ; the above length ; NOTE: the strings should be ; spelt backwards. str1: db ':esaB',0ah,0dh,0dh,'70.1',0 ; first string to look for SCANLN y !fg {2\h{E>2:Uu{̈  :esaB 70.1:esaB!\Ⱦ#~l @I Hɀ6DIR æ:ROOT OFF BDIR ) )ĝ@ >2/=Y+2/=Y+2-=Y+U G+ G+ $ :+~@w,U ,+>2-=>2.=Y+2.=@ >2.=Y+}+>}+:@/o:11":] !]L!] U-*&< =Directory names are not loaded &=Directory names removed e! L\Ʌo$*  =Too many directory table entries |}.U.6;~#_=~# L# U<>Ʌo$*  =Too manyDIR : y< B !4 t loaded &=Directory names removed e! L\Ʌo$*  =Too many! .z80 ;Utility to load directory names into the DIR RSX for use by the CCP ; ;Copyright (c) 1984 - Jim Lopushinsky ; bdos equ 5 fcb equ 5ch setdir: ld sp,stack ;set up local stack ld de,scbpb ld c,49 call bdos ;return SCB address ld (scbase),hl ;save SCB address ld a,(fcb+1) cp ' ' ;any command line options? jp nz,noroot ;jump if file spec ld hl,rootdir ;point to default name (ROOT.DIR) ld de,fcb+1 ld c,8 call move ;move it into place noroot: ld hl,fcb+1 ld de,off ;point to "OFF" ld c,8 call comp ;does he want to remove dir table? jp nz,notoff ;jump if he doesn't ld hl,(bdos+1) call delrsx ;remove the RSX just loaded ld de,rsx66 ld c,60 call bdos ;see if DIR RSX exists or a jp z,isdir ;jump if ok. call ilprt ;tell him the bad news db 'Directory names are not loaded',13,10,0 rst 0 isdir: call delrsx ;remove dir table call ilprt db 'Directory names removed',13,10,0 rst 0 ;.............. ; ;Here for normal load of directory table ; notoff: ld de,fcb+9 ld a,(de) ld hl,dir ld c,3 cp ' ' ;is file type specified? call z,move ;if not, move DIR into place ld de,fcb ld c,15 call bdos ;open the file inc a jp nz,isfile ;jump if open ok ld hl,(bdos+1) call delrsx ;delete RSX just loaded call ilprt db 'File not found.',13,10,0 rst 0 isfile: ld de,rsx66 ld c,60 call bdos ;see if old DIR RSX exists or a jp nz,nodir ;jump if no old DIR RSX exists ld (diradr),hl ld hl,(bdos+1) call delrsx ;remove RSX just loaded jp onward nodir: ld hl,(bdos+1) ld l,1bh ;point to init flag in RSX ld (hl),0ffh ;set DIR RSX as initialized ld de,rsx66 ld c,60 call bdos ;get table load address ld (diradr),hl onward: ld hl,(diradr) ;get table load address ld l,1bh ;point to init flag ld (hl),0 ;reset it in case of errors ld l,0eh ;point to remove flag ld (hl),0ffh ;set remove flag in case of errors ld l,0ffh inc h ;calculate highest usable table address ld (dirend),hl ld hl,(diradr) ;get directory load address ex de,hl ld hl,rootbuf ;point to file buffer call rootfill ;fill the buffer ld (rootloc),a ;reset offset into buffer jp nz,rootparse ;jump if not at end of file eof: call ilprt db 'Abnormal EOF reading directory file',13,10,0 errxit: ld hl,(bdos+1) call delrsx rst 0 findlf: call rootbyte jp z,done cp 10 jp nz,findlf rootparse: push de ld b,9 rootnmove: call rootbyte jp z,done1 call chkdir ld (de),a inc de cp ';' jp z,rootpass dec b jp nz,rootnmove jp golf rootpass: ld b,9 rootpmove: call rootbyte jp z,eof call chkdir cp ' ' jp z,rootdu ld (de),a inc de dec b jp nz,rootpmove golf: pop de jp findlf rootdu: xor a ld (de),a inc de call chkdir rootblk: call rootbyte jp z,eof cp ' ' jp z,rootblk sub 'A' jp m,golf cp 16 jp nc,golf ld (rootdrv),a ld b,0 rootu: call rootbyte jp z,eof cp ' ' jp z,rootudone sub '0'  jp m,golf cp 10 jp nc,golf push af ld a,b add a,a add a,a add a,b add a,a ld b,a pop af add a,b ld b,a cp 16 jp nc,golf jp rootu rootudone: ld a,b rept 4 add a,a endm ld b,a ld a,(rootdrv) or b ld (de),a inc de pop bc jp findlf done1: pop de done: call chkdir xor a ld (de),a ld hl,(diradr) ld l,1bh ld (hl),0ffh ld l,0eh ld (hl),0 call ilprt db 'Directory table initialized',13,10,0 rst 0 rootbyte: push hl push de push bc ld a,(rootloc) or a jp p,norootf call rootfill jp z,rootnon norootf: inc a ld (rootloc),a dec a call addhla ld a,(hl) and 7fh cp 26 rootnon: pop bc pop de pop hl ret rootfill: push hl push de ex de,hl ld c,26 call bdos ld de,fcb ld c,20 call bdos pop de pop hl or a jp z,goodr xor a ret goodr: inc a ld a,0 ret addhla: add a,l ld l,a ret nc inc h ret chkdir: push af push hl ld hl,(dirend) call cphlde pop hl jp nc,dirok call ilprt db 'Too many directory table entries',13,10,0 jp errxit dirok: pop af ret cphlde: ld a,h cp d ret nz ld a,l cp e ret delrsx: ld de,dir ld l,10h ld c,8 call comp ret nz ld l,0eh ld (hl),0ffh ld de,0 ld c,59 jp bdos ilprt: pop hl ld a,(hl) inc hl push hl or a ret z ld e,a ld c,2 call bdos jp ilprt move: ld a,(hl) ld (de),a inc hl inc de dec c jp nz,move ret comp: ld a,(de) cp (hl) ret nz inc de inc hl dec c jp nz,comp ret dseg stack equ 100h scbpb: db 3ah,0 rootdir: db 'ROOT ' off: db 'OFF ' rsx66: db 66 dir: db 'DIR ' diradr: ds 2 dirend: ds 2 rootbuf: ds 128 rootdrv: ds 1 rootloc: ds 1 scbase: ds 2 end setdir  addhla: add a,l ld l,a ret nc inc h ret chkdir: push af push hl ld hl,(dirend) call cphlde pop hl j"09/12/85 Jim Lopushinsky SUBMOD is a patch to CP/M 3 SUBMIT.COM to allow execution of .SUB files that are in user 0, and do not have the SYS attribute set. This in effect allows execution of submit files in the same manner as CCP+ allows execution of .COM files. Just run SUBMOD.SUB and the patch will install itself into SUBMIT.COM. Note that this patch is effective only if CCP102 is installed as well, because this version of the CCP passes the User number of the .SUB file for Submit to execute. ---- ; ;Patch to allow Submit to execute .SUB files from different ;user numbers. The user number is passed in the SCB from the CCP. ;The SYSINxx.$$$ file is always created in user 0 of the submit drive ; bdos equ 5 getscb equ 3e4h read equ 38fh open equ 35ch start equ 278h org 103h mvi c,3ah call getscb ;get address of System control block mvi l,0e0h ;point to BDOS user number shld useraddr mov a,m ;get current user sta subuser ;save it xra a ;set to zero mov m,a ;set user number to zero mvi l,0a4h ;point to submit user number mov a,m ani 1fh ;strip of high bits jz start ;jump if no sub user dcr a ;adjust sta subuser ;save submit user jmp start testuser: lda subuser ;get submit file user lhld useraddr ;get user number addr in SCB mov m,a ;set the BDOS user # push h call bdos ;do the function pop b push psw ;save return code xra a ;get current user # stax b ;set current BDOS user # pop psw ret useraddr: dw 0 subuser: db 0 org open call testuser org read call testuser end P. ;The SYSINxx.$$$ file is always created in user 0 of the submit drive ; bdos equ 5 getscb equ 3e4h read equ 38fh open equ 35ch start equ 278h org 103h mvi c,3ah call getscb ;get address of System control block mvi l,0e0h ;point to BDOS user number shld useraddr mov a,m ;get current user sta subuser ;save it xra a ;set to zero mov m,a ;set user number to zero mvi l,0a4h ;point to submit user number mov a,m ani 1fh ;strip of high bits jz start ;jump if no sub user dcr a ;adjust sta subuser ;save submit user jmp start testuser: lda subuser ;get submit file user lhld useraddr ;get user number addr in SCB mov m,a ;set the BDOS user # push h call bdos ;do the function pop b push psw ;save return code xra a ;get current user # stax b ;set current BDOS user # pop psw ret useraddr: dw 0 subuser: sid submit.com as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. Disk 1 of 2. CCP105+, a new Command Console Processor for CPM+. Filename Description -03-00 .87 This is the release date of the disk. -CPM163 .DOC This is the description of the disk contents. CCP .COM B553 4K ver. 1.05+ [CCP 1 of 62] A replacement Command Console Processor for CPM+ systems. Includes history trace of BDOS calls, assembling and loading instructions, information on RSX files, ASseMbler and 'C' source code, and much more. Not for novice users! BDOSRSX .ASM EF01 2K ver. 1.05+ [CCP 2 of 62] BDOSRSX .RSX CED0 1K ver. 1.05+ [CCP 3 of 62] CCP .EXT 3D9C 12K ver. 1.05+ [CCP 4 of 62] CCP102 .UPD C927 2K ver. 1.05+ [CCP 5 of 62] CCP102A .NOT 8A55 1K ver. 1.05+ [CCP 6 of 62] CCP103 .NOT 86CA 5K ver. 1.05+ [CCP 7 of 62] CCP104 .NOT 8AC4 2K ver. 1.05+ [CCP 8 of 62] CCP105 .NOT 3C27 5K ver. 1.05+ [CCP 9 of 62] CCP3 .DOC 541C 8K ver. 1.05+ [CCP 10 of 62] CCP3MAKE.SUB E354 2K ver. 1.05+ [CCP 11 of 62] CCP3STRT.ASM 800C 2K ver. 1.05+ [CCP 12 of 62] CCPEXT .C 21F1 1K ver. 1.05+ [CCP 13 of 62] CCPHDR .MAC 1177 6K ver. 1.05+ [CCP 14 of 62] CCPHDR .SUB 77A8 1K ver. 1.05+ [CCP 15 of 62] CMDRUN .COM 4519 3K ver. 1.05+ [CCP 16 of 62] CODE .C 0FEF 1K ver. 1.05+ [CCP 17 of 62] CODE .COM 8DC2 12K ver. 1.05+ [CCP 18 of 62] CODECLR .C 4585 1K ver. 1.05+ [CCP 19 of 62] CODECLR .COM 2A03 7K ver. 1.05+ [CCP 20 of 62] DIRNAME .COM 2AC0 1K ver. 1.05+ [CCP 21 of 62] DIRNAME .MAC 0ECC 1K ver. 1.05+ [CCP 22 of 62] DIRRSX .MAC E968 1K ver. 1.05+ [CCP 23 of 62] EXT .SUB C95A 1K ver. 1.05+ [CCP 24 of 62] FILES .DOC B08C 2K ver. 1.05+ [CCP 25 of 62] GETCCP .C 58AC 2K ver. 1.05+ [CCP 26 of 62] HISTORY .DOC 9123 7K ver. 1.05+ [CCP 27 of 62] LOADER .MAC 8D87 14K ver. 1.05+ [CCP 28 of 62] LRUNHDR .MAC 4A39 3K ver. 1.05+ [CCP 29 of 62] LRUNHDR .SUB 6647 1K ver. 1.05+ [CCP 30 of 62] MAKECCP .SUB 1E7C 1K ver. 1.05+ [CCP 31 of 62] MAKEFILE.DAT 9BA9 1K ver. 1.05+ [CCP 32 of 62] PUTCCP .C F410 2K ver. 1.05+ [CCP 33 of 62] RELHEX .COM 6A56 10K ver. 1.05+ [CCP 34 of 62] ROOT .DIR 5F18 1K ver. 1.05+ [CCP 35 of 62] SCANAS .ASM 03B2 5K ver. 1.05+ [CCP 36 of 62] SCANAS .RSX FB5D 1K ver. 1.05+ [CCP 37 of 62] SCANCZII.ASM 46AD 5K ver. 1.05+ [CCP 38 of 62] SCANCZII.RSX 040F 1K ver. 1.05+ [CCP 39 of 62] SCANLIST.DOC FBA2 1K ver. 1.05+ [CCP 40 of 62] SCANLN .ASM B31D 5K ver. 1.05+ [CCP 41 of 62] SCANLN .RSX 0833 1K ver. 1.05+ [CCP 42 of 62] SETDIR .COM 87B0 2K ver. 1.05+ [CCP 43 of 62] SETDIR .MAC C1BD 5K ver. 1.05+ [CCP 44 of 62] SUBMOD .DOC 555D 1K ver. 1.05+ [CCP 45 of 62] SUBMOD1 .ASM 327F 2K ver. 1.05+ [CCP 46 of 62] SUBMOD1 .SUB E34C 1K ver. 1.05+ [CCP 47 of 62] ASM 46AD 5K ver. 1.05+ [CCP 38 of 62] SCANCZII.RSX 040F 1K ver. 1.05+ [CCP 39 of 62] SCANLIST.DOC FBA2 1K ver. 1.05+ [CCP 40 of 62] SCANLN .ASM B31D 5K ver. 1.05+ [CCP 41 of 62] SCANLN .RSX 0833 1K ver. 1.05+ [CCP 42 of 62] SETDIR .COM$%&'