1y{0!B0}y|zx0y0{003ڀ\X COPYRIGHT (C) 1979, DIGITAL RESEARCH _͌> ͒> Ò> Ò͘~#͌ì _2<گ2 ۇ!2:2a{_:ʖ:>Ľʖ:=2–!B!6#5ʖ:Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!#͘*~ "ܷ"͌#>?͌͘ =_.:;<> O܅o$>!Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6" #~?  xDIR ERA TYPESAVEREN USER$!yO#< Ty#O 3ݯ21y_͸2y2ͽ:ڷ˜1͘A͌>>͌92^ :¥.!_~#fow]߭!v"!çREAD ERRORçNO FILE^: ! ~ 3#0 Wx x ܀ ܂ G ~ # 3x~#B!Y~ɯ2:=!ý:=!:ý^T!~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x  ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ ߯w4!Y~ʆ͌†t=ʆf ^ T ߯2o&)|+!<ͧÆNO SPACE^ :Ty!B*O=?_s#"^sG!~Ypsp2mÆÆf ͧÆFILE EXISTS _: É: :ʉ=2)ͽÉ T!@k!}|q=qf^!~2>`~22\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LOADCOMf^: ! Â$$$ SUB$"C{2!"E9"1A22!ty)K!G_^#V*C~E ,&-AGMS!!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$:BA2!~6 O͐  :E B 2>: b# : y! 4 5~yy5 6yҐ^H@Oy H H: –ͬ  #H: !  Hù H H $O͐: 2 *CN# x: 2 p&x~+é72 H! >w_: ! 5ͤNkͱ¦ͱxʊ#Nx: ! 2 ͤ! 5™#wO~x½p Hy<< ʑ :!qMD#2E>! ^#V w#P:BO|^#V#"##"##"##"!O*!O*|!6ʝ6>*w#w*w#w'û*! J*""!N#F*^#V*~#foyx*{_zW+*yx#*DM*s#r*s#ryOxG*0MD!!N: EG>O: \S*C :qn& ^#V>O^"*}:*)=":O:o"*C *C!ͮ~2~2ͦ:2ͮ:O:w:w |g}o*﯆# ):BO!yoxg*:BO}!N#F "*#*s#r^ ~!J! J*:o$*C~i6iw**{#zr+s{ozg**͕** ,w͜͸Ͳ!!N#F$**O!~#:A#~$=2Ek͌::/GyO>2!q*C"͡ʔ*JҔ^:Oyʃ?|x | s-|N-# S:2E!~Яw>T D^6k-äPYy 5*{zBK5ڋ>*Cw~#+w#w+ɯ2E22i^ *C :~w~͔͔# #  w ~>2!E5T*C!"C"C!w# F! w͌x2͢*C ~<wʃG:!ʎì 4~ʶ¬:<ʶ$ʶïZͻx>2>2ͻ:!Z2:Eẅ́͊Ͳ>2>2T*CGͻ:ẅ́n>2;O ^DM;}H>"*C ::ddslO s#r:E͊:==»y==»*Ww#*"͸*:G#š"͸:!w4 iw:Z!E~=262*C!!~~#~O~G#n,-.‹! w! yG!x͢.:E<ʄ! q!pQ:E<. ʄ$.:E<ʄi6}2ExN! ~态O>G~G!~G} *C!r#r#r ^ͥ_y#x#{s+p+q-*C ͥ!!q#p#w*:BOYG}*MD "ã:!Bw!>2*C~=2u:B2~2wE:A*Cw>"!""2B!"!rQQQâ~?ͦ~?rQ*"CQ-Q͜QüQrQ$Q*):B"*)*)Q;*"E:;:A2AQÓQÜQ*C}/_|/*W}_*"}o|g":ʑ*C6:ʑw:2E**E}DQ>23fö &81>>~!T]6 L:22!vÌ1>,2&f>2>2!"2!"28!"9>2:Oͼ  !:wn&6!y! ~22`i))))!qy2i`"`i#z n&:O@y §J:O@y ¬OQ>2!~w ͞͡>yxzͤo͞ʑ—͡ڑ—͡× `>y{xî>2!~w !w >Ӊxӊ  >ۉۋۈ>2!~w:@$ @ @/L->2:2 ʝ.>.:.*:~X#{=x) `>.ʴ )>.>*:6w#=)>!>>.~X#mWzG>.>6.>6> >.6)>:>22X.>6 m~O#v 62K CP/M VERS 2.2  0@-- -J+-yZ-4 ?      ?     I ABI$"$H$HO!.p+q*-LRRLR\LR" O!/q*/& L!1p+q*0#L~*##N!ͽ͞"T!Vq*VMͳ!Xp+q!W* >Wr#MͲ!_p+q!`6>!`6*`&*^*`&Y />!`4 >*]& ~ O!]49!a6:a*]& ~2bO>z*bM >!b/~,H~:H~*H~.H~>H~<H~=H*]& 6!]4T!]4!cq*a&Y :cw!a4!gr+s+p+q!h6>fr*d*f!is*d́"dPY! "f>!h#~Haͫo!h6:i0O͐!mr+s+p+q*lTZs#r*lڶ*l+s#r*jN#F+q#pÌ!nq!"o"q}2uo&"s* s:n*sDM2u:uqos*s"s*o͊O !v6>!vQ*v&w 6`i+46)A*:'ʓ:'O!) ~2vʍ:vO!w 6,]!v6>!v*v&w ~һ*vM !v4˜8AO͐:͐ͱ*##N!ͽ"* N#F*͠">!H% - *DM ͱͷDM  ͱ* N#F 9ͱ * ^#V))DM Tͱ* ~ *} *M!+s#r#4 !s+p+q!6!66:!ڄ !6!6>!r *&**&Y i !6!4+4A :} :!4- >!699 2¨ :!4: :2!6+6>! :O!9 DMi ͱ:!O!Y DMi :2:2͠!4 F :® )!6>!ګ ͠:O!9 DMi 8ͱ!6> !ڤ Å :2k ä  ͐:!O!Y DMi w !4C F :¿ >F : F :=229:Y= ;>9*&Y DM =2 I>!6:=28 :2:2 :!!29:Y T >:Y,e \>Ì !p+q*~:ʉ *N͐*#"o :͐!p+q!'"!6> **{2*́"PY! ">!+~H !6:0O͐à k͐͠Q" 8AO͐jͱͷDM͏ m  Z"l"!6>ʥ *}҆ *M ͱ*}x O͐} W͐ͱ !+s#r!+s#r#4D ͠:\ʹ :\=Oͳͩ !6!)6l :) :)=2) :] & !"}2\!h6?!j6?\:'C:'ƀo&")!)6!"):)/)HҘ]!)6> !)ڎ*)&*)*)&*) y!)6 Ä:) 2):)<2)M*)#")/:)ҩ*)+")`*")#"]!*)!/H!")!"]*)) *)s#r!)6> !).*)&*)*)&*) w:)<2)*)) >w#6*)) w#6*)!) w#6*)%) w#6*)) N#F*)) q#p*)%) *) ~e *) * ~o&͞ *)%) q#p!)6* >!)6!)6>!)=:)!)w=*)&*)~2):)*)& *):)2):):*)!) *)) s, >X\:)“>!d!")>!)d!")!")*++!)a*)) ^#V")]*)")*)) ^#V")]!)6> !)T*)&*)~2)*)&*)~2)O;*)) ^#V")*)) *)) N#Fq#p*)) *)s#r*)#")!)1y{0!B0}y|zx0y0{00܀\X COPYRIGHT (C) 1979, DIGITAL RESEARCH _͌> ͒> Ò> Ò͘~#͌ì _2<ܯ2 ݇!2:2a{_:ʖ:>Ľʖ:=2–!B!6#5ʖ:Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!#͘*~ "޷"͌#>?͌͘ =_.:;<> Oޅo$>!Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6" #~?  xDIR ERA TYPESAVEREN USER!yO#< Ty#O 3߯21y_͸2y2ͽ:ܷ˜1͘A͌>>͌92^ :¥.!_~#fow]!v"!çREAD ERRORçNO FILE^: ! ~ 3#0 Wx x ހ ނ G ~ # 3x~#B!Y~ɯ2:=!ý:=!:ý^T!~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x  ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ w4!Y~ʆ͌†t=ʆf ^ T 2o&)|+!<ͧÆNO SPACE^ :Ty!B*O=?_s#"^sG!~Ypsp2mÆÆf ͧÆFILE EXISTS _: É: :ʉ=2)ͽÉ T!@k!}|q=qf^!~2>`~22\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LOADCOMf^: ! Â$$$ SUB"C{2!"E9"1A22!ty)K!G_^#V*C~E ,&-AGMS!!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$:BA2!~6 O͐  :E B 2>: b# : y! 4 5~yy5 6yҐ^H@Oy H H: –ͬ  #H: !  Hù H H $O͐: 2 *CN# x: 2 p&x~+é72 H! >w_: ! 5ͤNkͱ¦ͱxʊ#Nx: ! 2 ͤ! 5™#wO~x½p Hy<< ʑ :!qMD#2E>! ^#V w#P:BO|^#V#"##"##"##"!O*!O*|!6ʝ6>*w#w*w#w'û*! J*""!N#F*^#V*~#foyx*{_zW+*yx#*DM*s#r*s#ryOxG*0MD!!N: EG>O: \S*C :qn& ^#V>O^MOVCPM COMNPIP COM: SUBMIT COM XSUB COM ED COM4 ASM COM@DDT COM&LOAD COMSTAT COM)SYSGEN COMDUMP COMDDFORM COMSDFORM COMSYSGEN2 COM PIP201 COM!"#$%&'()FORMAT COM *DUMP ASM!+,-BIOS21I ASM7./0123456789DEBLOCK ASMP:;<=>DDFORM ASM?@DISKDEF LIB1ABCD124997- 002,COPYRIGHT (C) DIGITAL RESEARCH, 1979 1] ʑ?ʑ! __0 r))) O @|r}r.g))å{u INVALID MEMORY SIZE$!$ʡ~/w/wʔ|g*"z|?¸>@G!>0w#w!4~:60+4~u!N#F! x, # =!v"z!w6!u#+w+wz >ZxG}o|g"|! :m c p!"xp ~#c*|!:m ʅ xä SYNCRONIZATION ERROR$ {°~#o}oҼüÅ*zZ# :m m! ~ #* DM! x  w#!N#F! D!_>0w#w1!`4~:60+4*"e@u READY FOR "SYSGEN" OR "SAVE 00 CPM00.COM"$*|  CONSTRUCTING 00k CP/M vers 2.2$>ͦ!q:_  !p+q.*   !q*&!p+q*2!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*1y{0!B0}y|zx0y0{00 \X COPYRIGHT (C) 1979, DIGITAL RESEARCH _͌> ͒> Ò> Ò͘~#͌ì _2<2 !2:2a{_:ʖ:>Ľʖ:=2–!B!6#5ʖ:Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!#͘*~ ""͌#>?͌͘ =_.:;<> Oo$>!Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6" #~?  xDIR ERA TYPESAVEREN USER$!yO#< Ty#O 321y_͸2y2ͽ:˜1͘A͌>>͌92^ :¥.!_~#fow]!v"!çREAD ERRORçNO FILE^: ! ~ 3#0 Wx x   G ~ # 3x~#B!Y~ɯ2:=!ý:=!:ý^T!~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x  ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ w4!Y~ʆ͌†t=ʆf ^ T 2o&)|+!<ͧÆNO SPACE^ :Ty!B*O=?_s#"^sG!~Ypsp2mÆÆf ͧÆFILE EXISTS _: É: :ʉ=2)ͽÉ T!@k!}|q=qf^!~2>`~22\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LOADCOMf^: ! Â$$$ SUB$"C {2!"E 9" 1A 22!ty)K!G_^#V*C   ~E , &-AGMS  !!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$ :B A2 ! ~6  O͐  : E  B 2 >: b # : y! 4 5~yy 5 6y Ґ ^H @Oy H  H : – ͬ   #H : !  H ù  H  H $O͐ : 2 *C N#  x : 2 p & x ~+é 7 2 H ! >w _ : ! 5ͤ N k ͱ ¦ ͱ xʊ #N x : ! 2 ͤ ! 5™ #wO ~x½  p H    y< < ʑ  : !qMD # 2E > ! ^#V w#P :B O|^#V#"##"##"##"!O *!O *|!6ʝ 6>*w#w*w#w'û *! J * ""!N#F*^#V*~#foyx *{_zW+ * yx # *DM*s#r*s#ryOxG*0MD!!N: E G>O: \ S *C  :q n& ^#V> O^ "*}:*)= ":O:o"*C  *C !ͮ ~2~2ͦ :2ͮ : O:w:w |g}o *# ) :B O! yoxg*:B O }!N#F "*#*s#r^  ~!J  ! J *:o$*C ~i 6i w**{#z r+s{ozg**͕ **  , w͜ ͸ Ͳ ! !N#F$**O !~#:A #~$=2E k͌ : :/GyO>2!q*C " ͡  ʔ*J Ҕ^ :Oyʃ?|x | s-|N-# S:2E !~Яw > T   D ^ 6k -äPYy 5*{zBK5ڋ>*C w~#+w#w+ɯ2E 22 i  ^ *C :~w~͔͔# #  w ~>2!E 5T *C !"C  "C !w# F! w͌ x 2͢ *C  ~<wʃG:!ʎì 4~ʶ ¬:<ʶ$ ʶïZͻ   x >2>2ͻ :!Z2:E w ̈́ ͊ Ͳ  >2>2T *C G ͻ : w ̈́ n> 2;O ^ DM;}H> "*C  ::dd slO s#r:E ͊ :==»y==»*Ww# *" ͸ *:G#š" ͸ :!w4 i w: Z!E ~=26 2*C !!~~#~O~G#n,-.‹! w! yG!x͢.:E <ʄ! q!pQ:E <. ʄ$.:E <ʄ i 6}2E x N! ~态O>G~G!~G} *C !r#r#r ^ ͥ_y#x#{s+p+q-*C  ͥ!!q#p#w*:B O Y G }*MD "ã:!B w!>2*C ~=2u:B 2~2wE:A *C w>" !""2B !" !r QQQâ~?ͦ ~?r Q *"C Q- Q͜QüQr Q$Q*):B  " *)*)Q;*"E :;:A  2A QÓQÜQ*C }/_|/*W}_*"}o|g":ʑ*C 6:ʑw:2E* *E }DQ>2I|46;@RWF 00k CP/M vers 2.2 1>>~!T]6 b:22!3û1@4;,R|*":ڲ!4<2”>2!"2!"28!"9:O  !:wn&6!y2! ~2`i))))!qy2i`"`i#z n&Y!~w !w ͷ:>ƒyxzÈӉxӊʈͷʪ°ڪ°ð j>:yۉ:{ۋ:xۈ~O#0o7o7M.UoFmUoF4 ?     @$@B B HH II$@DI ABI$"$H$H@$$I! H*  $H@@A I $D!!$I"BI"I"@$BIIH$$$$BBI$@BI!"$$A DI$@ A$@$$@H! "!$$" @B$!!!DH$$"H @@BHH  !$$A"D@ "A" "BHA " !$ D B I $ !$$ H@BD D$ HI DIA!$$$ $" "$D ! $"  $AB " BDD $$D!"DI$!$BH!"IB I$"D HD" " $"! @H !BI " I  $I$I$DI$ !I$@"$"$! $I$I HHA$   @@ ! !! D  000000000000000000000027 :1009D0000000000000000000000000000000000017 :1009E0000000000000000000000000000000000007 :1009F000000(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE) COPYRIGHT (C) 1979, DIGITAL RESEARCH, PIP VERS 1.5$$$ SUB =.:,<> _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PUNTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE RETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILE$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNIZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'! Ͳ:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: >ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6:͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ 2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 * "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :]:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<:<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2mͯ m!62m!62m!62m!62m'2:2:TҒ:2!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ *M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>!ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O>*M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g:[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ ÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H9Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:!:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020 :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&62*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚ͯ !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H:H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{ozgO{ozgi`N#Fogo&og H ©=¨ copyright(c) 1977, digital research $Error On Line $SUBNo 'SUB' File Present$Disk Write Error$Command Buffer Overflow$Command Too Long$Parameter Error$Invalid Control Character$Directory Full$Cannot Close, Read/Only?$!9"!͇͊!p+q* ͊!p+q*͍2!p+q*͍2!p+q*͊!p+q*͍!p+q*͍!p+q*͍2!s+p+q+p+q:=2ʦ** w*#"*#"!p+q(+*DM*p*& 6:ep\:=ͧ!t6>!t%\= >!t6:t<2t=O! ~2u b:<2O>9b!60+~9b!60+4:uat:u_2u:uMʉSͧ!v6!"v!|6:|Ҁ!x6 2}:} Hk:} h:}$6 2}$*}M3:}02}O> ͧ3!z6ͭ:}"!}5́ͭ́3*yM"h:}^a a2}O>Vͧ^:}>*z& ~ !z4í!{q*v#"v͙dͧ*vv :{w:x<2xO>}|ͧ-!6]:ͧz2~e:~2O! 6*~& 6$>!~_z*~& w!~5Bx:yͧ*v+"vv ~_{ozg001 $$$$ SUBW Extended Submit Vers 2.0Xsub Already Present$Requires CP/M Version 2.0 or later$:y*###ƒ# yk   җ 4!~=ŐW!xʵ ~#èbx {~#o}où.xsubb!np+q*m2_!pp+q*o ]xsub*"-!/"*"+!""1 M*!"́!"* (xsub active)$|*y ʥ*"*7***x*́͋<͛ :%*=26͋!7^#6 #6 #6$ 8*7~O #w# !6:6=2% ͋*-"*$$$ SUBq:(=2(N *$*& w*$#"$*&#"&' !"N*M^7 !)6:!)ھ *N*DM͆ 2*ʭ :*ʗ ͯ *N"P*6:2)÷ *N"N!) $@BA$! A "!$"" COPYRIGHT (C) 1979, DIGITAL RESEARCH DISK OR DIRECTORY FULL$FILE EXISTS, ERASE IT$NEW FILE$** FILE IS READ/ONLY **$"SYSTEM" FILE NOT ACCESSIBLE$BAK$$$BAK$$$-(Y/N)?$NO MEMORY$BREAK "$" AT $1mM"m +!8s~1m!f6 *M  *!M 1m! 6!6! 6: 2Ebͽ!e:d\::eH2 H҆ͽ:e2!:d2e:!2dû :!I¬!: :H2 ҮX:h2iҐ:!ʍ:!:!H:!H,!"! 6#~ F)ͷX:! X):i!h)9 e:!:h2jO>F L>!":i!jHҼ*"+M ~ ʼͲ!f6!h6!"! 6F!f6:h2k!iҠ:i2k:j2h:k!hҶ9 æ:h2j!!6:j2he:! >"Ͳ*"M ~2!O :! *+"!!6e*!M͛ /$^L:!@OL:! 2͑e:b:! L:h<2hb:! b:hO>!hw:! pX:! …!!6  LÊ!!6ûô:!ʛ͑:! ҩ OҸû:!R†!6G>!!!6 :2.t -? >!!6!6s, !6:xB!6OU2!SB!G6:҃!6:G҃*G& ~2!:G<2G_ Qқ=e  b:!-®! 6:!#¿͇;J:!:!!6Lv:!:Jv: *#"͎! 6:!B)! >w!"&*o"(R :!C:eR :!DKeX :!K\ͷX :!Lj^ :!Pš͎҇! 6F×͢җ:Ç :!T¨F :!U¾: 2 :!V͎"$DMͩ/ *oDMͩ : 2 :! (::H%^bF : ͎H :!Ay! 6*""&*o"(R͎an͢na! 6R :!F”͢ґ Ä :!J $:2$͢ :=2:<2!*& ~2!ü*""I*M*o/!:""&! 6R*I""ë :!M:H| ! 6>F ͛e: <2 O! Hqy d F : 2! 6*#s#r :!N ͢ *o/ Ҧ Ͷn! 6!"&R! 6o$ Î Ç :!S0 $͢- :2"+s#r!:* *& ~2!:<2 :!W> v :!X³ Z͎\ Ee ð :7/҃ E!76e ͕ :xƒ - ͷ*&"K(Kڰ *KM N͔*K"KҌ :!Z ͎  ͢ : :!  'v!gq:f *g&!lq:l $ !h4:l 1 !h6*lM :hB     !h55!mq:m :hO>H2ny} !m6 !o6:n!oښ *mM !o4‚ !pq:p ڪ >:p :p H:p H!qq*qM͛  ^W :q@2q*qMW   !sp+q*r !up+q *tDM !wp+q*v !zp+q*y2x!|p+q*{2x!~p+q*}2x!p+q*!p+q*!p+q*!p+q*2x!p+q*!6   >>! q* &!p+q*:7 e !p+q*DM  =? ) !p+q.*DMF -L *9"`!"b!h6!j6!|6.!=\ -x !e:dʥ *eM \R :xʥ @ *dM \, :x \͕ :x - V :e _ :f w : =e !e:d*eM =e : =e =͕ !]6:x>- !"!76!6!6!66*dM  *dM !6:8!*`*;DM \u 2xʻ>!xҨ- *`*;6:82*`"`:<2w!"`9`h*`*;~2*`#"`:*eM !b+!s{!f!6:!b*b*^DM =ͅ N- *b"b:<2)f!"b!q9bڀ*b*^:w*b#"b!q:6ڶZͅ ʱ- !66*6& :w:6<26!J6*b}:J<2Jm=? :x- : ;*dM .=\ -=ͨ ;: *eM =ͨ .M= -C!q:Y*M !q:a/>z!/H!q*MaҎ:_:!q:ҥ*My:!p+q!'"!6>**ͪ{2**ͪ"*! ͪ":!!6:0O  ú!p+q:/(*DMͩ:  : I N* *DM:aO>!Һ x!: ڦ> ʡ* +" >¡! 6: <2 =O! N͒:  O͒: ! 6:h!o$O* ͸ ! 6 !h6!: 2 3* & 6 : <2 =O! N͒*dM  :sGsu n>!6:<2=O! N͒!">!"͎/Ҵ*+">>!": *#"*""*!".+",*$"**o".!",!36:3{.*22*,**"0M ~ H3*0"**+"*+">23:2/k!36,*+s#rx:3x*0"*: “**"&*"+"(á*$#"&**#"(*"#""*$#"$*"+""*$+"$*#"!4qM*"*$: *(y"$DM}|C#~ *#"*&DMyxC 1*+":4?w+"$""ͷR: —*$"("҈!"&Ô""&*""&$mڸ*o"(**$"($"O26͛*"M :6w͢:6 !7q:*7M͒:7o$+͛ͪ*$M ~28Om:8 I͇͢u$oqo͛rP! 6!"&*$"(R͎ҔM͢ҡÔ($ҵ! 6R͇vͶ2!*!Mm$"*"M :!w͢:! e2!:! : /HH/Q:! @!!6 R!!6 :!KR$*& :!w:<2dn!:s+q*$";!>6:>/;oH*;#"(";:92=*=& *(M !::=2>/H:=<2=*(#"(æÀ:>*(+"(R:>!6$:2*o/*!My:<2=O!s Hq**DMͷ! 6: e!"*""?k*&"?*?+M ~2A :hHҏ *&"?(?:A ½8*#" ҽ*?M ~2AO *?"?ҕ!"*"*"^: 2B! 6F:B2 o(>&H6͛9!C6>!Ca R>:C<2C?! 6!"͇͢Ґq"ڊ͛Íq!!6 !!6 !6*!Ma2D*!M͒2!:D/!+w!6e2!͢!Eq!E:!:H:H!Fq*FM8 *FM   Oy2F :FY5>>:!02HO> /!";u*)))*) *H& "PҘ! 6+s#ré! 6"DM!>))덑o|g =±^#V) ^#V|g}o _{ozgi`N#Fogo&og_{_z#W H = LIBX$$$$$$$LIB1*" COPYRIGHT(C) 1978, DIGITAL RESEARCH á 4êü /L9ASMPRNHEX!4w_#~ ʸ A:4~~# ¼ > \ ?ʻ w# !ͼ ? !ͼ !)ͼ !ͼ :5͡ :6:6͡ :7͡ :\ ʻ 24!dͮ 25ͮ 27ͮ 26!8 ( ʃ !Y 1  :7ʞ !z 8  !"2D2X2#! 8 !ͼ z{* ! !"!8 w#  +6# *#"~!ͼ G:6QxJQS*!w#"! 1 !"!Y~~# …¡z!ͼ wʹ* ! w#" ! 8 !" ! zz_O4:  :6y:! G~#x=2> > ! >x6 #='G! ~ p( O*}O>4?:7w:#ĸ*"!͸* }w>ͪg( ʆ1 Y :7ʗ8 z !<ͼ CP/M ASSEMBLER - VER 2.0 NO SOURCE FILE PRESENT NO DIRECTORY SPACE SOURCE FILE NAME ERROR SOURCE FILE READ ERROR OUTPUT FILE WRITE ERROR CANNOT CLOSE FILES END OF ASSEMBLY G:7xʘ!#~ʄl͸Ä**!O {zʊ͸*"!!#^4!$wͯͯWƐ'@'ê>:ͪ!#^Ww*!{͚|͚}͚͚{!$~#͚͚> ͪ> ͪ@2 0 0:x0_<2! wI2 2> 2 >2ɯ22 !~@_6^4#: w~$w: 0 q: A: A͋q: a{_2  2 - !ɯ2I:  ;*:  ͭͷ ͭ͋>9q>9: '!2 >9 7:! 6 >2>2: 2 Qͭ:Ğ! :lj<͖<j<|<: OʊQ>ÖH >2 2 û: B­>ôD> ¸!52 !"!N#~#A07O! ~*!) " :  '<ͭ'<>V$>O$:Ğà\ÞØ`rÍÖ![w#w#b!"!F#v2[G*##~w*##~<*}q!~ڬ6![^![^#fk"͎͘!G#*####*^#Vû!^*"*{zA"*![N![ N#Fr+sq#p/>G=#w#w3#w#w!JSYMBOL TABLE OVERFLOW G*##~w*##~͎*_###s#r^#V`à 4 Wm ()*+,-/ABCDEHLMDBDIDSDWEIIFINORSPACIADCADDADIANAANDANICMACMCCMPCPIDAADADDCRDCXENDEQUHLTINRINXJMPLDALXIMODMOVMVINOPNOTORAORGORIOUTPOPPSWRALRARRETRLCRRCRSTSBBSBISETSHLSHRSTASTCSUBSUIXORXRAXRICALLENDMLDAXLHLDPCHLPUSHSHLDSPHLSTAXXCHGXTHLENDIFMACROTITLE  PF FP! ( 2/?'  v:P@< !  PP27 ( *"  NZZ NCC POPEP M x_BH!œ#¶ ¦{KÈCÈ<:JCR:  !6 s!#  ɯ<:O=_Z!F!V#fjQ̓E!^#Vo&)~#FxGyѯ<àn8!~ڢͅ6~44O! s#r!~ ڿ6ͅ^4!mw!wp!~ͅ!55N! N#fio&)^#fkz'{ͅ>ɯo>g"k!m6ů{_zW5>)D*kOxGd !m?FDM!xGyOڂÃ)sn55)=â|g}o=î--#zg{ozg{ozg{oÓ:: ;,!ɯ22=2l!"]!~H5_!m~0:ą:  *":  :‰:̅ԅ!^#=ʅVq”*qͦ1& O:lµ̅>2ly:_!w~!s!m~ùy !~=w_!m~ ͅͰ>2lyPLnR>UX:l̅2l͓*>E2C!" """ :ʼ:*1 |R|ͦ0FIL: R  R* } *" :¿::¿üX!C^#fk[@ :Œ:=ʌG!ʆF#H vÛc*| EH ͺ,^1 ͦ *""1 EH DH ͺ,1 ͦ :  1:  " > 2 :|: |Ë  |*" ͩ !6="1 :  1}1:n:>BʋSSͦSSxS 1:  1"" ͦ 1 |R >O U!" 1 1!|_!^#fk $8AP`ixH ñññ81Ľ y0îH ñGîG  ñH ñ(Ľ yîH ñîîĽ y0îîH ñG 1: :,; c*| } 8OĽ y0G G t :):,.>C :|: Jü;r :R: ʼʋ!ʼR!ʼʋ>SR{ozg!~4ʧͦ !6 ! **̈́**̈́\iͩ !w#H USE FACTOR !* "z{*"* "I !" :1 R O*UR X* G:xl :  *̩ : l x͖ *#"EH DH 0:~ ! ^4! w͆ Æ *! 6z͖ {͖ 4>R>V>D >P >L >N=COPYRIGHT (C) 1980, DIGITAL RESEARCH DDT VERS 2.2$10 !~=W!xe ~#Xbxʇ {z~#o}o҃i.2_!fp+q*e2_2_!hp+q*g!jp+q*i!lp+q*k!np+q*m2_!pp+q*oÃO$*sy͏ , $  ͌ 9!z6 # L!zw͌j# X:z 0 ͘=N#Fy}80*z{¯#z+++ ¥ z#½# · 9!`͠ y9!rͷ y=!z{w# % w!P͠ y͓}*w#"͌ @.@<!Eͷ~P !ͷ’P͌Q!ͷªP}QxQ!ͷ͓G@Q! ͷ y͓Gþ!ͷ ͓Q!ͷ͓Q͌Q!.ͷ6y#G͙Qà!2ͷQ͓͌Q!>ͷq eg͙Q:zJEËC–EQyQxQRQ** {zҷ*~#" <AOGƐ'@'OxƐ'@'ON# z8O!B N#N ¾SP.* |} !9":q!"28!"9:] !í 1͓ !" >- Ͷ Aګ ҫ _!7^#V~  \p Z z ů2[\͓͢ ҫ ͐ =« f " ͓ ҫ ͐ ʻf " =ʻf "=« ý> 2͐ f "]=f =« *]}o"_  *]"a. ~ #E }"]*a 6 *]}#|#*]E ͐ « f f f {zA|« W}d ͐ f f f DMʡڏ"=ʡͲ=ʡYPͲ1**!O~4#~#F#x~#s#r#w>͐ « f f  . ᯕo>g. 2|2\  !]w# ʫ .&  0 6 #& .K !e K w# ʫ : U 6 #K 6AW w#] !e~H#~E#~X*}|́ "!́ ͐ !ʬ =« f kʫ j \͢F w# ͋ t ʫ : W& _& & O { `i"F & & w# & ͋ « t Y t Y GтWx ͢!o ~Z #N  *. *.  NEXT PC͐ =« f  . ~ Ͷ ʻ .͓ =« f |« }w#Ä >2L͐ ! =« f }ʫ +"MD Å D  !  # ë «   Ͷ ͐ =« f xY |« }ҫ gA>S Ag}S S i |« }!w s#r:[ʔ _!~ʦ ![4ç \͢¦ 2[ 7 >?  e͢!g"c> _͢a_!f~> 5*c~#"c 0 7   > >  ͢| } @ >. *_}o| , 0 ë ^#V#!Y ))))o P q s#r#!V4 !V6# ,® >2Vñ m ͅ m ͅ m ͅ « Vʫ ! XN!~  ! _^! ^#V~ x+ >= = !~  . !   #x f L L ͓ͅ ҆ *" !6ï +"_*~ #E گ ʫ ^#V. ï ~ CZMEIABDHSP!"M"+"!91*~!O~6=G#^#V#~x (#"!N#FW( *J>7Å*M|N+"M N:LHͅÅD Å >* *͓ b" . *"] !/~##ʁtZ*F#n!Is!^#V&&##&))::^#V#*^#V>+)x-8_)*)þ))>+><7"9.Yͯ * M^2U :2:2ͳ:_³ͯ !6! @!!BH @@ABH B! "BHI$$BI$BI $ HI D$HD$$ H B!$D$"$B$DA!ABI$H B$I $HI$H$! $I $I$$A !A@$I$"!$H$I$I "! $A$  HHAA"I @BB $A"$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!I$I$I$UUU$$A$ @ COPYRIGHT (C) 1978, DIGITAL RESEARCH ERROR: $, LOAD ADDRESS $DISK READ$INVERTED LOAD ADDRESS$DISK WRITE$LOAD ADDRESS $ERROR ADDRESS $BYTES READ:$INVALID HEX DIGIT$CHECK SUM ERROR $FIRST ADDRESS $LAST ADDRESS $BYTES READ $RECORDS WRITTEN $HEXCANNOT OPEN SOURCE$COMNO MORE DIRECTORY SPACE$CANNOT CLOSE FILE$*!9"!e !" !" \!""͊: ƒde"\\\͊: ²d\͝: )d;! q* &f  ! q> ! : A O: 0O! q: O: O! p+q* |O* }O! p+q*  f! p+q* DMB! p+q)R* DMB1B* DM+;! p+q* i2 ! p+q* i2 ! p+q* i2 i2 !" p+q*! f!$ p+q*# i!& p+q*% i!( p+q*' i2 !* p+q*) f!/ s+p+q+p+q:/ =2/ X*+ *- w*+ #"+ *- #"- 1* #" ͖r*   ~!" ! ͸×* " x20 º*   DM":0 Ad*   6!" Ç!" : !"6 "8 ": }2< !"4 "= ! 6Y: !2 6=21 á:1 : r+s#r==_HL"4 " >6 ͪS* "6 =23 :1 =21 v=O* #" Y8  ͝҉* +"8 .!2 ʞR̀* "4 4 = ͝* #" çR*6 DM+R*8 DM+R*: DM+R*< M!? q=  ͝Kd*= ! ͸p!@ 6>!@ X*= }O!< *@ & w*= #"= !@ 4)!< 4\mad* }O!< :? wlR*4 DM+{R* DM+R 4 ͝*4 }¿= 4 ͝< N*4 #"4  å;*4 DM+: Y2A 0O> :A 0:A AO>&R̀:A A H.2B !2 w:B !D s+q*C &͍:D _og_{ozg^#V) _{ozgi`N#Fogo&og_{_z#W3 Copyright (c) 1979, Digital Research????????????CON:RDR:PUN:LST:DEV:VAL:USR:DSK:TTY:CRT:BAT:UC1:TTY:PTR:UR1:UR2:TTY:PTP:UP1:UP2:TTY:CRT:LPT:UL1:R/OR/WSYSDIRR/O R/W SYS DIR ** Aborted **Active User :Active Files: Drive Characteristics65536: 128 Byte Record CapacityKilobyte Drive Capacity32 Byte Directory EntriesChecked Directory EntriesRecords/ ExtentRecords/ BlockSectors/ TrackReserved Tracks is Temp R/O Disk: d:=R/OSet Indicator: d:filename.typ $R/O $R/W $SYS $DIRDisk Status : DSK: d:DSK:User Status : USR:Iobyte Assign: =Bad DelimiterInvalid AssignmentBad Delimiter: Bytes Remaining On R/, Space: Invalid File Indicator** Too Many Files **File Not Found Size Recs Bytes Ext Acc65536 set to R/O Invalid Disk AssignmentWrong CP/M Version (Requires 2.0)!9"2!T OË!]6:\:] Hr3 Ë:\ʀË͇ /ҋͺ *2!"q*"&L ͐ ͐ ͐!$p+q*#~*#N͐*##"#÷!&p+q͠*%DMͱ O O!(q*(&L!*p+q*)O2'!,p+q*+O2'O2'O!.p+q*-LRRLR\LR" O!/q*/& L!1p+q*0#L~*##N!ͽ͞"T!Vq*VMͳ!Xp+q!W* >Wr#MͲ!_p+q!`6>!`6*`&*^*`&Y />!`4 >*]& ~ O!]49!a6:a*]& ~2bO>z*bM >!b/~,H~:H~*H~.H~>H~<H~=H*]& 6!]4T!]4!cq*a&Y :cw!a4!gr+s+p+q!h6>fr*d*f!is*d́"dPY! "f>!h#~Haͫo!h6:i0O͐!mr+s+p+q*lTZs#r*lڶ*l+s#r*jN#F+q#pÌ!nq!"o"q}2uo&"s* s:n*sDM2u:uqos*s"s*o͊O !v6>!vQ*v&w 6`i+46)A*:'ʓ:'O!) ~2vʍ:vO!w 6,]!v6>!v*v&w ~һ*vM !v4˜8AO͐:͐ͱ*##N!ͽ"* N#F*͠">!H% - *DM ͱͷDM  ͱ* N#F 9ͱ * ^#V))DM Tͱ* ~ *} *M!+s#r#4 !s+p+q!6!66:!ڄ !6!6>!r *&**&Y i !6!4+4A :} :!4- >!699 2¨ :!4: :2!6+6>! :O!9 DMi ͱ:!O!Y DMi :2:2͠!4 F :® )!6>!ګ ͠:O!9 DMi 8ͱ!6> !ڤ Å :2k ä  ͐:!O!Y DMi w !4C F :¿ >F : F :=229:Y= ;>9*&Y DM =2 I>!6:=28 :2:2 :!!29:Y T >:Y,e \>Ì !p+q*~:ʉ *N͐*#"o :͐!p+q!'"!6> **{2*́"PY! ">!+~H !6:0O͐à k͐͠Q" 8AO͐jͱͷDM͏ m  Z"l"!6>ʥ *}҆ *M ͱ*}x O͐} W͐ͱ !+s#r!+s#r#4D ͠:\ʹ :\=Oͳͩ !6!)6l :) :)=2) :] & !"}2\!h6?!j6?\:'C:'ƀo&")!)6!"):)/)HҘ]!)6> !)ڎ*)&*)*)&*) y!)6 Ä:) 2):)<2)M*)#")/:)ҩ*)+")`*")#"]!*)!/H!")!"]*)) *)s#r!)6> !).*)&*)*)&*) w:)<2)*)) >w#6*)) w#6*)!) w#6*)%) w#6*)) N#F*)) q#p*)%) *) ~e *) * ~o&͞ *)%) q#p!)6* >!)6!)6>!)=:)!)w=*)&*)~2):)*)& *):)2):):*)!) *)) s, >X\:)“>!d!")>!)d!")!")*++!)a*)) ^#V")]*)")*)) ^#V")]!)6> !)T*)&*)~2)*)&*)~2)O;*)) ^#V")*)) *)) N#Fq#p*)) *)s#r*)#")!)6 J:)!)J!)6 :)<2)*)")҈q:tw͠ͱ!"))ҍ*)) ^#V")]͠.*)DM\ -°!\6:\ͣ:ͱ*}DM'ͫ*)%) N#F'ͫ*)!) N#F'k͐ͫ*)) N#FͫR͐/͐ *) ~IO͐NW͐ͫ8AO͐:͐ *) ~2)t(͐:)҃)͐*)#")Ã& \!"))\Ұ*)")]͠*)M! ^#V *) >*) w *) >*) w *) >*) w *) >*) w.*)DM\ -+!\6uͱ:)O! DMͱ*)#")Ù*))))))"):m w>.Yn -:YS:Z Hҧ!6> 2)½>!)6> !)*)&*)>2) :) .͐*)M͐:)<2)99:Y=/9&ͩ c,Hͩ 9 EHͺ i`N#Fog_og_ogDM!>))덑o|gҘ =†DM!>))ҭ =¥~ ³^#V) ½^#V|g}o _{ozgi`N#Fogo&og_{_z#WxCOPYRIGHT (C) 1978, DIGITAL RESEARCH  o&)))))))a{__> ̓> ̓͊~̓#ÚO****!*$*'! ">2!4:(wNͯ>2:)!4f!^!*FNͷyj*DMͿ2: K!͚u c͊<2:\_/:)j*"1!u͚:] \<œ!x͕c2|\ ¢! DMͿ\õ!͕c!͕u AnA2Aͦ͊!͚u c͊2!?͚!͕u cA7nA2Aͦ!͕u c͊!6!?͚>ͦ͊!Q͕SYSGEN VER 2.0SOURCE DRIVE NAME (OR RETURN TO SKIP)SOURCE ON , THEN TYPE RETURNDESTINATION DRIVE NAME (OR RETURN TO REBOOT)DESTINATION ON , THEN TYPE RETURNPERMANENT ERROR, TYPE RETURN TO IGNOREFUNCTION COMPLETEINVALID DRIVE NAME (USE A, B, C, OR D)NO SOURCE FILE ON DISKSOURCE FILE INCOMPLETE!9"1W͜Q>2!͢QG}DrYQ|͏}͏#> ex͏#r* _> e> e ҉0Ë7e}} :³ʳ7_<2!~ɯ2|\\FILE DUMP VERSION 1.4$ NO INPUT FILE PRESENT ON DISK$!Y , <    *$A!6 # T!w $r# *`: 0 *A*! ~ ʰxkb))))_y‘BK{ͅ*!66!"80*{#z+++ #( COPYRIGHT (C) 1979 DIGITAL RESEARCH 1w[8[a 1v!6v4vv!p6Jmv4k1{yzzx|y{@4 !" # $ % & '()*+,-./01234@4 %. &/ '0 (1 )2!*3"+4#, $-@4t()*+, -!."/ #0 $1 %2 &3 '4 Double Density Diskette Formatter Version 2.1 Skew-6/4 (CTL-C to Abort)$ DISK TO FORMAT IN B, TYPE RETURN$ ( COPYRIGHT (C) 1978 DIGITAL RESEARCH 1q 1!l6M>iӉ>ӊۈS!l4ۉۋK1p FORMATTER VERSION 1.4 (CTL-C TO STOP)$ DISK TO FORMAT IN SINGLE DENSITY DR 0 (C:), TYPE RETURN$ >!9*+++>!I#N#F s#r =aͰ cͶ.2Ͱ>22ͰͰ ʫͶc2Ͱ>2>2! " >22Ͱc AZA _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PUNTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE RETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILE$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNIZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'! Ͳ:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: >ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6:͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ 2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 * "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :]:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<:<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2mͯ m!62m!62m!62m!62m'2:2:TҒ:2!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ *M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>!ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O>*M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g:[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ ÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H9Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:!:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020 :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&62*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚ͯ !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H:H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{ozgO{ozgi`N#Fogo&og H ©=¨5~wN#Fq#p>BØ%!0" * F#%2NG*V0##~w*V0##~<͉:.t!.N!. yq~t +aG=#w#wY*M0!0n& {ozg"V0!K0{#z"M0b*M0!0N#yʢ ~Õb!."O1:N *M0!$/{#z"V0$ _!.*V0~#~1 ~#"M0û1 !͒%Þ%SYMBOL TABLE OVERFLOW G*V0##~w*V0##~=*V0_###1 s#r1 ^#V1 ##"X0P wP ~O!0~z 6~=ͼ !0N#~ͼ „ Ͳ O2Ny *\ ?=)$=)w#Ž&!\60 ڱ&>GO#w ³&>O # &6 &6L#6I#6B#w2|r&\u'>2]0!"%![0~2%wG&!,x&>82%2%!"b0*"M0!1"%"&"@&#"K0"T0' _#~6' D':%A6'>:6'D'>.6'D'>-6'x&!,N'!k-x&!,N':% '> ':%'_!% '6 4ɯ2%2]02e02d02g02%:\ =)!%w#w#w#w#w#w#>2^02_0:m$(!~#$,(~(# 3(%Aʩ(Pʩ(Sʩ(Hʩ(Lʩ(*t(+t(-¶(^0~Sʣ(Mʣ(e0Lʣ(d0Qʣ(g0Rʣ(%1¶(x#3(~AҶ(#3(#6 !)-x&!x&!%͉&!%͉&ͳ'(`&͛'͠':%)!&͉&l&͛'͠'!%60#60#60#>2f0!"&:O0*!"%2%2%2%Z&%u'!-x&z{:]0ʢ)*%F)w)!"%r&\‰)*%#"%+~):.2]0ʢ)r&\!~-N'*%F))Z&!"%*%B&%)¼))*)6# )G&*%*%#"%~!<-x&G:%7*$*x*7*x2*Ϳ'5*9**&*&w#"&!F)`&!"&*&%~ʅ*B&Œ*`*G&`*!S-x&ö,͟**>&*@&w#">&!F)l&!">&*@&&`*_!%~ *2%*b0}!,~ +*#+> *>#**> **b0~>+*#2+> *> *> *}2%!%*O*:/ :O0:%y*:%!O0•+:e0!]0+~,:/ ,!/~ +:f0,:/++:_0,+:/#,:/ ,:_0=+!/~ +!0s!%~!%*4:0!/,G~Y+#x=+> Y+> Y+20!/>x6 #=,G!/~ pͳ'*&}?,>*/,`&%͈':^0*+,!&6S#6Y#6M#w!&w:%2%!"&ͳ'*2%`&%͛'͠'+,:%ʶ,:%.*P0"%.*>&}ʶ,>͕*æ,+,:%,l&&͈'!-x&CP/M MACRO ASSEM 2.0 NO SOURCE FILE PRESENT NO DIRECTORY SPACE SOURCE FILE NAME ERROR INVALID PARAMETER: SOURCE FILE READ ERROR OUTPUT FILE WRITE ERROR CANNOT CLOSE FILES UNBALANCED MACRO LIB END OF ASSEMBLY G:%x-!%~--.-*P0*%O {-z-.*P0"%!%^4!%w..WƐ'@'Õ*>:͕*!%^Ww*%{-|-}--{?.!%~#-6.-> ͕*> ͕*͞*> ͞*;.L>(>;;H;;;;5;<=r=<<SETDMA INTERCEPT CODE LHLD IRDJ+ ; GET ORIG. READ VECTOR PUSH H ; HOLD IT LXI H,IREAD ; G INTERCEPT READ VECTOR SHLD IRDJ+1 0005H USE FACTOR ENDDATATA ORIG. WRITE VECTOR PUSH H ; HOLD IT LXI H,IWRITE X>C;<1TECSHLD IWRJ+1 ; SAVE IT IN COPIED JUMP TABLE POP H ; ORIG. WRITE VECTOR SHLD IWR1+1 ; PATCH IT INTO WRITE INTERz*;&***z*8z*z*9&*-&&, DW 63 ; DIRECTORY SIZE - 1 DB 0C0H ; TWO CLUSTERS RESERVED FOR DIRECTORY DB 0 ; ALLOC 2 DW 16 ; 16 SECTOR DIRECTORY DW 2 ; TWO SYSTEM TRACKS SKEW6: DB 1, 7, 13, 19, 25 DB 5, 11, 17, 23 DB 3, 9, 15, 21 DB 2, 8, 14, 20, 26 DB 6, 12, 18, 24 DB 4, 10, 16, 22 ; BEGIN$DATA EQU $ DIRBUF DS 128 ; SYSTEM DIRECTORY BUFFER ALV0 DS 31 CSV0 DS 16 ALV1 DS 31 CSV1 DS 16 ALV2 DS 31 CSV2 DS 16 ALV3 DS 31 CSV3 DS 16 END$DATA EQU $ DB 0 ; FORCE OUT LAST ADDRESS FOR RELOCATION END 1,26,6,1024,243,64,64,2,0 ; DISKDEF 1,0 ; DISKDEF 2,0 ; DISKDEF 3,0 ; ENDEF DPBASE: DW SKEW6,0 DW 0,0 DW DIRBUF, SINGGLE$TAB DW CSV2, ALV2 DW SKEW6, 0 DW 0,0 DW DIRBUF, SINGLE$TAB DW CSV3, ALV3 SINGLE$TAB: DW 26 ; SECTORS PER TRACK DB 3 ; 2**3 (=8) SECTORS PER CLUSTER DB 7 ; 2**3-1 (BLICK MASK) DB 0 ; EXTENT MASK DW 242 ; NUMBER OF LAST CLUSTER INGLETAB 423D SKEW6 4141 SWAP 4149 SWP1 41B3 TRYCOUNT 418B WAIT0 416B WAITIO 41B3 WERROR 41AD WREADY 0006 WRITF 41E2 XFLAG 4155 XREAD 412A XSECTRN 4102 XSELDSK 415A XWRITE 40BE ZZZZZZ 00000000000000057422E42834364431A00FE :10423000030700F2003F00C0001000020001070D5C :104240001319050B111703090F1502080E141A068E :074250000C1218040A1016FD :014393000029 :0000000000 D>=RETRY NUMDISKSz;BASE;DSTATRTYPER;RBYTE=ILOW?;IHIGHf;READFWRITF;RECAL<IORDY>BEGIN@=CCPVEC@DUMMY6@PIPJMP@ ;NEWJMP@|<ISDJ@<ISTJ!@"<ISSJ$@7<ISMJ'@U<IRDJ*@IWRJ-@s<ISXJ3@MOVERK@EXIT5A@<ISELDSK@;ISD1@L<ISETTRK@;IST1@<ISETSEC@;ISS1@+<ISETDMA@;ISM1@ <IREAD@;IRD1@;IWRITE@h<IWR1@<ISECTRN@;ISX1@=SWAPAAZZZZZZ@<XFLAGA<XSELDSKA_<IOTA<IOSAh=IODA<XREADUAXWRITEZA<XSECTRN*A=DBANKA'=SELTABLEA=IOFA!;DPBASEASWP1IA >SETFUNC\A=WAITIOkA+;REWAITmA<INTYPEA=INBYTEAp;IOPBA =IODR1A3=WAIT0A=INSTATA\;WREADYA=WERRORATRYCOUNTAI=INTYP1AT=INBYT1A|=INSTA1A_=IONA<SKEW6=B=DIRBUFWB=CSV0B=CSV1%C>CSV2TCCSV3C=SINGLETAB.BBEGINDATAWB1>ALV0B:>ALV1CC>ALV25CALV3dC;ENDDATACVI C,READF ;SET TO READ FUNCTION JMP SETFUNC ; XWRITE: ;DISK WRITE FUNCTION MVI C,WRITF ; SETFUNC: ; SET FUNCTION FOR NEXT I/O (COMMAND IN REG-C) LXI H,IOF ;IO FUNCTION ADDRESS MOV A,M ;GET IT TO ACCUMULATOR FOR MASKING ANI 1111$1000B ;REMOVE PREVIOUS COMMAND ORA C ;SET TO NEW COMMAND MOV M,A ;REPLACED IN IOPB ; SINGLE DENSITY DRIVE 1 REQUIRES BIT 5 ON IN SECTOR # ; MASK THE BIT FROM THE CURRENT I/O 6@6@6@6@6@6@6@6@6@6@6@6@6@6@6@6@6@*"@!@"*!@0w# K@!5A"@*@!@"@"@*"@!@""@"@*%@!@"%@"@*(@!@"(@"@*+@!@"+@"@*.@!@".@"@*4@!@"4@"AAA@2AyA6@y2A6@y2A6@i`"A6@:AUA6@:AZA6@:A*A6@>2A!y2A!A ~2A`i))))A`i#z n`AA*@"*@0Fwx# IA\A!A~w !Aw ͺAA:A>A†AӉxӊËAәxӚAʋAͺAʭA³AAڭA³AAóA mA>:AAۉۙ:AAۋۛ:AAۈۘ00=BWB.BBB=BWB.B%CC=BWB.BTC5C=BWB.BCdC?      ADDRESS JMP WAIT0 ;TO WAIT FOR COMPLETE IODR1: ;DRIVE BANK 1 OUT ILOW+10H ;88 FOR DRIVE BANK 10 MOV A,B OUT IHIGH+10H WAIT0: CALL INSTAT ;WAIT FOR COMPLETION ANI IORDY ;READY? JZ WAIT0 ; CHECK IO COMPLETION OK CALL INTYPE ;MUST BE IO COMPLETE (00) UNLINKED ; 00 UNLINKED I/O COMPLETE, 01 LINKED I/O COMPLETE (NOT USED) ; 10 DISK STATUS CHANGED 11 (NOT USED) CPI 10B ;READY STATUS CHANGE? JZ WREADY ; MUST BE 00 IN THE ACCUMULATOR ORA A JNZ WERROR ;SOME OTHER CONDITION, RETRY ; CHECK I/O ERROR BITS CALL INBYTE RAL JC WREADY ;UNIT NOT READY RAR ANI 11111100B ;MASK OUT CRC ERRORS AND DELETED DATA OK JNZ WERROR  !9*+++>!#N#F s#r =K2VA4Z4AO|4#~&f&|202q ƒ:Ò0o:o02 ^#V~2#~3:ʀ4ʺ3~*!E5" ʺWʺ:W:_z2:VA!j2j:,?>@2i!"n/<xHy{:>2liyyxzxVy{:l<2lMM5,N3Y€:ʤ?>@2i/<>2lͶ:i@>:!~#!i>>~#͕:l<2lMºͻ5ä{44!>w#F:G:_!~l:<2P:w<2#:w:W:_:ʍڍ2Pͩ>>> >͜ 0: AG0_!p~>!$'* FUNCTION COMPLETE $ GENERAL PURPOSE DISKETTE FORMATER $ SPECIFY SKEW (0-9) OR RETURN TO TAKE DEFAULT OF $ CAN NOT SUPPORT THIS DEVICE AT THIS TIME $ IS THIS THE INTEGRATED SINGLE DENSITY DISKETTE? $ SPECIFY DRIVE ADDRESS (A,B,C ETC.) $ INSERT DISK TO BE FORMATTED IN DRIVE U. RETURN WHEN READY. CTL-C TO END $ I/O ERROR. RETURN TO RESTART. CTL-C TO ABORT $ SPECIFY HEX BYTE TO BE WRITTEN ONTO DISK. RETURN TO TAKE DEFAULT OF E $ DO NOT FORMAT DISKS WITH 1.4 ADDRESSES!! 2.2 ADDRESSES MUST BE USED. THE DATA ON THE DISK WILL BE THE SAME.$ ; FILE DUMP PROGRAM, READS AN INPUT FILE AND PRINTS IN HEX ; ; COPYRIGHT (C) 1975, 1976, 1977, 1978 ; DIGITAL RESEARCH ; BOX 579, PACIFIC GROVE ; CALIFORNIA, 93950 ; ORG 100H BDOS EQU 0005H ;DOS ENTRY POINT CONS EQU 1 ;READ CONSOLE TYPEF EQU 2 ;TYPE FUNCTION PRINTF EQU 9 ;BUFFER PRINT ENTRY BRKF EQU 11 ;BREAK KEY FUNCTION (TRUE IF CHAR READY) OPENF EQU 15 ;FILE OPEN READF EQU 20 ;READ FUNCTION ; FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS BUFF EQU 80H ;INPUT DISK BUFFER ADDRESS ; ; NON GRAPHIC CHARACTERS CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED ; ; FILE CONTROL BLOCK DEFINITIONS FCBDN EQU FCB+0 ;DISK NAME FCBFN EQU FCB+1 ;FILE NAME FCBFT EQU FCB+9 ;DISK FILE TYPE (3 CHARACTERS) FCBRL EQU FCB+12 ;FILE'S CURRENT REEL NUMBER FCBRC EQU FCB+15 ;FILE'S RECORD COUNT (0 TO 128) FCBCR EQU FCB+32 ;CURRENT (NEXT) RECORD NUMBER (0 TO 127) FCBLN EQU FCB+33 ;FCB LENGTH ; ; SET UP STACK LXI H,0 DAD SP ; ENTRY STACK POINTER IN HL FROM THE CCP SHLD OLDSP ; SET SP TO LOCAL STACK AREA (RESTORED AT FINIS) LXI SP,STKTOP ; READ AND PRINT SUCCESSIVE BUFFERS CALL SETUP ;SET UP INPUT FILE CPI 255 ;255 IF FILE NOT PRESENT JNZ OPENOK ;SKIP IF OPEN IS OK ; ; FILE NOT THERE, GIVE ERROR MESSAGE AND RETURN LXI D,OPNMSG CALL ERR JMP FINIS ;TO RETURN ; OPENOK: ;OPEN OPERATION OK, SET BUFFER INDEX TO END MVI A,80H STA IBP ;SET BUFFER POINTER TO 80H ; HL CONTAINS NEXT ADDRESS TO PRINT LXI H,0 ;START WITH 0000 ; GLOOP: PUSH H ;SAVE LINE POSITION CALL GNB POP H ;RECALL LINE POSITION JC FINIS ;CARRY SET BY GNB IF END FILE MOV B,A ; PRINT HEX VALUES ; CHECK FOR LINE FOLD MOV A,L ANI 0FH ;CHECK LOW 4 BITS JNZ NONUM ; PRINT LINE NUMBER CALL CRLF ; ; CHECK FOR BREAK KEY CALL BREAK ; ACCUM LSB = 1 IF CHARACTER READY RRC ;INTO CARRY JC FINIS ;DON'T PRINT ANY MORE ; MOV A,H CALL PHEX MOV A,L CALL PHEX NONUM: INX H ;TO NEXT LINE NUMBER MVI A,' ' CALL PCHAR MOV A,B CALL PHEX JMP GLOOP ; FINIS: ; END OF DUMP, RETURN TO CCP ; (NOTE THAT A JMP TO 0000H REBOOTS) CALL CRLF LHLD OLDSP SPHL ; STACK POINTER CONTAINS CCP'S STACK LOCATION RET ;TO THE CCP ; ; ; SUBROUTINES ; BREAK: ;CHECK BREAK KEY (ACTUALLY ANY KEY WILL DO) PUSH H! PUSH D! PUSH B; ENVIRONMENT SAVED MVI C,BRKF CALL BDOS POP B! POP D! POP H; ENVIRONMENT RESTORED RET ; PCHAR: ;PRINT A CHARACTER PUSH H! PUSH D! PUSH B; SAVED MVI C,TYPEF MOV E,A CALL BDOS POP B! POP D! POP H; RESTORED RET ; CRLF: MVI A,CR CALL PCHAR MVI A,LF CALL PCHAR RET ; ; PNIB: ;PRINT NIBBLE IN REG A ANI 0FH ;LOW 4 BITS CPI 10 JNC P10 ; LESS THAN OR EQUAL TO 9 ADI '0' JMP PRN ; ; GREATER OR EQUAL TO 10 P10: ADI 'A' - 10 PRN: CALL PCHAR RET ; PHEX: ;PRINT HEX CHAR IN REG A PUSH PSW RRC RRC RRC RRC CALL PNIB ;PRINT NIBBLE POP PSW CALL PNIB RET ; ERR: ;PRINT ERROR MESSAGE ; D,E ADDRESSES MESSAGE ENDING WITH "$" MVI C,PRINTF ;PRINT BUFFER FUNCTION CALL BDOS RET ; ; GNB: ;GET NEXT BYTE LDA IBP CPI 80H JNZ G0 ; READ ANOTHER BUFFER ; ; CALL DISKR ORA A ;ZERO VALUE IF READ OK JZ G0 ;FOR ANOTHER BYTE ; END OF DATA, RETURN WITH CARRY SET FOR EOF STC RET ; G0: ;READ THE BYTE AT BUFF+REG A MOV E,A ;LS BYTE OF BUFFER INDEX MVI D,0 ;DOUBLE PRECISION INDEX TO DE INR A ;INDEX=INDEX+1 STA IBP ;BACK TO MEMORY ; POINTER IS INCREMENTED ; SAVE THE CURRENT FILE ADDRESS LXI H,BUFF DAD D ; ABSOLUTE CHARACTER ADDRESS IS IN HL MOV A,M ; BYTE IS IN THE ACCUMULATOR ORA A ;RESET CARRY BIT RET ; SETUP: ;SET UP FILE ; OPEN THE FILE FOR INPUT XRA A ;ZERO TO ACCUM STA FCBCR ;CLEAR CURRENT RECORD ; LXI D,FCB MVI C,OPENF CALL BDOS ; 255 IN ACCUM IF OPEN ERROR RET ; DISKR: ;READ DISK FILE RECORD PUSH H! PUSH D! PUSH B LXI D,FCB MVI C,READF CALL BDOS POP B! POP D! POP H RET ; ; FIXED MESSAGE AREA SIGNON: DB 'FILE DUMP VERSION 1.4$' OPNMSG: DB CR,LF,'NO INPUT FILE PRESENT ON DISK$' ; VARIABLE AREA IBP: DS 2 ;INPUT BUFFER POINTER OLDSP: DS 2 ;ENTRY SP VALUE FROM CCP ; ; STACK AREA DS 64 ;RESERVE 32 LEVEL STACK STKTOP: ; END ;****************************************************************************** ;****************************************************************************** ; BIOS21I VERSION 820505/1200|RACIII/JCM ;------------------------------------------------------------------------------ ; SUPPORTING ; DRIVE NAME DENSITY CONTROLLER BASE ADDRESS ; ---------- ------- ---------- ------------ ; A:, B: DOUBLE 202 78H ; C:, D: SINGLE 201 88H ; E: SINGLE IOC C0H ;------------------------------------------------------------------------------ ; COPYRIGHT (C) 1978, 1979 | COPYRIGHT (C) 1982 ; DIGITAL RESEARCH | INTEL CORP. ; BOX 579, PACIFIC GROVE | 3065 BOWERS AVENUE ; CALIFORNIA, 93950 | SANTA CLARA, CALIFORNIA 95051 ;****************************************************************************** ;****************************************************************************** ;******************** EQUATES ************************************************* MACLIB DISKDEF VERS EQU 22 ; CP/M VERSION 2.2 FALSE EQU 0 TRUE EQU NOT FALSE RELOC EQU FALSE IF NOT RELOC MSIZE EQU 62 ; MEMORY SIZE IN KILOBYTES RAM$TOP EQU MSIZE*1024 ; TOP ADDRESS+1 BIOS EQU RAM$TOP-800H ; BASIC INPUT/OUTPUT SYSTEM BDOS EQU BIOS-0E00H ; BASE OF THE BDOS CCP EQU BDOS-0800H ; THE CONSOLE COMMAND PROCESSOR ORG BIOS ENDIF IF RELOC ORG 0 ; OR 0100H FOR REL-1 CCP EQU $ BDOS EQU CCP+0800H BIOS EQU BDOS+0E00H MSIZE EQU 0 ; DUMMY FOR SIGN-ON MESSAGE ORG 0800H+0E00H ; PLUS ANOTHER 0100H FOR REL-1 ENDIF CPML EQU BIOS-CCP NSECTS EQU CPML/128 ; NUMBER OF SECTORS TO LOAD CDISK EQU 0004H ; ADDRESS OF LAST LOGGED DISK ON WARM START BUFF EQU 0080H ; DEFAULT BUFFER ADDRESS IOBYTE EQU 0003H ; ADDRESS OF IO BYTE FOR MONITOR IOBYTI EQU 0081H ; Initial value for IOBYTE INT$CONT$1 EQU 0FDH ; INTERRUPT PRIORITY RESTORE PORT INT$CONT$0 EQU 0FCH ; INTERRUPT MASK PORT MON$INT EQU 0F3H ; INTERRUPT CONTROL PORT INT$MASK EQU 0111$1110B ; ENABLE RST 0(WBOOT), RST 7 (MONITOR) ; MDS MONITOR EQUATES MON80 EQU 0F800H RMON80 EQU 0FF0FH ; RESTART MON80 (BOOT ERROR) CI EQU 0F803H CO EQU 0F809H CSTS EQU 0F812H RI EQU 0F806H PO EQU 0F80CH LO EQU 0F80FH CR EQU 0DH ; CARRIAGE RETURN LF EQU 0AH ; LINE FEED ;*************** DISK EQUATES ************************************************* RETRY EQU 10 ; MAX RETRIES ON DISK I/O BEFORE ERROR NUM$DISKS EQU 5 ; NUMBER OF DRIVES AVAILABLE ;*************** 202 CONTROLLER EQUATES *************************************** BASE2 EQU 78H ; BASE OF DISK COMMAND IO PORTS DSTAT2 EQU BASE2 ; DISK STATUS (INPUT) RTYPE2 EQU BASE2+1 ; RESULT TYPE (INPUT) RBYTE2 EQU BASE2+3 ; RESULT BYTE (INPUT) ILOW2 EQU BASE2+1 ; IOPB LOW ADDRESS (OUTPUT) IHIGH2 EQU BASE2+2 ; IOPB HIGH ADDRESS (OUTPUT) READF EQU 4H ; READ FUNCTION WRITF EQU 6H ; WRITE FUNCTION RECAL EQU 3H ; RECALIBRATE DRIVE IORDY EQU 4H ; I/O FINISHED MASK ;*************** 201 CONTROLLER EQUATES *************************************** BASE EQU 88H ; BASE OF DISK COMMAND IO PORTS DSTAT EQU BASE ; DISK STATUS (INPUT) RTYPE EQU BASE+1 ; RESULT TYPE (INPUT) RBYTE EQU BASE+3 ; RESULT BYTE (INPUT) ILOW EQU BASE+1 ; IOPB LOW ADDRESS (OUTPUT) IHIGH EQU BASE+2 ; IOPB HIGH ADDRESS (OUTPUT) READF EQU 4H ; READ FUNCTION WRITF EQU 6H ; WRITE FUNCTION RECAL EQU 3H ; RECALIBRATE DRIVE IORDY EQU 4H ; I/O FINISHED MASK ;*************** IOC CONTROLLER EQUATES *************************************** ;*** IOC COMMANDS *** RDSTAT EQU 00011B ; READ DEVICE STATUS WPBC EQU 10101B ; WRITE FIRST BYTE OF PBC WPBCC EQU 10110B ; WRITE NEXT BYTE OF PBC (5 BYTES TOTAL) WDBC EQU 10111B ; WRITE DISKETTE DATA BYTES RDBC EQU 11001B ; READ DISKETE DATA BYTES RRSTS EQU 11011B ; READ DISKETTE RESULT BYTE RDSTS EQU 11100B ; READ DISKETTE STATUS BYTE ;**** I/O PORTS **** IOCDATA EQU 0C0H ; DATA PORT IOCCNTR EQU 0C1H ; CONTROL PORT ;**** DISK RESULT BYTE **** SEEKERR EQU 0000100B ; SEEK ERROR ;**** DBB STATUS BYTE **** OBF EQU 1B ; OUTPUT BUFFER FULL IBF EQU 10B ; INPUT BUFFER FULL F0 EQU 100B ; COMMAND STATUS FLAG (ON=ACCEPTED OFF=COMPLETED) CD EQU 1000B ; COMMAND/DATA FLAG (ON=STATUS OFF=DATA) ;**** DISKETTE STATUS BYTE FLAGS **** READY EQU 1B ; ON=DEVICE IS READY OPCOMP EQU 100B ; OPERATION COMPLETED PRESENT EQU 1000B ; DEVICE IS PHISICALLY PRESENT ILLDATA EQU 100000B ; ILLEGAL DATA SENT ILLSTAT EQU 1000000B ; ILLEGAL INTERUPT REQUEST ;**** DEVICE STATUS BYTE **** DSKERR EQU 10000000B ; DISK ERROR FLAG ;**** UNIQUE DISKETTE OPERATION CODES **** RECALB EQU 011B ; RECALIBRATE DISK ;****************************************************************************** ; JUMP VECTOR FOR INDIVIUAL ROUTINES ;****************************************************************************** JMP BOOT WBOOTE: JMP WBOOT JMP CONSTAT JMP CONIN JMP CONOUT JMP LIST JMP PUNCH JMP READER JMP HOME JMP SELDSK JMP SETTRK JMP SETSEC JMP SETDMA JMP READ JMP WRITE JMP LIST$ST ; LIST STATUS POLL JMP SECT$TRAN ; SECTOR TRANSLATION ;****************************************************************************** ; CODE SECTION ;****************************************************************************** BOOT: LXI SP,BUFF+80H ; TEMPORARY STACK POINTER ; SET UP INTERRUPTS FOR 0 AND 7 ENABLED DI MVI A,12H ; GIVE NON-EXISTANT I8259 INTERRUPT CONTROLLER OUT INT$CONT$1 ; IT'S INTIALIZATION SEQUENCE XRA A OUT INT$CONT$0 ; THIS ACTUALLY ALLOWS PENDING INTERRUPTS ; ON TO HAPPEN, BUT INTEL SEZ ; DO IT TO IT FOR THE I8259 COMPATIBILITY MVI A,INT$MASK ; RST0 AND RST7 BITS ON OUT INT$CONT$0 XRA A OUT MON$INT ; MASK ALL MONITOR BOARD INTERRUPTS ; PLUG ALL UNUSED INTERRUPT VECTORS WITH RST 7 ; SO UNEXPECTED INTERRUPTS WILL BREAKPOINT TO MDSMON LXI H,00008H ; POINT TO RESTART 1 LOCATION MOV D,H ; KEEP VALUE 8 FOR INCREMENT MOV E,L ; MVI C,6 ; WE WANT TO INIT. SIX RESTARTS FILL$LOOP: MVI M,0FFH ; PLUG IN A RESTART 7 INSTR. DAD D ; POINT TO NEXT RESTART LOCATION DCR C ; DROP COUNT JNZ FILL$LOOP ; AND ITERATE LDA 5 ; GET MDSMON'S LOCATION 5 TO SAVE STA HOLD$5 ; FOR COMPATIBILITY WITH MDS230 XRA A ; CLEAR ACCUMULATOR STA CDISK ; SET INITIALLY TO DISK A/USER 0 LXI H,SIGN$ON ; CALL PRMSG ; JMP GOCPM ; GO TO CP/M WBOOT: LXI SP,0100H ; TEMP STACK POINTER WBOOT0: LXI B,CCP ; SET DMA ADDRESS TO START OF DISK SYSTEM CALL SETDMA MVI C,0 ; BOOT FROM DRIVE 0 CALL SELDSK CALL HOME MVI C,2 ; START READING SECTOR 2 CALL SETSEC ; READ MULTIPLE SECTORS, COUNT NSECTS TO ZERO ;* IF NSECTS EVER GETS LARGER THAN 51 THAN THIS BOOT NEEDS TO ;* BE MODIFIED. MVI A,NSECTS STA ION ; SAVE IN IOPB CALL READ ; DO READ JNZ WBOOT ; REPEAT IF ERROR MVI A,1 ; SET NUMBER OF SECTORS TO 1 STA ION ; FOR REST OF WORLD ; GOCPM: ;(ENTER HERE FROM COLD START BOOT) ; SET UP PAGE ZERO JUMPS TO WARM BOOT, BDOS, AND MDSMON BREAKPOINT MVI A,JMP STA 0 LXI H,WBOOTE SHLD 1 ; JMP WBOOT AT LOCATION 00 STA 5 LXI H,BDOS+6 SHLD 6 ; JMP BDOS AT LOCATION 5 STA 7*8 ; JMP TO MON80 (MAY HAVE BEEN CHANGED BY DDT) LXI H,RMON80 SHLD 7*8+1 ; Set I/O byte MVI A,IOBYTI ; Initial value for IOBYTE STA IOBYTE ; *** LDA CDISK ; LAST LOGGED DISK NUMBER MOV C,A ; SEND TO CCP TO LOG IT IN EI JMP CCP CONIN: CALL CI1 ANI 7FH RET CI1: CALL MON DB 0FFH AND CI CONOUT: CALL MON DB 0FFH AND CO CONSTAT: CALL MON DB 0FFH AND CSTS LIST: CALL MON DB 0FFH AND LO READER: CALL MON DB 0FFH AND RI PUNCH: CALL MON DB 0FFH AND PO MON: ; PATCH FOR LOC. 5 LXI H,00005H ; RESTORE MDS LOC. 5 LDA HOLD$5 ; MOV M,A ; XTHL ; FETCH & BUILD MON CALL ADDRESS MOV L,M ; MVI H,0F8H ; CALL CALLER ; VECTOR TO APPROPRITIATE MDSMON ENTRY POP H ; RESTORE CP/M'S BDOS VECTOR OPCODE MVI M,0C3H ; RET ; CALLER: PCHL LIST$ST:XRA A ; NOT IMPLEMENTED RET ; SELDSK: ;SELECT DISK GIVEN BY REGISTER C LXI H,0000 ; FIRST, INSURE GOOD SELECT MOV A,C ; CPI NUM$DISKS ; RNC ; LXI H,SEL$TABLE ; MVI B,0 ; DAD B ; MOV A,M ; STA IOF ; STA IOFSV ; SAVE DRIVE ADDRESS MOV H,B ; GET DRIVE CODE TO [HL] MOV L,C ; DAD H ; MULTIPLY BY 16 DAD H ; DAD H ; DAD H ; LXI D,DPBASE ; AND MAKE ADDRESS OF DRIVE TABLE DAD D ; RET HOME: ;MOVE TO HOME POSITION MVI C,0 SETTRK: ;SET TRACK ADDRESS GIVEN BY C LXI H,IOT MOV M,C RET ; SETSEC: ; SET SECTOR NUMBER GIVEN BY C MOV A,C ; SECTOR NUMBER TO ACCUM STA IOS ; STORE SECTOR NUMBER TO IOPB RET ; SETDMA: ; SET DMA ADDRESS GIVEN BY REGS B,C MOV L,C MOV H,B SHLD IOD RET SECT$TRAN: ; TRANSLATE THE SECTOR # IN IF NEEDED MOV H,B ; IN CASE OF NO TRANSLATION MOV L,C ; INX H ; MOV A,D ; (TRANTAB) = 0 , AND RETURN ORA E ; RZ ; XCHG ; ELSE, OFFSET TABLE LOGICAL SECTOR DAD B ; MOV L,M ; THEN FETCH THE PHYSICAL SECTOR MVI H,0 ; RET ;****************************************************************************** ; DISK DRIVERS ;****************************************************************************** READ: LDA IOFSV ; CHOOSE WHICH DRIVER CODE TO USE MOV C,A ; HOLD SELECT CODE ANI 040H ; TEST IF IOC SELECTED JNZ READI ; YES - USE IOC DRIVER MOV A,C ; RESTORE [A] ANI 020H ; TEST IF 201 SELECTED JNZ READ1 ; YES - USE 201 DRIVER JMP READ2 ; IF NONE OF THE ABOVE - USE 202 DRIVER WRITE: LDA IOFSV ; CHOOSE WHICH DRIVER CODE TO USE MOV C,A ; HOLD SELECT CODE ANI 040H ; TEST IF IOC SELECTED JNZ WRITEI ; YES - USE IOC DRIVER MOV A,C ; RESTORE [A] ANI 020H ; TEST IF 201 SELECTED JNZ WRITE1 ; YES - USE 201 DRIVER JMP WRITE2 ; IF NONE OF THE ABOVE - USE 202 DRIVER ;*************** 202 CONTROLLER DRIVER CODE *********************************** READ2: ; READ NEXT DISK RECORD ( DISK/TRK/SEC/DMA SET) MVI C,READF ; SET TO READ FUNCTION JMP SETFUNC2 WRITE2: ; DISK WRITE FUNCTION MVI C,WRITF SETFUNC2: ; SET FUNCTION FOR NEXT I/O (COMMAND IN REG-C) MVI A,80H ; INITIALIZE IOPB FOR DUAL DENSITY 202 STA IOPB ; * LXI H,IOF ; IO FUNCTION ADDRESS MOV A,M ; GET IT TO ACCUMULATOR FOR MASKING ANI 1111$1000B ; REMOVE PREVIOUS COMMAND ORA C ; SET TO NEW COMMAND MOV M,A ; REPLACED IN IOPB WAITIO2: MVI C,RETRY ; MAX RETRIES BEFORE PERM ERROR REWAIT2: ; START THE I/O FUNCTION AND WAIT FOR COMPLETION CALL INTYPE2 ; IN RTYPE CALL INBYTE2 ; CLEARS THE CONTROLLER MVI A,IOPB AND 0FFH ; LOW ADDRESS FOR IOPB MVI B,IOPB SHR 8 ; HIGH ADDRESS FOR IOPB OUT ILOW2 ; LOW ADDRESS TO CONTROLLER MOV A,B OUT IHIGH2 ; HIGH ADDRESS WAIT02: CALL INSTAT2 ; WAIT FOR COMPLETION ANI IORDY ; READY? JZ WAIT02 ; CHECK IO COMPLETION OK CALL INTYPE2 ; MUST BE IO COMPLETE (00) UNLINKED ; 00 UNLINKED I/O COMPLETE, 01 LINKED I/O COMPLETE (NOT USED) ; 10 DISK STATUS CHANGED 11 (NOT USED) CPI 10B ; READY STATUS CHANGE? JZ WREADY2 ; MUST BE 00 IN THE ACCUMULATOR ORA A JNZ WERROR2 ; SOME OTHER CONDITION, RETRY ; CHECK I/O ERROR BITS CALL INBYTE2 RAL JC WREADY2 ; UNIT NOT READY RAR ANI 11111110B ; ANY OTHER ERRORS? (DELETED DATA OK) JNZ WERROR2 ; READ OR WRITE IS OK, ACCUMULATOR CONTAINS ZERO RET WREADY2: ; NOT READY, TREAT AS ERROR FOR NOW CALL INBYTE2 ; CLEAR RESULT BYTE JMP TRYCOUNT2 WERROR2: ; RETURN MALFUNCTION (CRC, TRACK, SEEK, ETC.) ; THE MDS CONTROLLER HAS RETURNED A BIT IN EACH POSITION ; OF THE ACCUMULATOR, CORRESPONDING TO THE CONDITIONS: ; 0 - DELETED DATA (ACCEPTED AS OK ABOVE) ; 1 - CRC ERROR ; 2 - SEEK ERROR ; 3 - ADDRESS ERROR (HARDWARE MALFUNCTION) ; 4 - DATA OVER/UNDER FLOW (HARDWARE MALFUNCTION) ; 5 - WRITE PROTECT (TREATED AS NOT READY) ; 6 - WRITE ERROR (HARDWARE MALFUNCTION) ; 7 - NOT READY ; (ACCUMULATOR BITS ARE NUMBERED 7 6 5 4 3 2 1 0) TRYCOUNT2: ; REGISTER C CONTAINS RETRY COUNT, DECREMENT 'TIL ZERO DCR C JNZ REWAIT2 ; FOR ANOTHER TRY ; CANNOT RECOVER FROM ERROR MVI A,1 ; ERROR CODE RET ; INTYPE, INBYTE, INSTAT READ DRIVE BANK 00 OR 10 INTYPE2: IN RTYPE2 RET INBYTE2: IN RBYTE2 RET INSTAT2: IN DSTAT2 RET ;*************** END 202 CODE *** ;*************** 201 CONTROLLER DRIVER **************************************** READ1: ; READ NEXT DISK RECORD ( DISK/TRK/SEC/DMA SET) MVI C,READF ; SET TO READ FUNCTION JMP SETFUNC ; WRITE1: ; DISK WRITE FUNCTION MVI C,WRITF ; SETFUNC: ; SET FUNCTION FOR NEXT I/O (COMMAND IN REG-C) mvi a,80h sta iopb ; restore IOPB channel command 820504 LXI H,IOF ; IO FUNCTION ADDRESS MOV A,M ; GET IT TO ACCUMULATOR FOR MASKING ANI 1111$1000B ;REMOVE PREVIOUS COMMAND ORA C ; SET TO NEW COMMAND MOV M,A ; REPLACED IN IOPB ; SINGLE DENSITY DRIVE 1 REQUIRES BIT 5 ON IN SECTOR # ; MASK THE BIT FROM THE CURRENT I/O FUNCTION ANI 0010$0000B ;MASK THE DISK SELECT BIT LXI H,IOS ;ADDRESS THE SECTOR SELECT BYTE ORA M ;SELECT PROPER DISK BANK MOV M,A ;SET DISK SELECT BIT ON/OFF ; WAITIO: MVI C,RETRY ; MAX RETRIES BEFORE PERM ERROR REWAIT: ; START THE I/O FUNCTION AND WAIT FOR COMPLETION CALL INTYPE ; IN RTYPE CALL INBYTE ; CLEARS THE CONTROLLER MVI A,IOPB AND 0FFH ; LOW ADDRESS FOR IOPB MVI B,IOPB SHR 8 ; HIGH ADDRESS FOR IOPB OUT ILOW ; LOW ADDRESS TO CONTROLLER MOV A,B OUT IHIGH ; HIGH ADDRESS JMP WAIT0 ; TO WAIT FOR COMPLETE WAIT0: CALL INSTAT ; WAIT FOR COMPLETION ANI IORDY ; READY? JZ WAIT0 ; CHECK IO COMPLETION OK CALL INTYPE ; MUST BE IO COMPLETE (00) UNLINKED ; 00 UNLINKED I/O COMPLETE, 01 LINKED I/O COMPLETE (NOT USED) ; 10 DISK STATUS CHANGED 11 (NOT USED) CPI 10B ; READY STATUS CHANGE? JZ WREADY ; MUST BE 00 IN THE ACCUMULATOR ORA A JNZ WERROR ; SOME OTHER CONDITION, RETRY ; CHECK I/O ERROR BITS CALL INBYTE RAL JC WREADY ; UNIT NOT READY RAR ANI 11111110B ; ANY OTHER ERRORS? (DELETED DATA OK) JNZ WERROR ; READ OR WRITE IS OK, ACCUMULATOR CONTAINS ZERO RET WREADY: ; NOT READY, TREAT AS ERROR FOR NOW CALL INBYTE ; CLEAR RESULT BYTE JMP TRYCOUNT WERROR: ; RETURN MALFUNCTION (CRC, TRACK, SEEK, ETC.) ; THE MDS CONTROLLER HAS RETURNED A BIT IN EACH POSITION ; OF THE ACCUMULATOR, CORRESPONDING TO THE CONDITIONS: ; 0 - DELETED DATA (ACCEPTED AS OK ABOVE) ; 1 - CRC ERROR ; 2 - SEEK ERROR ; 3 - ADDRESS ERROR (HARDWARE MALFUNCTION) ; 4 - DATA OVER/UNDER FLOW (HARDWARE MALFUNCTION) ; 5 - WRITE PROTECT (TREATED AS NOT READY) ; 6 - WRITE ERROR (HARDWARE MALFUNCTION) ; 7 - NOT READY ; (ACCUMULATOR BITS ARE NUMBERED 7 6 5 4 3 2 1 0) TRYCOUNT: ; REGISTER C CONTAINS RETRY COUNT, DECREMENT 'TIL ZERO DCR C JNZ REWAIT ; FOR ANOTHER TRY ; CANNOT RECOVER FROM ERROR MVI A,1 ; ERROR CODE RET INTYPE: IN RTYPE RET INBYTE: IN RBYTE RET INSTAT: IN DSTAT RET ;*************** END 201 CODE *** ;*************** IOC CONTROLLER DRIVER CODE *********************************** READI: ; READ NEXT DISK RECORD ( DISK/TRK/SEC/DMA SET) MVI C,READF ; SET TO READ FUNCTION JMP SETFUNCI ; WRITEI: ; DISK WRITE FUNCTION MVI C,WRITF ; SETFUNCI: ; SET FUNCTION FOR NEXT I/O (COMMAND IN REG-C) MVI A,80H ; INITIALIZE IOPB FOR DUAL DENSITY 202 STA IOPB ; * LXI H,IOF ; IO FUNCTION ADDRESS MOV A,M ; GET IT TO ACCUMULATOR FOR MASKING ANI 1111$1000B ; REMOVE PREVIOUS COMMAND ORA C ; SET TO NEW COMMAND MOV M,A ; REPLACED IN IOPB LDA IOFSV ; RESTORE DRIVE ADDRESS ANI 0100$0000B ; IOC ? JZ WAITIO ; NO - CONTINUE WITH DUAL ;* VERIFY DISK IS READY * CALL DISABLE ; DISABLE INTERRUPTS SDSKSTAT: MVI C,RETRY ; SET RETRY COUNT SDSK1: CALL DSKSTAT ; GET THE STATUS BYTE PUSH PSW ; SAVE STATUS BYTE ANI READY ; DISK READY ? JNZ SDSKSOK ; YES ... NO ERROR ; NO ... TEST FOR MAX RETRIES DCR C ; = MAX RETRIES? JZ SDERROR ; YES ... REPORT ERROR POP PSW JMP SDSK1 ; RETRY! SDSKSOK: POP PSW ; RESTORE STATUS BYTE ANI OPCOMP ; ANY PENDING OPERATIONS ? JZ BLDIOPB ; NO - GO BUILD THE CONTROL BLOCK ;* CLEAR ANY ACTIVITY ON THE DISK DRIVE * CALL DSKRSLT ; GET THE RESULT BYTE JMP SDSKSTAT ; GO MAKE SURE IT IS CLEARED ;**** MODIFY CONTROL BLOCK TO IOC FORMAT *** ;* BYTE TWO - MODIFY OP CODE * BLDIOPB: ;* BYTE 1 MVI A,0H ; SET FIRST BYTE TO 0 STA IOPB ; LDA IOF ; PUT 202 OP CODE IN ACCUMULATOR ANI 0000$0111B ; ISOLATE OP CODE STA IOF ; PUT BACK IN IOPB MVI C,RETRY ; INITIALIZE RETRY COUNTER ;* DETERMINE IF READ OR WRITE * CPI READF ; READ ? JZ SDREAD ; YES - BRANCH ;*** BEGIN IOC WRITE ROUTINE *** SDWRITE: CALL DBBWAIT ; WAIT FOR IOC TO BE READY MVI A,WDBC ; LOAD WRITE COMMAND OUT IOCCNTR ; ISSUE COMMAND TO IOC CALL DBBWAIT ; WAIT FOR IOC TO HANDLE COMMAND LDA ION ; # OF SECTORS OUT IOCDATA ; SEND TO IOC CALL DBBWAIT ; WAIT FOR IOC TO HANDLE ;* PASS DATA TO IOC RAM * LHLD IOD ; LOAD ADDRESS OF DATA LDA ION ; LOAD NUMBER OF SECTORS SDWLP1: PUSH PSW ; SAVE SECTOR COUNT MVI D,128 ; INITIALIZE BYTE COUNT FOR SECTOR SDWLP2: MOV A,M ; PUT DATA IN ACCUMULATOR OUT IOCDATA ; PASS TO IOC RAM CALL OUTWAIT ; WAIT FOR IOC TO HANDLE INX H ; BUMP CHARACTER POINTER DCR D ; DECREMENT CHARACTER COUNTER JNZ SDWLP2 ; LOOP TILL SECTOR DONE POP PSW ; LOAD SECTOR COUNT DCR A ; DECREMENT JNZ SDWLP1 ; LOOP TILL END OF SECTORS CALL OUTIOPB ; PASS IOPB TO IOC CALL ENABLE ; ENABLE INTERRUPTS CALL CKRESULT ; CHECK RESULTS OF WRITE ORA A ; SET FLAGS RZ ; RETURN OF OK DCR C ; OVER RETRY LIMIT ? JNZ SDWRITE ; NO - TRY AGAIN MVI A,1 ; ELSE SET BAD RETURN CODE RET ; AND RETURN ;* IOC READ ROUTINE * SDREAD: CALL DBBWAIT ; WAIT FOR DBB TO BE READY CALL OUTIOPB ; SEND IOPB TO IOC CALL CKRESULT ; CHECK RESULT OF READ ORA A ; SET FLAGS JZ SDRDATA ; GET DATA IF OK DCR C ; BEYOND RETRY LIMIT ? JNZ SDREAD ; NO - TRY AGAIN CALL ENABLE ; ENABLE THE INTERRUPTS MVI A,1 ; ELSE SET BAD RETURN CODE RET ; AND RETURN ;* GET THE DATA * SDRDATA: CALL DBBWAIT ; WAIT FOR IOC TO BE READY MVI A,RDBC ; SET COMMAND TO GET THE DATA OUT IOCCNTR ; SEND TO IOC LHLD IOD ; LOAD DMA ADDRESS LDA ION ; LOAD NUMBER OF SECTORS SDRLP1: PUSH PSW ; SAVE SECTOR COUNT MVI D,128 ; SET BYTES/SECTOR COUNT SDRLP2: CALL INWAIT ; WAIT FOR A BYTE TO BE READY IN IOCDATA ; GET THE BYTE MOV M,A ; MOVE TO BUFFER INX H ; INCREMENT POINTER DCR D ; DECREMENT CHARACTER COUNTER JNZ SDRLP2 ; LOOP THROUGH SECTOR POP PSW ; LOAD SECTOR COUNTER DCR A ; DECREMENT JNZ SDRLP1 ; LOOP THROUGH THE SECTORS CALL ENABLE ; ENABLE INTERRUPTS AT END OF DATA MVI A,0 ; SET GOOD RETURN CODE RET ; RETURN ;* IOC SUBROUTINES * ;* PASS THE IOPB * OUTIOPB: LXI H,IOPB ; POINT AT IOPB MVI D,5 ; LOAD BYTE COUNTER MVI A,WPBC ; LOAD COMMAND FOR IOC JMP SDWPB ; GO ISSUE THE COMMAND SDWPBL1: MVI A,WPBCC ; LOAD COMMAND FOR IOC SDWPB: OUT IOCCNTR ; OUTPUT COMMAND TO IOC CALL DBBWAIT ; WAIT FOR IOC TO HANDLE MOV A,M ; PUT DATA IN ACCUMULATOR OUT IOCDATA ; PASS TO IOC CALL OUTWAIT ; WAIT FOR IOC TO HANDLE INX H ; INCREMENT CHARACTER POINTER DCR D ; DECREMENT CHARACTER COUNTER JNZ SDWPBL1 ; LOOP THROUGH IOPB RET ; RETURN ;* CHECK RESULTS OF I/O * CKRESULT: CALL DSKWAIT ; WAIT FOR WRITE TO COMPLETE CALL DSKRSLT ; GET THE RESULT BYTE MOV D,A ; SAVE ANI 1111$1110B ; DELETED DATA ? RZ ; YES - RETURN (OK FOR NOW) MOV A,D ; RESTORE BYTE ANI SEEKERR ; SEEK ERROR ? CNZ RECALIB ; YES - TRY TO RECOVER MVI A,1 ; SET BAD RETURN CODE RET ; RETURN ;* GET DISK STATUS BYTE * DSKSTAT: CALL DBBWAIT ; WAIT FOR IOC TO BE FREE MVI A,RDSTS ; SET COMMAND FOR OUTPUT OUT IOCCNTR ; ISSUE COMMAND CALL INWAIT ; WAIT FOR DATA TO BE READY IN IOCDATA ; GET THE RESULT BYTE RET ; RETURN ;* GET DISK RESULT BYTE * DSKRSLT: CALL DBBWAIT ; WAIT FOR IOC TO BE FREE MVI A,RRSTS ; SET UP COMMAND FOR OUTPUT OUT IOCCNTR ; ISSUE COMMAND CALL INWAIT ; WAIT FOR COMMAND TO COMPLETE IN IOCDATA ; READ RESULT BYTE RET ; RETURN ;* DISABLE INTERRUPTS * DISABLE: MVI A,0DH ; SET DISABLE COMMAND OUT 0FFH ; WRITE TO CONTROL PORT RET ; RETURN ;* ENABLE INTERRUPTS * ENABLE: MVI A,05H ; SET ENABLE COMMAND OUT 0FFH ; WRITE TO CONTROL PORT RET ; RETURN ;* WAIT FOR IOC TO BE FREE * DBBWAIT: IN IOCCNTR ; READ DBB STATUS BYTE ANI F0 OR OBF OR IBF ; ANYTHING PENDING JNZ DBBWAIT ; YES - SPIN RET ; ELSE RETURN ;* WAIT FOR INPUT TO BE READY * INWAIT: IN IOCCNTR ; GET THE IOC STATUS BYTE ANI OBF OR F0 OR IBF ; OUTPUT BUFFER FULL ? CPI OBF ; VALID BUFFER ? JNZ INWAIT ; NO - SPIN RET ; RETURN ;* DISK NOT READY * SDERROR: POP PSW ; CLEAN UP STACK CALL ENABLE ; ENABLE INTERRUPTS MVI A,1 ; SET RETURN CODE RET ; RETURN ;* RECALIBRATE DISK DRIVE * RECALIB: LDA IOF ; LOAD CURRENT OP CODE PUSH PSW ; SAVE MVI A,RECALB ; SET RECALIBRATE OP CODE STA IOF ; STORE IN IOPB CALL OUTIOPB ; SEND IOBP TO IOC POP PSW ; RELOAD OP CODE STA IOF ; PUT BACK IN IOPB RET ; RETURN ;* WAIT FOR IOC TO TAKE DATA ON WRITE * OUTWAIT: IN IOCCNTR ; READ STATUS PORT ANI IBF OR F0 ; DATA TAKEN ? JNZ OUTWAIT ; NO - SPIN RET ; RETURN WHEN TAKEN ;* GET DEVICE STATUS * DEVSTAT: CALL DBBWAIT ; WAIT FOR IOC TO BE READY MVI A,DSTAT ; SET OP CODE FOR GET STATUS BYTE OUT IOCCNTR ; SEND TO IOC CALL INWAIT ; WAIT FOR IT TO BE READY IN IOCDATA ; GET IT RET ; RETURN ;* WAIT FOR DISK TO BE READY * DSKWAIT: CALL DSKSTAT ; GET DISK STATUS ANI OPCOMP ; OPERATION COMPLETED ? JZ DSKWAIT ; NO - SPIN RET ; ELSE RETURN ;*************** END IOC CODE *** ;****************************************************************************** ; UTILITY SUBROUTINES PRMSG: ; PRINT MESSAGE AT H,L TO 0 MOV A,M ; ORA A ; END OF STRING? RZ ; YES PUSH H ; NO - PRINT THIS CHARACTER MOV C,A ; CALL CONOUT ; POP H ; INX H ; JMP PRMSG ; ;****************************************************************************** ; DATA AREA ;****************************************************************************** SIGNON: ;SIGNON MESSAGE: XXK CP/M VERS X.Y DB CR,LF DB MSIZE/10+'0',MSIZE MOD 10 + '0' DB 'K CP/M VERS ' DB VERS/10+'0','.',VERS MOD 10+'0',CR,LF DB 0 ; END OF SIGNON MESSAGE IOPB: ; IO PARAMETER BLOCK DB 80H ; NORMAL I/O OPERATION IOF: DB READF ; IO FUNCTION, INITIAL READ ION: DB 1 ; NUMBER OF SECTORS TO READ IOT: DB 2 ; TRACK NUMBER IOS: DB 1 ; SECTOR NUMBER IOD: DW BUFF ; IO ADDRESS SEL$TABLE: ;* DRIVE SELECT BITS * DB 00H,10H,20H,30H,40H DISKS NUM$DISKS ; GENERATE DRIVE TABLES DISKDEF 0,1,52,,2048,243,128,128,2 DISKDEF 1,0 DISKDEF 2,1,26,6,1024,243,64,64,2 DISKDEF 3,2 DISKDEF 4,2 ENDEF IOFSV DS 1 ; SAVE AREA FOR DRIVE ADDRESS HOLD$5 DS 1 IF RELOC DB 0 ; FORCE OUT LAST ADDRESS FOR RELOCATION ENDIF END  ;***************************************************** ;* * ;* Sector Deblocking Algorithms for CP/M 2.0 * ;* * ;***************************************************** ; ; utility macro to compute sector mask smask macro hblk ;; compute log2(hblk), return @x as result ;; (2 ** @x = hblk on return) @y set hblk @x set 0 ;; count right shifts of @y until = 1 rept 8 if @y = 1 exitm endif ;; @y is not 1, shift right one position @y set @y shr 1 @x set @x + 1 endm endm ; ;***************************************************** ;* * ;* CP/M to host disk constants * ;* * ;***************************************************** blksiz equ 2048 ;CP/M allocation size hstsiz equ 512 ;host disk sector size hstspt equ 20 ;host disk sectors/trk hstblk equ hstsiz/128 ;CP/M sects/host buff cpmspt equ hstblk * hstspt ;CP/M sectors/track secmsk equ hstblk-1 ;sector mask smask hstblk ;compute sector mask secshf equ @x ;log2(hstblk) ; ;***************************************************** ;* * ;* BDOS constants on entry to write * ;* * ;***************************************************** wrall equ 0 ;write to allocated wrdir equ 1 ;write to directory wrual equ 2 ;write to unallocated ; ;***************************************************** ;* * ;* The BDOS entry points given below show the * ;* code which is relevant to deblocking only. * ;* * ;***************************************************** ; ; DISKDEF macro, or hand coded tables go here dpbase equ $ ;disk param block base ; boot: wboot: ;enter here on system boot to initialize xra a ;0 to accumulator sta hstact ;host buffer inactive sta unacnt ;clear unalloc count ret ; home: ;home the selected disk home: lda hstwrt ;check for pending write ora a jnz homed sta hstact ;clear host active flag homed: ret ; seldsk: ;select disk mov a,c ;selected disk number sta sekdsk ;seek disk number mov l,a ;disk number to HL mvi h,0 rept 4 ;multiply by 16 dad h endm lxi d,dpbase ;base of parm block dad d ;hl=.dpb(curdsk) ret ; settrk: ;set track given by registers BC mov h,b mov l,c shld sektrk ;track to seek ret ; setsec: ;set sector given by register c mov a,c sta seksec ;sector to seek ret ; setdma: ;set dma address given by BC mov h,b mov l,c shld dmaadr ret ; sectran: ;translate sector number BC mov h,b mov l,c ret ; ;***************************************************** ;* * ;* The READ entry point takes the place of * ;* the previous BIOS defintion for READ. * ;* * ;***************************************************** read: ;read the selected CP/M sector xra a sta unacnt mvi a,1 sta readop ;read operation sta rsflag ;must read data mvi a,wrual sta wrtype ;treat as unalloc jmp rwoper ;to perform the read ; ;***************************************************** ;* * ;* The WRITE entry point takes the place of * ;* the previous BIOS defintion for WRITE. * ;* * ;***************************************************** write: ;write the selected CP/M sector xra a ;0 to accumulator sta readop ;not a read operation mov a,c ;write type in c sta wrtype cpi wrual ;write unallocated? jnz chkuna ;check for unalloc ; ; write to unallocated, set parameters mvi a,blksiz/128 ;next unalloc recs sta unacnt lda sekdsk ;disk to seek sta unadsk ;unadsk = sekdsk lhld sektrk shld unatrk ;unatrk = sectrk lda seksec sta unasec ;unasec = seksec ; chkuna: ;check for write to unallocated sector lda unacnt ;any unalloc remain? ora a jz alloc ;skip if not ; ; more unallocated records remain dcr a ;unacnt = unacnt-1 sta unacnt lda sekdsk ;same disk? lxi h,unadsk cmp m ;sekdsk = unadsk? jnz alloc ;skip if not ; ; disks are the same lxi h,unatrk call sektrkcmp ;sektrk = unatrk? jnz alloc ;skip if not ; ; tracks are the same lda seksec ;same sector? lxi h,unasec cmp m ;seksec = unasec? jnz alloc ;skip if not ; ; match, move to next sector for future ref inr m ;unasec = unasec+1 mov a,m ;end of track? cpi cpmspt ;count CP/M sectors jc noovf ;skip if no overflow ; ; overflow to next track mvi m,0 ;unasec = 0 lhld unatrk inx h shld unatrk ;unatrk = unatrk+1 ; noovf: ;match found, mark as unnecessary read xra a ;0 to accumulator sta rsflag ;rsflag = 0 jmp rwoper ;to perform the write ; alloc: ;not an unallocated record, requires pre-read xra a ;0 to accum sta unacnt ;unacnt = 0 inr a ;1 to accum sta rsflag ;rsflag = 1 ; ;***************************************************** ;* * ;* Common code for READ and WRITE follows * ;* * ;***************************************************** rwoper: ;enter here to perform the read/write xra a ;zero to accum sta erflag ;no errors (yet) lda seksec ;compute host sector rept secshf ora a ;carry = 0 rar ;shift right endm sta sekhst ;host sector to seek ; ; active host sector? lxi h,hstact ;host active flag mov a,m mvi m,1 ;always becomes 1 ora a ;was it already? jz filhst ;fill host if not ; ; host buffer active, same as seek buffer? lda sekdsk lxi h,hstdsk ;same disk? cmp m ;sekdsk = hstdsk? jnz nomatch ; ; same disk, same track? lxi h,hsttrk call sektrkcmp ;sektrk = hsttrk? jnz nomatch ; ; same disk, same track, same buffer? lda sekhst lxi h,hstsec ;sekhst = hstsec? cmp m jz match ;skip if match ; nomatch: ;proper disk, but not correct sector lda hstwrt ;host written? ora a cnz writehst ;clear host buff ; filhst: ;may have to fill the host buffer lda sekdsk sta hstdsk lhld sektrk shld hsttrk lda sekhst sta hstsec lda rsflag ;need to read? ora a cnz readhst ;yes, if 1 xra a ;0 to accum sta hstwrt ;no pending write ; match: ;copy data to or from buffer lda seksec ;mask buffer number ani secmsk ;least signif bits mov l,a ;ready to shift mvi h,0 ;double count rept 7 ;shift left 7 dad h endm ; hl has relative host buffer address lxi d,hstbuf dad d ;hl = host address xchg ;now in DE lhld dmaadr ;get/put CP/M data mvi c,128 ;length of move lda readop ;which way? ora a jnz rwmove ;skip if read ; ; write operation, mark and switch direction mvi a,1 sta hstwrt ;hstwrt = 1 xchg ;source/dest swap ; rwmove: ;C initially 128, DE is source, HL is dest ldax d ;source character inx d mov m,a ;to dest inx h dcr c ;loop 128 times jnz rwmove ; ; data has been moved to/from host buffer lda wrtype ;write type cpi wrdir ;to directory? lda erflag ;in case of errors rnz ;no further processing ; ; clear host buffer for directory write ora a ;errors? rnz ;skip if so xra a ;0 to accum sta hstwrt ;buffer written call writehst lda erflag ret ; ;***************************************************** ;* * ;* Utility subroutine for 16-bit compare * ;* * ;***************************************************** sektrkcmp: ;HL = .unatrk or .hsttrk, compare with sektrk xchg lxi h,sektrk ldax d ;low byte compare cmp m ;same? rnz ;return if not ; low bytes equal, test high 1s inx d inx h ldax d cmp m ;sets flags ret ; ;***************************************************** ;* * ;* WRITEHST performs the physical write to * ;* the host disk, READHST reads the physical * ;* disk. * ;* * ;***************************************************** writehst: ;hstdsk = host disk #, hsttrk = host track #, ;hstsec = host sect #. write "hstsiz" bytes ;from hstbuf and return error flag in erflag. ;return erflag non-zero if error ret ; readhst: ;hstdsk = host disk #, hsttrk = host track #, ;hstsec = host sect #. read "hstsiz" bytes ;into hstbuf and return error flag in erflag. ret ; ;***************************************************** ;* * ;* Unitialized RAM data areas * ;* * ;***************************************************** ; sekdsk: ds 1 ;seek disk number sektrk: ds 2 ;seek track number seksec: ds 1 ;seek sector number ; hstdsk: ds 1 ;host disk number hsttrk: ds 2 ;host track number hstsec: ds 1 ;host sector number ; sekhst: ds 1 ;seek shr secshf hstact: ds 1 ;host active flag hstwrt: ds 1 ;host written flag ; unacnt: ds 1 ;unalloc rec cnt unadsk: ds 1 ;last unalloc disk unatrk: ds 2 ;last unalloc track unasec: ds 1 ;last unalloc sector ; erflag: ds 1 ;error reporting rsflag: ds 1 ;read sector flag readop: ds 1 ;1 if read operation wrtype: ds 1 ;write operation type dmaadr: ds 2 ;last dma address hstbuf: ds hstsiz ;host buffer ; ;***************************************************** ;* * ;* The ENDEF macro invocation goes here * ;* * ;***************************************************** end  TITLE 'D.D. MDS DISKETTE FORMAT PROGRAM 1/21/79' ; FORMAT DISKETTE ON MDS SYSTEM ; COPYRIGHT (C) 1976, 1977, 1978, 1979 ; DIGITAL RESEARCH ; BOX 579, PACIFIC GROVE ; CALIFORNIA, 93950 nsects equ 52 dbb macro v1,v2 db v1,v2 endm SKEWER MACRO SKEW TRELT SET 1 TRBASE SET 1 REPT nsects ; SECTORS / TURN dbb %trelt, 0e5h TRELT SET TRELT+SKEW IF TRELT GT nsects TRBASE SET TRBASE+1 TRELT SET TRBASE ENDIF ENDM ENDM ; ORG 100H JMP START DB ' COPYRIGHT (C) 1979 DIGITAL RESEARCH ' BASE EQU 78H RTYPE EQU BASE+1 RBYTE EQU BASE+3 ILOW EQU BASE+1 IHIGH EQU BASE+2 DSTAT EQU BASE RESET EQU BASE+7 ; CR EQU 13 LF EQU 10 CTLC EQU 03H ;CONTROL C ; ; BDOS CONSTANTS BOOT EQU 0000H BDOS EQU 0005H RCHARF EQU 1 ;READ CHARACTER PBUFF EQU 9 ; START: LXI SP,STACK ; SIGN-ON MESSAGE LXI D,SIGNON CALL PRINT RESTART: LXI D,RETMSG CALL PRINT CALL READC CPI CTLC ;CONTROL C? JZ BOOT ;RESTART CP/M CPI CR ;CARRIAGE RETURN JNZ RESTART ; CARRIAGE RETURN ENCOUNTERED OUT RESET ;RESET DISK SYSTEM lxi d, recalibrate call exec$iopb ; ; first, format first two tracks with alternating sectors LXI H, IOPBA MVI M, 0 LXI D, IOPB CALL exec$iopb INR M ; TO TRACK 1 CALL exec$iopb ; FORMAT DIRECTORY TRACK WITH SLOW SKEW LXI D, IOPB2 CALL EXEC$IOPB ; finally, format rest of disk with FAST SKEW sectors... LXI H,IOPBa1 ;NEXT TRACK MVI M,3 ; set it mvi b, 74 ; 74 tracks left LXI D, IOPb1 FLOOP: CALL exec$iopb ; IO COMPLETE, GO TO NEXT INR M ;NEXT TRACK DCR B JNZ FLOOP JMP RESTART exec$iopb: MOV A,E ; GET LOW BYTE ADDR OUT ILOW MOV A,D ; GET HIGH BYTE ADDRESS OUT IHIGH WAIT: IN DSTAT ANI 4 JZ WAIT ; IN RTYPE IN RBYTE ;CLEAR IT RET ; recalibrate: db 0 db 0001$0011b ; recalibrate command db 0 db 0 db 0 dw 0 IOPB: DB 40H ; RANDOM MODE DB 0001$0010B ; FORMAT TRACK ON DRIVE 1 DB 52 IOPBA: DB 0 ;NEXT TRACK DB 1 ;SECTOR ADDRESS DW BUFF ;BUFFER ADDRESS BUFF: ; RANDOM SEQUENCE BUFFER SKEWER 26 IOPB2: DB 40H, 12H, 52, 2, 1 DW BUFFY BUFFY: SKEWER 9 iopb1: db 40h,0001$0010b,nsects iopba1: db 0 db 1 dw buff1 buff1: skewer 13 SIGNON: DB CR,LF db 'Double Density Diskette Formatter Version 2.1' db 0dh,0ah,'Skew-6/4 (CTL-C to Abort)$' RETMSG: DB CR,LF DB 'DISK TO FORMAT IN B, TYPE RETURN$' ; PRINT: MVI C,PBUFF CALL BDOS RET ; READC: MVI C,RCHARF CALL BDOS RET ; DS 16 STACK: END ; CP/M 2.0 disk re-definition library ; ; Copyright (c) 1979 ; Digital Research ; Box 579 ; Pacific Grove, CA ; 93950 ; ; CP/M logical disk drives are defined using the ; macros given below, where the sequence of calls ; is: ; ; disks n ; diskdef parameter-list-0 ; diskdef parameter-list-1 ; ... ; diskdef parameter-list-n ; endef ; ; where n is the number of logical disk drives attached ; to the CP/M system, and parameter-list-i defines the ; characteristics of the ith drive (i=0,1,...,n-1) ; ; each parameter-list-i takes the form ; dn,fsc,lsc,[skf],bls,dks,dir,cks,ofs,[0] ; where ; dn is the disk number 0,1,...,n-1 ; fsc is the first sector number (usually 0 or 1) ; lsc is the last sector number on a track ; skf is optional "skew factor" for sector translate ; bls is the data block size (1024,2048,...,16384) ; dks is the disk size in bls increments (word) ; dir is the number of directory elements (word) ; cks is the number of dir elements to checksum ; ofs is the number of tracks to skip (word) ; [0] is an optional 0 which forces 16K/directory entry ; ; for convenience, the form ; dn,dm ; defines disk dn as having the same characteristics as ; a previously defined disk dm. ; ; a standard four drive CP/M system is defined by ; disks 4 ; diskdef 0,1,26,6,1024,243,64,64,2 ; dsk set 0 ; rept 3 ; dsk set dsk+1 ; diskdef %dsk,0 ; endm ; endef ; ; the value of "begdat" at the end of assembly defines the ; beginning of the uninitialize ram area above the bios, ; while the value of "enddat" defines the next location ; following the end of the data area. the size of this ; area is given by the value of "datsiz" at the end of the ; assembly. note that the allocation vector will be quite ; large if a large disk size is defined with a small block ; size. ; dskhdr macro dn ;; define a single disk header list dpe&dn: dw xlt&dn,0000h ;translate table dw 0000h,0000h ;scratch area dw dirbuf,dpb&dn ;dir buff,parm block dw csv&dn,alv&dn ;check, alloc vectors endm ; disks macro nd ;; define nd disks ndisks set nd ;;for later reference dpbase equ $ ;base of disk parameter blocks ;; generate the nd elements dsknxt set 0 rept nd dskhdr %dsknxt dsknxt set dsknxt+1 endm endm ; dpbhdr macro dn dpb&dn equ $ ;disk parm block endm ; ddb macro data,comment ;; define a db statement db data comment endm ; ddw macro data,comment ;; define a dw statement dw data comment endm ; gcd macro m,n ;; greatest common divisor of m,n ;; produces value gcdn as result ;; (used in sector translate table generation) gcdm set m ;;variable for m gcdn set n ;;variable for n gcdr set 0 ;;variable for r rept 65535 gcdx set gcdm/gcdn gcdr set gcdm - gcdx*gcdn if gcdr = 0 exitm endif gcdm set gcdn gcdn set gcdr endm endm ; diskdef macro dn,fsc,lsc,skf,bls,dks,dir,cks,ofs,k16 ;; generate the set statements for later tables if nul lsc ;; current disk dn same as previous fsc dpb&dn equ dpb&fsc ;equivalent parameters als&dn equ als&fsc ;same allocation vector size css&dn equ css&fsc ;same checksum vector size xlt&dn equ xlt&fsc ;same translate table else secmax set lsc-(fsc) ;;sectors 0...secmax sectors set secmax+1;;number of sectors als&dn set (dks)/8 ;;size of allocation vector if ((dks) mod 8) ne 0 als&dn set als&dn+1 endif css&dn set (cks)/4 ;;number of checksum elements ;; generate the block shift value blkval set bls/128 ;;number of sectors/block blkshf set 0 ;;counts right 0's in blkval blkmsk set 0 ;;fills with 1's from right rept 16 ;;once for each bit position if blkval=1 exitm endif ;; otherwise, high order 1 not found yet blkshf set blkshf+1 blkmsk set (blkmsk shl 1) or 1 blkval set blkval/2 endm ;; generate the extent mask byte blkval set bls/1024 ;;number of kilobytes/block extmsk set 0 ;;fill from right with 1's rept 16 if blkval=1 exitm endif ;; otherwise more to shift extmsk set (extmsk shl 1) or 1 blkval set blkval/2 endm ;; may be double byte allocation if (dks) > 256 extmsk set (extmsk shr 1) endif ;; may be optional [0] in last position if not nul k16 extmsk set k16 endif ;; now generate directory reservation bit vector dirrem set dir ;;# remaining to process dirbks set bls/32 ;;number of entries per block dirblk set 0 ;;fill with 1's on each loop rept 16 if dirrem=0 exitm endif ;; not complete, iterate once again ;; shift right and add 1 high order bit dirblk set (dirblk shr 1) or 8000h if dirrem > dirbks dirrem set dirrem-dirbks else dirrem set 0 endif endm dpbhdr dn ;;generate equ $ ddw %sectors,<;sec per track> ddb %blkshf,<;block shift> ddb %blkmsk,<;block mask> ddb %extmsk,<;extnt mask> ddw %(dks)-1,<;disk size-1> ddw %(dir)-1,<;directory max> ddb %dirblk shr 8,<;alloc0> ddb %dirblk and 0ffh,<;alloc1> ddw %(cks)/4,<;check size> ddw %ofs,<;offset> ;; generate the translate table, if requested if nul skf xlt&dn equ 0 ;no xlate table else if skf = 0 xlt&dn equ 0 ;no xlate table else ;; generate the translate table nxtsec set 0 ;;next sector to fill nxtbas set 0 ;;moves by one on overflow gcd %sectors,skf ;; gcdn = gcd(sectors,skew) neltst set sectors/gcdn ;; neltst is number of elements to generate ;; before we overlap previous elements nelts set neltst ;;counter xlt&dn equ $ ;translate table rept sectors ;;once for each sector if sectors < 256 ddb %nxtsec+(fsc) else ddw %nxtsec+(fsc) endif nxtsec set nxtsec+(skf) if nxtsec >= sectors nxtsec set nxtsec-sectors endif nelts set nelts-1 if nelts = 0 nxtbas set nxtbas+1 nxtsec set nxtbas nelts set neltst endif endm endif ;;end of nul fac test endif ;;end of nul bls test endm ; defds macro lab,space lab: ds space endm ; lds macro lb,dn,val defds lb&dn,%val&dn endm ; endef macro ;; generate the necessary ram data areas begdat equ $ dirbuf: ds 128 ;directory access buffer dsknxt set 0 rept ndisks ;;once for each disk lds alv,%dsknxt,als lds csv,%dsknxt,css dsknxt set dsknxt+1 endm enddat equ $ datsiz equ $-begdat ;; db 0 at this point forces hex record endm ;