IMD 1.17: 14/12/2009 9:44:05 MOD797 Files 6/20/84    0ISIS.PDS VOL1ISISPDS M 04 1                         FINDBAD COMFINDBAD DOC.XDIR COMMODEM797IQF MODEM797LQBc MODEM797SQTMCNFG797AQMLMODEM797SET-MCNFG797ASMh !"MODEM797INF#$MODEM797LIB%&'()*+,MODEM797LIB-.MNUMB797ASM/MODEM COMN01234MAC COM\56789:MOD797 ASM;<=>?@ABMOD797 ASMCDEFGHIJMOD797 ASMKLMNOPQRMOD797 ASMSTUVWXYZMOD797 ASM[\]^_`abMOD797 ASM?cdef        1eh FINDBAD - ver 5.41 Bad sector lockout program Universal version Type CTL-C to abort $ ͦA}6ͮ> ͵*|ʖ͌Û  *" "x"p"{ " |2*.":\O ͵> _*.*.   Test aborted by control-C $ FINDBAD.HEX ver. 5.4 (revised 05/21/81) NON-DESTRUCTIVE DISK TEST PROGRAM FINDBAD will find all bad blocks on a disk and build a file named [UNUSED].BAD to allocate them, thus "locking out"ou are using CP/M 2.x, AND if you know your CBIOS to be bug-free, leave me a message on the CBBS mentioned below ...I am interested in making this program as "universal" as possible. I can't help with any version of CP/M 1.4, other than "st Y:)|^#V#"!~#folC::_ :K͓j Testing data area... $  *DM*PYxͮ* |ͳ Testing system tracks... $ !"#"_**  Testing directory area... *eDM6# x }o|g}/o|/g#~#&8Ɛ'@'õ:X:Xi&"_ Zɷ|g}o:|&*.:^#"^#"~#2~#2^#"^#"^"> _[UNUSED]BAD  TesNo$ bad blocks found $ the bad blocks so CP/M will not use them. Originally written by Gene Cotton, published in "Interface Age", September 1980 issue, page 80. NOTE -- Ron Fowler Westland, Mich 7 April, 1981 This proandard" versions (whatever that means), because there are just too many heavily modified versions available. One possible problem you may find is with the system tracks of your diskettes...if they are of a different density than the data tra$ =*+PY 1:*͵!"**DM Ϳ:»g" Bad block: $ x/y/ͮ* :<_" *#"* q#e total sectors read $T HLT CMC STC CMA DAA RAR RAL RRC RLC NOP CPI ORI XRI ANI SBI IN SUI OUT ACI ADI CALLJMP LDA STA LHLDSHLDMOV ADD ADC SUB SBB ANgram has been re-written to allow it to work with (hopefully) all CP/M 2.x systems, and most 1.4 CP/M systems. It has been tested on several different disk systems, including Northstar, Micropolis, DJ2D, and Keith Petersen's 10 MByte hacks, then see the note regarding the "SYSTST" equate. ------------------------------------------------------------- NOTE: If you have any difficulties with this program, please contact the "TECHNICAL CBBS" in Dearborn, Michigan - phone 313-846-: p#" j:2!e" :X!yQ)=L:GdV}2* DMڑxʆ`i͑" f͑" !:<22|ʼڪ|¼.:22}2:G* !w#:w#$Þ Drive specrd disk system. I have tested it personally on my "modified" Northstar, under several different formats (including >16K per extent), and have had no difficulties. If you have have difficulties getting this program to run, AND if y6127 (110, 300, 450 or 600 baud). ------------------------------------------------------------- SYSTST and BADUSR options: Many double-density disk systems have single-density system tracks. If this is true with your system, you can      change the program to skip the system tracks. To do this, set the byte at 103H to a 0 if you don't want the system tracks tested, otherwise leave it 1. This is also necessary if you have a "blocked" disk system; that is, when the same aim" a diskette, it is recommended that the diskette be reformatted. If this is not possible, at least assure yourself that any existing files on the diskette do not contain unreadable sectors. If you have changed disks since the last warm-bo drive is assumed to contain the diskette to check. The program first checks the CP/M System tracks (0 and 1), and any errors here prohibit the disk from being used on drive "A", since all "warm boots" occur using the system tracks fred in the allocation map of the directory entry for [UNUSED].BAD, and the file is closed. Note, that when the number of "bad blocks" exceeds 16, the program will open additional extents as required to hold the overflow. I sugg physical disk is separated into logical disks by use of the SYSTRK word in the disk parameter block. If you are a CP/M 2.x user, you may assign the user number where [UNUSED.BAD] will be created by changing the byte at 104H to the desireot, you must warm-boot again before running this program. To use the program, insert both the disk containing the program FINDBAD.COM and the diskette to be checked into the disk drives. It is possible that the diskette containing the om the "A" drive. The program next checks the first two data blocks (groups to some of us) containing the directory of the diskette. If errors occur here, the program terminates and control returns to CP/M (no other data blocks are checked sest that if the diskette has more than 32 "bad blocks", perhaps it should be sent to the "big disk drive in the sky" for the rest it deserves. The nifty part of all this is that if any "bad blocks" do occur, they are allocated to [UNUSED].d user number. If you want it in the default user, then leave it 0FFH. CP/M 1.4 users can ignore this byte altogether. Note that these changes can be done with DDT as follows: A>DDT FINDBAD.COM -S103 103 01 0 ;DON'T TEST SYSTEM TRA program is the one to be checked. Assume that the program is on drive "A" and the suspected bad disk is on drive "B". In response to the CP/M prompt "A>", type in FINDBAD B:. This will load the file FINDBAD.COM from drive "A" and test the ince errors in the directory render the disk useless). Finally, all the remaining data blocks are checked. Any sectors which are unreadable cause the data block which contains them to be stored temporarily as a "bad block". At the BAD and no longer will be available to CP/M for future allocation...bad sectors are logically locked out on the diskette! AD and no longer will be available to CP/M for future allocation...bad sectors are logically locked out on the diskette! CKS 104 FF F ;PUT [UNUSED.BAD] IN USER 15 105 31 . ;DONE WITH CHANGES -^C A>SAVE XX FINDBAD.COM ------------------------------------------------------------- USING THE PROGRAM Before using this program to "recl diskette on drive "B" for unreadable sectors. The only allowable parameter after the program name is a drive specification (of the form "N:") for up to four (A to D) disk drives. If no drive is specified, the currently logged in end of this phase, the message "XX bad blocks found" is displayed (where XX is replaced by the number of bad blocks, or "No" if no read errors occur). If bad blocks occur, the filname [UNUSED].BAD is created, the list of "bad blocks" is plac    SD 4.4 - 28feb82!9" 1  }2  W2t 2p 2[ W2s <2!\~P:s ?͊͞: W:^#~))))!^ o&:^ /o*~ "~ *| #"| T>k͞*` |ʚ Ĕ͊2n ppp>0Þ0|rx0”:n >0ž:w Ü2n Þ2w *| |2l:\@͞7vs}*~ TT|:78:o !p 4veMODEM797.INFV o "!#%$'&)(*+,-./102435678:9;=<>?@BA5l51?𧻧֗ϘU_x\~SZ~WPYg]nTD1HǘʩiXy4M˷gi:κtѢEeBq敿ghVNyb`uˤ7pNC:\=!_!~2o !p !]~ > 6?#7>?2ht!\^W7x##~2_ #~2^ ##^#V"\ #^#VÔ*.;^#~2_ #~2^ #^"\ "b *\ #ڭW+}ʾz¨äi`:_ )="d *b #) "x "q *{zf7:p _ W!"` "| :[ w!~6:!~62&*6#=W;W!~6\!5:\@2h[|4:8>!\4:p څ>1͞:p 0Þ> ͞> Þ͜>|͞> G:*:W;!>p#"=2x_:W{ : :<H CDEGFHJIKLMNOQSPTURօ|d; g__33}WBAw0nqyzܾlg3q}Zf`;~E\:]oDκGb FqjDݘe| Xg]:ܨN[}DžfuV3I>gI*o"]?=u^7Ũ'h#3te'G_W~OwO[qݳ׌SX%PLX4&Y'?=}Džfu{cuQмN1&HOͧcpӻy j\nu*޼QIsE<7R@LX1|7*~iĤQQALGV3*7:Pqln4a1U1,DguXkި"~ t \W ͺ*j *l ͥ*j *f {ozg*u *-2_~͞#͞*. V*.V--7:t _ WwW*d T^#V#N#F_~W #£’ ) ) Nq#Nq ) ) N#F^#V_~W #>2͊R͊ WW:4Ҹ=Kn|Uٖ'fb}JOYyb@ZèøiiDe"#i'Z$?ٗpV7YoòVWwR<Ϧxjup~*?j#4eD.qijPcyS:SZ\|>*j( !M>Fj,7)z*i:qaFuu\_)uȞD$bP ;$?𧻧 **ո[}Dut=N{zF4b" ʩM`LYwk~c꣧bg2j\MST8pVIκ ͽl;.p(Jh #{z*f ç:¹!¹5W ͈##"q *q ^#V#"q >.͞::s _W* *}#>d2. >FNpq#=*: 1 Driv[ More ] $ ERRO - NO FILE on - ->Drive, user containsK in files withK freUser ADFNPR==SD DIRtw/~~HDuh'?ܾCw;pqD$?!{; )t w6Y j"غ_ή~/ńaDuh'?t^N}50MJzWPu>pk;SN#+?𧻧|Dutw/<1Zz15wnT:#0}L=uUu68!ߏC6al~?~;Iv/Pg] w6Ҏ/^J;.#X<"(bZ!eJ w`:D(!G^ YAkч    )upǵ}Ph:D{)d8+7V rPh/:D{)!!<ɣ/N " RCBEuYׁ~5 g!:êxߘ鼡;1~)~Vچ7*q_ńaΪn~c꣧BzTެp{V!\`FFsgUj{Ϊn~c'랗`FY˱Nv~MODEM797.LIB[ ! "#$%'&)(+*,.-/0213456789:;<=>@?ABoCEDFRտbg 4# 8k*1(0"o 8>Q)KX`Ԑhyv#Aݣ?ෞ6jH=)k-Ϯ8gיo|k-Ϯj1}-.?7PO|hsYٚSl c:)-b|sZNu֜bK0FRɝt?;w5ܙ@[xs,U?GHIJKLNMPOQRSTUVWXZYI>#}\>fkWrଟ5b+P8Wqk85PMnQ ! >-ϮяA bY70.S[E@9!_8+`5DPSEA%@T\Ӏ Տ\jrԘNLOWyv]?>ߪRV*Ϯ[~%;`ޮ`5DPS% xZT | Ӏ BB"<-l.?SCuqMU,*v@Hx+P۩0olx+PDN5D}W5?cWp9:xN@| A݃L.m`ՇU"k !`Yri!i?[:)V邨!6jtsaxG&ޟ[/Tڏߨ16]N!k:VͅIgWOWJWjLߦ IV˿?Y}F7m]n.?Ibؖ~IyYqo6jtK-ϮCf=~aFC"yF^z^=[VnjϝDo ?)+^g|VgrN"\'Aq wDX 8p9Hu V`o;7j~Xғ L 8o5<[J+DTCuxZVʭ";K(@.t9mo!N D j@D *wip )[ +Q7j"}X,TM:-@D r: Pr·-!!Ωx͇Ua>wRڪ~=5I4ZW)fmUCp' ?) V#wV385ZMMb֖I"bVXLΰO~h\d G^r}ƪ+J^=O_u=_m=_+m75x's٪l*ǟ*Ϯy5xsl٪ԘNLlq w돣g![dUڏ?i=o=5N    IPH<돣kwS$:!'es6gū캞Wɝ;+Wr&ItBOJ1kzP#w!ګJf& $lVWxYi\FDM_t+>7_+}VxԈx$O_4(5k50Rcv50 -ϮCϷɪz^ ^WhD!۪UY[Y8I'A#G[׊uMnhyv5C?Ԉg}POjLwbH|#_`_j3v5;Sl1[j3tzg-fKnhyv56Z]Q>xnjLwbԈg][̖bɝL j33Wɝttzg-fK?k5g? j]-5b=P> N`P#wO{WCj|-`5h5}G|uZz^V&_PSCէ!΂/m ", N@|n |`gQ C@Yjޮ[xE85=@B1vv% v»9F06PN1,v&՘AXSk?85p& $zg%lԘA8N&{OѭG0 l?85p& jL ,$ZOW]U٨ͅ!G&_Zk%Z;%5N"Rl:~"rgrN?[Xkr',IjLw?O>՘N\4®F7؞ڂs'|)P %Kh+_o2Fk65zGZ4y=_Y[שc٨1͍D5^Kfi#붹͕Ӡ~Qw!{$W|sE_W%>Tc`CLjt\4Iҫ[5d'en_0ڧqχDM¡hlUOb])Whjt??M!5NS#$鴺F~uBO*ojKvqXmDY s}̰1ޙbR)K ? j33q 8ڪ+e޿e8~Qcg@&^OZˍq3}7ԘNLl )-5agWc:3F_wy5Nhcuy?;w5`>ùps5`Rc:sӤZ?w5ܹq wqU+@JUWՕr5;e:Di k ʝLV;7j]&wj|@C?jUi?Up-T;hu|ps5;e:M?3Wҵ[jH 6LI4Xd])/c%^\ї@ ~߇f?;sm6A4(9ղ\jY}]Ux=l6jts5zhq=^7GLV;q w5䙫ѭpVZ5z1yՖ\ W#W$:-5z롮6%ׂq̘D_xNOmMn.Fpjm]!yj.jt?\ jHé!kF|эljGpWcHݚ ѻ[jH6Ԑh|$Q®tzg-fK>xf՘NLl -ϮF˳˫ )-5agWc:3? j\?Z-5;^HtRY[+ǟ;NIYyv]huM&w$Of?;6NR#w3&}p]ƺFj|vW>xf靣uǟsWK 65zW#wq w5䙫ѭpѻ[jH-qm@Up-T^ū_;mj\5f΄D͐u ZoZϵ*qȒK/1 ?x[ jH ؞" !``S| rDX 8p9H»ǐop)oPSP*wmag-Z7MĢ[@ `G vS YoP9!_M*0S Q ⺝ۇ% :5T෩:CeIz3ſ:Uu^ب!5N)7onjHwGmm    ZrUڏ?i=?;)⿫;όIt8ڒb6J.?ڧ?<$z-TJ.?g\jts<3aPc?ݚ [\&8ڄAn)⿫!< #ѸU75ڐ{gZWh$l}|+ףF $l>cX峴FlufF&OF.?gU3ZxUr>(WR?5gPh$:8S-5\>Kkǟ;>ߪ'e\q1މy5|Q)=7O#65ڀWCjH w*'XS*xҏO򑎮ѯ?;s5grqU-R#ѥ¸8.ej0;ZyR?3Wk {5qטr,>fkP@E@}; d`[ v}D dZ lQ3aPhjm Ɛ&ՈgaR[s!RCjH s|1,Q' \>R_DS YNQiQ6&}/>ШI'"k5>|"2‰(DdtUJ9ԮJcpjW}|"2^)wWpj|-`5h5ka #Aݣ?ෞԐ*uZdg%x`ȶs*.HM ".BӢr.0D 8Ր{L3_'otVW%lY$5;CNfhܝ]_}= Ph; >“urnf5쏭d--O75^[?|F ϫ!p{xj33乿 >dj3?5&|U{g >dj75x癃>j056a QWCVkRd0a$*Y\㵥ƽ pJf' >du+٨qNPhqV̷>RCj|-`5h5uRzR#Zz^V&_PCj{o! YNQiQ6:BB";c4t~oPS단c!~ N5T|o\[9XS_J -YiQ6PD% pmC]⭀+@@ PvDHT-\"O Dp}oSdk} 0䋳tL C`[\N5TԽCjH _৆t裍U:!;tԘ~L>װ]x(7YjH A>ϡC5uO?xf:?jH UA._'"{rPСR#+31 乿~|"r5uys*e޿JRCUСKQСR#/0]08~19 t ߏƐv} 51Ū Sc{Om/E*Ŭᥘ-~U᥁OWRrʝ Sc:3쓘-~?*9\^VlԘNK!v>,L9_j 9o.`U $|J-tVj0Ԉo>$oU}W''dpu56aN3,R[b. QZUO|R!MNp*Y\㵥? $**ѫ1@:-g[jH )vX*5_ku?={5Z~~zj"˿V4n{qOP+Vxj}hccRhNp*5>+ry>zr_!y5z5_ !5 [ /!Ωx.1csbM}o[AGEKdȶj>ONg9?j\_D 5[pnԐ+%P9 K[[>J\ې/\`"OtmO@c4A1y+]iQ6P 5*AԷt} 8 ]:--P`6P1L;(|jH=ӋG|'bR> Ԙ~L~WՐu:TCjt?`pjj0RCUСKR}CjH82?_)pjL?i+jH UA.}['ϡC5FO||1ҧWՐ0.Ր N ![o5jq:TCjQFB|]c"P\@-5u@ !qjbBX)ޡC55yxWj«oh^_>HWh]8F\R~?ڪ£e_#65;GRcy/ιn3L}2w?j >dK[j0HT)g!{DohMꊾg=5T%qV} _ǪkܗRFj-5lWc]8FRk G!5,#Aݣ?ෞԐ{L3?YPCj}OԈaC,>ߪdYR O8C@'MxB!]5H4qU8p8ڪ+E_ZzjS8ߜ~<f|5`WD0?3Rgϫt:O5K6||R&kR[TCjFWɷtz/Lp&"(Q?VVV8\ijF'~!5$Q 5-jY/Gdp]j|-KbZRc Rka\j[\ղ^d0u5ƥqU-ht:#5;9r:j\O05ܹHv?W#W2,!5:WWWZJCjH|1Y PCj:tVוrՐ'Q+o(rߢRCС2:TCjo!5 L 8%4Z  jj!'H W_IjO?~jJgj?5 O;({PCj8ޟ'wx盏 $-IbF<3&[jϝDoWc:g}D8k[}TMN_kjLwZ{Wc:SڻrީF|gᥘ-~Uk%_-_#65;GRcy+',n3LdK t @}[X" M~05ԐRcpMWgW`33ܖgwߏԘNCjLwƐV ·9_3L-5,?0 -f| m7w]m6H0ؖn3lA#m6rp0ؖn ]lK0ؖnm"`[!5ڀ~RCja>">GG-o=/+/!5NgW;-^9 b{P?vSct7Y8_;͟of~|n߷9vSct^7?    _{-˿pz/?~]=5NO OÜpȳVihF+j}v5jLwўdpOr5;GJTc"DoUqjP_)Wc"]$W4|N~R&wҵ EȅRҵSs!~DW8__b])Wc kخF|L\5;'Qv j"Qu|['V3U-jm]8fI?(3!џF|L[":!'eū {LgҊ^56>gFk>\^=&J1kV,ڧs?;乿:tֈNI΄A>I$ߪ1=){LPRS=O'{\FG0Wkq];|H$U>TcHj3w5F| 3L}2_v*S[j '0ѿԐ|YN@X }uz\}Rx'"WV!?ෞuBOJ5PeoзS< |!5~A30H /-IZτADܟ\e8bH(I/E+y )\ZD- g}W_%WR'a>WՈi>BkxJӮtzgTca׵ͅ-^?5Kja?ZϷNj0 \%Q.V]ї)P)fm1F<3VcGn.lo'QՇ\5F5d<v5`p8ڪkK^YˏrԈgj_1މq }0Rc:Sc:s/߷~j y t 6 mm.XG_Ozr\_Ozr.AF|<3v5u~Aɒ^}2f~\>fHb7Y%iWc:3Q10|_VcQ WcG ԘNCj=۹MQOԂo?5gfs'[2?_~=Y~F?yjLwbԘNK! |D 8k*ns3 _ xԘNK!źFԐmYSPΏ! @/ԐZ>áiR\՗CUI+z5u}\Rh$3׊  F<3&[5:Pjm]M;ߌIsf[jH uoN5v靣~19uajo!5rԈg9h\ӠjR>ןrtsY Pc iRFQhj 3W[sFRO}2"]}2f~15`> jt?q?x5Z3Z>~Ր['56j'[cp+lU D' N'5xxBQ G8F    vMODEM797.SET\   "!o$#&%'(*),+-.0/124365879:;<=>?A@BCDEFH֛ѳz^tٌޭ:/h[^ \x[׷w)P NgYc6Fϊ7~AxNs/rܤq|Y0cyo4˙fj=.wYϚ~ٌN򃦡2ad|fc?Ȭx| 8'2S |oֻheXz剽wyCɴ$C-1+4S{]*ɴ$׉eëc{]*J'T_' bwLQϑֵ=/3Ɯ.?L@R=Q*|ݎj r|.e?'Toc|ϣGyyw8h,#Ufo4TZtyulv Ƽ޺YUfas\l\9w')qeO%OO@\OFOSp%?%NSmiޞiili m]9λTmnIۤeLC %kw' $o5glX35~~V5fG[wޥO ~1x+t<~2KxK%p+vH&E,k7ފa|!Ϛ:p[fs%wޥ@R6)gYc*/yp[fs%wޥ_I'TMY֘. xGIJKLNMPORSUQTYWZ[XVޝx#Ʃ:Ɍ&`>+['߂fٻ :QΌAc;}4.q6m:?kA'!K)njc<tFmw4 NxB93b=Y'{ OWQa'.Fی>hٻ޴Wfw,xd4яg.1;ρ~+λTJ'T_chţSQ>H;WS;%Ket2mI)}~+_噁{ul=z{>kgYû@[#4}-VCqsU۝w'\A8ۙڞ)ˌ1(Z e~kޝY-O%OPŮ Tå}9TkVbvwulv/We^}/MeױyqC+(\yTCɴ$CbG\GywLN >hqfSESVܨtUft<{Ke2Cɴ$CbGpfSES(S λTʟɴ$էv}KCsALKV(wޥ2t2mIFQv;2j"ַ_m붋[KebS:6eëcλT&臠iHSR:aO5h[*Jn?*v.7ϡ];RY%ɴ$Jc zvxx)|Uwޝ0z]槲t䧯V6b=ʙqulv+wyJ~oԝL@RFom)M e֖3;R)= *t}k?FK)NxnlXplqxQnj}~zwUY mh?Qs?s?s?s?s?s?s?s?s?s?sya?hMWfwgM^ X9afQLֻ1u Q;;_o ý%2%ulv+w_?|)M:G-JJjԍj81)EAŋ1ֵG)jd?Få_Jߥ@mc3S"U핚0Nf[SQ*z=\](_Pcw$N (S>nG]SQ*zWֽ.%iH7JŔQmwዮ-FXeKe t2mIAcdvwmgm,k?hz]*K?iHoj?H ̵=Fmq)pQ;%"PүFqÞe6bλpBݽk#?Ӌ3V6ȹQ;K%_I'TMY֘. xt|%zd?Fwޥo'TMY֘6l_Hdz&`G1ُ~w3I?׆ xVd(&1z.@vH&E,kذgj ,Y{u{]*T@R6)gYc~ƆE>S    v;MCNFG797.ASM[ ! "#%$'&()+*,-./0123457689;:=<?>@AoBCDEFH7qN͛羡OR( rY(ύOYTDz< s%<7Z4?x5Eq<^s{SJj 㽩)WT%ڛpTAN#'7q;gT6sÐ!qMyk"./a嬙Nm{<7.&܆"\&r<7aSȍUyg97J9"K ?x5Eq;yZn>ޭ|OO2^9a~ﻷ0:kUvћv5c{X>ۺQօdxL:oQI/qz7ݨz{<ߩ0:kn~{%6*c=\KoatT$"^t_㼆>LFGOc{2^02u}u$ >PtMQRoatTNCynL?0iV"}4on 0:(yc.MoI7*S/zSémH$$g%sC`"{SHwId!+j ޔmЧOI75L>&JBynY`y#(*Gޔy }tSô <2c2[Qs?4XToMeZ;ݗJ '>ϻ$Xw$a}[CI8L OoQ}AI$j.zSDpI{PoyrӛnT_THO2^}fzSD픒"n yuse=(G=F[xVەpVx׆򆙽;%N) n %ZnXzӍўӺ/8KyToȝN) n %0Np',?FEu$afo7ENsT\qkӜ79~P0:gm\J?[}cچGeQ?zӼ7:7"y֍.$#8/zSE=[q^Va 7cVي#/n h?rC=GB~ `]o ًRګ́\R J;ˉ<7I`dOJ{.j=T΢OK#()z\y @5"[Pʞ ǿO%aoG`dx߲^J uI^oY{ׁ`dx߲^*JO2s}[8{Sޔ?|LdGG_*&~zG.hޔy 2cKLA`U 9dlWەyv,7՛M:fM"Pj.q@Pg 0oAes*7՛8 3ڋ[U VnƖ2 2[2ڬ-< ՉYٛ:o -NJ´ s?FI#̝9e齭(wܟ9MMϤnTgUbnf/8o 5J2zSy[7sceOx^=1'u\y2s"W{S筁r+G7iڣy7՛M ;4ۊyOH?*#޽m΍].oӴG[3~6T-Osߥf%ikx{[ʛMy[÷0r>[տO%aڷW9AD$=<ҏ_k5hg9{\%_qPy[7JB訴u[-+q([q^zS`U bBQ1lWV^*dқ+[x1h? ۅ@P[ PRv%ؗÂ:úa!9QY) *0H6]&1|֟^ s K]%RUToRD "d}8= [e57H2zcxסt[\m(w;\T-c+JyJKEy֍|'8 2qW%TS#xU5\}wl0:?7X2qmQp}u<ߩ7y PW3]`[{ \F    H;z;3IH2zc!cʯodh5wgyЛ?3#+=1P7nN&}s_5R-qӦ͂/>}u֯j`Cc]H9M3$|o+s_L%_ r 7s+33c{Xn̟W'y( >AUU 8BP7i%Y{[w2͡$|Q͖r#1ĴAT QiqfAyG%aڷk?޻0:{&FIxF{z7-=B#жyVA9%}e)hj*} z ͂6'Ϸ|_z zo41J57cٰx+=BC45MgAyG4?r?rX4o osU!**fů8v\#DPoAI({*xrߧVs7߫O.~B߫r+,OSHW ̿}ߧV([̂rM 5T O]ϲ1A>r=? [C%`=5O&_pIAP>r=?鯃G\_/B%`=5O&_"Bo2 u[ , Z-8{Sށ8K0bv.zzJz[AEV[z d5%'xoW{ zVx׽ޢvpخ6ڭWIzo`ǡoE+lWVx׽ Y^ڭec~$=v+߇s@6m3gf0BՇ#\U`[ X[X>r]v`՛8  v?YiAzX?Ñve80k{m6|>=1օdʯo4!JZ"=0|2/,Ag ٺf+=Bc]H9M3$|o+s{#NAz zo41Jc%q@e.- =}oy<7FIۣD~(9M3쩼xǟF( z :|F{'(ibݛϝѮWzc!cʯo-x"y䐱^=1Pu65ĠH?|nnBq^A%TO[y=d7[!ghYia>÷74{[q57]{[ϡ<7(s>CQ%EoMPn<ҏN>P֐pc{Eo7uMw0_'ks Rګw)}`缹{㟬%^K?Ӿ_ QFo)mʼnkn7G}%m~U"BP7i%Y{[({*m -31I B4sPi fq0&r̦!y,p.FGǩ51ۺ1l7Yg/,ǰ r!y NtZ8:zSI[ ԃq2 Pa4pN)v{jHY aAh [D=h0F8gBolXomVU09z`ǽYۃ7Cf!*ՄAuCf!*Bo6` Ϫ轩ޢ-<2+8 -|{ ԃzS?ˆysOOa@W/Bi;YO7I9]J^wJ?̳\xgo7uMwʲd!9G(ys}L p?.      r!BMLiՉEor]z}h29A ^4a5g^wJ?̳\{m$A@\PC&H?jcԵx& jG023GAP6ȁ́ E0wR;aߧhyikϲ~g>ԛ\@H7ح!= PR`^ ϲ'<ҏ~{%7՛MύG2tVik( 4/xlyoq{aWٵ_zwoohӃWa31 Pt7՛v[:l31 ?u "[ǘvJ-xEX֙}z\fKo+yOKokOr-xEM#!;Jz:lIG?)7%=xEgyokOA-xExos{\rʲ{lcȎR"BM%ڭWނae4L~.?u Y6+-DJ7![Pv@IJ7՛Zys#=0l̝9eSoG)3FNPBoGi0;1r"υގyCyBoGIPrsЛhH齅<BfA佩ނJzTo\ٛ C A-xExos{\r - Irv Hoff 11/30/82 Updated to v7.94 - Paul Kelley This information is given for those who do not wish to re-assemble the modem program for their system because they do not have the source code, or find this method simpxample of memory mapped I/O. 0103 FF <--- FF if PMMI modem, else 00. 0104 00 <--- Don't change. 0105 00 <--- Don't change. 0106 04 <--- Clock speed in MHz, 08 maximum 0107 00 <--- 00 if you want files that exist toWa$bako`ǡj^{Sx$Lmşy[ܘ?u Y6Gynxiԛ*ύk[-ylT&G:'s%SAVE 64 MODEM797.COM Experienced assembly language programmers should note that there is more be deleted if a file of the same name is sent in multi-file transfer. FF if you want the existing file to be changed to "BAK". Note: In CP/M 2.x, existia;PGr<-uH&_J-|{ ԃq/5hH/-O\^'o3yn!{L[emHs?K{ y K/E}_k_K flexiblity if MCNFG797.HEX is used to overlay MODEM797.COM. MCNFG797.ASM allows you to set the parameters discussed below. It also provides a permanent source file for your modem initialization routines as well as allowing you to change the values of ng R/O or SYS files are changed to "BAK" whether this byte is set or not. 0108 00 <--- 00 for default to CRC, FF for default to checksum 0109 FF <--- FF allows toggling of Checks     um to CRC 010A 00 <--- 00 leave backspace normal, FF convert to rubout 010B FF <--- FF allows toggling of backspace to rubout 010C 00 <--- 00 send CR-only, FF send CR-LF both (00 normal) 010D FF <--- FF allows toggling ofthe time" as you can easily change it temporarily using a menu command. Use one of these: 00=110, 01=300, 02=450, 03=600, 04=710, 05=1200 06=2400, 07=4800, 08=9600 0117 00 <--- 00 for no delay betwenly) have one, set now to warm reboot Put "LSP" part first, then "MSP". (the following addresses skip bytes not necessary to change) 0128 C0 <--- Your modem control port (port C0H shown here).  = = = = = = = = 014D C3 D9 01 "JMP 01D9" Many CP/M systems initialize the modem port via CONFIG.COM, etc. If you wish to NON-PMMI initialize the ports yourself, use the address shown here (01D9H) for your routine. End  line feed after carriage return 010E 00 <--- 00 don't change 010F FF <--- FF to prevent overwriting CCP, 00 if ok to overwrite 0110 00 <--- 00 not local command if control-^ precedes 0111 FF <--- FF allows toggling of localen characters. In terminal mode there are times when a delay is nice, like sending a pretyped file to a bulletin board system. Choices from 0-9. 00=no delay, 01=.02 secon 012B C1 <--- Your modem data port "OUT" (port C1H shown here). 012E C1 <--- Your modem data port "IN" (port C1H shown here). 0131 01 <--- Your modem status bit for "transmit ready". 0134 01 <--- Your modem status bit level when rit with a C9 (RET). You have space up to 0617H. = = = = = = = = = = = = = = = = = = = = = = = = When finished with the changes, exit 'DDT' via CTL-C then save as shown at the start of this file.  command on next char 0112 FF <--- FF allows toggling of printer on/off 0113 00 <--- FF for XOFF testing in terminal mode text file output 0114 00 <--- FF for wait for XON after CR in terminal mode output, useful for certain ds -- 09=0.18 seconds, etc. 0118 00 <--- 00 for no extra delay after CR. Some bulletin board systems, etc. require an extra delay after each CR. Choices from 0-9. 00=no delay, 01=.08 seconds -- 09=0.72 seconds, etc. 0119 1eady to send. 0137 02 <--- Your modem status bit for "receive ready". 013A 02 <--- Your modem status bit for "receive ready". 013D C2 <--- Your modem Baud rate port "IN" (PMMI only) 0140 C2 <--- Your modem Baud rate By Irv Hoff  When finished with the changes, exit 'DDT' via CTL-C then save as shown at the start of this file. timesharing systems 0115 FF <--- FF allows toggling of XOFF/XON testing 0116 01 <--- Sets the default speed for showing time to send a file in "S" command. Select the one you normally use "most of E <--- Bell repeat timing, 1E = about 1 second (area from 011A through 0120 does not need to be changed) 0121 7D <--- 7D for 20 PPS, FA for 10 PPS (PMMI board) 0122 00 00 <--- Put cold reboot address here if you (PMMI o port "OUT" (PMMI only) 0143 C3 <--- Your modem control port #2 (PMMI only) 0146 C0 <--- Your modem control port "OUT" (PMMI only) = = = = = = = = = = = = = = = =     ; ; MCNFG797.ASM ; ; Patches for overlaying distribution version of MODEM797. ; ;You will want to look this file over carefully, there are a number ;of options that you can use to configure MODEM797 to suit your taste. ; ;After you have finisheCOM file: ; ; A>DDT MODEM797.COM ; DDT VERS 2.2 ; NEXT PC ; 4080 0100 ; -IMCNFG797.HEX (note the "I" command) ; -R (loads in the .HEX file) ; NEXT PC ; 4080 0000 ; -G0 (return to CP/M) ; A>SAVE 64 MODEM797.COM (now have modifie ;PLK ; ;10/03/82 - First version of this file. ;PLK ; TRUE EQU 0FFH FALSE EQU 0 ; BELL EQU 07H ;bell CR EQU 0DH ;carriage return LF EQU 0AH ;linefeed ESC EQU 1BH ;escape ; VERMSG EQU FALSE ;change to TRUE if you have given at ;loca EQU true ;change to TRUE if you have defined the ;home cursor and clear screen sequence ;for you terminal. PMMI EQU true ;change to TRUE for PMMI. ; IF NOT PMMI ;THE FOLLOWING MUST BE CHANGED FOR YOUR MICRO IF YOU DON'T HAVE AN H89 ;d editing this file use DDT to overlay the HEX ;file onto MODEM797 and SAVE 64 MODEM797.COM. ; ;All users should set CLOCK to the right value for their system. ; ;PMMI users should set PUSERATE and CLDBOOT to their proper values. ; ;Non-PMMI, non-H8d .COM file) ; ;12/15/82 - Modified to work with version 7.96 of MODEM7 ;PLK ; ;11/26/82 - Modified to work with version 7.94 of MODEM7 ;PLK ; ;11/19/82 - Modified to work with version 7.92 of MODEM7 ;PLK ; ;11/02/82 - Modified to work with versiontion SYSVERMSG the name of the ;system for which MODEM7 has been ;configured. ; INIT EQU FALSE ;change to TRUE if you have written a ;routine at location INITMOD in this ;file to initialize your modem port ;on MODEM7 execution. OR A PMMI MODEM BOARD. MODDATP EQU 0D8H ;data port for H89 MODCTLP EQU MODDATP+5 ;modem status port for H89 MODSNDB EQU 20H ;bit to test for ready to send MODSNDR EQU MODSNDB ;change to 0 if bit is 0 when ;ready to send MODRCVB EQU 1 ;bit to 9 users who want to get MODM797 working quickly ;and who do not need to set their modem parameters using this program ;should change VERMSG, INIT, SETUP, CLEAR and PMMI to FALSE and ;change the equates for MODDATP, MODCTLP, MODSNDB, MODSNDR, MODRCVB ;a 7.90 of MODEM7. ; Included "how to use" instructions at start of file. ;IMH ; ;10/20/82 - Modified to work with version 7.89 of MODEM7. ;IMH ; ;10/16/82 - Modified to work with version 7.71 of MODEM7. ;PLK ; ;10/15/82 - Fixed lack of ENDIF aftePMMI users should ;use FALSE here. ; SETUP EQU FALSE ;change to TRUE if you have written a ;routine at location SETUPR to change ;baud rate, etc and MSPEED. PMMI users ;should use FALSE here. ; EOSCLR EQU true ;change to TRUE if test for received data MODRCVR EQU MODRCVB ;change to 0 if bit is 0 when ;data received ENDIF ;NOT PMMI ; ;CHANGE CLR1, CLR2, CLR3, AND CLR4 TO THE APPROPRIATE VALUES FOR ;YOUR TERMINAL IF YOU DO NOT HAVE AN H19 OR H89 AND EOSCLR IS TRUE IF End MODRCVR before assembly. ; ; ; TO USE: First edit this file filling in answers for your own ; equipment. Then assemble with ASM.COM or equivalent ; assembler. Then use DDT to overlay the the results ; of this program to the original MODEM797.r IF VERMSG AND (NOT PMMI) ;PLK ; ;10/12/82 - Modified to give version message. ;PLK ; ;10/09/82 - Modified to work with version 7.70 of MODEM7. ;PLK ; ;10/04/82 - Fixed so can also be easily used for making optional ; changes with PMMI modem.you have defined the ;clear to end of screen sequence for ;your terminal. Clear to end of screen is ;used on returning from terminal mode to ;keep the screen from becoming jumbled if ;the remote can positon your cursor. ; SCRNCLROSCLR CLR1 EQU 7eh ;tilde ctl-X is the Visual 200 clear CLR2 EQU 'X'-40h ;to end of screen sequence CLR3 EQU 0 ;the unused bytes MUST be 0 CLR4 EQU 0 ENDIF ;EOSCLR ; ;CHANGE SCLR1, SCLR2, SCLR3, AND SCLR4 TO THE APPROPRIATE VALUES FOR ;YOUR TER     MINAL IF YOU DO NOT HAVE AN H19 OR H89 AND SCRNCLR IS TRUE IF SCRNCLR SCLR1 EQU 7eh ;tilde ctl-\ is the Visual 200 home SCLR2 EQU '\'-40h ;cursor and clear screen sequence SCLR3 EQU 0 ;the unused bytes MUST be 0 SCLR4 EQU 0 ENDIF ;SCRNCLR ; ;I 103H SETUPTST: DB SETUP ;don't change this line 104H SCRNTEST: DB SCRNCLR ;test for home cursor and clear screen 105H ;routine at CLRSCRN, don't change this CLOCK: DB 4 ;clock speed in MHz, 8 MHz maximum 106H BAKUPBYTE: DB FALSE ;true=make .Bling of printer on/off 112H ;in terminal mode, set to false if your ;printer can't keep up with the modem XOFFTST: DB true ;true=allow testing of XOFF from remote 113H ;while transmitting a file in terminal mode XONWAIT: DB FALSE ;true=wa0H ; ^P = Toggle printer 11CH UNSAVE: DB 'R'-40H ; ^R = Close input text buffer 11DH TRANCHR: DB 'T'-40H ; ^T = Transmit file to remote 11EH SAVECHR: DB 'Y'-40H ; ^Y = Open input text buffer 11FH EXTCHR: DB '^'-40H ; ^^ = Send next character 12F YOU HAVE A PMMI YOU MAY NEED TO CHANGE THE BASE ADDRESS. ;ALSO, CHANGE PORT NUMBER IN THE PMMI MESSAGE BELOW SYSVERMSG. IF PMMI PORT EQU 0C0H ;PMMI BASE ADDRESS MODCTLP EQU PORT ;MODEM CONTROL PORT MODDATP EQU PORT+1 ;MODEM DATA PORT BAUDRP EAK file 107H CKSUMDFLT: DB FALSE ;true=default to Checksum checking 108H ;false=default to CRC checking TOGGLECRC: DB TRUE ;true=allow toggling of Checksum to CRC 109H CONVBKSP: DB FALSE ;true=convert backspace to rub 10AH TOGGLEBK: DB TRUE ;trit for XON after sending CR 114H ;while transmitting a file in terminal mode TOGXOFF: DB TRUE ;true=allow toggling of XOFF testing 115H MSPEED: DB 1 ;0=110 1=300 2=450 3=600 4=710 5=1200 116H ;default modem speed, PMMI and H89 routines 0H ; ;Equates used only by PMMI routines grouped together here. PULSERATE: DB 125 ;125 for 20pps, 250 for 10pps on PMMI 121H ;not used if PMMI FALSE CLDBOOT: DW 00000H ;currently set to warm boot with 122H ;BYE routine for PMMI, put your coldQU PORT+2 ;BAUD RATE PORT MODCTL2 EQU PORT+3 ;2ND MODEM CONTROL PORT ENDIF ;PMMI ; ; ;CLOCK SHOULD BE CHANGED TO SUIT YOUR SYSTEM. ;PMMI USERS SHOULD ALSO CHANGE PULSERATE AND CLDBOOT AS NECESSARY. ; ;You can change locations 107H to 120H, and 1ue=allow toggling of bksp to rub 10BH ADDLF: DB FALSE ;true=add LF after CR 10CH TOGGLELF: DB TRUE ;true=allow toggling of LF after CR 10DH TRANLOGON: DB FALSE ;true=allow transmission of logon 10EH ;write logon sequence at location LOGON SAVCC;reset this value and so should your own ;modem routines BYTDLY: DB 0 ;0=0 delay, 1=0.02 sec, -- ,9=0.18 sec 117H ;default time to send character in ;terminal mode file transfer CRDLY: DB 0 ;0=0 delay, 1=0.08 sec, -- ,9=0.72 sec 118H  ;boot entry here if you have one and ;desire to do on BYE BRKCHR: DB '@'-40H ; ^@ = Transmit "BREAK" with PMMI 124H CHGBAUD: DB 'B'-40H ; ^B = Used with PMMI in terminal 125H ; mode to change baud rate on fly DISCCHR: DB 'D'-40H ; ^D =23H to 125H ;to suit your taste. ; ;*** WARNING - DO NOT INSERT OR DELETE LINES BEFORE SYSVERMSG *** ; THE DEFINED LOCATIONS ARE GIVEN ON THE RIGHT MARGIN. ; ; ORG 100H ; DS 3 ;(for JMP START) PMMIBYTE: DB PMMI ;don't change this line P: DB TRUE ;true=do not overwrite CCP 10FH LOCONEXTCHR: DB FALSE ;true=local command if EXTCHR precedes 110H ;false=not local command if EXTCHR precedes TOGGLELOC: DB TRUE ;true=allow toggling of LOCONEXTCHR 111H LSTTST: DB TRUE ;true=allow togg ;default time for extra wait after CR ;in terminal mode file transfer BELRPT: DB 30 ;bell repeat time = value*0.03 sec 119H EXITCHR: DB 'E'-40H ; ^E = Exit without disconnect 11AH LOGCHR: DB 'O'-40H ; ^O = Send logon 11BH LSTCHR: DB 'P'-4 PMMI Disconnect 126H ; IN$MODCTLP: IN MODCTLP ! RET ;in modem control port 127H OUT$MODDATP: OUT MODDATP ! RET ;out modem data port 12AH IN$MODDATP: IN MODDATP ! RET ;in modem data port 12DH ; IF NOT PMMI ANI$MODSNDB: ANI MODSNDB ! RET ;     bit to test for send ready 130H CPI$MODSNDR: CPI MODSNDR ! RET ;value of send bit when ready 133H ANI$MODRCVB: ANI MODRCVB ! RET ;bit to test for receive ready 136H CPI$MODRCVR: CPI MODRCVR ! RET ;value of rcv. bit when ready 139H DS 15 ;PMMI only c; IF SCRNCLR DB SCLR1,SCLR2,SCLR3,SCLR4,0 ENDIF ;SCRNCLR ; IF NOT SCRNCLR DB 0,0,0,0,0 ENDIF ;NOT SCRNCLR ; RET ; JMP$ILPRT: DS 3 ; 165H JMP$ILCOMP: DS 3 ; 168H JMP$INBUFF: DS 3 ; 16BH JMP$SYSVERMSG: IF PMMI DS 3 ; - IF YOU MAKE INITMOD AND SETUPR TOO LONG YOU MAY *** ;*** GO BEYOND THE LENGTH OF THE PMMI INITMOD ROUTINE. *** ;*** YOU CAN MODIFY UP TO THE BYTE BEFORE NUMBLIB *** ;*** NUMBLIB CURRENTLY IS AT 0617H. *** ;*** IF YOU NEED MORE SPACE USE1200 EQU 0 ;MSD for 1200 baud WORDLEN EQU 3 ;8 bit word, no parity, no break ;deaccess baud rate divisor latches DTR EQU 1 ;turn on DTR ;End of H89 specific equates for initialization. ; ; ;The following is used to initialize the H89 on ealls 13CH LOGONPTR: DW LOGON ; 14BH JMP$INITMOD: JMP INITMOD ;go to user written routine 14DH ENDIF ;NOT PMMI ; IF PMMI DS 12 ;not changed 130H IN$BAUDRP: IN BAUDRP ! RET ;in baudrate port 13CH OUT$BAUDRP: OUT BAUDRP ! RET ;out baudra 16EH ELSE JMP SYSVERMSG 16EH ENDIF JMP$DIALPL: DS 3 ; 171H JMP$DISCONNT: DS 3 ; 174H ; SYSVERMSG: ; IF (NOT VERMSG) AND (NOT PMMI) CALL JMP$ILPRT DB 'Version for: UNSPECIFIED SYSTEM',CR,LF,0 ;NOTE: 0 MUST BE AT END  AN APPROPRIATE DS BEFORE NUMBLIB *** ; IF INIT ; ;The following are used in setting up the 8250 ACE on the H89. ;No need to change for another micro if INIT and SETUP are FALSE. ; ;control and status ports MODIER EQU MODDATP+1 ;interrupt enable xecution ;of MODEM7. Change it to initialize the modem port on ;your micro if you wish. ; ; INITMOD: MVI A,5 ;MSPEED 1200 baud value STA MSPEED INITMOD2: MVI A,DISABL OUT MODIER MVI A,LOOP$NODTR OUT MODMCR MVI A,ACCBAUD OUT MODLCR Lte port 13FH OUT$MODCTL2: OUT MODCTL2 ! RET ;out modem control port #2 142H OUT$MODCTLP: OUT MODCTLP ;out modem control port 145H DS 9 ;not changed 147H ENDIF ;PMMI ; JMP$SETUPR: ; 150H ; IF SETUP JMP SETUPR ENDIF ;SETUP ; OF ALL ILPRT MESSAGES RET ENDIF ;NOT VERMSG AND NOT PMMI ; ;This is where the message goes giving the system for ;which MODEM7 has been customized. IF VERMSG AND (NOT PMMI) CALL JMP$ILPRT DB 'Version for: HEATH H89',CR,LF,0 RET ENDIF ;VERM MODIIR EQU MODDATP+2 ;interrupt ident. MODLCR EQU MODDATP+3 ;line control MODMCR EQU MODDATP+4 ;modem control MODLSR EQU MODDATP+5 ;line status, same as MODCTLP above MODMSR EQU MODDATP+6 ;modem status ; ;baud rate latches MODDLL EQU MODDATP ;diviSBD: MVI A,LSD1200 OUT MODDLL MSBD: MVI A,MSD1200 OUT MODDLH MVI A,WORDLEN OUT MODLCR MVI A,DTR OUT MODMCR RET ; ENDIF ;INIT ; ; ;The following routine changes the baud rate for the H89 from ;the command level. Write your own routine  IF NOT SETUP RET NOP NOP ENDIF ;NOT SETUP ; CLREOS: CALL JMP$ILPRT ; 153H ; IF EOSCLR DB CLR1,CLR2,CLR3,CLR4,0 ENDIF ;EOSCLR ; IF NOT EOSCLR DB 0,0,0,0,0 ENDIF ;NOT EOSCLR ; RET ; CLRSCRN: CALL JMP$ILPRT ; 15CH SG AND NOT PMMI ; IF NOT PMMI ;INSERT YOUR LOGON HERE, MUST END IN 0. ;FOR A LOGON, PMMI USERS MUST MODIFY MODM797.ASM LOGON: DB 0 ENDIF ;NOT PMMI ; IF (NOT INIT) AND (NOT PMMI) INITMOD: RET ENDIF ;NOT INIT AND NOT PMMI ; ;*** WARNINGsor latch low MODDLH EQU MODDATP+1 ;divisor latch high ; ;control bytes DISABL EQU 0 ;disable interrupts LOOP$NODTR EQU 10H ;set loop back, turn off DTR ACCBAUD EQU 80H ;access baud rate divisor latches LSD1200 EQU 60H ;LSD for 1200 baud MSDhere to change your ;modem parameters. ; ; IF SETUP ; SETUPR: PUSH H AGAIN: LXI D,BAUDBUF ;point to input buffer for ILCOMP CALL JMP$ILPRT DB 'Input Baud Rate (300, 450, 600, 1200): ',0 CALL JMP$INBUFF LXI D,BAUDBUF+2 CALL JMP$ILCOMP ;c     ompare BAUDBUF+2 with characters below DB '300',0 JNC OK300 ;go if got match CALL JMP$ILCOMP DB '450',0 JNC OK450 CALL JMP$ILCOMP DB '600',0 JNC OK600 CALL JMP$ILCOMP DB '1200',0 JNC OK1200 CALL JMP$ILPRT ;all matches failed - tell TOPIC : INFORMATION FILE FOR INSTALLING THE MODEM797 TELEPHONE PROGRAM FROM : IRVIN M. HOFF and PAUL L. KELLEY DATE : 17 DEC 82 REVISED: 24 DEC 82 by Bruce R. Ratoff The MODEM7 program was originally written by Ward Christensen ral overlay file) MCOSB797.ASM (MCOSB797.AQM) (Osborne overlay file) (The minimum would be any pair in one of the examples shown below.) There are numerous ways by which you can set the proper ports, status pin values, etc.  operator DB '++ Incorrect entry ++',CR,LF,BELL,0 JMP AGAIN ;try again ; OK300: MVI A,1 ;MSPEED 300 baud value LHLD BD300 ;get 300 baud parameters in HL JMP LOADBD ;go load them ; OK450: MVI A,2 LHLD BD450 JMP LOADBD OK600: MVI A,3 in Sept. 1977. It has since undergone a considerable number of changes. MODEM797.HIS (for history) contains a list of those changes. The current version is 7.97 as of 24-DEC-82. To adapt this version to your equipment, you will want to get sfor your equipment. 1) Use DDT, SID or DUU with: MODEM797.COM and MODEM797.SET or 2) Use your editor, ASM, MODEM79 LHLD BD600 JMP LOADBD ; OK1200: MVI A,5 LHLD BD1200 JMP LOADBD ; LOADBD: STA MSPEED MOV A,L ;get least significant baud rate byte STA LSBD+1 ;store in INITMOD MOV A,H ;get most signifcant baud rate byte STA MSBD+1 ;store in INITMOD ome of the following programs: Program name Squeezed Name Purpose MODEM797.ASM (MODEM797.AQM) (source code file) MODEM797.COM (MODEM797.OBJ) (object code file) MODEM797.HIS (MODEM797.7.COM and and DDT or SID with: MCNFG797.ASM (Osborne owners use MCOSB797.ASM not MCNFG797.ASM) or 3) Use your editor, and MAC with: MODEM797.ASM and  POP H JMP INITMOD2 ;reset H89 8250 ; ;Table of baud rate parameters BD300: DW 0180H BD450: DW 0100H BD600: DW 00C0H BD1200: DW 0060H ; BAUDBUF: DB 10,0 DS 10 ; ENDIF ;SETUP ; ; END ; HQS) (history file) MODEM797.INF (MODEM797.IQF) (information file) MODEM797.LIB (MODEM797.LQB) (library file) MODEM797.SET (MODEM797.SQT) (how to set file) MCNFG797.ASM (MCNFG797.AQM) (gene MODEM797.LIB One of those should appeal to you. Possibly the first suggest- ion is the easiest to use. After asking for the program, type 'H', hit RET and it will display helpful information on the command     s. There are so many commands there are several pages. The program has received numerous worthwhile optional features in the past several months. SUPPLEMENTAL INFORMATION OF INTEREST: If using your editor with MCNFG797.ASM or 2661 information is for a typical Heath/Zenith Z-100 series computer. The 8250 information for a typical Heath/Zenith H8 or H89 computer. The first PMMI board with UART for a typical S-100 computer.) ; MACROS LIBRARY FOR CP/M ROUTINE SIMULATION 12/27/82 ; ; ; CONTAINS: ; ; 1) INBUF - Duplicates 'read buffer' routine same as CP/M ; function 10, but does not use CTL-C (reason for ; for the routine). Does allow controls U, R, E ; and LF,CONIN,COUNOUT,CONIN1 LOCAL CONOUT1,NOUCASE,CTLRLP,CONSTAT,CONST1,CONINLP ; PUSH PSW PUSH H PUSH B PUSH D ;'DE' REGISTERS MUST BE PUSHED LAST START CALL CLEAR ;CLEAR THE BUFFER AREA POP D ;GET ADDRESS OF BUFFER ON RETRIES PUSH D ;REMODEM797.ASM, the following might be helpful: (A typical port number will be shown for each.) PMMI UART 8251 2661 8250 PORT (control or status) 0C0H 31H 0EDH 0D8H+5 BAUDRP (baud rate poH (backspace). Outputs bell if the input is ; greater than the buffer. ; 2) CMDLINE - Parses a CPM/M buffer into format same as CP/M ; command line. ; 3) INLNCOMP - Compares a string following 'CALL ILCOMP' to a ; string addressed by the 'DESTORE STACK XRA A INX D ;ADDRESS COUNT FIELD STAX D ;INITIALIZE WITH A ZERO IN COUNT BYTE INX D XCHG ;ADDRESS FIRST BUFFER BYTE WITH 'HL' INBUFA CALL CONIN CPI 0DH ;IS IT A RETURN? JZ INBUFR ;IF SO, THEN RETURN CPI 7FH ;IS IT A DErt) PORT+2 --- --- --- MODCTL2 (2nd control port) PORT+3 --- --- --- MODCTLP (control or status) PORT PORT PORT PORT MODDATP (data port) PORT+1 PORT-1 PORT-1 PORT-5 MODRCVB (receive ' registers. ; 4) MFACCESS - Multi-file access routine from the CP/M user's ; group. ; 5) SENDTIME - Shows the time needed to send a file for current ; baud rate. (For 110-9600 baud). ; 6) PRTBAUD - Shows baud rates set for 'time to send' filLETE? JZ DELETE CPI 8 ;CTL-H WILL BACKSPACE.. JZ DELETE ;..OVER DELETED CHAR. CPI 'U'-40H ;IS IT A CTL-U JZ INBUFO ;OUTPUT # CR-LF AND START OVER CPI 'R'-40H ;CTL-R RETYPES LINE JZ RETYPE CPI 'E'-40H JZ PCRLF CPI 20H ;NO CONTROL Cbit) 02H 02H 02H 01H MODRCVR (receive ready) 02H 02H 02H 01H MODSNDB (send buffer empty bit) 01H 01H 01H 20H MODSNDR (send ready) 01H 01H 01H 20H (The e ; transfer. ; 7) DIRLIST - Lists directory and gives free space remaining ; on the requested drive. ; ; INBUF MACRO ;NO PARAMETERS USED. ; LOCAL START,INBUFO,INBUFA,DELETE,NODEL,ALERT,INBUFLT,CLEAR LOCAL CLEARL,INBUFR,RETYPE,BKSPC,PCRHARACTERS OTHER.. JC INBUFA ;..THAN ABOVE ALLOWED. MOV B,A ;SAVE INPUTTED CHARACTER XCHG ;SAVE 'HL' IN 'DE' POP H ;GET ADDRESS OF BUFFER IN 'HL' PUSH H ;RESTORE STACK INX H ;ADDRESS COUNT BYTE INR M ;INCREASE COUNT BYTE DCX H ;ADDR     ESS MAXIMUM MOV A,M ;PUT MAXIMUM IN 'A' INX H ;ADDRESS COUNT CMP M ;COMPARE COUNT TO MAXIMUM JC ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR XCHG ;RESTORE BUFFER POINTER TO 'HL' MOV M,B ;PUT INPUTTED CHARACTER IN BUFFER MOV A,B ;OUTPUIF 08H MVI A,20H CALL CONOUT MVI A,8 CALL CONOUT JMP INBUFA ; INBUFO MVI A,'#' CALL CONOUT MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT JMP START ; RETYPE POP D PUSH D INX D ;POINT TO CURRENT NUMBER.. LDAX D ;..OF CHARACALL CONSTAT ORA A JZ CONINLP CALL CONIN1 CPI 61H ;CHANGE TO UPPER.. JC NOUCASE ;..CASE SINCE CP/M.. CPI 7BH ;..DOES THE SAME. JNC NOUCASE ANI 5FH NOUCASE POP B POP D POP H RET ; CONIN1 LHLD 1 LXI D,6 DAD D PCHL ; COL1,FILL,FILL2,INIT,INITL1 LOCAL INITL2,INITL3,INITL4,NAME1,NAME2,SCAN,TRANS,TSTNAM LOCAL TSTTYP,TSTTYPL,TYPE1,TYPE2,NAME2C ; PUSH PSW PUSH B PUSH D PUSH H ; CALL INIT ;FILLS FCBS WITH BLANKS AND NULLS ; XCHG ;GET START OF COMMAND LINET IT CALL CONOUT INX H ;BUMP POINTER JMP INBUFA ;GET NEXT CHARACTER ; DELETE XCHG ;SAVE BUFFER POINTER IN 'DE' POP H ;ADDRESS BEGINNING OF BUFFER PUSH H ;RESTORE STACK INX H ;ADDRESS COUNT FIELD MOV B,A ;SAVE DELETE CHAR - 7FH OR CTERS. MOV B,A MVI A,'#' CALL CONOUT MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT MOV A,B ;TEST IF ZERO INPUT ORA A JZ INBUFA CTLRLP INX D LDAX D CALL CONOUT DCR B JNZ CTLRLP JMP INBUFA ; ALERT MVI A,7 CALL CONOUT NSTAT PUSH H PUSH D PUSH B CALL CONST1 POP B POP D POP H RET ; CONST1 LHLD 1 LXI D,3 DAD D PCHL ; CONOUT PUSH H PUSH D PUSH B PUSH PSW CALL CONOUT1 POP PSW POP B POP D POP H RET ; CONOUT1 LHLD 1 LXI D,9 D IN 'HL' INX H ;ADDRESS # BYTES IN CMD LINE MOV E,M ;LOAD 'DE' PAIR WITH # BYTES MVI D,0 INX H DAD D ;POINT TO BYTE AFTER LAST CHAR.. MVI M,0DH ;..IN CMD LINE AND STORE DELIMITER POP H ;RESTORE 'HL' AND 'DE' POP D PUSH D PUSH H I08H MOV A,M SUI 1 ;DECREASE COUNT MOV M,A JC NODEL ;DON'T DELETE PAST BEGINING OF BUFFER. XCHG ;RESTORE BUFFER POINTER TO 'HL' DCX H ;POINT TO LAST BYTE INPUTTED MOV A,B ;GET BACK EITHER 7FH OR 08H MOV B,M ;GET CHARACTER BEING DELETEDCR M XCHG JMP INBUFA ; PCRLF MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT JMP INBUFA ; INBUFR MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT POP D POP B POP H POP PSW RET ; CLEAR POP D ;ACCOUNTS FOR CALL POP H ;ADDRAD D MOV C,A PCHL ; ENDM ;..... ; ; CMDLINE MACRO ;NO PARAMETERS USED ; Loads a command line addressed by 'DE' registers (max # characters in ; line in 'DE', number of characters in the line in 'DE'+1, line starts ; in 'DE'+2) into FCB adNX D ;ADDRESS START OF COMMAND INX D ; CALL DRIVE NAME1 MVI C,8 ;TRANSFER FIRST FILENAME TO FCB CALL TRANS CPI 0DH JZ DONE CPI 20H ;IF SPACE, THEN START OF.. JZ NAME2 ;..SECOND FILENAME. TYPE1 POP H ;FILETYPE MUST BE AFTER.. PUSD MVI M,20H ;RESTORE BLANK CPI 8 JZ BKSPC CPI 7FH JZ BKSPC0 JMP INBUFA ;GET NEXT CHARACTER ; NODEL INR M ;DON'T LEAVE COUNT NEGATIVE XCHG ;RESTORE POINTER TO 'HL' JMP INBUFA ; BKSPC0 MVI A,08H BKSPC CALL CONOUT ;TRUE ERASE ESS BUFFER IN 'HL' PUSH H ;RESTORE.. PUSH D ;..STACK MOV B,M ;SAVE MAXIMUM IN 'B' INX H ;POINT TO FIRST.. INX H ;..BUFFER BYTE. MVI A,20H CLEARL MOV M,A INX H DCR B JNZ CLEARL RET ; CONIN PUSH H PUSH D PUSH B CONINLP dressed by 'HL' registers. The FCB should be at ; least 33 bytes in length. The command line buffer must have a maximum ; length of at least one more than the greatest number of characters ; that will be needed. ; LOCAL CMDLINE,DEFDR,DONE,DRIVE,FILH H ;..EIGHTH BYTE OF NAME LXI B,9 DAD B MVI C,3 ;TRANSFER TYPE OF FIRST FILE CALL TRANS CPI 0DH JZ DONE NAME2 LDAX D ;EAT MULTIPLE SPACES.. CPI 20H ;..BETWEEN NAMES JNZ NAME2C INX D JMP NAME2 LDAX D CPI 0DH ;TEST IF FIRST N     AME.. JZ DONE ;..ONLY AND THEN SPACE NAME2C POP H ;SECOND NAME STARTS IN 16TH BYTE PUSH H ;POINT 'HL' TO THIS BYTE LXI B,16 DAD B CALL DRIVE MVI C,8 CALL TRANS CPI 0DH JZ DONE TYPE2 POP H ;SECOND TYPE STARTS IN 25TH BYTE. PUSH THEN DRIVE WAS SPECIFIED DCX D CPI ':' JNZ DEFDR ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO) LDAX D ANI 5FH SUI 40H ;CALCULATE DRIVE (A=1, B=2,...).. MOV M,A ;..AND PLACE IT IN FCB INX D ;ADDRESS FIRST BYTE OF.. INX D ;..IN CMD LTTYPL MOV A,M ;..SPECIFIED ABOVE CPI '*' JZ FILL2 INX H DCR B RZ JMP TSTTYPL ; FILL2 ; FILL MVI M,'?' ;ROUTINE TRANSFERS '?' INX H DCR B JNZ FILL RET ; ENDM ;..... ; ; INLNCOMP MACRO ;NO PARAMETERS USED ; ; In-line co.. ; ; MFACCESS MACRO ;NO PARAMETERS USED ; ; Multi-file access subroutine. Allows processing of multiple files ; (i.e., *.ASM) from disk. This routine builds the proper name in the ; FCB each time it is called. This command would be used in suc H LXI B,25 DAD B MVI C,3 CALL TRANS DONE POP H PUSH H INX H ;POINT TO 1ST CHAR OF 1ST NAME IN FCB CALL SCAN ;CHECK FOR * (AMBIGUOUS NAMES). POP H PUSH H LXI B,17 ;POINT TO 1ST CHAR OF 2ND NAME IN FCB. DAD B CALL SCAN POP H INE.. DEFDR INX H ;..AND NAME FIELD IN FCB RET ; TRANS LDAX D ;TRANSFER FROM CMD LINE TO FCB.. INX D ;..UP TO NUMBER OF CHARS SPECIFIED.. CPI 0DH ;..BY 'C' REG. KEEP SCANNING FIELD.. RZ ;..WITHOUT TRANSFER UNTIL A DELIMITING.. CPI '.mpare. Compares string addressed by 'DE' pair to string af- ; the call (ends with '0'). Return with carry set means strings not the ; same. All registers (except 'A') are unaffected. ; SAME. ALL REGISTERS EXCEPT A-REG ARE UNAFFECTED. ; LOCAL ILCOh pro- ; grams such as modem transfer, tape save, etc. in which you want to ; process single or multiple files. ; ; The FCB will be set up with the next name, ready to do normal proces- ; sing (OPEN, READ, etc.) when routine is called. ; ; Carry is  POP D POP B POP PSW RET ; ; INIT PUSH H ;INITIALIZES FCB WITH 1 NULL (FOR 1ST DRIVE),.. PUSH B ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE),.. MVI M,0 ;..11 BLANKS, AND 4 NULLS INX H MVI B,11 MVI A,20H CALL INITFILL MVI B,5 M' ;..FIELD CHAR SUCH AS '.', BLANK, OR.. RZ ;..C/R (FOR END OF CMD LINE) CPI 20H RZ DCR C JM TRANS ;ONCE 'C' REG IS LESS THAN '0' KEEP READING MOV M,A ;..CMD LINE BUT DO NOT TRANSFER TO FCB INX H JMP TRANS ; SCAN MVI B,8 ;SCAN FILMPL,SAME,NOTSAME,NSLP ; XTHL ;POINT 'HL' TO 1ST CHARACTER PUSH D ILCOMPL MOV A,M ;'HL' POINTS TO IN-LINE STRING ORA A ;END OF STRING IF ZERO JZ SAME LDAX D CMP M JNZ NOTSAME INX H INX D JMP ILCOMPL ; NOTSAME MVI A,0 ;IF NOTset if no more names can be found ; ; Define data move MACRO ; LOCAL MOVE,CPM,MFNAME,MFN01,MFN02,MFFIX1,MFREQ,MFCUR,MOVER LOCAL SRCHF,SRCHN,STDMA,BDOS,FCB,FCBEXT,FCBRNO ; ; ;MFFLG1 IS NOT SET LOCAL BECAUSE IT MUST ; ;BE RESET IN MAIN MODEMVI A,0 CALL INITFILL MVI B,11 MVI A,20H CALL INITFILL MVI B,4 MVI A,0 CALL INITFILL POP B POP H RET ; INITFILL MOV M,A INX H DCR B JNZ INITFILL RET ; DRIVE INX D ;CHECK 2ND BYTE OF FILENAME. IF IT.. LDAX D ;..IS A ":",E NAME ADDRESSED BY 'HL' TSTNAM MOV A,M CPI '*' ;IF '*' FOUND, FILL IN REST OF FIELD.. JZ FILL1 ;..WITH '?' FOR AMBIGUOUS NAME INX H DCR B JNZ TSTNAM JMP TSTTYP FILL1 CALL FILL TSTTYP MVI B,3 ;SCAN AND FILL TYPE FIELD FOR NAME.. TS SAME, FINISH THRU.. NSLP INX H ;..STRING SO RETURN WILL.. CMP M ;..GO TO INSTRUCTION AFTER.. JNZ NSLP ;..STRING AND NOT REMAINDER OF STRING STC SAME POP D INX H ;AVOIDS A NOP INSTRUCTION.. XTHL ;..WHEN RETURNING RET ; ENDM ;... PROGRAM ON AN ; ;ABORT ; MOVE MACRO ?F,?T,?L,?I IF NOT NUL ?F LXI H,?F ENDIF IF NOT NUL ?T LXI D,?T ENDIF IF NOT NUL ?L LXI B,?L ENDIF IF NOT NUL ?I LOCAL ?B,?Z CALL ?Z ?B DB ?I ?Z POP H ;GET TO LXI B,?Z-?B ENDIF CAL     L MOVER MF SET -1 ;SHOW EXPANSION ENDM ;... ; ; ;DEFINE CP/M MACRO - CPM FNC,PARM ; CPM MACRO ?F,?P PUSH B PUSH D PUSH H IF NOT NUL ?F MVI C,?F ENDIF IF NOT NUL ?P LXI D,?P ENDIF CALL BDOS POP H POP D POP B ENDM ;...  STA MFFLG1 RET ; ; MFFIX1 ; ;<> DCR A ANI 3 ADD A ADD A ADD A ADD A ADD A ADI 81H MOV L,A MVI H,0 PUSH H ;SAVE NAME POINTER MOVE ,MFCUR+1,11 ; ;<> ; POP H MOVE ,FOF RECORDS CALL ILPRT DB ' (',0 CALL DHXOUT ;NOW PRINT SIZE IN HEX. CALL ILPRT DB ' Hex) Records',CR,LF DB 'Send time: ',0 LDA MSPEED ;GET THE SPEED INDICATOR MVI D,0 MOV E,A ;SET UP FOR TABLE ACCESS LXI H,BTABLE ;POINT TO BAUD FACT,29,49,96,192,384,0 ;RECORDS/MIN FOR 110-9600 BAUD SECTBL DB 192,74,51,38,33,20,11,5,3,0 ; ; ;----> DVHLDE: DIVIDES 'HL' BY VALUE IN 'DE', ; UPON EXIT: 'BC'=QUOTIENT,'L'=REMAINDER ; DVHLDE PUSH D ; SAVE DIVISOR MOV A,E CMA ; NEGATE DIVISO ; ; ; MULTI-FILE ACCESS SUBROUTINE ; ; The routine is commented in pseudo code, each pseudo code statement is ; in <<...>> ; MFNAME ; ;<> ; CPM STDMA,80H XRA A STA FCBEXT ; ;<> ; LDA MFFLG1 ORA A CB+1,11 ; ;<> ; XRA A STA FCBEXT STA FCBRNO ; ;<> ; RET ; ; ; Multi-file access work area MFFLG1 DB 0 ;1ST TIME SW MFREQ DS 12 ;REQ NAME MFCUR DS 12 ;CURR NAME ; ; Move subroutine ; MOVER MOV A,M STAX D INX OR TABLE DAD D ;INDEX TO PROPER FACTOR DAD D ;FACTOR IN DE MOV E,M INX H MOV D,M LHLD RCNT ;GET # OF RECORDS CALL DVHLDE ;DIVIDE 'HL' BY VALUE IN DE (RECORDS/MIN) PUSH H MOV L,C MOV H,B CALL DECOUT ;PRINT THE MINUTES PORTION CAR MOV E,A MOV A,D CMA MOV D,A INX D ; DE IS NOW TWOS COMPLEMENTED LXI B,0 ; INIT QUOTIENT DIVL1: DAD D ; SUBTRACT DIVISOR FROM DIVIDEND INX B ; BUMP QUOTIENT JC DIVL1 ; LOOP TILL SIGN CHANGES DCX B ; ADJUST QUOTIENT POP D ; RE JNZ MFN01 ; ; <> ; MVI A,1 STA MFFLG1 ; ; <> ; MOVE FCB,MFREQ,12 ;SAVE ORIG REQ LDA FCB STA MFCUR ;SAVE DISK IN CURRENT FCB ; ; <> ; MOVE MFREQ,FCB,12 CPM SRCHF,FCB H INX D DCX B MOV A,B ORA C JNZ MOVER RET ; ; ; Equates used by multi-access subroutine SRCHF EQU 17 SRCHN EQU 18 STDMA EQU 26 BDOS EQU 5 FCB EQU 5CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32 ENDM ;..... ; ; SENDTIME MACRO ;NO PALL ILPRT DB ' mins, ',0 LXI H,SECTBL ;POINT TO DIVISORS FOR SECONDS LXI D,0 ; CALCULATION LDA MSPEED ;GET INDEX FOR BAUD RATE MOV E,A DAD D ;INDEX INTO TABLE MOV A,M ;GET MULTIPLIER POP H ;GET REMAINDER CALL MULHLA ;MULTIPLY THE 'TRIEVE DIVISOR DAD D ; ADJUST REMAINDER RET ; ; ;----> MULHLA: MULTIPLY THE VALUE IN 'HL' BY THE VALUE IN 'A' ; RETURN WITH ANSWER IN 'HL' MULHLA XCHG ; MULTIPLICAND TO DE LXI H,0 ; INIT PRODUCT INR A ; ADJUST MULTIPLIER FOR ZERO TEST  ; ;<> ; JMP MFN02 MFN01 ; ; <> ; MOVE MFCUR,FCB,12 CPM SRCHF,FCB ; ; <> ; MOVE MFREQ,FCB,12 CPM SRCHN,FCB ; ;<> ; MFN02 ; ;<> ; INR A STC JNZ MFFIX1RAMETERS USED ; ; Shows the time to transfer a file at various baud rates ; LOCAL BTABLE,SECTBL,DVHLDE,DIVL1,MULHLA,MULLP,SHFTHL CALL ILPRT ;PRINT: DB 'File open: ',0 LHLD RCNT ;GET RECORD COUNT. CALL DECOUT ;PRINT DECIMAL NUMBER HL' x 'A' CALL SHFTHL CALL SHFTHL CALL SHFTHL CALL SHFTHL MVI H,0 CALL DECOUT ;PRINT THE SECONDS PORTION CALL ILPRT DB ' secs at ',0 CALL BAUDPRT CALL ILPRT DB 'To cancel: ctrl-X',CR,LF,0 RET ; ; BTABLE DW 5,13,19,25 MULLP DCR A RZ DAD D JMP MULLP ; ; ; SHIFT 'HL' REGISTER PAIR ONE BIT TO THE RIGHT ; SHFTHL MOV A,L RAR MOV L,A ORA A ;CLEAR THE CARRY MOV A,H RAR MOV H,A RNC MVI A,80H ORA L MOV L,A RET ; ENDM ;..... ; ; PRTB    AUD MACRO ;NO PARAMETERS USED ; LOCAL BAUDSPD ; LXI H,BAUDSPD MVI D,0 LDA MSPEED ;GET BAUD RATE CODE MOV E,A ;X1 ADD A ;X2 ADD A ;X4 ADD E ;X5 MOV E,A DAD D ;POINT TO CORRECT RATE XCHG MVI C,PRINT CALL BDOS CALL ILPRT DO FIRST SEARCH CALL BDOS CPI 0FFH JZ NOFILE PUSH PSW DIRLP POP PSW CALL GETADD LXI D,15 ;OFFSET FOR RECORD COUNT DAD D MOV A,M ORA A JZ NEXTSR ;NO LIST IF FILE IS ZERO LENGTH LXI D,-5 DAD D ;POINT TO $SYS ATTRIB BYTE MOV A,ISK PARAMETER BLOACK CALL BDOS INX H INX H MOV A,M ;GET BLOCK SHIFT FACTOR STA BSHIFTF INX H ;BUMP TO BLOCK MASK MOV A,M ;GET IT STA BMASK INX H INX H MOV E,M ;GET MAX BLOCK NUMBER INX H MOV D,M XCHG SHLD BMAX ;PUT IT AWAREKLP DAD H ;MULTIPLY BLOCKS BY 'K PER BLOCK' DCR A JNZ FREKLP PRTFREE PUSH H CALL ILPRT DB CR,LF,'Drive ',0 LDA SRCHFCB ;IF NO DRIVE, GET ORA A ;LOGGED IN DRIVE JNZ PRNTHD MVI C,CURDSK CALL BDOS INR A PRNTHD ADI 'A'-1 STA  DB ' baud',CR,LF,0 RET ; BAUDSPD DB '110$',0,'300$',0,'450$',0,'600$',0,'710$',0 DB '1200$','2400$','4800$','9600$' ; ENDM ;..... ; ; DIRLIST MACRO ;NO PARAMETERS USED ; LOCAL DIRLP,PRTNAME,NOFILE,DIRDONE,QSTMARK,QSTLP,PRNTNAME LOCAL M ANI 80H JNZ NEXTSR ;NO LIST IF $SYS FILE LXI D,-10 DAD D ;POINT TO BEGINNING OF NAME INX H ;POINT TO FIRST LETTER LXI D,PRNTNAME MVI B,8 CALL MOVE INX D MVI B,3 CALL MOVE CALL ILPRT PRNTNAME DB ' ','.',' ',' ', 0 Y MVI C,GETALC ;ADDRESS OF CP/M ALLOCATION VECTOR CALL BDOS XCHG ;GET ITS LENGTH LHLD BMAX INX H LXI B,0 ;INITIALIZE BLOCK COUNT TO ZERO GSPBYT PUSH D ;SAVE ALLOCATION ADDRESS LDAX D MVI E,8 ;SET TO PROCESS 8 BLOCKS GSPLUP RAL DRNAME CALL ILPRT DRNAME DB ' has ',0 POP H ;GET NUMBER OF BYTES AVAILABLE CALL DECOUT CALL ILPRT DB 'K bytes free',CR,LF,0 RET ; ; Subroutines ; FENCE CALL ILPRT DB '| ',0 RET ; QSTMARK MVI A,'?' ;IF BLANK IN FCB, PUT IN 11NEXTSR,MOVENAME,GETADD,SRCHFCB,NAMECT,PRNTHD,DRNAME LOCAL FENCE,GSPBYT,GSPLUP,NOTFRE,ENDALC,FREKLP,PRTFREE LOCAL PRTHD,DRNAME ; LXI D,CMDBUF ;PUT COMMAND LINE IN FCB LXI H,5CH CALL CPMLINE LXI H,SRCHFCB CALL INITFCBS LDA 6CH ;GET DRIVE # ;8 SPACES, PERIOD, 3 SPACES, 1 SPACE MVI A,0FFH STA NAMEGD NEXTSR LXI D,SRCHFCB MVI C,SRCHN ;DO NEXT SEARCH CALL BDOS CPI 0FFH JZ DIRDONE PUSH PSW LDA NAMEGD ORA A JZ DIRLP LDA NAMECT INR A STA NAMECT ANI 03H ORA A CZ CR ;TEST BIT JC NOTFRE INX B NOTFRE MOV D,A ;SAVE BITS DCX H MOV A,L ORA H JZ ENDALC ;QUIT IF OUT OF BLOCKS MOV A,D ;RESTORE BITS DCR E ;COUNT DOWN 8 BITS JNZ GSPLUP ;DO ANOTHER BIT POP D ;BUMP TO NEXT COUNT OF ALLOCATION VECTOR  ?'s MVI B,11 LXI H,SRCHFCB+1 QSTLP MOV M,A INX H DCR B JNZ QSTLP RET ; MOVENAME LXI H,6DH LXI D,SRCHFCB+1 MVI B,11 JMP MOVE ;MOVE IN MAIN PROGRAM ; GETADD ANI 03H ;GET MOD4 FOR CP/M 1.4 ADD A ;ADD 32 ADD A ADD A ADD STA SRCHFCB LDA 6DH CPI 20H ;IF BLANK GET ALL NAMES PUSH PSW CZ QSTMARK POP PSW CNZ MOVENAME ;ELSE MOVE NAME INTO FCB LXI D,80H MVI C,STDMA CALL BDOS XRA A STA NAMEGD STA NAMECT ;CR AFTER 4 NAMES LXI D,SRCHFCB MVI C,SRCHF ;LF CNZ FENCE MVI A,0 STA NAMEGD JMP DIRLP ; NOFILE CALL ILPRT DB 'NO FILE',0 ; ; ; Determines free space remaining ; DIRDONE LDA SRCHFCB ORA A JZ DEFLT DCR A MOV E,A MVI C,SELDSK CALL BDOS DEFLT MVI C,GETPARM ;CURRENT D INX D JMP GSPBYT ;PROCESS IT ; ENDALC POP D ;CLEAR ALLOCATION VECTOR FROM STACK MOV L,C ;COPY BLOCK TO 'HL' MOV H,B LDA BSHIFTF ;GET BLOCK SHIFT FACTOR SUI 3 ;CONVERT FROM RECORDS TO THOUSANDS JZ PRTFREE ;SKIP SHIFTS IF 1K BLOCKS F A ADD A MOV E,A MVI D,0 LXI H,80H ;ADD DMA OFFSET DAD D RET ; ; ; Parameters used ; GETALC EQU 27 ;CP/M ALLOCATION VECTOR ADDRESS GETPARM EQU 31 ;CURRENT DISK PARAMETERS ADDRESS ; ; ; Unitialized storage ; SRCHFCB DS 33 NAMEGD D    S 1 NAMECT DS 1 BMAX DS 2 ;HIGHEST BLOCK NUMBER ON DRIVE BMASK DS 1 ;(RECORDS/BLOCK)-1 BSHIFTF DS 1 ;NUMBER OF SHIFTS TO MULTIPLY BY REC/BLOCK ; ENDM ; ; MNUMB797.ASM ; ; Telephone number overlay file for MODEM797. ; ; This file can be edited to make a new library of telephone ; numbers for MODEM7. Each entry must be 32 bytes long and ; no more than 26 (A-Z) telephone numbers are allowed. Follo ' DB 'F=Dan Woddard 646-3447' DB 'G=Gasnet NASA 301-344-9156' ;'G' DB 'I=Wayne Hammerly 301-953-3753' ;'I' DB 'J=RBBS Pasadena 213-356-1034' ;'J' DB 'K=David Kozinn 216-334-4604' ;'K' DB 'L=Prow ; the format for the library entries already in the file; be ; sure spaces are used, not tabs. R at the end of a number ; indicates a ringback system. ; ; Procedure for use: ; ; 1) Edit this file for new numbers, ; 2) Assemble the file, ; 3) Ovegram Store 202-337-4694' ;'L' DB 'M=Kelly Smith 805-527-9321' ;'M' DB 'N=SuperBrain Sys 617-862-0781' ;'N' DB 'O=R.L.Plouffe 703-524-2549' ;'O' DB 'P=K.Petersen 313-759-6569R' ;'P' DB 'Q=Bruce Ratoff 201-272-1874' ;'Q' Drlay MODEM797.COM with MNUMB797.HEX using DDT, ; 4) SAVE 64 MODEM797.COM ; ; NOTE FOR THOSE REVISING MODEM7: Check the location of NUMBLIB in ; MODEM7 to make sure the ORG is correct in this file. ; ; ORG 06D4H ; NUMBLIB: ; '----5---10---15---20B 'R=Bill Earnest 215-398-3937' ;'R' DB 'S=SYSOP BBS (pw rq) 313-885-0506' ;'S' DB 'T= ' ;'T' DB 'U= ' ;'U' DB 'V= ' ;'V' DB 'W= '---25-----32' DB 'A=Dave Morgans RCPM 641-7276' DB 'B=Chuck Forsberg RCPM 1-621-3193' DB 'C=CBBS Northwest 646-5510' DB ' 284-5260' DB 'D=BackWater Message 230-1041' DB 'E=No-Name BBS 1-654-9352' DB '  ;'W' DB 'X= ' ;'X' DB 'Y= ' ;'Y' DB 'Z= ' ;'Z' ; '----5---10---15---20---25-----32' ; END ;     AۑӐې-rrsp2M'A= B=Beaverton RCP/M 641-7276C=CBBS/NW 646-5510D= E=Ron Fowler 313-729-1905RF= G= /2*=n''!("@'>2N&:L'2J'>2M'>>2M'FʿQG:&>2&x¼"ʴ̀*G:xʆ\iʿʬ¼:N&ʿ> 9> 9>:9>î>2ÿ>2&ÿ **9:w#"@'G:x/ >:9: QUIT: &#,&!a =$a a !~L FF Q#2 M 9 ô ++File transfer unsucc ʺ Fʂ QG:xʱ iʂ 9 9 f:Z& >2C':&Ģ >B2Z&>:] ʑP'6!&N!& 6 !&F#P ~  #P ~ "F'+#P ~ 0 :I'<2I'#P ~ B 0 6 *F''~ i #\ #~ i "F'!'p \ȇ!o ~¬ #~+] P!e~w#~w\!\l P!u6B#6A#6Kl!l6\: H=Hyde Park 1-312-955-4493I= J= K= L=Dick Lieber 1-312-326-4392M= N= O= P=K.Peters ::=**>22&8!(V:w#9V:w#9>:K'*:uʶu9:ʲw#"@'W:zʥ/u u>:9uu:K'**@': ::=* Memory save buffer full *:͆( 22w&:f&=8J  >J( 2f&f:Z&W >2C'ͻ b >B2Z&:] ʑh x =ͮ:Z&| :S&ʝ File open, ready to receive :f&>¨ >C:f& CRC in effect Checksum in effect  2 h:S\< 2h:W>2!\ :\2!\ \Ë!\ \!\ \<7”2=Ɓo& ] 2h2|w#~w\!\l P~# xɯ2w&2x&:S& Awaiting # en 313-759-6569RQ=R.L.Ploufe 703-524-2549R=Bruce Ratoff 201-272-1874S=SYSOP Sys 1-313-885-0506T=Tech. CBBS 1-313-846-6127U= V= W= X=   x6#}l&)>o(b'b+|;'!'͹!\' P!a ͹!l͹:&    ++File does not exist++ Type "R" to return to modem Type "A" to re-enter name: & Awaiting name NAK P0>!H'5@ *D'\ P"D'G >7 !]~:S&~9sڇ ] #O >:S&,Qsʴ >u:S&ʧ Checksum error P0>H >!\ͻ:S& Awaiting file name ͐  7!]s+ *u&#d (͈H)}:&f2&:f&fsn ++Switching to CHECKSUM MODE++ >C2f&>s ;H7G:V&ʐ:S&ʮx,͕H recv'd, not SOH sҮ>:w&<2w& :V&:S&ͬh" ++Unable to receive block - A Y= Z= !9"'1'h MODEM 7.67 - 07/04/82 $ ͖>2N&/2:L'>2M'>2M':O&X >2:O&G:xʱCY M#!>2N&:O&Eʂ TS R6 D":N&*:] >2N&Q[9,AʐRʴ$ @g- @ʑ# ++File transfer completed++ ô ++File transfer unsuccessful++ ô ++ Transfer cancelled ++ 6# 6 #¾6# Enter file name to be transferred - C/R TO :S&( Time out receiving filename d ʎ O w:S&~9>#}d :S&,ysʎ !\ͻ:S&ʅ Checksum error ͐ څ >s7>2&2H' !g"D'T !\'=$  :f¿ *D'\ P"D'!H'4ÿ !I'5³ !g"D':H'A>@2H'!Iborting++ $:V&:S&ʮ ++ Timeout ++ :w&͕,î:x&F7:V&V:S&ʮ :x& }++Framing error++ :x&ʞ++Overrun error++ :x&ʾ++Parity error++ î:w&͕,s ;HWs ;H/:V&:S&ʮ     ++ Bad sector # in Hdr îz2t&>2&ͮ!s ;Hw,.:f&pQ2&s ;H¯:t&G:u&<s ;Hr_:V&ʙ:S&ʮ ++CRC error++/:V&ʽ:S&ʮ++Cksum error++ />:S&  Send # *u&d (Æ*z&!N"z&:|&<2|&:|&O'\P! %2|&!'"z&"Error writing file $:~xG: ʟ„„~7:ʮ 82x&ͷO:T&:V&:&:U&:V&:&ͷO   >(͕>)_> 9> 9Oa{_ n |d{0|͕}͕͞ ڧ09:Z&µ<ɯ2w&Multiple errors encountered. Type Q to quit, R to retry: Q,p:3b No answer after time-out. Redial? (Y/N/C): Q9[,NYbC/232w} Connection established - Select options: Fv!>9 ¯¯à&!\=$:]EMG:xCTMS R:Z&  ++Bad Opt͈H)>:u&:u&/>2&ͮ!~,+2&yz{mڽG:S&{x,͕H Recv'd, not ACK :w&<2w& :V&ʓ:S&ʘͬ7" Can't send sector -- Aborting $:S&{ Timeout on ACK {:V&:S&FQ1's>:V&:S&0Awaiting initial NAK sCG0CRC request received 2f&::Y&z:M'Æ:X&:M' -::M'-*"J"U"?:!: 2.<22<2%2(<2+]2O& !P& O2L'A>2L'6#[RQ¬~# :Z&>Q2S&*': ~#P:ȯ23w!&~!&Ç Waiting for dial tone >-d͹ ++No dial tone after 10 seconds++ 7 !4'PP > > > ion++ :m  Re-enter PRIMARY option and file name only: &#ú:m c>2>2N&/>2N&: Enter New Baudrate: !e6Q ›,-0ڍ:ҍwO9#Í!"O*yO}o|g|g}!o"ͷͷ*T]*|>!g&s>  Routine cancelled >B2Z&*u&#"u&}:Z&ʈ\<File exists -- Type 'Y' to erase: Q9[Y,\ No file specified \<"Error - Can't make file Directory is likely full $#\*}"~&!&:f&:O&R‚&:V&2S&:Z&:S&Z!]<PP Transferred :\2B'!\͹:B'2\!g&t&P:C' : >2&2N&/2:V&ʝ:S&ʽ All transfers completed :Q& ++Press RETURN to disconnect++   ++Disc>$ ',Enter number or library letter - Type C/R when finished, CTRL-X cancels while dialing: &#:&!&A~ʛ ʼÎ!4{ʰ~ ¦&pP:&_!&~' #FQ#*-t&P![&P& P>2/2&:D! CPM - Exit to CP/M DEL - Delete present file (From Terminal mode) RET - Return to Terminal mode - no loss of Data WRT - Write file to disk (From Terminal mode) : CAL - Dial Number DSC - Disconnect "}ɯ2h\<'"Can't open file$:Z&3:S&File open, size: *~&d (͈H) sectors \<"Can't close file$:|&=2|&*z&N"z&:y&7'\="++ File read error ++$! yé>2y&y2|&!'"z&onnected++ :͉>C2f&>2&:W&,*1:0>20]-! N)F>@ӑ>6,* G0O]! ~)v>@ӑ>6Ӄ}Ӏ|Ӏ>ӑ>%ӑ Choose One 1 9600 2 4800 3 2400 4 1200 5 600 6 300 $!l\P2|2h  >'$$90R6{ʀ:@> O:'$G$O>-$\>-$i W>-:&2&F͹ڳ$¢2wҼ,â$FQ ¹7">?*>-,>*>]-DIR - Directory listing (may specify drive) XPR - Expert mode Toggle (turns Menu on/off) ^E - Exit to MENU ^R - Stops copy into file (Terminal mode) ^Y - Copies into file (Terminal mode) E - Echo (if in Terminal mode) R - Receive CP/M fil    e S - Send CP/M file T - Terminal mode (optional file name)  DEFAULT DRIVE: A9 Command: &#,&"CPM:"DIRp""RETڬ!:J'2R&*@'*:!"DSC""BYE:""WRTҚ""XPR""DELv":!"CAL!> 2& ":$w#$~*%# %%-%~*)%#%-%6?#-%&!\=$!,&͹:l2,&:m %%&2M&,&%%~ʼ%~¼%#%PP | :M&<2M&,,&%s%NOT FOUND,>? !-&w#%!m-& P_( COPYRIGHT (C) 1977 DIGITAL RESEARCH 112O02Z0̀%!"K2.>2.*M0"$/̓%!"":g0i!"P0"R0"2:0v: 0$  :[0-ʬ+ʬ* :[0!_0M!f0P p  !   :O0Ĝ!":O0:0 : 0 -Ͳ !/6+:.;?*$/*."$/?"$/:.l*.^#V{r+s5*.^#V ʓ:. r+s!06#wÚ> 209!e/~6![0~6". :0: 0,!0699*.~6 *.: 0,Ĵ".2f/*.s#r2&!""ͺà: ++Disconnected++ : Goodbye, happy up/down loading ps* 5%D!:' 'b>2N&/2!'͹:N&:' *@'8Y>2N&/2!'͹:/2F#""7SRTEM~""#">#"7!:,&&@&A2'& DRIVE 6?#-%&!\=$!,&͹:l2,&:mADOQRSVT01ADOQRSVT01BC''Invalid option  | :M&<2M&,,&%s%NOT FOUND,>? !-&w#%!m-& P_*V0}|<r ͪ*|Ĵ:O0_͑H *V0"Ù*V0"E V» ͪ»**»"Ù*K0"X0!0NA#~' ~p"K0*K0N"X0!0q#*w œ:0!x ͜ *V0*R0:_0̍"V02*M0r; !:r [02e/*.#"X0$<5ͬ*$/"M00:T/2:/2[0 v>20*.".2[0v*R0m "R0͍"R0!/w >=G*R0*I0"R0"R0 m :/ }>͞ ¥͢ :O0*V0*ʿ͜">2:O0:0:O0!!4:0: 0,##կ# #N#N#ʄ#ʖ## #G#4+~#ڻ#px($###G~wm#+xF6 t#r##4#>($> ($>($#>#($> ($> ($#G>#($> ($> ($x#($¯##>($5#> ($> ($#> ($> ($F##> w##$#$a!:,&&@&A2'& ++Bad library number called++ $&͹:l2,&:,N'!k-$[M&/$J [MA&[D 7&Bs% '> ':%'_!% '6 4ɯ2%2]02e02d02g02%:\:0F: 0e%;m ">2:0b: 020 W,F:0b: 0e,ʹ:re*X0#![0~ʇww2/ͬ:2T/-"."$/2/>2.v:.ʸ!/6+͕%>20:.ʮ:.0209$<!5*}Ģ*V0":0>"4:O0: 2\0:0=: 0 F!Fʹ%*X0"`0>2Z0*X0":0k: 0T!T:\0¦:O0¦:0=ʦ ʦ*"X0 !':[0'Tx»!Z04TT!Z05T:\0!":]0!**V0":O0*X0~ Ĵ* ${ $_* $*4$* Oͷ$#^#6 $$ ʣ$ u$ $ ʣ$ …$u$ ʣ$ $$ ʣ$ $#% %6# > $>$ > $>$w#$:$_@w# . y: 0:yv! X! ^#fkX _~ 0^ Z   2 5 8  :0‰:0=ʉG! 0ʃF#2sÖ*I0| E2V ,[ ͊m *R0"R0"P0 m E2D2V ,ʾ ͊:/ m :/ "> 2/:ĮX06 '>#G*I0!" :0 :Z0 !0N*K0:O0Ÿ"b0+"X0yʛ 'É' Ͳ >ͮ 222:0: 0 !ͮ-:0    :0!4 :0& : 0::0!xI !4̨ e ::̮>͞ } !~5:Į ͵ !4̨!~5 G!~Ҩ4_!p!~ʮ5^!~> >2\0:0N *K0"+"X0:0 >''!: 'd ! ^#V#*0}o|g*  ":D x=D y0P 2!0^4! 0q :0Ė: 0,; Ė*I0m |}$† ͌oy Ԍ͋ 8O͖ Ăy01y 1m X:0 : 0, >C͘%:0 : 0 v;:0P'!5^!/~ !~620͕%2.|z}z> u!.~w:.W=*u!.4C*V0^#V"V0ý!.5¯:20͕%!^4!/w>R͘%>V͘%>Dý>Pý>Lý>Oý>Bý>Sý>N͘%2 yU`:10_!~0!1s! ~͔ yU!1~N=w_! ~QZP>2 ypP͘% >U̘%>: 2 3>E͘%0N : 0,N :0 >  > !0N#~' ) > ''*K0"V0:\0x ʹ:\0" m }*K0"+"X0''*K0"V0>"4ͬ:2T/:[0 “ 2/-*M0"$/*X0!{#zڿ ~+"X0*M0+"M0wß #"K0*M0".:\0 N]T s#r+*V0*{_zW".:\02.R   : 0 v-!v !v-ʹ {ozg:.7ͮ2Z0!O0~4l!"*|>"V0*""J͊!/6 !/͒%:^0ʏ>2.͡%ͱ*K0*T0&*M0*T0&\ ͍!/w#õH USE FACTOR !/͒%*"P0Þ%z{*P0"R0*"V0 !":O-!2~B6~44O!! s#r!1~ _6^4! w!p!2~~!55N!! N#fiooo&)^#fk9BIO[ov ͌z{>ɯo>g͌"!6ů{_zW5>óf:.O*.~H:.=!4>͕%0:/#".R͆%2G:0xa{_ ʇ ʇ:0x҇_<20!/w:e/S:e/9ɯ2f/2d/2e/:0:e/ !2f/g/~#»S͉!f/~4!g/_:e/w2e/ɯ<*V0"36   % *I0:/ ͪ% ͬ:O0ĭ%  :.ʢ :0¢ *K0+"X0!2<20*#"" : 00Ĩ!??" 09"K0+"X0$< :0¢ : 0,? ʹ  *} :]0 :O0 :0 ͤ%:e0ĭ%:0 : 0  ͬͧ%vʹ 0Ģ*R0̜*R0ĜG:O0xě%:/ *R0̍:xz*P0#"P0E2D20:b!^4!/wjj*R0!6zz{z4A_A?ɯ2.2*T0"V0!.8w# *V0*K0{zҤ*b0+"X0 =$*)D*OxG !?DM!xGyO23)#͌)=R|g}o=^͌͌roz{͉͌͌}|͉͌Þ͌Þ͌ë͉͌!!o#Ã͌zg{o͌zg{o͌zg{*"V0ɯ2!4!f/6".!f/~55!d/^4!g/~f:.:e/JGwf^l͗^{:e/&{!f/4#ww&ʞGʱ2e/xf͗ :e/&ʕ:0  ý͗&{&{ý͗  !e/~&>62/-!.6*M0"$/B".2f/*"V0͗ 2f/2e/2[020  ͺ :0: 0 !;* _!5 ^#fkS \ h n 2 ͠ ͻ ͵ ͠ ͖ 8{ Ăy0 2͵ ͖ Gͻ ͋ ͖ 1ͻ ͯ 2ͯ ͖ (Ăy 2͵ ͋ ͖ ͖ Ăy0 ͖ 2ͯ 1*X0#Þ!.*V0".#"X0$:d0<:0<! 0~?<#ʐ: 0͡!.".^#V"V0}{##~2.*.^#V#"."V0*V0}d##~<2.G*V0##"X0:.> u!.~w>w> u:.oolo&3:0: 0 ;!,ɯ2122=2 !"I0&q!1~\5_! ~͔D:2:/ *!"I0:/ :0:0! 0^#=ʙV¨*0!҂ :0:0& !!>O: >> 2͕%>20ɯ202!0~@$6^4#:[0w~$w:[00 6:[0A:[0?e@eAɷP6 o2[0:Z0ʦ:\0 :O0¦:[0':[0 !20:[0 R;/>20:Z0?:\0:O0?́;B*`0*X0++{z~     ++!+"X0:Z02Z0́ͪ'2Z0X:[0*K: ḰͪX? X́ö20Pg>ã6r>ã:[0'ƒ2[0>ã ¡:.ʔ>+2/͕%!/6 >20>20:[02́:0:Z0: 0=!EQ<!LT:[0=!LE>!GT:[0=!GE2[0" 0!04 =;>?>P?<=?>>=<<i;m=>c==>o>v<=<;8?N!Nw#w#W!"V0!.w#w#l2N!.~4^!.~w!.ͼ!.ͼ!.ͼ!/~w!$/ͼ!D/~w!T/~wN#Fp+q!.~^!.!. !. !. !/!$/ !D/!T/&À# $b${$*!:!X!!M"p"""""4#\#j# ()*+,-/ABCDEHLMDBDIDSDWEIEQGEGTIFINLELTNEORSPACIADCADDADIANAANDANICMACMCCMPCPIDAADADDCRDCXENDEQUHLTINRINXIRPJMPLDALOWLXIMODMOVMVINOPNOTNULORAORGORIOUTPOPPSWRALRARRETRLCRRCRSTSBBSBISETSHLSHRSTASTCSUBSUIXORXRAXRIASE0000000000000000000@@@@@@@@@@@@@@@@AA AAQQQ"Q'Q,Q1Q6a20![0:0/ʦg¦´/ʦA¦:[0O<QA>HHR>22[0m:B_>fD> j!052!"0!0N#~#A҄0Æ7O!~*0!ʩң)Ú "0 x:[0 '¦́'æ:[0 :[0,;%:[0 !:[0; ,5~wN#Fq#p>BØ%!0" * F#%2NG*V0##~w*V0##~<͉:.t!.N!. yq~t +a *\ ?=)$=)w#Ž&!\60 ڱ&>GO#w ³&>O # &6 &6L#6I#6B#w2|r&\u'>2]0!"%![0~2%wG&!,x&>202́/>20:[02́:0G:0::0l:[0'́:[0' 20/:[0'|>20^—́:[0  <¨!~4 >¼!~5 : >20>V>O>I>B͘%!0^*K0"V0*M0{z"K0!N"O1#w#w*V0!NN*O N#Fr+sq#p0U>G=#w#wY*M0!0n& {ozg"V0!K0{#z"M0b*M0!0N#yʢ ~Õb!."O1:N *M0!$/{#z"V0$ _!.*V0~#~1 ~#"M0û1 !͒%Þ%SYMB<& #*)&# PP%27&#(&#  $ %*%"$  NZZ NCC POPEP M x#_BH!™# 0#³# £#{ڽ#KÅ#CÅ#<: 0 JCR:0 $# $! 06 p#! 0$#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%:\!QéÉ $ ? H Y ` e Ò ü ò ~ÏGÇåûfD?<==:e>?; ><>; ;<=R>>>F>;>G==<==>=s;=P=*>=$?P:-?]>*<<==<;=>>y> ;:OL TABLE OVERFLOW G*V0##~w*V0##~=*V0_###1 s#r1 ^#V1 ##"X0P wP ~O!0~z 6~=ͼ !0N#~ͼ „ Ͳ O2Ny2^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&*%*%#"%~O 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.2 TITLE 'CP/M MODEM PROGRAM Version 7.97 12/27/82' ; ;THE FOLLOWING IS AN EXTENSIVE REVISION OF THE CP/M MODEM PROGRAM ;CREATED BY WARD CHRISTENSEN FOR THE CP/M USERS LIBRARY. IT ALSO ;INCORPORATES ROUTINES FOUND IN THE POTOMAC MICRO-MAGIC MODEM ;M ;##### as a reference for directly setting the modem equates ##### ;##### and configuration options with the S command in DDT. ##### ; ;Fix log in MODEM797.HIS ; ; MACLIB MODEM797 ;Contains the CMDLINE, INBUF, INLNCOMP, ;DIRLIST, SEND!<-x&G:%7*$*x*7*x2*Ϳ'5*9**&*&w#"&!F)`&!"&*&%~ʅ*B&Œ*`*G&`*!S-x&ö,͟**>&*@&w#">&!F)l&!">&*@&&`*_!%~ .WƐ'@'Õ*>:͕*!%^Ww*%{-|-}--{?.!%~#-6.-> ͕*> ͕*͞*> ͞*wsANUAL WHICH MAY BE USED IF YOU HAVE A PMMI MODEM BOARD. ; ; ********* N O T I C E S ********* ; ; Revisers releasing new versions should only ; change the version number by 1 digit in the ; last place. ; ; Except for PMMI routines, revisers shTIME, PRTBAUD, and MFACCESS ;routines. ; ;Note that the library has not been changed since version 7.97. ; ; TRUE EQU 0FFH FALSE EQU 0 ; CPM2X EQU TRUE ;TRUE IF CP/M 2.X DBUFSIZ EQU 16 ;BUFFER SIZE FOR FILE TRANSFER IN KBYTES ; ERRCRC EQU 6*2%*b0}!,~ +*#+> *>#**> **b0~>+*#2+> *> *> *}2%!%*O*:/ :O0:%y*:%!O0•+:e0!]0+~,:/ ,!/~ +:f0,:/++:_0,+:/#,:/ ,:_0=+!/~ +!0s!%~!%*4:0!/,G~Y+ould ; only make nonspecialized changes for ; distribution. Please make configuration files, ; such as MCNFG7xx.ASM and MCOSB7xx.ASM, for ; particular computers, uarts or modems. ; ; ********************************** ; ;##### This file requir ;NUMBER OF TIMES TO TRY CRC MODE BEFORE ;SWITCHING TO CHECKSUM ERRLIM EQU 10 ;NUMBER OF TIMES TO RETRY ;SEND/RECEIVE ERRORS BEFORE QUIT ; ; PMMI EQUATES PORT EQU 090H ;PMMI BASE ADDRESS ; MODCTLP EQU PORT+1 ;MODEM CONTROL PORT MODDATP EQU#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 Nes MODEM797.LIB and MAC.COM to assemble. ##### ; ;##### The file MCNFG797.ASM can be used to overlay the HEX ##### ;##### or COM file versions with your own modem routines and ##### ;##### configuration options. The file MODEM797.SET can be used #####  PORT ;MODEM DATA PORT BAUDRP EQU PORT+2 ;BAUD RATE PORT MODCTL2 EQU PORT+3 ;2ND MODEM CONTROL PORT MODRCVB EQU 02H ;MODEM RECEIVE BIT (DAV) MODRCVR EQU 02H ;MODEM RECEIVE READY MODSNDB EQU 01H ;MODEM SEND BIT (XMIT BUFF EMPTY) MODSNDR EQU 01H     ;MODEM SEND READY NOPARMSK EQU 10H ;MASK TO RESET TO NO PARITY EVPARMSK EQU 20H ;MASK TO SET EVEN PARITY ODPARMSK EQU 0CFH ;MASK TO SET ODD PARITY BRKMSK EQU 0FBH ;MASK TO SET BREAK ERRCDMSK EQU 38H ;MASK TO BLOCK ALL BITS EXCEPT ERROR CODES FRMER RIAGE RETURN XON EQU 'Q'-40H ; ^Q = XON CHARACTER XOFF EQU 'S'-40H ; ^S = XOFF CHARACTER NAK EQU 'U'-40H ; ^U = NOT ACKNOWLEDGE CAN EQU 'X'-40H ; ^X = CANCEL SEND/RECEIVE EOFCHAR EQU 'Z'-40H ; ^Z LSE ;true=convert backspace to rub TOGGLEBK: DB TRUE ;true=allow toggling of bksp to rub ADDLF: DB FALSE ;true=add LF after CR TOGGLELF: DB TRUE ;true=allow toggling of LF after CR TRANLOGON: DB FALSE ;true=allow transmission of logon ;write logo4800 8=9600 BYTDLY: DB 0 ;default time to send character in ;terminal mode file transfer ;0=0 delay, 1=0.02 sec, -- ,9=0.18 sec CRDLY: DB 0 ;default time for extra wait after CR ;in terminal mode file transfer ;0=0 delay, 1=0.02 secEQU 20H ;FRAMING ERROR MASK ORUNER EQU 10H ;OVERRUN ERROR MASK PARER EQU 08H ;PARITY ERROR MASK ANSWMOD EQU 1EH ;ANSWER MODE ORIGMOD EQU 1DH ;ORIGINATE MODE WAITCTS EQU 255 ;NUMBER OF SECONDS X 10 TO WAIT FOR COMPUTER ;TONE AFTER PMMI AUT= END OF FILE BDNMCH EQU 75H ; BAD NAME MATCH RUB EQU 7FH ; RUB ; BOTTRAM SET LAST+100H AND 0FF00H ; ORG 0100H ; JMP START ; ;THESE ROUTINES AND EQUATES ARE AT THE BEGINNING OF THE PROGRAM SO ;THEY n sequence at location LOGON SAVCCP: DB TRUE ;true=do not overwrite CCP LOCONEXTCHR: DB FALSE ;true=local command if EXTCHR precedes ;false=not local command if EXTCHR precedes TOGGLELOC: DB TRUE ;true=allow toggling of LOCONEXTCHR LSTTST: DB TR, -- ,9=0.18 sec BELRPT: DB 30 ;bell repeat time = value*0.03 sec EXITCHR: DB 'E'-40H ; ^E = Exit without disconnect LOGCHR: DB 'O'-40H ; ^O = Send logon LSTCHR: DB 'P'-40H ; ^P = Toggle printer UNSAVECHR: DB 'R'-40H ; ^R = Close input text buffer O-DIAL FUNCTION 255 MAX. ; CRC EQU 'C' ;USED TO REQUEST 'CRC' INSTEAD OF 'CKSUM' ESC EQU '['-40H ; ^[ = ESCAPE SOH EQU 'A'-40H ; ^A = START OF HEADER EOT EQU 'D'-40H ; ^D = END OF TEXT ACK EQU 'F'CAN BE PATCHED BY A MONITOR OR OVERLAY FILE WITHOUT RE-ASSEMBLING ;THE PROGRAM. ; PMMIBYTE: DB FALSE ;true=PMMI modem SETUPTST: DB TRUE ;true=non-PMMI setup routine SCRNTEST: DB FALSE ;true=if home cursor and clear screen ;routine at CLRSCRN CLUE ;true=allow toggling of printer on/off ;in terminal mode. Set to false if your ;printer can't keep up with the modem XOFFTST: DB FALSE ;true=allow testing of XOFF from remote ;while transmitting a file in terminal mode XONWAIT: DB FALSE TRANCHR: DB 'T'-40H ; ^T = Transmit file to remote SAVECHR: DB 'Y'-40H ; ^Y = Open input text buffer EXTCHR: DB '^'-40H ; ^^ = Send next character ; ;Equates used only by PMMI routines grouped together here. PULSERATE: DB 125 ;125 for 20pps, 250 for-40H ; ^F = ACKNOWLEDGE OKNMCH EQU 'F'-40H ; ^F = OKAY NAME MATCH BELL EQU 'G'-40H ; ^G = BELL CHARACTER BKSP EQU 'H'-40H ; ^H = BACKSPACE LF EQU 'J'-40H ; ^J = LINEFEED CR EQU 'M'-40H ; ^M = CAROCK: DB 5 ;clock speed in MHz, 8 MHz maximum BAKUPBYTE: DB FALSE ;true=make .BAK file CKSUMDFLT: DB FALSE ;true=default to Checksum checking ;false=default to CRC checking TOGGLECRC: DB TRUE ;true=allow toggling of Checksum to CRC CONVBKSP: DB FA ;true=wait for XON after sending CR while ;transmitting a file in terminal mode TOGXOFF: DB TRUE ;true=allow toggling of XOFF/XON testing MSPEED: DB 1 ;sets the display time to send a file ;0=110 1=300 2=450 3=600 4=710 5=1200 ;6=2400 7= 10pps on PMMI ;not used if PMMI FALSE CLDBOOT: DW 00000H ;currently set to warm boot with ;BYE routine for PMMI, put your cold ;boot entry here if you have one and ;desire to do on BYE BRKCHR: DB '@'-40H ; ^@ = Transmit "BREAK" with     PMMI CHGBAUD: DB 'B'-40H ; ^B = Used with PMMI in terminal ; mode to change baud rate on fly DISCCHR: DB 'D'-40H ; ^D = PMMI Disconnect ; ; IN$MODCTLP: IN MODCTLP ! RET ;in modem control port OUT$MODDATP: OUT MODDATP ! RET ;out modem data port0 RET CLRSCRN: CALL JMP$ILPRT DB ESC,'E',0,0,0 RET ; ;NEXT THREE LINES SHOULD NOT BE CHANGED BY USER OVERLAY JMP$ILPRT: JMP ILPRT JMP$ILCOMP: JMP ILCOMP JMP$INBUFF: JMP INBUFF JMP$SYSVER: JMP SYSVER JMP$DIALPL: JMP DIALPL JMP$DISCONNT: JMH ;SET DUNFLG TRUE STA DUNFLG ; GETBD: MVI C,09 ;BDOS PRINT MSG LXI D,BRMSG ; CALL 05 ;DO IT MVI C,01 ;BDOS INPUT CALL 05 ; MOV B,A ;SAVE INPUT VALUE SUI '0' ;CHANGE FROM ASCII MOV C,A ;SAVE VALUE CPI 07 ;IS IT VALID? JNC GETBD ;IF NOTF,LF DB ' 1. 9600 BAUD',CR,LF DB ' 2. 4800 BAUD',CR,LF DB ' 3. 2400 BAUD',CR,LF DB ' 4. 1200 BAUD',CR,LF DB ' 5. 600 BAUD',CR,LF DB '  IN$MODDATP: IN MODDATP ! RET ;in modem data port ANI$MODSNDB: ANI MODSNDB ! RET ;bit to test for send ready CPI$MODSNDR: CPI MODSNDR ! RET ;value of send bit when ready ANI$MODRCVB: ANI MODRCVB ! RET ;bit to test for receive ready CPI$MODRCVR: CPI MOP DISCONNT ; SYSVER: LDA PMMIBYTE ;USING THE PMMI S-100 MODEM? ORA A JZ SYSVER1 ;GO IF NOT CALL ILPRT DB 'Version for: PMMI S-100 MODEM Starting at Port ',0 LDA IN$MODCTLP+1 CALL HEXO CALL ILPRT DB 'H',CR,LF,0 RET ; SYSVER1: CALL ASK AGAIN MVI B,8 ;SPEED CODE LXI H,10 ;VALUE FOR 9600 BAUD BDLOOP: DCR C ;COUNT DOWN JZ DOIT ;DONE SET BUADRATE DAD H ;DOUBLE COUNT DCR B ;DECREMENT SPEED CODE JMP BDLOOP ;REPETE UNTIL DONE DOIT: MOV A,B ;GET SPEED CODE CPI 5 ;CHECK FOR S 6. 300 BAUD',CR,LF,LF,LF DB '$' CHGMSPD: ;CHANGES MSPEED BY LOOPING BACK INTO INITMOD JMP GETBD ; ;DIALING ROUTINES TAKEN (AND GREATLY MODIFIED) FROM PMMI MANUAL. ;MODEM CONTROL COMMAND WORDS ; CLEAR EQU 3FH ;IDLE MODE MAKEM DRCVR ! RET ;value of receive bit when ready ; ;THE FOLLOWING ARE TYPICALLY USED ONLY BY PMMI IN$BAUDRP: IN BAUDRP ! RET ;in baudrate port OUT$BAUDRP: OUT BAUDRP ! RET ;out baudrate port OUT$MODCTL2: OUT MODCTL2 ! RET ;out modem control port #2 OUT$M ILPRT ;IF NOT USING THE PMMI S-100 BOARD DB 'Version for: Non-PMMI MODEM',CR,LF,0 RET ; ;INSERT YOUR LOGON HERE, MUST END IN 0. LOGON: DB 'MODEM7.97 iPDS 1/13/83',CR,LF,0 ; ;INSERT YOUR INITIALIZATION ROUTINE HERE IF NEEDED. ;CAN REPLACE THE LOW JC BD300 ; JZ BD600 ; JMP IT ;ELSE DON'T CORRECT BD300: MVI A,1 ; JMP IT ; BD600: MVI A,3 ; IT: STA MSPEED ;SET SPEED MVI A,40H ;RESET 8251A OUT 91H ; MVI A,36H ;8253 MODE COMMAND OUT 83H ; MOV A,L ;GET LSB OF BUAD RATE OUT 80H ;EQU 1 ;TELE LINE MAKE (OFF HOOK) BRKM EQU 0 ;TELE LINE ON HOOK (BREAK DURING DIALING) DTMSK EQU 1 ;DIAL TONE MASK RBLMT EQU 70 ;# OF SEC*10 TO WAIT BEFORE GIVING NO RING HEARD MSG RBWAIT EQU 50 ;# OF SEC*10 DELAY BEFORE REDIALING NUMBER TMPUL EQU 80H ODCTLP: OUT MODCTLP ;out modem control port STA UARTCTLB ! RET ;and store control byte ; LOGONPTR: DW LOGON JMP$INITMOD: JMP INITMOD JMP$SETUPR: JMP SETUPR ;Clear sequences are for H19. Change to yours. CLREOS: CALL JMP$ILPRT DB ESC,'J',0,0,FOLLOWING SECTION WHICH IS PRESENTLY ;USED FOR THE PMMI BOARD. ; INITMOD: JMP AROUND ;LEAVE SPACE FOR FLAG DUNFLG: DB 00 ;SET INITIAL VALUE TO 0 AROUND: LDA DUNFLG ;GET DONE FLAG ORA A ;TEST IF DONE BEFORE RNZ ;IF DONE DO NOT REPETE MVI A,0FF MOV A,H ;GET MSB OUT 80H ;SEND IT ALSO MVI A,0CEH ;MODE WORD FOR 8251A OUT 91H ; MVI A,25H ;COMMAND FOR 8251A OUT 91H ; RET ; BRMSG: DB ' Baud Rate Initialization Routine',CR,LF,LF DB ' Choose one by number',CR,L;TIMER PULSES MASK BIT TRATE EQU 250 ;VALUE FOR 0.1 SECOND ; DIALPL: LDA PMMIBYTE ;FLAG FOR PMMI OPERATION ORA A ;SET FLAGS RZ ;PMMI FALSE, RETURN XRA A ;0 STA CRFLAG ;CONTINUOUS REDIAL FLAG DPL1: LXI H    ,CMDBUF+1 ;POINT # OF CHARS IN BUFF MOV A,M ;GET # OF CHARS CPI 4 ;4 OR MORE CHARS TYPED BEFORE ? JC ENTNUM ;NO, ASK FOR NUMBER LXI H,CMDBUF+6 ;POINT TO NUMBER TO DIAL JMP DIAL10 ;CHECK IF LIB #, & DIAL ; DIALPL0:  ;START WITH CRLF STAX D ;+LF INX D ;AND BUMP IT ENTNUM1: MVI B,32 ;NUMBER OF BYTES TO MOVE CALL MOVE ;MOVE TO BUFFER CALL SPACES ;2 ENTRIES + 3 SPACES = 67 CHARACTERS MVI B,32 CALL MOVE CALL NEWLINE DCR C ;NUMBER OF26 ;NUMBER OF LETTERS IN ALPHABET MOV A,M ;GET CHAR BUFFER DIAL11: CMP B ;NUMBER FROM TABLE? JZ LIBSET INR B ;MAKE NEXT LETTER (A-Z) INR E ;COUNT UP DCR C ;COUNT DOWN JZ DIALLPX ;NOT A LETTER JMP DIAL11 ;LOOP ; LIBSET: LXI H,NUMBLIB ;PGS JNZ NOBLMSG ; ; PRINT BAD LIBRARY MESSAGE AND ABORT IF NULL ENCOUNTERED DIALLPA: CALL ILPRT DB CR,LF,'++ Bad library number called ++',CR,LF,0 JMP BORTIT ;ABORT ; ; DIAL A DIGIT, CHECK KBD FOR ABORT ; NOBLMSG: CALL DIAL ;DIAL IT CALL CALL DISCONNT CALL ILPRT DB CR,LF,'Waiting for dial tone',CR,LF,0 MVI A,MAKEM ;MAKE MAKE (OFF-HOOK) CALL OUT$MODCTLP ;DO IT MVI D,DTMSK ;DIAL TONE MASK MVI C,100 ;10 SECOND WAIT CALL WAIT ;WAIT FOR DIAL TONE NOP  LINES TO PRINT JZ ENTNUM2 JMP ENTNUM1 ; ENTNUM2: MVI A,'$' STAX D CALL CLRTST MVI C,PRINT LXI D,DBUF ;POINT TO TABLE OF NUMBERS TO PRINT CALL BDOS CALL ILPRT DB CR,LF,'Enter number or library letter - when finished,' DB CR,LF,HONE NUMBER LIBRARY LXI B,32 ;LENGTH OF LIBRARY ENTRY MOV A,E ;NUMBER OF TIMES TO ADD 32 TO HL ORA A ;SET FLAGS JZ DIAL13 DIAL12: MOV A,M ;GET FIRST CHAR OF SELECTED LIB ENTRY ORA A ;SET FLAGS JZ DIALLPA ;SEND BAD LIBRARY MSG AND ABORT DADSTAT ; KEYPRESS? ORA A ;SET FLAGS CNZ KEYIN ;YES, GO GET IT CPI CAN ;^X? JZ BORTIT ;YES, ABORT INX H ;BUMP POINTER PUSH D ;SAVE DE PUSH H ;SAVE HL MVI B,1 ;WAIT 1 TIME INTERVAL CALL TIMER POP H ;RESTORE HL POP D ;RESTORE DE DCR E ;C ;DELAY ; ; WAIT SUBROUTINE WILL RETURN WITH CARRY SET IF UNABLE TO ; GET DIALTONE, ELSE CARRY NOT SET MEANS DIALTONE RECEIVED ; RNC ;IF DIAL TONE WITHIN 10 SECONDS CALL ILPRT ;ELSE, MESSAGE AND RETURN WITH CARRY SET DB CR,LF,'<< No dial'Ctrl-X cancels while dialing: ',0 LXI D,CMDBUF CALL INBUFF DIALLP1: LDA CMDBUF+1 ORA A ;NULL MEANS WAS TYPED JZ BORTIT ;ABORT DIALING, RETURN TO MENU LXI H,CMDBUF+2 ;FIRST TYPED CHAR OF NUMBER TO DIAL ; ; ENTER THIS ROUTINE WITH HL POI B ;INCREMENT HL BY 32 DCR E ;COUNTDOWN JNZ DIAL12 ;NOT THERE YET, LOOP DIAL13: MVI B,32 ;NUMBER OF CHARACTERS TO GET FROM TABLE LXI D,CMDBUF+1 ;POINT TO BUFFER XCHG ;HL POINTS TO CMDBUF+1 MOV M,B ;STORE # OF BYTES IN A TABLE ENTRY XCHG ;ROUNT DOWN CHARS IN BUFF JNZ DIALLP2 ;NOT DONE, LOOP JZ DIALDN ;DIALING DONE DISCONNT: XRA A ;0 CALL OUT$MODCTL2 ;CLEAR DAV, ESD, ETC CALL OUT$MODCTLP ;HANG-UP PUSH B MVI B,8 ;WAIT FOR PMMI TO DISCONNECT CALL TIMER POP B RET TIMER: M tone >>',CR,LF,0 CALL DISCONNT STC RET ; ;THIS IS ALL THE SET-UP FOR THE PRINT AT 'ENTNUM2'. ; ENTNUM: MVI C,13 ;NUMBER OF LINES TO MOVE LXI H,NUMBLIB ;ADDRESS OF SOURCE MEMORY LXI D,DBUF ;ADDRESS OF TARGET MEMORY CALL NEWLINENTING TO NUMBER TO DIAL ; DIAL10: PUSH H ;SAVE HL CALL DIALPL0 ;DISCONNECT, RECONNECT, WAIT FOR DIAL TONE POP H ;GET HL JC DILAGN ;NO DIALTONE?, ASK RETRY MVI B,'A' ;FIRST LETTER OF ALPHABET MVI E,0 ;COUNTS NUMBER OF LETTERS TO MATCH MVI C,ESTORE REG. INX D ;POINT TO FIRST CHAR POSITION IN BUFFER CALL MOVE ;MOVE TABLE ENTRY TO BUFFER DIALLPX: LDA CMDBUF+1 MOV E,A ;NUMBER OF CHARS IN BUFF LXI H,CMDBUF+2 ;POINT FIRST CHAR DIALLP2: MOV A,M ;GET FIRST # FROM BUFFER ORA A ;SET FLAVI A,TRATE ;TRATE 250, VALUE FOR .1 SEC INTERVAL CALL OUT$BAUDRP ;B-REG CONTAINS NUMBER OF .1 SEC INTERVALS TIMES: CALL IN$BAUDRP ;TO COUNT ANI TMPUL JZ TIMES ;WAIT FOR TIMER TO GO HIGH TIMEE: CALL IN$BAUDRP ANI TMPUL JNZ TIMEE      ;WAIT FOR TIMER TO GO LOW DCR B JNZ TIMES RET BORTIT: CALL DISCONNT CALL CRLF JMP MENU ; ;AUTO DIALER ; DIAL: CALL TYPE ;PRINT WHATEVER CHARACTER, DASHES, ETC. CPI 30H RC ;DIGIT MUST BE AT LEAST 0.. CPI 'R' ;COULD IT BE A RINGBAEM CALL OUT$MODCTLP MVI B,2 CALL TIMER RET ; RINGBK: POP PSW ;TO GET IT OFF THE STACK LDA CMDBUF+1 ;GET # OF CHAR IN BUFFER SUI 01H ;SUBTRACT 1 TO AVOID THE RINGBACK CHAR STA CMDBUF+1 ;STORE THE NEW VALUE MVI D,DTMSK ;LOP ;PMMIADDR+2 (MODEM STATUS PORT) ANA D ;(CTS or DIALTONE MASK) RZ ;ACTIVE LOW, SO RETURN ON 0 PUSH B ;SAVE.. PUSH D ;..ACTIVE REG'S CALL STAT ;KEYPRESS? ORA A ;SET FLAGS CNZ KEYIN ;YES, GET CHAR CPI CAN ;^X? JZ WAIT1 ;YES, DISCONNECT, Jafter time-out. Redial? (Y/N/C): ',BELL,0 CALL KEYIN ;GET RESPONSE CALL TYPE ;ECHO IT CALL UCASE ;ANI 5FH CALL CRLF ;NEW LINE CPI 'N' ;REDIAL? JZ MENU ;NO, GO MENU CPI 'Y' ;REDIAL? JZ DILAGN0 ;YES, REDIAL CPI 'C' ;CONTINUOUS REDIAL? JNCK CHARACTER JNZ DIAL1 ;NO? - JUMP PUSH PSW ;SAVE ACCUMULATOR & FLAGS MOV A,E ;GET # OF CHAR LEFT INTO ACC. CPI 01H ;IS THIS THE LAST CHARACTER? JZ RINGBK ;IF SO, IT MUST BE RINGBACK CHAR - DO RINGBACK POP PSW ;EVERYTHING BACK AS IT WAS DIAL1:AD TONE DETECT MASK MVI C,RBLMT ;SET TIMER FOR RBLMT NUMBER OF SECONDS CALL WAIT JC RBTIME ;JUMP IF NO RING DETECTED MVI B,25 ;WAIT 2.5 SEC CALL TIMER CALL IN$BAUDRP ;IS TONE STILL PRESENT? ANA D JNZ RNGBK1 JMP DILAGN ;YES, MMP TO MENU POP D ;RESTORE.. POP B ;..REGS DCR C ;COUNT-DOWN JNZ WAIT STC ;SET CARRY TO INDICATE MASK NOT SET RET ; WAIT1: POP D ;RESET.. POP B ;..STACK JMP DISCON1 ;DISCONNECT ; HANGP: MVI A,CLEAR CALL OUT$MODCTL2 MVI A,0 Z DILAGN ;INVALID RESPONSE, ASK AGAIN XRA A CMA ;0FFH STA CRFLAG ;CONTINUOUS REDIAL FLAG DILAGN0: MVI B,70 ;7 SECONDS WAIT FOR PMMI RESET CALL TIMER ;ELSE BUSY TONE MAY BE SENSED AS DIALTONE LXI H,CMDBUF+1 ;CHECK IF 'CAL LIBNUM' MOV A,M  CPI 3AH RNC ;..AND NOT MORE THAN 9 ANI 0FH ;STRIP ASCII -- COULD ALSO DO SUI 30H ('0') JNZ DIALS MVI A,10 ;CONVERT ZERO TO 10 PULSES DIALS: MOV C,A LDA PULSERATE ;CONTAINS VALUE FOR DIAL SPEED CALL OUT$BAUDRP DIALC: CALL IN$BAUDRP ANI TMPUST BE BUSY ; RNGBK1: CALL HANGP ;HANG UP THE PHONE MVI B,RBWAIT ;WAIT X SEC CALL TIMER CALL DIALPL0 ;GO OFF HOOK & LISTEN FOR DIAL TONE JNC DIALLPX ;GO REDIAL NUMBER JMP DILAGN ;NO DIAL TONE HEARD ; RBTIME: CALL CRLF JMP RNCALL OUT$MODCTLP RET ; DIALDN: CALL CRLF MVI A,07FH ;TURN ON DTR CALL OUT$MODCTL2 ;TIMER RATE? MVI B,1 CALL TIMER ;WAIT FOR MODEM TO TURN ON DTR MVI A,5DH ;2 STOP BITS, NO PARITY, 8 DATA BITS CALL OUT$MODCTLP MVI D,CPI 4 ;MORE THAN 4 CHARACTERS TYPED JC DIALLP1 ;NO, THEN GET MENU CHOICE JMP DPL1 ;YES, THEN USE CAL LETTER ; CONMADE: CALL ILPRT DB CR,LF,'Connection established - Select options: ',BELL,0 DILAGN1: CALL STAT ;KEYPRESS? ORA A ;SET FLAGS JNUL JNZ DIALC DIALB: CALL IN$BAUDRP ANI TMPUL JZ DIALB MAKEP: MVI A,MAKEM CALL OUT$MODCTLP TIMEM: CALL IN$BAUDRP ANI TMPUL JNZ TIMEM MVI A,BRKM CALL OUT$MODCTLP TIMEB: CALL IN$BAUDRP ANI TMPUL JZ TIMEB DCR C JNZ MAKEP MVI A,MAKGBK1 ;HANGUP, REDIAL, & LISTEN FOR CARRIER ; ;TIME OUT ROUTINE. MUST BE CALLED WITH MASK IN D REG FOR INPUT ;AT RELATIVE PORT 2 AND NUMBER OF SECONDS * 10 IN C REG. ; WAIT: MVI B,1 CALL TIMER ;WAIT FOR TIMER TO GO HIGH THEN LOW CALL IN$BAUDR4 ;CLEAR TO SEND MASK MVI C,WAITCTS ;WQAIT TIME FOR CTS (25.5 SEC MAX) CALL WAIT JNC CONMADE ;CONNECTION MADE CALL DISCONNT DILAGN: LDA CRFLAG ;CONTINUOUS REDIAL FLAG ORA A JNZ DILAGN0 CALL ILPRT DB CR,LF,'No answer Z GETCMD ;KEY PRESSED, GO GET OPTIONS MVI A,BELL CALL TYPE ;RING BELL LXI B,2000H DILAGN2: DCR C JNZ DILAGN2 ;KILL SOME TIME FOR TERMINAL TO PROCESS BELL DCR B JNZ DILAGN2 JMP DILAGN1 ;LOOP ; CRFLAG: DB 0 ;CONTINUOUS REDIAL FLAG ; ;     END OF PMMI ROUTINES ; ; ;THE NON PMMI SETUP ROUTINES ARE INTENDED TO COME FROM ;THE USER OVERLAY. THE FOLLOWING IS A SAFETY NET ; SETUPR: RET ; ; PHONE NUMBER LIBRARY TABLE FOR DIALING FROM LIBRARY ; OF NUMBERS STORED IN THESE DB'S AT ASSEMBLY-T1-202-337-4694' ;'L' DB 'M=Kelly Smith 1-805-527-9321' ;'M' DB 'N=SuperBrain Sys 1-617-862-0781' ;'N' DB 'O=R.L.Plouffe 1-703-524-2549' ;'O' DB 'P=K.Petersen 1-313-759-6569R' ;'P' DB 'Q=Bruce Ratoff 1-201-272-1874' ;'Q' DB 'R=Mark Pul ;0 STA SAVEFLG LDA FCB+1 ;IS THERE A COMMAND TAIL? STA OPTION CPI ' ' JNZ START0 ;IF YES, DIGEST IT SUB A STA EXITFLG ;ELSE SAY WE WANT MENU JMP START1 START0: LXI H,80H ;SIMULATE COMMAND LINE INPUT FROM MENU MOV B,M ;SAVE CHAR ISCON1 ;YES, DISCONNECT & GO MENU S1: CPI ' ' ;NO OPTION SPEC'D? JZ MENU ;TRUE, GO MENU CPI 'H' ;MENU ASKED FOR? JZ MENU2 ;YES, GO MENU2 CALL JMP$INITMOD CALL MOVEFCB CALL IN$MODDATP ;GOBBLE UP GARBAGE.. CALL IN$MODDATP ;..CHARACTERS ON LINEIME. ; EACH DB MUST BE 32 CHARACTERS LONG FOR PROPER OPERATION. ; A 'DB 0' INDICATES NO DIALING, PROGRAM WILL DISCONNECT ; AND RETURN TO COMMAND MODE. LAST DB MUST BE DB 0. UP TO ; 26 NUMBERS ARE ALLOWED. ; NUMBLIB: ; '----5---10---15---20---25----ver 1-312-789-0499' ;'R' DB 'S= ' ;'S' DB 'T= ' ;'T' DB 'U= ' ;'U' DB 'V= ' ;'V' DB 'W= ' ;'W' DB 'X=CNT STARTA: INX H MOV A,M ;SKIP OVER LEADING SPACES IN COMMAND TAIL CPI ' ' JNZ STARTB DCR B JMP STARTA STARTB: MOV A,B STA CMDBUF+1 ;STORE COMMAND CHAR COUNT LESS LEADING SPACES INR B ;MOVE 1 EXTRA BYTE (SHOULD BE A NULL) LXI D,CMD XRA A STA ECHOFLG ;RESET ECHO FLAG STA LOCFLG ;RESET LOCAL FLAG LDA OPTION ;PROCESS MAIN OPTION CPI 'E' ;ECHO MODE? JNZ NOECH ;JUMP IF NOT MVI A,TRUE ;SET ECHO TO TRUE STA ECHOFLG JMP DSKSAVE NOECH: CPI 'L' ;LOCAL ECHO MODE JNZ NOLOC -32' DB 'A=Amrad 1-703-734-1387' ;'A' DB 'B=Ben Bronson 1-312-955-4493' ;'B' DB 'C=CBBS Pasadena 1-213-799-1632' ;'C' DB 'D=PMMI 1-703-379-0303' ;'D' DB 'E=Tech. CBBS 1-313-846-6127' ;'E' DB 'F=Ron Fowler 1-313-729 ' ;'X' DB 'Y= ' ;'Y' DB 'Z= ' ;'Z' DB 0 ; end ; '----5---10---15---20---25-----32' ; START: LXI H,0 DAD SP ;GET CP/M'S STACK SHLD STACK ;SAVE IT LXI SBUF+2 CALL MOVE CALL SETFCB ;DIGEST COMMAND LINE AND OPTIONS START1: LDA UARTFLG ORA A MVI A,ANSWMOD STA UARTCTLB JNZ RESTART MVI A,ORIGMOD STA UARTCTLB ; RESTART: LXI SP,STACK;MAKE SURE WE HAVE A CLEAN STACK LXI D,CMDBUF+1 ;MAY B MVI A,TRUE STA LOCFLG JMP DSKSAVE NOLOC: CPI 'T' ;TERMINAL MODE? JZ DSKSAVE ;YES CPI 'S' ;SEND A FILE? JZ SENDFIL ;YES CPI 'R' ;RECEIVE A FILE? JZ RCVFIL ;YES CPI 'B' ;CHANGE BAUD? JZ CHGMSPD ;DO IT CALL NOTVLDMSG ;SAY NOT A VALID OP-1905R' ;'F' DB 'G=Gasnet NASA 1-301-344-9156' ;'G' DB 'H=Dave Hardy 1-313-846-6127' ;'H' DB 'I=Wayne Hammerly 1-301-953-3753' ;'I' DB 'J=RBBS Pasadena 1-213-356-1034' ;'J' DB 'K=David Kozinn 1-216-334-4604' ;'K' DB 'L=Program Store P,STACK ;START LOCAL STACK CALL ILPRT DB CR,LF,'MODEM 7.97 - 12/27/82',CR,LF,0 CALL INITADR ;INITIALIZE ADDRESSES CALL JMP$SYSVER ;GIVE CONFIGURATION MESSAGE CALL GETUSR ;GET USER STA SAVUSR ;SAVE FOR EXIT MVI A,TRUE ;0FFH STA NFILFLG CMAE USEFUL WHERE WE ARE GOING LDA OPTION ;GET MAIN OPTION MOV B,A ;SAVE IT LDA PMMIBYTE ;PMMI? ORA A ;SET FLAGS MOV A,B ;GET OPTION BACK JZ S1 ;NOT PMMI CPI 'C' ;CALL (DIAL) FUNCTION? JZ JMP$DIALPL ;YES, GO TO IT CPI 'D' ;DISCONNECT? JZ DTION JMP MENU ;NO VALID OPTION SPEC'D, GO MENU ; ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE ; DSKSAVE: LDA FCB+1 ;FIRST CHAR OF FILENAME CPI ' ' ;FILE SPEC'D JNZ GOODNM ;YES, GOOD NAME MVI A,TRUE ;0FFH STA NFILFLG CMA ;0 STA SAVEFL    G JMP TERM ; GOODNM: CALL ERASFIL CALL MOVE2 LXI D,FCB3 MVI C,MAKE CALL BDOS LXI D,FCB3 MVI C,OPEN CALL BDOS LXI H,BOTTRAM SHLD HLSAVE XRA A STA NFILFLG STA LISTMOR ;STOP ANY BUFFERED PRINTER OUTPUT TERM: LDA UARTFLG STA O;SEND IF EXTCHR JMP LOCCHK ;OTHERWISE DO LOCAL STUFF NOTEXAFLG: LDA EXTCHR ;TREAT NEXT CHARACTER IN SPECIAL WAY? CMP B JZ EXTFLG ;YES, SET EXAFLG FOR NEXT CHAR LDA LOCONEXTCHR ORA A ;SHOULD WE SEND IF NOT EXAFLG MOV A,B JNZ NOTOG ;YES, IF  BUFFER? CMP B JZ S2A ;IF YES, DISABLE COPY LDA SAVECHR ;OPEN INPUT BUFFER? CMP B MOV A,B ;RESTORE CHARACTER TYPED JNZ NOTOG LDA NFILFLG ;DO NOT ALLOW SAVE IF.. CPI TRUE ;..THIS FLAG IS SET. JZ TERML MVI A,TRUE ;0FFH -- ALLOW COPY INTO GON MESSAGE LOGLP: CALL SENDREADY JNZ NOSENDLOG ;GO IF NOT READY MOV A,M ;GET LOGON BYTE INX H CPI 0 ;IS IT THE END? JZ ENDLOG ;GO IF SO CALL OUT$MODDATP JMP LOGLP NOSENDLOG: CALL EXITTEST ;TEST SO DON'T GET HUNG UP JNC EXITLOG ;GO RIGSAV ORA A MVI A,ANSWMOD STA UARTCTLB JNZ TERM2 MVI A,ORIGMOD STA UARTCTLB TERM2: LDA LISTMOR ;ANY BUFFERED PRINTER OUTPUT? ORA A CNZ GOLIST ;GO IF SO CALL STAT ;KEYPRESS? JZ TERML ;NO, CHECK LINE CALL KEYIN ;GET CHAR FROM KBD LOCONEXTCHR TRUE LOCCHK: LDA EXITCHR ;RETURN TO MENU? CMP B JZ EXITMEN ;YES, RETURN TO MENU LDA TRANCHR ;OUTPUT TEXT FILE TO REMOTE? CMP B CZ TRANSFER ;SEND-A-FILE (BLIND SEND) JZ TERM2 ;LOOP LDA TRANLOGON ORA A JZ SKPLOGON LDA LOGCFILE JMP S2B S2A: MVI A,FALSE ;0 -- STOP COPY INTO FILE S2B: STA SAVEFLG CALL BUFMSG JMP TERML ; BUFMSG: CALL ILPRT DB CR,LF,LF,'** Memory buffer ',0 LDA SAVEFLG ORA A JZ BUFMSG2 CALL ILPRT DB 'open **',CR,LF,LF,':',BELL,0 RET ; BIF OPERATOR WANTS EXIT JMP LOGLP ; ENDLOG: POP H JMP TERML ; EXITLOG: POP H JMP EXITMEN ; EXITTEST: CALL STAT ;KEYPRESS? JZ NOKEY CALL KEYIN MOV B,A LDA EXITCHR ;SEE IF OPERATOR WANTS EXIT CMP B JNZ NOKEY ;GO IF WRONG KEY SCPI ' ' JNC NOTOG ;GO IF NOT CONTROL CHARACTER MOV B,A ;SAVE CPI BKSP ;TEST FOR BACKSPACE JNZ NOBKSP LDA CONVBKSP ;CONVERT BACKSPACE TO RUB? ORA A JZ NOBKSP ;GO IF NO CONVERSION MVI A,RUB JMP NOTOG NOBKSP: LDA EXACFLG ORA A ;EXACT? HR ;SEND LOGON? CMP B JZ SENDLOG SKPLOGON: LDA LSTTST ORA A JZ NOLST LDA LSTCHR CMP B JNZ NOLST LDA LISTFLG CMA STA LISTFLG CALL CRLF CALL CRLF CALL LSTMSG CALL CRLF JMP TERML NOLST: LDA PMMIBYTE ORA A JZ S2 LDA DISCUFMSG2: CALL ILPRT DB 'closed **',CR,LF,LF,BELL,0 RET ; EXITMEN: CALL CRLF CALL CLREOS ;CLEAR TO END OF SCREEN TO CLEAN UP ANY MESS JMP MENU0 ; SENDREADY: CALL IN$MODCTLP CALL ANI$MODSNDB JMP CPI$MODSNDR ; SENDLF: CALL SENDREADY JTC CMC ;RESET FOR EXIT RET NOKEY: STC ;SET FOR NO KEY OR WRONG KEY RET ; EXTFLG: MVI A,TRUE STA EXACFLG JMP TERML ; RCVREADY: CALL IN$MODCTLP CALL ANI$MODRCVB JMP CPI$MODRCVR ; LSTMSG: LDA LISTFLG ORA A JZ LSTMSG2 CALL ILPRT MVI A,0 STA EXACFLG ;CLR FOR NEXT TIME JZ NOTEXAFLG ;GO OF EXAFLG FALSE LDA LOCONEXTCHR ORA A ;SHOULD WE SEND ON EXAFLG? MOV A,B JZ NOTOG ;YES, IF LOCONEXTCHR FALSE LDA EXTCHR ;WE WANT TO SEND EXTCHR IN ANY CASE CMP B MOV A,B JZ NOTOG CHR ;PMMI DISCONNECT? CMP B JZ DISCON1 ;YES, DISCONNECT & RETURN TO MENU LDA BRKCHR ;PMMI BREAK? CMP B JZ BREAK LDA CHGBAUD ;PMMI CHANGE BAUD? CMP B PUSH PSW PUSH H CZ NEWBAUD POP H POP PSW JZ TERML S2: LDA UNSAVECHR ;CLOSE INPUTNZ NOLFYET ;GO IF NOT READY FOR OUTPUT YET MVI A,LF JMP NOTOG ;SEND LF NOLFYET: CALL EXITTEST JNC EXITMEN ;GO IF SO, SO DON'T GET HUNG UP JMP SENDLF ;ELSE KEEP TRYING TO SEND LF ; SENDLOG: PUSH H LHLD LOGONPTR ;HL POINTS TO START OF LO DB 'Printer is on',CR,LF,0 RET LSTMSG2: CALL ILPRT DB 'Printer is off',CR,LF,0 RET ; NOTOG: CALL OUT$MODDATP MOV B,A LDA LOCFLG ORA A JNZ LTYPE LDA ECHOFLG ORA A JZ CHKCR LTYPE: MOV A,B CALL TYPE CALL CHKSAVE ;TO STORE LOCA    L IF BUFFER OPEN CALL CHKPRNT CHKCR: MVI A,CR CMP B JNZ TERML LDA ADDLF ORA A JZ TERML JMP SENDLF ; TERML: CALL RCVREADY ;TEST FOR RECEIVED CHARACTER JNZ TERM2 CALL IN$MODDATP ANI 7FH ;STRIP PARITY JZ TERM2 GIVLF: CALL TYPE MO FOR FILE? ORA A JZ NOBUFF ;DON'T BUFFER PRINTER IF SO, HOWEVER CHARACTERS ;WILL BE LOST IF PRINTER IS SLOWER THAN MODEM CALL GETMAX ;GET MAXIMUM FOR BUFFER LHLD HLSAVE1 CMP H ;ARE WE THERE? JNZ NOTMAX ;GO IF NOT LXI H,BOTTRAM ;FLUSH BUFLSAVE2 XRA A STA LISTMOR RET ; INTDSKSV: MVI A,XOFF ;SEND A CTRL-S TO STOP.. CALL OUT$MODDATP ;..REMOTE COMPUTER OUTPUT. MVI D,0 ;D IS THE BUFFER COUNT CALL INMODEM ;GET LAST BYTES SENT.. STA LASTBYT1 ;..AFTER CTR CALL FIXCNT PUSH H POP B POP H BRK1: CALL TIMERL JZ BRK2 ;IF TIME IS UP RESET BREAK CPI 0 ;CHECK FOR NULLS JZ BRK1 ;DON'T PROCESS THEM ANI 7FH ;STRIP PARITY CALL TYPE PUSH PSW LDA SAVEFLG CPI FALSE JZ NOSAVEB POP PSW MOV M,AV B,A CALL CHKSAVE CALL CHKPRNT LDA ECHOFLG ORA A JZ NOECHO MOV A,B CALL OUT$MODDATP NOECHO: MVI A,CR CMP B JNZ TERM2 LDA ADDLF JZ TERM2 LDA ECHOFLG ORA A JNZ SENDLF MVI A,LF JMP GIVLF ; CHKSAVE: LDA SAVEFLG ORA A RFER SHLD HLSAVE1 SHLD HLSAVE2 NOTMAX: MOV M,B ;SAVE CHARACTER IN BUFFER INX H ;INCREMENT END OF BUFFER SHLD HLSAVE1 MVI A,TRUE ;SET FLAG FOR PRINTER OUTPUT STA LISTMOR RET ; NOBUFF: CALL LSTSTAT RZ ;RETURN IF PRINTER BUSY MOV C,L-S. CALL INMODEM ;ADD MORE CALLS TO INMODEM.. STA LASTBYT2 ;..AND STA LASTBYT# IF YOU ARE.. PUSH D CALL NUMREC1 CALL WRTDSK ;WRITE THE RECORDS POP D LXI H,BOTTRAM INR D DCR D ;TEST BUFFER COUNT FOR ZERO JZ CTR INX H SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG.. ;..GET HL WHEN ENTERING VIA 'NOL' CMD. COLONB: CPI LF JNZ BRK1 ;..TYPE ":" AFTER EACH LINE FEED.. MVI A,':' ;..WHEN MEMORY SAVE ACTIVE. CALL TYPE JMP BRK1 ; NOSAVEB: POP PSW ;RESTOREZ MOV M,B INX H SHLD HLSAVE ;MENU COMMAND DESTROYS HL-REG.. MVI A,LF CMP B JNZ NOCOLON ;..TYPE ":" AFTER EACH LINE FEED.. MVI A,':' ;..WHEN MEMORY SAVE ACTIVE. CALL TYPE NOCOLON: CALL GETMAX CMP H PUSH B CZ INTDSKSV POP B RET B ;ELSE PRINT CHARACTER JMP LISTER ; GOLIST: CALL LSTSTAT RZ ;RETURN IF PRINTER BUSY LHLD HLSAVE2 ;GET LOCATION OF NEXT CHARACTER TO PRINT MOV C,M ;GET CHARACTER INX H ;INCREMENT POINTER SHLD HLSAVE2 CALL CMPBUFF ;CHECK FOR END OF BUFFERLQ LDA LASTBYT1 ;GET THE LAST BYTES THAT WERE.. MOV M,A ;..SAVED AND PUT THEM IN.. INX H ;..BOTTRAM. CALL TYPE DCR D JZ CTRLQ LDA LASTBYT2 MOV M,A INX H CALL TYPE CTRLQ: MVI A,XON ;SEND START CHARACTER. IT JMP BRK1 ; BRK2: LDA MODCTLB ;GET MODEM CONTROL BYTE CALL OUT$MODCTL2 POP D LHLD HLSAVE ;LAST ADDRESS WRITTEN IF DATA BEING SAVED LDA SAVCCP ORA A JZ SUB2 LDA 7 ;CHECK TO SEE IF.. SBI 8 ;..PAGE BELOW CCP .. JMP SUB2A ; SUB2: ; GETMAX: LDA SAVCCP ORA A LDA 7 JZ SUB1 SBI 8 ;..PAGE BELOW CCP .. SUB1: DCR A ;..OR BDOS HAS BEEN.. RET ;..REACHED AND DISKSAVE IS NEEDED. ; CHKPRNT: LDA LISTFLG ;OUT TO PRINTER? ORA A RZ ;RETURN IF NOT LDA NFILFLG ;IS BUFFER USED JMP LISTER ;PRINT ; ;ROUTINE CHECKS FOR END OF BUFFER, RESETS BUFFER IF SO AND STOPS ;PRINTER OUTPUT ; CMPBUFF: LHLD HLSAVE2 XCHG LHLD HLSAVE1 MOV A,L SUB E MOV L,A MOV A,H SBB D ORA L RNZ LXI H,BOTTRAM SHLD HLSAVE1 SHLD H. JMP OUT$MODDATP ;..TO REMOTE COMPUTER. ; BREAK: PUSH D ;SAVE IT LXI D,0 ;ZERO IT LDA MODCTLB ;GET THE LAST MODEM CONTROL BYTE ANI 0FBH ;SET THE TRANSMIT BREAK BIT LOW - ACTIVE LOW CALL OUT$MODCTL2 ;SEND IT TO THE MODEM PUSH H LXI H,225 LDA 7 SUB2A: DCR A ;..OR BDOS HAS BEEN .. CMP H ;..REACHED AND DISKSAVE IS NEEDED. JNZ TERM2 ;NO PROBLEM - GO BACK TO NORMAL ROUTINE CALL ILPRT DB CR,LF,'Memory save buffer full',CR,LF,BELL,0 JMP TERM2 ; ;THIS SUBROUTINE WILL LOOP UNTIL THE     MODEM RECEIVES A CHARACTER ;OR 100 MILLISECONDS. IF A CHARACTER IS RECEIVED, A FLAG IS SET ;TO STORE THE CHARACTER. A MAXIMUM OF TWO CHARACTERS ARE STORED, ;BUT MORE MAY BE STORED IF DESIRED (SEE COMMENT IN "INTDSKSV" ;ABOVE). ; INMODEM: PUSH H  PUSH B PUSH D PUSH H PUSH PSW CALL BDOS POP PSW POP H POP D POP B RET ; MOVE2: LXI H,FCB3 CALL INITFCBS LXI H,FCB LXI D,FCB3 MVI B,12 JMP MOVE ; ;FILE TRANSFER ROUTINE - CALLED WITH ;CONTROL-T FROM TERMINAL ROUTINE. D OF FILE JZ RETURNS CPI 2 ;BAD READ JZ RETURNU CALL SEND80C CPI EOFCHAR ;END OF FILE - OMIT IF OBJECT.. JZ RETURNS ;..CODE IS TO BE SENT. CPI CAN ;CANCELLATION? JZ TRANCAN JMP READMR ; RETURNS: CALL ILPRT DB CR,LF,'++File transfer I H,FCB4 JMP CPMLINE ; OPEN4: LXI D,FCB4 MVI C,OPEN JMP BDOS ; READ80: LXI D,FCB4 MVI C,READ JMP BDOS ; SEND80C: MVI B,80H LXI H,80H SENDCH1: PUSH D CALL SPEED POP D MOV A,M CALL MODOUT CPI EOFCHAR RZ CALL STAT ;TESLXI H,625 CALL FIXCNT PUSH H POP B POP H TIMERL: CALL RCVREADY JZ GETBYTE DCX B MOV A,B ORA C JNZ TIMERL RET ; GETBYTE: CALL IN$MODDATP INR D RET ; NUMRECS: MVI M,EOFCHAR INX H LXI D,127 DAD D NUMREC1: LXI D,-(BO;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X. ; TRANSFER: PUSH H PUSH D PUSH B PUSH PSW LXI H,FCB4 CALL INITFCBS ;INITIALIZES FCBS POINTED.. LXI H,FCB+16 ;..TO BY HL REG. CALL INITFCBS GET: CALL GETNAME LDA CMDBUF+2 ;Wcompleted++',CR,LF,BELL,0 JMP RETURN ; RETURNU: CALL ILPRT DB CR,LF,'++File transfer unsuccessful++',CR,LF,BELL,0 JMP RETURN ; TRANCAN: CALL ILPRT DB CR,LF,LF,'++ Transfer cancelled ++',CR,LF,BELL,0 RETURN: POP PSW POP B POP D POP T TO SEE IF ORA A ;CANCELLATION REQUESTED JZ SKIP12 CALL KEYIN CPI CAN RZ SKIP12: INX H DCR B JNZ SENDCH1 RET ; MODOUT: PUSH PSW MODOUTL: LDA XOFFTST ORA A CNZ TXOFF CALL SENDREADY JNZ MODOUTL POP PSW CALL OUT$MODDATP TTRAM) DAD D MOV A,L ;DIVIDE HL BY 128.. ORA A RAL ;..TO GET THE.. MOV L,H ;..NUMBER OF SECTORS MVI H,0 PUSH PSW DAD H POP PSW MVI A,0 ADC L MOV L,A ;RETURNS WITH NUMBER OF.. RET ;..128 BYTE RECORDS IN HL. ; WRTDSK: LXI D,BOTTAS FILE ENTERED CPI 20H JZ TRANSL2 CALL MOVE4 CALL OPEN4 CPI 0FFH ;RETURN WITH 0FFH MEANS JNZ CONTIN ;FILE DOES NOT EXIST TRANSL1: CALL ILPRT DB CR,LF,'++File does not exist++',CR,LF,0 TRANSL2: CALL ILPRT DB 'Type "R" to return to modH RET ; INITFCBS: ;ENTRY AT +2 WILL LEAVE.. MVI M,0 ;..DRIVE NO. INTACT. INX H ;WILL INITIALIZE AN FCB.. MVI B,11 ;..POINTED TO BY HL-REG. FILLS 1ST POS LOOP10: MVI M,' ' ;..WITH 0, NEXT 11 WITH.. INX H ;..WITH BLANKS, AND LAST.. DCR B ;. CALL TYPE CPI CR JZ DLYCR RET ; DLYCR: INX H ;ALWAYS DISPLAY LF AFTER CR MVI A,LF CMP M DCX H JZ LFSKIP CALL TYPE LFSKIP: LDA XONWAIT ;WAIT FOR XON AFTER CR? ORA A JNZ WAITXON LDA CRDLY ;EXTRA DELAY AFTER CR JMP DLYCR2 ; SPEERAM NEXTWRT: MVI C,STDMA CALL BDOSRT PUSH D LXI D,FCB3 MVI C,WRITE CALL BDOSRT POP D XCHG PUSH D LXI D,128 DAD D POP D XCHG DCX H MOV A,H ORA L JNZ NEXTWRT RET ; CLOSE3: LXI D,FCB3 MVI C,CLOSE JMP BDOS ; BDOSRT:em',CR,LF DB 'Type "A" to re-enter name: ',BELL,0 CALL KEYIN CALL UCASE CALL TYPE ;ECHO RESPONSE CALL CRLF CPI 'A' JZ GET CPI 'R' JZ RETURN JMP TRANSL2 ; CONTIN: LXI D,80H MVI C,STDMA CALL BDOS READMR: CALL READ80 CPI 1 ;EN.21 WITH NULLS. JNZ LOOP10 MVI B,21 LOOP11: MVI M,0 INX H DCR B JNZ LOOP11 RET ; GETNAME: CALL ILPRT DB CR,LF,'Enter file name to be transferred - C/R TO QUIT: ',0 LXI D,CMDBUF CALL INBUFF JMP CRLF ; MOVE4: LXI D,CMDBUF LXD: LDA BYTDLY ;GET SPEED VALUE (0-9) ;DELAY IS FROM 0.02 SEC FOR SPDVAL = 1 ;TO 0.18 SEC FOR SPDVAL = 9 DLYCR2: ORA A RZ ;RETURN IF 0 MOV C,A SPDLP: CALL SPD1 ;OUTER LOOP DCR C RZ JMP SPDLP ; SPD1: PUSH H LXI H,357 ;ABOUT 0.02 SEC     AT 2 MHZ LDA XOFFTST ORA A JZ SPD2 LXI H,102 ;ADJUST FOR XOFF TESTING LDA ECHOFLG ORA A JZ SPD2 LDA LOCFLG ORA A JZ SPD2 LXI H,76 ;ADJUST AGAIN FOR REMOTE ECHO SPD2: CALL FIXCNT PUSH H POP D POP H SPDLP1: DCX D ;INNER LOOP LR MULTIPLE NAMES. CALL SENDFN ;SENDS FILE NAME TO RECEIVER JNC SENDC2 ;CARRY SET MEANS NO MORE FILES. MVI A,'B' ;STOP BATCH.. STA BATCHFLG ;..MODE OPTION. MVI A,EOT ;FINAL XFER END CALL SEND JMP DONE ; SENDC1: LDA FCB+1 CPI ' ' JZ BL STA BATCHFLG ;..MODE OPTION. JMP DONE ; RCVC1: LDA FCB+1 ;MAKE SURE FILE IS NAMED CPI ' ' JZ BLKFILE ; RCVC2: CALL CKCPM2 CALL CKBAKUP RCVC3: CALL ERASFIL CALL MAKEFIL LDA BATCHFLG ORA A ;DON'T PRINT MSG IF.. JZ RCVFST ;..IN BLD NBSAVE ;GET FILE NAME.. LXI D,FCB ;..IN FCB MVI B,12 CALL MOVE SHLD NBSAVE CALL SENDNM ;SEND IT ORA A ;CLEAR CARRY RET ; NOMRNM: MVI A,EOT CALL SEND STC RET ; SENDNM: PUSH H SENDNM1: MVI D,11 ;COUNT CHARS IN NAME MVI C,0 ;INDA XOFFTST ORA A CNZ TXOFF MOV A,E ORA D RZ JMP SPDLP1 ; TXOFF: CALL RCVREADY RNZ CALL IN$MODDATP ANI 7FH CPI XOFF CZ WAITXON RET ; WAITXON: CALL RCVREADY JNZ WTXON2 CALL IN$MODDATP ANI 7FH CPI XON RZ WTXON2: CALL SKFILE SENDC2: CALL CNREC ;GET NUMBER OF RECORDS CALL OPENFIL MVI E,80 CALL WAITNAK SENDLP: CALL RDSECT JC SENDEOF CALL INCRSNO MVI A,1 STA ERRCT SENDRPT: CALL SENDHDR CALL SENDSEC LDA CKSUMFLG ORA A CZ SENDCRC CNZ SENDCKS ATCH CALL ILPRT DB 'File open, ready to receive',CR,LF,0 RCVFST: LDA CKSUMFLG ORA A MVI A,NAK JNZ RCVFIL2 MVI A,CRC RCVFIL2: CALL SEND LDA QFLG ORA A JZ RCVLP LDA CKSUMFLG ORA A JNZ RCVNAKM ;IF IN CRC MODE CALL ILPRT ;THENIT CHECKSUM MOV A,C STA FTYCNT ;INITIATE FILE TYPE COUNT LXI H,FCB+1 ;ADDRESS NAME NAMLPS: MOV A,M ;SEND NAME ANI 7FH ;STRIP HIGH ORDER BIT SO CP/M 2.. CALL SEND ;..WON'T SEND R/O FILE DESIGNATION. LDA QFLG ;SHOW NAME IF.. ORA A ;..QFLG NOT TAT ;TEST TO SEE IF ORA A ;CANCELLATION REQUESTED JZ WAITXON ;SO DON'T GET HUNG UP CALL KEYIN CPI CAN RZ JMP WAITXON ; ;SEND A CP/M FILE ; SENDFIL: MVI A,TRUE ;ALWAYS FORCE CHECKSUM MODE INITIALLY ON SEND STA CKSUMFLG SENDFIL1: CALL  CALL GETACK JC SENDRPT JMP SENDLP ; SENDEOF: MVI A,EOT CALL SEND CALL GETACK JC SENDEOF JMP DONE ; ;RECEIVE A FILE ; RCVFIL: LDA CKSUMDFLT ;GET MODE REQUESTED BY OPERATOR STA CKSUMFLG ;STORE IT RCVFIL1: CALL PARITY ;SET PARITY I SAY SO DB 'CRC in effect',CR,LF,0 JMP RCVLP RCVNAKM: CALL ILPRT ;ELSE SAY CHECKSUM MODE DB 'Checksum in effect',CR,LF,0 RCVLP: CALL RCVSECT JC RCVEOT CALL WRSECT CALL INCRSNO CALL SENDACK JMP RCVLP ; RCVEOT: CALL WRBLOCK CALL SET. MOV A,M JZ ACKLP CALL FTYTST ;TYPE CHARACTER ETC. ACKLP: PUSH B ;SAVE CKSUM MVI B,1 ;WAIT FOR RECEIVER.. CALL RECV ;..TO ACKNOWLEDGE.. POP B ;..GETTING LETTER. JC SCKSER CPI ACK JNZ ACKLP INX H ;NEXT CHAR DCR D JNZ NAMLPS MVPARITY ;SET PARITY IF REQUESTED LDA BATCHFLG ;CHECK IF MULTIPLE FILE.. ORA A ;..MODE IS SET. JNZ SENDC1 MVI A,TRUE ;INDICATE SEND FOR BATCH MODE STA SENDFLG LDA FSTFLG ;IF FIRST TIME THRU.. ORA A ;..SCAN THE COMMAND LINE.. CNZ TNMBUF ;..FOF REQUESTED LDA BATCHFLG ;CHECK IF MULT.. ORA A ;..FILE MODE. JNZ RCVC1 MVI A,FALSE ;FLAG WHERE TO RETURN.. STA SENDFLG ;..FOR NEXT FILE TRANS. CALL GETFN ;GET THE FILE NAME. JNC RCVC2 ;CARRY SET MEANS NO MORE FILES. MVI A,'B' ;STOP BATCH..SENDACK CALL CLOSFIL JMP DONE ; ;SUBROUTINES ; SENDFN: LDA QFLG ORA A JZ SWNAK CALL ILPRT DB 'Awaiting name NAK',CR,LF,0 SWNAK: MVI E,80 CALL WAITNLP MVI A,ACK ;GOT NAK, SEND ACK CALL SEND LXI H,FILECT DCR M JM NOMRNM LHI A,EOFCHAR ;TELL RECEIVER END OF NAME CALL SEND LDA QFLG ORA A CNZ CRLF MOV D,C ;SAVE CHECKSUM MVI B,1 CALL RECV ;GET CHECKSUM.. CMP D ;..FROM RECEIVER. JZ NAMEOK SCKSER: MVI A,BDNMCH ;BAD NAME-TELL RECEIVER CALL SEND LDA QFLG ORA     A JZ SKCSER1 CALL ILPRT DB 'Checksum error',CR,LF,0 SKCSER1: MVI E,80 ;DO HANDSHAKING OVER CALL WAITNLP ;DON'T PRINT "AWAITING NAK" MSG MVI A,ACK CALL SEND JMP SENDNM1 ; NAMEOK: MVI A,OKNMCH ;GOOD NAME-TELL RECEIVER CALL SEND POP G ORA A JZ SKPTYP CALL FTYTST SKPTYP: PUSH B ;SAVE CKSUM MVI A,ACK ;ACK GETTING LETTER CALL SEND POP B INX H ;GET NEXT CHAR MOV A,L ;DON'T LET NOISE... CPI 7FH ;..CAUSE OVERFLOW.. JZ GCKSER ;..INTO PROGRAM AREA. JMP NAMELPG ; FTYTS1 JMP GETNM1 ; GNRET: POP H RET ; HSNAK: MVI A,NAK ;SEND NAK UNTIL.. CALL SEND ;..RECEIVING ACK. CALL CKABORT ;DON'T GET HUNG UP HERE MVI B,2 ;WAIT 2 SECONDS.. CALL RECV ;..IN RECEIVE. CPI ACK ;IF ACK,RETURN WITH.. RZ ;..CARRY CLEAR. CT RET ; ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE) ;AFTER LAST NAME ; SCAN: PUSH H LXI H,NAMECT MVI M,0 LXI H,CMDBUF+1 ;FIND END OF CMD LINE.. MOV C,M ;..AND PUT SPACE THERE. MVI B,0 LXI H,CMDBUF+2 DAD B MVIH RET ; GETFN: LXI H,FCB CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE LDA QFLG ORA A JZ GNAMELP CALL ILPRT DB 'Awaiting file name',CR,LF,0 GNAMELP: CALL HSNAK JC GNAMELP CALL GETNM ;GET THE NAME CPI EOT ;IF EOT, THEN NO MORE FILES T: LDA FTYCNT INR A STA FTYCNT CPI 9 ;ARE WE AT THE FILE TYPE? JZ SPCTST ;GO IF SO ENDSPT: MOV A,M CPI ' ' ;TEST FOR SPACE CNZ TYPE ;TYPE IF NOT RET ; SPCTST: MOV A,M CPI ' ' ;TEST FOR SPACE IN FIRST FILE TYPE BYTE RZ ;DON'T OUTPUT  STC RET ; TNMBUF: MVI A,FALSE ;CALL FROM SENDFIL ONLY ONCE. STA FSTFLG STA FILECT CALL SCAN LXI H,NAMEBUF SHLD NBSAVE ;SAVE ADDR OF 1ST NAME TNLP1: CALL TRTOBUF LXI H,FCB LXI D,FCBBUF CALL CPMLINE ;PARSE NAME TO CP/M FORMAT TNLP2: CA M,20H LXI H,CMDBUF+1 MOV B,M INR B INR B SCANLP1: INX H DCR B JZ DNSCAN MOV A,M CPI 20H JNZ SCANLP1 SCANLP2: INX H ;EAT EXTRA SPACES DCR B JZ DNSCAN MOV A,M CPI 20H JZ SCANLP2 SHLD BGNMS ;SAVE START OF NAMES IN CMDBUF  JZ NOMRNMG ORA A ;CLEAR CARRY RET ; NOMRNMG: STC RET ; GETNM: PUSH H GETNM1: MVI C,0 ;INIT CHECKSUM MOV A,C STA FTYCNT ;INITIATE COUNT FOR FILE TYPE LXI H,FCB+1 NAMELPG: MVI B,5 CALL RECV ;GET CHAR JNC GETNM3 LDA QFLG ORAPERIOD IF SPACE MVI A,'.' CALL TYPE JMP ENDSPT ;OUTPUT FIRST FILE TYPE BYTE ; ENDNAME: LDA QFLG ORA A CNZ CRLF MOV A,C ;SEND CHECKSUM CALL SEND MVI B,1 CALL RECV ;CHECKSUM GOOD? CPI OKNMCH ;YES IF OKNMCH SENT.. JZ GNRET ;..ELSE DLL MFNAME ;SEARCH FOR NAMES (* FORMAT) JC NEXTNM LDA FCB+10 ;IF CP/M 2 $SYS FILE.. ANI 80H ;..DON'T SEND JNZ TNLP2 LHLD NBSAVE ;GET NAME LXI D,FCB ;MOVE IT TO FCB XCHG MVI B,12 CALL MOVE XCHG SHLD NBSAVE ;ADDR OF NEXT NAME LXI H,FIL INR B DCX H SCANLP3: INX H DCR B JZ DNSCAN MOV A,M CPI 20H JNZ SCANLP3 LDA NAMECT ;COUNTS NAMES INR A STA NAMECT SCANLP4: INX H ;EAT SPACES DCR B JZ DNSCAN MOV A,M CPI 20H JZ SCANLP4 JMP SCANLP3 ; DNSCAN: MVI M,20H  A JZ GETNM2 CALL ILPRT DB 'Time out receiving filename',CR,LF,0 GETNM2: JMP GCKSER ; GETNM3: CPI EOT ;IF EOT, THEN NO MORE FILES JZ GNRET CPI EOFCHAR ;GOT END OF NAME JZ ENDNAME MOV M,A ;PUT NAME IN FCB LDA QFLG ;CAN TYPE IT IF NO QFLO OVER. GCKSER: LXI H,FCB ;CLEAR FCB (EXCEPT DRIVE).. CALL INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED.. LDA QFLG ;..BY TOO MANY CHARS. ORA A JZ GCKSER1 CALL ILPRT DB 'Checksum error',CR,LF,0 GCKSER1: CALL HSNAK ;DO HANDSHAKING OVER JC GCKSERECT ;COUNT FILES FOUND INR M JMP TNLP2 ; NEXTNM: LXI H,NAMECT ;COUNT NAMES FOUND DCR M JNZ TNLP1 LXI H,NAMEBUF ;SAVE START OF BUFFER SHLD NBSAVE LDA FILECT CPI 65 ;NO MORE THAN 64 TRANSFERS RC MVI A,64 ;ONLY X'FER FIRST 64 STA FILE;SPACE AFTER LAST CHAR POP H RET ; ;PLACES NEXT NAME IN BUFFER SO 'CPMLINE' MAY PARSE IT ; TRTOBUF: LHLD BGNMS MVI B,0 LXI D,FCBBUF+2 TBLP: MOV A,M CPI 20H JZ TRBFEND STAX D INX H INX D INR B ;COUNT CHARS IN NAME JMP TBLP ;      TRBFEND: INX H MOV A,M ;EAT EXTRA SPACES CPI 20H JZ TRBFEND SHLD BGNMS LXI H,FCBBUF+1 ;PUT # CHARS BEFORE NAME MOV M,B RET ; ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'. ; CKCPM2: MVI C,12 CALL BDOS ORA A ;RETURN N DIR CALL BDOS ; ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE ; PLANCHG: LXI H,FCB ;CHANGE NAME TO TYPE "BAK" LXI D,6CH MVI B,9 ;MOVE DRIVE AND NAME (NOT TYPE) CALL MOVE LXI H,75H ;START OF TYPE IN FCB2 MVI M,'B' INX H MVI M DECOUT ;PRINT SECTOR NUMBER IN DECIMAL CALL ILPRT DB ' (', 0 CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT CALL ILPRT DB 'H)',0 MOV A,L ;ONLY LOW BYTE USED BY PROGRAM POP H ;RESTORE IT ; RCVSQ: ;WAIT FOR SOH OR EOT MVI B,10 ;10 SECONDS  INR A ;..WE HAVE REACHED.. STA ERRCT ;..THE ERROR.. CPI ERRLIM ;..LIMIT? JC RCVRPT ;..NO, TRY AGAIN LDA QFLG ORA A JZ RCVSABT RCVCKQ: CALL CKQUIT JZ RCVSECT RCVSABT: CALL CLOSFIL CALL ERXIT DB CR,LF,'++ Unable to receive block - Abo0 MEANS CP/M 1 RZ MVI C,STDMA LXI D,80H CALL BDOS MVI C,SRCHF ;SEARCH FOR FILE LXI D,FCB CALL BDOS CPI 0FFH RZ ADD A ADD A ;MULT A-REG BY.. ADD A ADD A ;..32 TO FIND.. ADD A ;..NAME IN DMA. LXI H,80H ADD L MOV L,A ;HL POIN,'A' INX H MVI M,'K' LXI D,6CH MVI C,ERASE ;ERASE ANY PREV BACKUPS CALL BDOS LXI H,6CH ;FCB2 DR FIELD SHOULD.. MVI M,0 ;..0 FOR RENAME. LXI D,FCB MVI C,23 ;RENAME JMP BDOS ; CKBAKUP: LDA BAKUPBYTE ORA A RZ MVI C,SRCHF LXI D, CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR ERRORS JC RCVDERR ;JUMP IF THERE WAS AN ERROR CPI SOH JZ RCVSOH ORA A JZ RCVSQ CPI EOT STC RZ MOV B,A LDA QFLG ORA A JZ RCVSERR RCVSEH: MOV A,B CALL CRLF CALL HEXO CALL ILPRTrting ++',CR,LF,'$' ; RCVSTOT: LDA QFLG ORA A JZ RCVSCRC RCVSPT: CALL ILPRT DB CR,LF,'++ Timeout ++ ',0 RCVPRN: LDA ERRCT PUSH H MVI H,0 MOV L,A CALL DECOUT POP H CALL CRLF RCVSCRC: CALL RCVSCRC2 JMP RCVSERR ; ;ROUTINE WILL STS TO DIR NAME LXI D,9 DAD D ;POINT TO R/O ATTRIB BYTE MOV A,M ANI 80H ;TEST MSB JNZ MKCHG ;IF SET, MAKE CHANGE INX H ;CHECK SYSTEM ATTRIB BYTE MOV A,M ANI 80H RZ ;NOT $SYS OR $R/O DCX H MKCHG: LXI D,-8 DAD D ;POINT HL TO FILENAME +FCB CALL BDOS INR A RZ ;FILE NOT FOUND JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE ; ;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP ;FIXED BY MARK ZEIGER 8/17/80 ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND ; MFNAME: MFACCESS ;A MACRO IN DB 'H recv''d, not SOH',CR,LF,0 RCVSERR: MVI B,1 ;WAIT FOR 1 SEC.. CALL RECV ;..WITH NO CHARS JNC RCVSERR ;LOOP UNTIL SENDER DONE LDA CKSUMFLG ;GET CHECKSUM FLAG ORA A ;CRC IN EFFECT? MVI A,NAK ;PUT NAK IN ACCUM JNZ RCVSER2 ;NO, SEND THE WITCH FROM CRC TO CHECKSUM IF ERCNT REACHES ERRCRC ;AND FIRSTME IS TRUE ; RCVSCRC2: LDA ERRCT CPI ERRCRC RNZ LDA FIRSTME ORA A RZ LDA CKSUMFLG ORA A RNZ CMA STA CKSUMFLG STA CKSUMDFLT LDA QFLG ORA A RZ CALL ILPRT DB '++ 1 LXI D,FCB+1 ;MOVE DIR NAME TO FCB.. MVI B,11 ;..WITHOUT CHANGING DRIVE. CALL MOVE LXI H,FCB+9 ;R/O ATTRIB MOV A,M ANI 7FH ;STRIP R/O ATTRIB MOV M,A INX H ;SYS ATTRIB MOV A,M ANI 7FH MOV M,A LXI D,FCB MVI C,30 ;SET NEW ATTRIBS I MACROS.LIB ; RCVSECT: MVI A,1 STA ERRCT RCVRPT: XRA A ;ZERO ACCUM STA ERRCDE ;CLEAR RECEIVE ERROR CODE LDA QFLG ORA A JZ RCVSQ CALL ILPRT DB CR,'Awaiting # ',0 PUSH H ;SAVE IT LHLD SECTNO ;GET SECTOR NUMBER INX H ;BUMP IT CALLNAK LDA FIRSTME ;GET FIRST TIME SWITCH ORA A ;HAS FIRST SOH BEEN RECEIVED? MVI A,NAK ;PUT NAK IN ACCUM JZ RCVSER2 ;YES, THEN SEND NAK MVI A,CRC ;TELL SENDER CRC IS IN EFFECT RCVSER2: CALL SEND ;..THE NAK or CRC request LDA ERRCT ;ABORT IF..  Switching to Checksum mode ++',CR,LF DB '++ Sender may not be CRC capable ++',CR,LF,BELL,0 RET ; ;----> RCVERR: ; ; Checks for framing, overrun, and parity errors. Parity errors ; cannot be detected unless the parity option has been selected. ;     1.Error code (ERRCDE) was set in RECV routine. ; 2.ERRCDE=0 for no errors, ERRCDE<>0 for errors. ; 3.If there is an error, routine returns with carry flag set. ; RCVERR: PUSH PSW ;SAVE CHAR TRANSMITTED LDA ERRCDE ;GET RECEIVE ERROR CODE ANA A ;IS IGO CHECK FOR PARITY ERROR CALL ILPRT DB '++ Overrun error ++ ',0 CALL RCVDERR5 RCVDERR3: LDA ERRCDE ;GET RECEIVE ERR CODE ANI PARER ;WAS THERE A PARITY ERROR? JZ RCVDERR4 ;NO, GO PURGE LINE CALL ILPRT DB '++ Parity error ++ ',0 CALL RCVD STA RCVSNO MVI A,1 STA DATAFLG MVI C,0 CALL CLRCRC ;CLEAR CRC COUNTER LXI H,80H RCVCHR: MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR MOV M,A INR L JNZ RCVCHR LDA CKSUMFLG ORA A JZ RCVCRC MCR,'Sending # ',0 PUSH H LHLD SECTNO ;GET SECTOR NUMBER CALL DECOUT ;PRINT IT IN DECIMAL CALL ILPRT DB ' (',0 CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT CALL ILPRT DB 'H)',0 POP H SENDHNM: MVI A,SOH CALL SEND LDA SECTNO CALL SENT ZERO? JZ RCVERR2 ;YES, NO RECEIVE ERROR POP PSW ;RESTORE CHAR TRANSMITTED STC ;SET CARRY ON TO INDICATE AN ERROR RET RCVERR2: POP PSW ;RESTORE CHAR TRANSMITTED RET ; ;----> RCVDERR: Checks for a receive error and displays appropriate ; ERR5 RCVDERR4: JMP RCVSERR ;GO PURGE LINE, SEND NAK ; ;Display the number of the error, do a carriage return and line feed. ; RCVDERR5: LDA ERRCT ;GET ERROR NUMBER PUSH H MVI H,0 MOV L,A CALL DECOUT ;DISPLAY IT POP H JMP CRLF ;DO CR, LOV D,C XRA A STA DATAFLG MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR CMP D JNZ RCVCERR CHKSNUM: LDA RCVSNO MOV B,A LDA SECTNO CMP B JZ RECVACK INR A CMP B JNZ ABORT RET ; RCVCRC: MVID LDA SECTNO CMA JMP SEND ; SENDSEC: MVI A,1 STA DATAFLG MVI C,0 CALL CLRCRC LXI H,80H SENDC: MOV A,M CALL SEND INR L JNZ SENDC XRA A STA DATAFLG RET ; SENDCKS: MOV A,C JMP SEND ; SENDCRC: CALL FINCRC MOV A,D  error message. Then goes to RCVSERR to purge the line ; and send a NAK. ; RCVDERR: LDA QFLG ;QUIET... ORA A ;...MODE? JZ RCVSERR ;YES, NO MSG RCVDERRP: CALL ILPRT DB CR,LF,0 LDA ERRCDE ;GET RECEIVE ERR CODE AF ; ;Got SOH - get block #, block # complemented ; RCVSOH: XRA A ;ZERO ACCUM STA FIRSTME ;INDICATE FIRST SOH RECV'D MVI B,1 ;TIMEOUT = 1 SEC CALL RECV ;GET SECTOR JC RCVSTOT ;GOT TIMEOUT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR MOV E,2 ;NUMBER OF CRC BYTES RCVCRC2: MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR JC RCVDERR DCR E JNZ RCVCRC2 CALL CHKCRC ORA A JZ CHKSNUM LDA QFLG ORA A JZ RCVSERR RCVCRER: CALL ILPRT DB CR,LF,'++ CRC error ++',0 JMP RCVPRN ;CALL SEND MOV A,E CALL SEND XRA A RET ; GETACK: MVI B,10 ;10 SECONDS CALL RECVDG JC GETATOT CPI ACK RZ MOV B,A LDA QFLG ORA A JZ ACKERR MOV A,B CALL CRLF CALL HEXO CALL ILPRT DB 'H Recv''d, not ACK',CR,LF,0 ACKERR: LDANI FRMER ;WAS THERE A FRAMING ERROR? JZ RCVDERR2 ;NO, GO CHECK FOR OVERRUN CALL ILPRT DB '++ Framing error ++ ',0 CALL RCVDERR5 ;PRINT # OF ERROR RCVDERR2: LDA ERRCDE ;GET RECEIVE ERR CODE ANI ORUNER ;WAS THERE AN OVERRUN JZ RCVDERR3 ;NO,  D,A MVI B,1 CALL RECV JC RCVSTOT CALL RCVERR ;CHECK FOR RECEIVE ERROR JC RCVDERR CMA CMP D JZ RCVDATA LDA QFLG ORA A JZ RCVSERR RCVBSE: CALL ILPRT DB CR,LF,'++ Bad sector # in Hdr',CR,LF,0 JMP RCVSERR ; RCVDATA: MOV A,D  RCVCERR: LDA QFLG ORA A JZ RCVSERR RCVCPR: CALL ILPRT DB CR,LF,'++ Checksum error ++ ',0 JMP RCVPRN ; RECVACK: CALL SENDACK JMP RCVSECT ; SENDACK: MVI A,ACK JMP SEND ; SENDHDR: LDA QFLG ORA A JZ SENDHNM CALL ILPRT DB  ERRCT INR A STA ERRCT DCR A CPI ERRLIM RC LDA QFLG ORA A JZ CSABORT GACKV: CALL CKQUIT STC RZ CSABORT: CALL ERXIT DB CR,LF,'Can''t send sector -- Aborting',CR,LF,'$' GETATOT: LDA QFLG ORA A JZ ACKERR CALL ILPRT DB CR,L    F,'Timeout on ACK',CR,LF,0 JMP ACKERR ; CKABORT: LDA QFLG ORA A RZ CKABGO: CALL STAT RZ CALL KEYIN CPI CAN RNZ ABORT: LXI SP,STACK ABORTL: MVI B,1 CALL RECV JNC ABORTL MVI A,CAN CALL SEND ABORTW: MVI B,1 CALL RECV ecified',CR,LF,BELL,0 JMP MENU MAKEFIL: LXI D,FCB MVI C,MAKE CALL BDOS INR A RNZ CALL ERXIT DB 'Error - Can''t make file',CR,LF DB 'Directory is likely full',CR,LF,'$' ; IF CPM2X ; CNREC: MVI C,FILSIZ ;COMPUTE FILE SIZE FUNCTION I MOV D,H LDA RCNT ;GET RECORD COUNT OF MAX EXTENT SEEN MOV E,A ;SAVE IT IN DE DAD H DAD H ;MULTIPLY # OF EXTENTS -1 DAD H ; TIMES 128 DAD H DAD H DAD H DAD H DAD D ;ADD IN SIZE OF LAST EXTENT SHLD RCNT ;SAVE TOTAL RECORD COUNT RET ALL BDOS INR A JNZ OPENOK CALL ERXIT DB 'Can''t open file$' OPENOK: LDA BATCHFLG ORA A ;ONLY IF SINGLE FILE... RZ JMP SENDTIM ;A LIB MACRO SHOWS TIME TO SEND ; CLOSFIL: LXI D,FCB MVI C,CLOSE CALL BDOS INR A RNZ CALL ERXIT  JNC ABORTW MVI A,' ' CALL SEND CALL ILPRT DB CR,LF,'Routine cancelled',CR,LF,BELL,0 MVI A,'B' ;TURN MULTI-FILE MODE.. STA BATCHFLG ;..OFF SO ROUTINE ENDS. JMP DONETCE ; INCRSNO: PUSH H LHLD SECTNO ;GET SECTOR NUMBER INX H ;BUMP N CP/M 2.x LXI D,FCB ;POINT TO FILE CONTROL BLOCK CALL BDOS LHLD FCB+33 ;GET RECORD COUNT SHLD RCNT ;STORE IT LXI H,0 ;ZERO HL SHLD FCB+33 ;RESET RANDOM RECORD IN FCB RET ; ENDIF ;CPM2X ; IF NOT CPM2X ; CNREC: MVI A,'?' ;MATCH ALL EXT ;AND EXIT ; ;POINT TO DIRECTORY ENTRY ; SOME: DCR A ;UNDO PREV 'INR A' ANI 3 ;MAKE MODULUS 4 ADD A ;MULTIPLY... ADD A ;..BY 32 BECAUSE ADD A ;..EACH DIRECTORY ADD A ;..ENTRY IS 32 ADD A ;..BYTES LONG LXI H,80H POINT TO BUFFER ADD L ;PO DB 'Can''t close file$' RDSECT: LDA SECINBF DCR A STA SECINBF JM RDBLOCK LHLD SECPTR LXI D,80H CALL MOVE128 SHLD SECPTR RET ; RDBLOCK: LDA EOFLG CPI 1 STC RZ MVI C,0 LXI D,DBUF RDSECLP: PUSH B PUSH D MVI C,STDMA IT SHLD SECTNO ;STORE IT MOV A,L POP H RET ; ERASFIL: LDA BATCHFLG ;DON'T ASK FOR ERASE.. ORA A ;..IN MULTI-FILE MODE,.. JZ NOASK ;..JUST DO IT. LXI D,FCB MVI C,SRCHF CALL BDOS INR A RZ CALL ILPRT DB 'File exists -- Type ''Y''ENTS STA FCBEXT MVI A,0FFH STA MAXEXT ;INIT MAX EXT NO. MVI C,SRCHF ;GET 'SEARCH FIRST' FNC LXI D,FCB CALL BDOS ;READ FIRST INR A ;WERE THERE ANY? JNZ SOME ;GOT SOME CALL ERXIT DB '++ File not found ++$' ; ;READ MORE DIRECTORY ENTRIESINT TO ENTRY ADI 15 ;OFFSET TO RECORD COUNT MOV L,A ;HL NOW POINTS TO REC COUNT MOV B,M ;GET RECORD COUNT DCX H DCX H ;BACK DOWN TO EXTENT NUMBER DCX H LDA MAXEXT ;COMPARE WITH CURRENT MAX. ORA A ;IF NO MAX YET JM BIGGER ;THEN SAVE RECORDCALL BDOS LXI D,FCB MVI C,READ CALL BDOS POP D POP B ORA A JZ RDSECOK DCR A JZ REOF CALL ERXIT DB '++ File read error ++$' RDSECOK: LXI H,80H DAD D XCHG INR C MOV A,C CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS JZ RD to erase: ',BELL,0 CALL KEYIN PUSH PSW CALL TYPE POP PSW CALL UCASE CPI 'Y' JNZ MENU CALL CRLF NOASK: LXI D,FCB MVI C,ERASE JMP BDOS ; BLKFILE: CALL ILPRT ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE" DB CR,LF,'No file sp ; MOREDIR: MVI C,SRCHN ;SEARCH NEXT LXI D,FCB CALL BDOS ;READ DIR ENTRY INR A ;CHECK FOR END (0FFH) JNZ SOME ;NOT END OF DIR...PROCESS EXTENT LDA MAXEXT ;HIT END...GET HIGHEST EXTENT NO. SEEN MOV L,A ;WHICH GIVES EXTENT COUNT -1 MVI H,0  COUNT ANYWAY CMP M JNC MOREDIR BIGGER: MOV A,B ;SAVE NEW RECORD COUNT STA RCNT MOV A,M ;SAVE NEW MAX. EXTENT NO. STA MAXEXT JMP MOREDIR ;GO FIND MORE EXTENTS ; ENDIF ;NOT CPM2X ; OPENFIL: XRA A STA FCBEXT LXI D,FCB MVI C,OPEN CBFULL JMP RDSECLP ; REOF: MVI A,1 STA EOFLG MOV A,C RDBFULL: STA SECINBF LXI H,DBUF SHLD SECPTR LXI D,80H MVI C,STDMA CALL BDOS JMP RDSECT ; WRSECT: LHLD SECPTR XCHG LXI H,80H CALL MOVE128 XCHG SHLD SECPTR LDA SECINBF     INR A STA SECINBF CPI DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS RNZ WRBLOCK: LDA SECINBF ORA A RZ MOV C,A LXI D,DBUF DKWRLP: PUSH H PUSH D PUSH B MVI C,STDMA CALL BDOS LXI D,FCB MVI C,WRITE CALL BDOS POP B POP D HAR: LDA PMMIBYTE ;IS THE MODEM A PMMI? ORA A ;SET FLAGS JZ MCHAR1 ;YES, JUMP CALL IN$MODCTLP ;GET ERROR-STATUS BYTE ANI ERRCDMSK ;MASK OUT ALL EXCEPT ERROR BITS (3-5) STA ERRCDE ;SAVE THE ERROR CODE MCHAR1: CALL IT CRC FLAG CPI CAN ;CANCEL? JZ ABORT DCR E JZ ABORT JMP WAITNLP ; WAITCRC: LDA QFLG ORA A JZ WAITCRC1 CALL ILPRT DB 'CRC request received',CR,LF,0 WAITCRC1: XRA A STA CKSUMFLG RET ; ;--->PARITY: Routine to setup PMMI for odd/ ;RESET PARITY BIT ON PMMI JMP OUT$MODCTLP ; INITADR: LHLD 1 LXI D,3 DAD D SHLD VSTAT+1 DAD D SHLD VKEYIN+1 DAD D SHLD VTYPE+1 DAD D SHLD VLIST+1 LXI D,30 DAD D SHLD VLSTAT+1 LDA PMMIBYTE ORA A RZ ;RETURN DONE FROM THIPOP H ORA A JNZ WRERR LXI H,80H DAD D XCHG DCR C JNZ DKWRLP XRA A STA SECINBF LXI H,DBUF SHLD SECPTR RET ; WRERR: MVI C,CAN CALL SEND CALL ERXIT DB CR,LF,'Error writing file',CR,LF,'$' ; ;----> RECV: Receive a character ;N$MODDATP POP D PUSH PSW CALL UPDCRC ;CALCULATE CRC ADD C MOV C,A LDA RSEEFLG ORA A JZ MONIN LDA VSEEFLG ORA A JNZ NOMONIN LDA DATAFLG ORA A JZ NOMONIN MONIN: POP PSW PUSH PSW CALL SHOW NOMONIN: POP PSW ORA A Reven parity. ; PARITY: LDA PMMIBYTE ;IS MODEM A PMMI? ORA A ;SET FLAGS RZ ;NO, RETURN LDA OPARITY ;GET ODD PARITY REQUEST BYTE ORA A ;SET FLAGS JNZ EVENPAR ;IF NOT ODD SEE IF IT IS EVEN LDA UARTCTLB ;GET UART/MODEM CONTROL BYTE ANI ODPARS ROUTINE.. LDA IN$MODCTLP+1 ;..IF NOT PMMI STA OUT$MODCTLP+1 INR A STA OUT$MODDATP+1 STA IN$MODDATP+1 INR A STA IN$BAUDRP+1 STA OUT$BAUDRP+1 INR A STA OUT$MODCTL2+1 RET ; ; CHECK OPTIONS, PUT 0 IN APPROPRIATE PLACES IN OPTION TABLE ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage ;characters on the line. For example, having just sent a sector, calling ;RECVDG will delete any line noise induced characters LONG before the ;ACK/NAK would be received. ; RECVDGET ; SEND: PUSH PSW LDA SSEEFLG ORA A JZ MONOUT LDA VSEEFLG ORA A JNZ NOMONOT LDA DATAFLG ORA A JZ NOMONOT MONOUT: POP PSW PUSH PSW CALL SHOW NOMONOT: POP PSW PUSH PSW CALL UPDCRC ;CALCULATE CRC ADD C MOV C,A SENDW: CALMSK JMP PARITY1 ; EVENPAR: LDA EPARITY ;GET EVEN PARITY REQUEST BYTE ORA A ;SET FLAGS RNZ ;IF EVEN PARITY NOT SPECIFIED RETURN LDA UARTCTLB ;GET UART/MODEM CONTROL BYTE ANI ODPARMSK ;SET FOR PARITY ORI EVPARMSK ;N ; IF OPTION SELECTED ; PROCOPT: LXI D,FCB+1 LDAX D STA OPTION OPTLP: INX D LDAX D CPI ' ' JZ ENDOPT LXI H,OPTBL MVI B,OPTBE-OPTBL OPTCK: CMP M JNZ OPTNO CPI 'O' JNZ OPTCK1 XRA A STA UARTFLG JMP OPTCK2 ; OPTCK1: CPI 'A' : EQU $ CALL IN$MODDATP CALL IN$MODDATP RECV: PUSH D MSEC: PUSH H LXI H,7500 CALL FIXCNT PUSH H POP D POP H CALL CKABORT MWTI: CALL RCVREADY JZ MCHAR DCR E JNZ MWTI DCR D JNZ MWTI DCR B JNZ MSEC POP D STC RET ; MCL SENDREADY JNZ SENDW POP PSW JMP OUT$MODDATP ; WAITNAK: LDA QFLG ORA A JZ WAITNLP CALL ILPRT DB 'Awaiting initial NAK',CR,LF,0 WAITNLP: CALL CKABORT MVI B,1 CALL RECV CPI NAK RZ CPI CRC ;CRC REQUEST? JZ WAITCRC ;YES, GO SEOW SET FOR EVEN PARITY PARITY1: JMP OUT$MODCTLP ;SEND TO PMMI - ;WHEN OUT$MODCTLP DOES RET IT ;WILL GO BACK TO CALLING ROUTINE ; NOPARIT: LDA PMMIBYTE ORA A RZ LDA UARTCTLB ;GET UART/MODEM CONTROL BYTE ORI NOPARMSK  JNZ OPTCK2 MVI A,TRUE STA UARTFLG OPTCK2: MVI M,0 JMP OPTLP ; OPTNO: INX H DCR B JNZ OPTCK CALL NOTVLDMSG POP PSW ;PRESERVE STACK JMP MENU ; ENDOPT: LDA VSEEFLG ORA A RNZ STA QFLG ;IF VIEWING SUPPRESS ALL ELSE RET ; DONE:      LDA BATCHFLG ORA A JNZ DONETC LDA QFLG ORA A JZ NMSTRNS MVI B,12 ;ZERO OUT FTRNMSG LXI H,FTRNMSG MVI A,0 ZEROLP: MOV M,A INX H DCR B JNZ ZEROLP MVI B,12 ;PUT FILE NAME IN FTRNMSG LXI H,FCB+1 LXI D,FTRNMSG LOADMSG: MVI A..FOR NEW FILE TRANSFER. MVI B,SECTNOE-SECTNOB ;ROUTINE ALSO DONE IN MENU. CALL MOVE LDA SENDFLG ;GOES TO EITHER SEND OR.. ORA A ;..RECEIVE FILE, DEPENDING.. JNZ SENDFIL1 ;..UPON WHICH ROUTINE SET.. JMP RCVFIL1 ;..THE FLAG IN MULTI-FILE MODE. POINTERS SHLD HLSAVE1 SHLD HLSAVE2 LDA TERMFLG ;SEE IF RETURN TO.. ORA A ;..TERMINAL MODE.. JNZ MENU ;..AFTER X'FER. CALL CRLF JMP TERM ; MOVEFCB: LXI H,FCB+16 LXI D,FCB MVI B,16 CALL MOVE XRA A STA FCBSNO STA FCBEXT RET ; STSTAT: PUSH B PUSH D PUSH H VLSTAT: CALL $-$ POP H POP D POP B ORA A RET ; UCASE: CPI 61H ;CHANGES LOWER CASE CHARACTER.. RC ;..IN A-REG TO UPPER CASE. CPI 7BH RNC ANI 5FH RET ; DECOUT: PUSH PSW PUSH B PUSH D PUSH H,4 ;START OF FILE TYPE? CMP B JZ PERIOD ;PUT IN PERIOD IF SO MOV A,M CPI ' ' ;DON'T PUT IN SPACE JZ SKPSP STAX D ;STORE IN FTRNMSG INX D SKPSP: INX H DCR B MOV A,B ORA A ;END OF FILE NAME? JZ FTRNMSG0 ;DISPLAY FILE NAME JMP LOAD; DONETC: CALL ILPRT DB CR,LF,'All transfers completed',CR,LF,BELL,0 DONETCA: LDA DISCFLG ;SEE IF DISCONNECT WHEN THROUGH ORA A JNZ DONETCE ;NO, DON'T DISCONNECT DONETCB: CALL ILPRT DB CR,LF,'Press RETURN to disconnect',BELL,CR,LF,0 MVI  SHOW: CPI LF JZ CTYPE CPI CR JZ CTYPE CPI 9 JZ CTYPE CPI ' ' JC SHOWHEX CPI 7FH JC CTYPE SHOWHEX: PUSH PSW MVI A,'(' CALL CTYPE POP PSW CALL HEXO MVI A,')' JMP CTYPE ; CTYPE: PUSH B PUSH D PUSH H MOV E,A MVI C,WR LXI B,-10 LXI D,-1 DECOU2: DAD B INX D JC DECOU2 LXI B,10 DAD B XCHG MOV A,H ORA L CNZ DECOUT MOV A,E ADI '0' CALL CTYPE POP H POP D POP B POP PSW RET ; ;----> DHXOUT: - DOUBLE PRECISION HEX OUTPUT ROUTINE. ; DHXOUMSG ;LOOP FOR ANOTHER CHARACTER ; PERIOD: MOV A,M CPI ' ' ;IS FILE TYPE EMPTY? JZ FTRNMSG0 ;GO IF SO MVI A,'.' ;ELSE PUT PERIOD IN MESSAGE STAX D INX D DCR B JMP LOADMSG ; FTRNMSG0: CALL ILPRT DB CR,LF FTRNMSG: DS 12 DB 0 C,RDCON CALL BDOS ;WAIT FOR RESPONSE CPI 0DH ;CARRIAGE RETURN JNZ DONETCB ;NOPE CALL ILPRT DB CR,LF,'Disconnected',CR,LF,0 CALL JMP$DISCONNT ;HANG-UP THE PMMI JMP EXIT ;GO TO CP/M ; DONETCE: CALL NOPARIT ;RESET TO NO PARITY MVI A,TRUE CON CALL BDOS POP H POP D POP B RET ; CRLF: PUSH PSW MVI A,CR CALL TYPE MVI A,LF CALL TYPE POP PSW RET ; TYPE: PUSH PSW PUSH B PUSH D PUSH H MOV C,A VTYPE: CALL $-$ POP H POP D POP B POP PSW RET ; STAT: PUSHT: PUSH H PUSH PSW MOV A,H ;GET MS BYTE CALL HEXO ;OUTPUT HIGH ORDER BYTE MOV A,L ;GET LS BYTE CALL HEXO ;OUTPUT LOW ORDER BYTE POP PSW POP H RET ; HEXO: PUSH PSW RAR RAR RAR RAR CALL NIBBL POP PSW NIBBL: ANI 0FH CPI  CALL ILPRT DB ' Transferred',CR,LF,LF,0 NMSTRNS: LDA FCB ;SAVE DRIVE NO. STA DISKNO LXI H,FCB ;BLANK OUT FILE CONTROL BLOCKS CALL INITFCBS LDA DISKNO ;PUT DRIVE NUMBER BACK STA FCB LXI H,RESTSN ;RESTORE SECTORE NUMBERS.. LXI D,SECTNOB ; STA FIRSTME ;SET FIRST-TIME FLAG STA FSTFLG ;RESET MULTIFILE TRANS STA NFILFLG ;..USED IN TERMINAL ROUTINE CMA STA SAVEFLG ;STOP MEMORY SAVE IN TERM ROUTINE STA LISTMOR ;STOP ANY BUFFERED OUTPUT TO PRINTER LXI H,BOTTRAM ;RESET PRINTER BUFFER  B PUSH D PUSH H ; VSTAT: CALL $-$ POP H POP D POP B ORA A RET ; KEYIN: PUSH B PUSH D PUSH H VKEYIN: CALL $-$ POP H POP D POP B RET ; LISTER: PUSH B PUSH D PUSH H VLIST: CALL $-$ POP H POP D POP B RET ; L10 JC ISNUM ADI 7 ISNUM: ADI '0' JMP TYPE ; ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN ;NO QUESTIONS ASKED, JUST QUIT ; CKQUIT: LDA BATCHFLG ORA A JNZ CKQTASK ;ASK FOR RETRY INR A ;RESET ZERO FLG RET ; CKQTASK:      MVI A,1 STA ERRCT CALL ILPRT DB CR,LF,'Multiple errors encountered.',CR,LF DB 'Type Q to quit, R to retry: ',BELL,0 CALL KEYIN PUSH PSW CALL CRLF POP PSW CALL UCASE ;INSTEAD OF "ANI 5FH" CPI 'R' RZ CPI 'Q' JNZ CKQUIT ORA A  CALL CPMLINE CALL PROCOPT CHECKNM: LDA FCB+1 ;CHECK ON THE PRIMARY OPTION CPI 'E' ;RETURN IF ECHO OPTION RZ CPI 'H' ;RETURN IF HELP OPTION RZ CPI 'L' ;RETURN IF LOCAL ECHO OPTION RZ MOV B,A LDA PMMIBYTE ORA A MOV A,B JZ S4 CPte: ',0 LXI H,FCB+9 MVI M,0 ;PUTS A ZERO IN FIRST POSITION SO AS TO LOOP5: CALL KEYIN ;FORCE THE DEFAULT OPTION OF 300 BAUD. CPI CR ;CARRIAGE RET ENTERS BAUD RATE JNZ CONNEWB ;GOES TO THE ESTABLISHED ROUTINE - RETURN TO MAIN CALL CRLF ;PROGRAM99.9969% of all 17-bit error bursts, and 99.9984% * ;* of all possible longer error bursts. (Ref: Computer * ;* Networks, Andrew S. Tanenbaum, Prentiss-Hall, 1981) * ;* * ;* Designed & coded by Paul Hansknecht, June 13, 1981 * ;* RET ; SHFTYPE: PUSH PSW CALL ILPRT DB 'ctrl-',0 POP PSW ADI 40H CALL TYPE ; ;WRITE A STRING OF CHARACTERS ; ILPRT: XTHL ILPLP: MOV A,M ORA A JZ ILPRET CALL CTYPE INX H JMP ILPLP ILPRET: XTHL RET ; PRTMSG: MVI C,PRII 'C' RZ S4: CPI 'T' JZ TERMSEL CPI 'S' JZ CKFILE CPI 'R' JNZ BDOPT LDA BATCHFLG ;IF MULT FILE MODE, THEN.. ORA A ;..RECV OPT DOES NOT NEED.. RZ ;..NAME. JMP CKFILE BDOPT: CALL ILPRT DB CR,LF,'++ Bad Option ++',CR,LF,0 JMP REEN IS DONE THERE. JMP JMP$INITMOD ; CONNEWB: CPI 30H ;MAKE SURE IT'S.. JC LOOP5 ;..A DIGIT, ELSE.. CPI 3AH ;..DON'T ACCEPT IT. JNC LOOP5 MOV M,A MOV C,A CALL TYPE ;ECHO THE CHARACTER ENTERED INX H JMP LOOP5 ; ;************************ * ;* Copyright (c) 1981, Carpenter Associates * ;* Box 451 * ;* Bloomfield Hills, MI 48013 * ;* 313/855-3074 * ;* * ;* This program may be freely reproduced for non-profit use. * ;* * ;************NT JMP BDOS ; ERXIT: POP D CALL PRTMSG MVI A,BELL CALL TYPE LDA BATCHFLG ORA A JNZ DONETCE MVI A,'Q' ;RESET QFLG STA QFLG JMP ABORT ;ABORT OTHER COMPUTER ; EXIT: LDA SAVUSR MOV E,A CALL SETUSR LXI D,80H MVI C,STDMA CALL T CKFILE: LDA FCB+17 ;IF OPTION THAT NEEDS FILE NAME,.. CPI ' ' ;..THEN CHECK TO SEE IF NAME.. RNZ ;..EXISTS. IF NOT.. REENT: CALL ILPRT ;..DO EVERYTHING OVER. DB CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0 LXI D,CMDBUF CALL IN**************************************** ;* * ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20 * ;* 8080 Mnemonics * ;* * ;* These subroutines will compute and check a true 16-bit * ;* Cyclic Redundancy Code f**************************************************** ; ; ENTRY CLRCRC,UPDCRC,FINCRC,CHKCRC ; CLRCRC: EQU $ ;RESET CRC ACCUMULATOR FOR A NEW MESSAGE. PUSH H LXI H,0 SHLD CRCVAL POP H RET ; UPDCRC: EQU $ ;UPDATE CRC ACCUMULATOR USING BYTE IN BDOS LHLD STACK SPHL LDA SAVCCP ORA A JZ 0 ;WARM BOOT RET ; MOVE128: MVI B,128 MOVE: MOV A,M STAX D INX H INX D DCR B JNZ MOVE RET ; ;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH ; SETFCB: LXI D,CMDBUF LXI H,FCB BUFF JMP SETFCB ; TERMSEL: LDA FCB+17 CPI ' ' JNZ SAVAGN MVI A,FALSE STA SAVEFLG MVI A,TRUE STA NFILFLG RET ; SAVAGN: MVI A,FALSE STA NFILFLG RET ; NEWBAUD: LDA PMMIBYTE ORA A RZ CALL ILPRT DB CR,LF,'Enter New Baudraor a message of arbitrary length. * ;* * ;* The use of this scheme will guarantee detection of all * ;* single and double bit errors, all errors with an odd * ;* number of error bits, all burst errors of length 16 or * ;* less, (A). PUSH PSW PUSH B PUSH H MVI B,8 MOV C,A LHLD CRCVAL UPDLOOP: MOV A,C RLC MOV C,A MOV A,L RAL MOV L,A MOV A,H RAL MOV H,A JNC SKIPIT MOV A,H ;THE GENERATOR IS X^16 + X^12 + X^5 + 1 XRI 10H ;AS RECOMMENDED BY CCITT.      MOV H,A ;AN ALTERNATE GENERATOR WHICH IS OFTEN MOV A,L ;USED IN SYNCHRONOUS TRANSMISSION PROTOCOLS XRI 21H ;IS X^16 + X^15 + X^2 + 1. THIS MAY BE MOV L,A ;USED BY SUBSTITUTING XOR 80H FOR XOR 10H SKIPIT: DCR B ;AND XOR 05H FOR XOR 21H IN THE ADJACE: MOV A,L ORA H DCX H JNZ BILOOP DCR C JNZ BCLOOP MVI A,BELL CALL TYPE DCR B JNZ BLOOP JMP MENU1 ; MENU: LDA EXITFLG ORA A JNZ EXIT MENU1: LXI H,RESTSN ;RESTORE SECTOR NUMBERS.. LXI D,SECTNOB ;..FOR NEW FILE TRANSFER. MV ' R - Receive file using Christensen Protocol',CR,LF DB ' S - Send file using Christensen Protocol',CR,LF DB ' Command is: R(or S) FILENAME.TYP',CR,LF DB ' R and S can use the following subcommands:',CR,LF DB ' B - Bulkparity',CR,LF DB ' 0 - Set and check for even parity',CR,LF DB ' Both ends must be capable of these options',CR,LF DB ' which are available only in S and R modes.',CR,LF DB ' The parity checking will be part of the',NT CODE JNZ UPDLOOP SHLD CRCVAL POP H POP B POP PSW RET ; FINCRC: EQU $ ;FINISH CRC CALCULATION FOR OUTPUT MESSAGE PUSH PSW XRA A CALL UPDCRC CALL UPDCRC PUSH H LHLD CRCVAL MOV D,H MOV E,L POP H POP PSW RET ; CHKCRC: EI B,SECTNOE-SECTNOB CALL MOVE LXI H,RESTROPT ;RESTORE OPTION TABLE LXI D,OPTBL MVI B,OPTBE-OPTBL CALL MOVE MVI A,0 STA MFFLG1 ;RESET MFACCESS ROUTINE.. CMA ;..AND MULTI TRANS IN CASE.. STA FSTFLG ;..OF ABORT. JMP XPRT ; MENU2: CALL transfer using wildcards (e.g. *.*)',CR,LF DB ' Q - Quiet mode (no messages to console)',CR,LF DB ' T - Return to terminal mode after transfer',CR,LF DB ' V - View bytes transferred on console',CR,LF,LF DB 'The singleCR,LF DB ' file transfer protocol.',CR,LF,LF DB ' Speed Options:',CR,LF DB ' After entering your primary and secondary options,' DB CR,LF DB ' you can set the modem speed by placing a "." after' DB CR,LF DB ' the optiQU $ ;CHECK CRC BYTES OF RECEIVED MESSAGE PUSH H LHLD CRCVAL MOV A,H ORA L POP H RZ MVI A,0FFH RET ; CRCVAL: DW 0 ; MENU0: LDA NFILFLG ORA A JNZ MENU ;GO IF NO FILE ACTIVE CALL ILPRT ;ELSE PRINT MESSAGE DB CR,LF,LF DB '**  CLRTST CALL ILPRT DB ' Single Letter Commands',CR,LF,LF DB ' H - Display this information',CR,LF DB ' ? - Display current settings',CR,LF,LF DB ' B - Change Baudrate of Port.',CR,LF,LF DB ' T - Terminal mode',CR,LF  letter commands may also be used on the',CR,LF DB 'command line when the program is initially executed.' DB CR,LF,LF,0 ; CALL NXTSCRN ; LDA PMMIBYTE ORA A JZ THREELTR CALL ILPRT DB ' Additional Subcommands for PMMI Modem',CR,LF,Lons followed by the speed e.g. 110, 300.',CR,LF DB ' For example: SBO1T.600 will set the modem to run',CR,LF DB ' at 600 baud.',CR,LF,LF,0 ; CALL NXTSCRN ; THREELTR: CALL ILPRT DB ' Three Letter Commands',CR,LF,LF DBThere may be text in the memory buffer **',CR,LF DB '** It will be lost unless NOL or WRT commands are used **' DB CR,LF,BELL,0 MVI B,2 ;2 MORE BELLS BLOOP: LDA BELRPT ;GET TIME MOV C,A BCLOOP: LXI H,1000 ;ABOUT 0.03 SECONDS CALL FIXCNT BILOOPDB ' E - Terminal mode with echo',CR,LF DB ' L - Terminal mode with local echo',CR,LF DB ' For capturing text use T(or E or L) FILENAME.TYP and' DB CR,LF DB ' Start & Stop toggles described on subsequent screen.' DB CR,LF,LF DB F DB ' Modem control:',CR,LF DB ' O - Send or receive on Originate tone',CR,LF DB ' A - Send or receive on Answer tone',CR,LF DB ' D - Disconnect option',CR,LF,LF DB ' Parity options:',CR,LF DB ' 1 - Set and check for odd  'DIR - List directory and space free (may specify drive)' DB CR,LF DB 'END - Exit from this program',CR,LF DB 'ERA - Erase file (may specify drive)',CR,LF DB 'LOG - Change default drive/user (specify drive/user)' DB CR,LF DB ' and re    set disks. e.g. LOG A0, LOG B (user unchanged)' DB CR,LF DB 'SPD - Set speed of file output in terminal mode',CR,LF,0 ; CALL SORPTST JNZ NOTIME CALL ILPRT DB 'TIM - Set S mode time-to-send message',CR,LF,0 ; NOTIME: LDA TOGGLECRC ORA A tems',CR,LF,0 LDA SETUPTST ORA A JZ NOSETUP CALL ILPRT DB 'SET - Set communication ports',CR,LF,0 ; NOSETUP: MVI A,LF CALL TYPE JMP NOPMMI ; NONUM: CALL ILPRT DB 'CAL - Dial number',CR,LF DB 'DSC - Disconnect',CR,LF  CALL SHFTYPE DB ' - Change baud rate',CR,LF,0 ; S5A: LDA TRANLOGON ORA A JZ NOTRANLOG LDA LOGCHR CALL SHFTYPE DB ' - Transmit logon',CR,LF,0 ; NOTRANLOG: LDA LSTTST ORA A JZ NOLST2 LDA LSTCHR CALL SHFTYPE DB ' - Toggle pr,0 ; XPRT: CALL ILPRT DB CR,LF,'Drive ',0 MVI C,CURDSK ;CURRENT DISK FUNCTION CALL BDOS ADI 'A' ;MAKE ASCII CALL TYPE ; IF CPM2X ;IF CPM VER 2.X ; CALL GETUSR ;GET CURRENT USER NUMBER CPI 0 JZ SR3B ;SKIP IF USER 0 PUSH PSW CAL JZ NOTOGCRC CALL ILPRT DB 'TCC - Toggle Checksum/CRC mode on receive',CR,LF,0 ; NOTOGCRC: LDA TOGGLEBK ORA A JZ NOTOGBK CALL ILPRT DB 'TBR - Toggle backspace to rub conversion',CR,LF,0 ; NOTOGBK: LDA TOGGLELOC ORA A JZ NOTOGLOC  DB 'BYE - Disconnect and reboot',CR,LF,LF,0 ; NOPMMI: CALL ILPRT DB ' The following are terminal text buffer commands:' DB CR,LF,0 LDA PMMIBYTE ORA A JNZ SKIPLF MVI A,LF CALL TYPE SKIPLF: CALL ILPRT DB 'DEL - Delete memory binter',CR,LF,0 ; NOLST2: MVI A,LF CALL TYPE LDA SAVECHR CALL SHFTYPE DB ' - Start copy into buffer',CR,LF,0 LDA UNSAVECHR CALL SHFTYPE DB ' - Stop copy into buffer',CR,LF DB ' Start & Stop may be toggled as often as desired.'L ILPRT DB ', User ',0 POP PSW MVI H,0 MOV L,A CALL DECOUT ;REPORT USER ; ENDIF ;CPM2X ; SR3B: CALL CRLF LDA NFILFLG ORA A JNZ NOBUFMSG CALL GETSPC CALL ILPRT DB ' bytes of buffer free',CR,LF,0 NOBUFMSG: CALL ILPRT DB 'COMMCALL ILPRT DB 'TLC - Toggle 1) local command immediate',CR,LF DB ' 2) local command after ',0 LDA EXTCHR CALL SHFTYPE DB CR,LF,0 ; NOTOGLOC: LDA TOGGLELF ORA A JZ NOTOGLF CALL ILPRT DB 'TLF - Toggle send linefeed after cuffer and file',CR,LF DB 'NOL - Return to terminal mode - no loss of data in buffer' DB CR,LF DB 'WRT - Write memory buffer to disk file',CR,LF,LF,0 CALL NXTSCRN ; CALL ILPRT DB ' Local Commands while in Terminal Mode',CR,LF,LF,,CR,LF DB ' A ":" at start of line indicates buffer is open.',CR,LF DB ' XOFF automatically used to stop input when writing',CR,LF DB ' full buffer to disk, XON sent to resume.',CR,LF,LF,0 LDA TRANCHR CALL SHFTYPE DB ' - Transfer AAND (H for Help): ',0 GETCMD: LXI D,CMDBUF ;ENTER COMMAND CALL INBUFF CALL CRLF LXI D,CMDBUF+2 ;POINT TO COMMAND CALL ILCOMP DB 'END',0 JNC EXIT CALL ILCOMP DB 'LOG',0 JNC LOGNEW CALL ILCOMP DB 'DIR',0 JNC DIR CALL ILCOMP DB arriage return',CR,LF,0 ; NOTOGLF: LDA TOGXOFF ORA A JZ NOTOGXOFF CALL ILPRT DB 'TXO - Toggle XOFF/XON testing in terminal mode file output' DB CR,LF,0 ; NOTOGXOFF: LDA PMMIBYTE ORA A JNZ NONUM CALL ILPRT DB 'NUM - List remote sys0 LDA EXITCHR CALL SHFTYPE DB ' - Exit to command mode',CR,LF,LF,0 ; LDA PMMIBYTE ORA A JZ S5A ; LDA DISCCHR CALL SHFTYPE DB ' - Disconnect',CR,LF,0 LDA BRKCHR CALL SHFTYPE DB ' - Send break',CR,LF,0 LDA CHGBAUD SCII file to remote',CR,LF,LF,0 LDA LOCONEXTCHR ORA A LDA EXTCHR JNZ REMDFLT CALL SHFTYPE DB ' - Send local control character to remote',CR,LF,0 JMP XPRT REMDFLT: CALL SHFTYPE DB ' - Next character will be used for local control',CR,LF'ERA',0 JNC ERASEF CALL ILCOMP DB '?',0 JNC CURPAR CALL ILCOMP DB 'SPD',0 JNC SETSPD CALL ILCOMP DB 'TIM',0 JNC SETTIM CALL ILCOMP DB 'TCC',0 JNC TOGCRC CALL ILCOMP DB 'TBR',0 JNC TOGBKSP CALL ILCOMP DB 'TLC',0 JNC TOG    LOC CALL ILCOMP DB 'TLF',0 JNC TOGLF CALL ILCOMP DB 'TXO',0 JNC TOGTXOFF LDA PMMIBYTE ORA A JNZ NONUM2 CALL ILCOMP DB 'NUM',0 JNC NUMPRN NONUM2: LDA SETUPTST ORA A JZ NOSETUP2 CALL ILCOMP DB 'SET',0 JNC SETUPENT NOSETUP2CHAR IN A-REG. JC NOTVLD ;CARRY SET = NO MATCH DOOPT: PUSH H ;LOAD ORIGINAL FCB WITH TRANSFER.. CALL SETFCB ;..CMDS AND GO TO BEGINNING OF.. POP H ;..PROGRAM. WILL FOLLOW SAME LOGIC.. JMP RESTART ;..AS IF PROGRAM WERE CALLED WITH.. ;..CP/M COMF CPM VER. 2.X ; CALL GETUSR ;PICK UP CURRENT USER NUMBER MOV B,A ;SAVE IT LDA CMDBUF+7 ;GET NEW USER NUMBER CPI ' ' ;CHECK FOR SPACE JZ SR7B ;EXIT IF NO NEW USER NUMBER SPECIFIED CALL NUMCHK ;CHECK TO SEE IF IT IS A NUMBER MOV B,A ;SACR CALL CRLF MVI C,RESET CALL BDOS LDA DISKSAV MOV E,A MVI C,SELDSK CALL BDOS ; IF CPM2X LDA SAVUSR MOV E,A CALL SETUSR ENDIF ; JMP XPRT ; IF CPM2X ; GETUSR: MVI E,0FFH ;GET CURRENT USER SETUSR: MVI C,USER ;SET-UP FUNCT: CALL ILCOMP DB 'NOL',0 JC NXTOPT1 ;CARRY SET = NO MATCH LDA NFILFLG ORA A JNZ NOFILOPN ;GO TELL OPERATOR IF NO FILE OPEN LDA ORIGSAV STA ORIGFLG CALL BUFMSG LHLD HLSAVE ;RETURN TO TERMINAL.. JMP TERM ;..MODE WITH SAVE OPTION.. MAND LINE. ; NOTVLD: CALL NOTVLDMSG JMP XPRT ; NOTVLDMSG: CALL ILPRT DB '++ Invalid Command ++',CR,LF,BELL,0 RET ; DISCON1: CALL JMP$DISCONNT CALL ILPRT DB CR,LF,'<< Disconnected >>',CR,LF,BELL,0 JMP EXITMEN ; BYEBYE: CALL ILPRTVE LDA CMDBUF+8 ;GET SECOND DIGIT CPI ' ' JZ SR7B ;GO IF SPACE CALL NUMCHK MOV C,A ;SAVE MOV A,B ;GET SAVED FIRST DIGIT ADD A ; X2 ADD A ; X4 ADD A ; X8 ADD B ; X9 ADD B ; X10 ADD C MOV B,A ;SAVE LDA CMDBUF+9 ;GET THIRDION CALL JMP BDOS ;NUMBER IN RETURNED IN A ; ENDIF ;CPM2X ; NORESET: CALL ILPRT DB '++ Terminal mode file open ++',CR,LF DB '++ Use WRT or DEL before LOG command ++',CR,LF DB CR,LF,LF,BELL,0 XRA A JMP XPRT ; ERASEF: LXI D,CM;..IF PREVIOUSLY ENABLED. ; NXTOPT1: CALL ILCOMP DB 'WRT',0 JNC WRTFIL CALL ILCOMP DB 'DEL',0 JNC NEWFILE LDA PMMIBYTE ORA A JZ S6 CALL ILCOMP ;DE SET FROM 1ST ILCOMP CALL DB 'DSC',0 JNC DISCON1 CALL ILCOMP DB 'BYE',0 JNC BY DB CR,LF,'Goodbye...',CR,LF,0 XRA A CALL OUT$MODCTLP CALL OUT$MODCTL2 LDA SAVUSR MOV E,A CALL SETUSR LHLD CLDBOOT ;GET COLD BOOT PROM ADDRESS OR WARM BOOT PCHL ;JUMP TO IT ; DIR: MVI C,CURDSK CALL BDOS STA DISKSAV CALL DIRLST  DIGIT CPI ' ' JZ SR7B ;GO IF SPACE CALL NUMCHK MOV C,A ;SAVE MOV A,B ;GET SAVED FIRST & SECOND DIGIT ADD A ; X2 ADD A ; X4 ADD A ; X8 ADD B ; X9 ADD B ; X10 ADD C ; CPI 16 ;CHECK FOR < 16 ; JNC NOTVLD ;GO IF NOT MOV B,ADBUF ;PUT CMD LINE INTO FCB AT HL LXI H,FCB CALL CPMLINE CALL MOVEFCB ;MOVE FCB+16 TO FCB LDA FCB+1 CPI ' ' JZ NOTVLD ;GO IF NO FILE SPECIFIED LXI D,FCB MVI C,SRCHF CALL BDOS INR A ;0 IF FILE NOT FOUND JNZ ERAFILE ;OK, GO ERASE CALLEBYE CALL ILCOMP DB 'CAL',0 JC S6 MVI A,20H ;FOOL THE SYSTEM STA CMDBUF+4 ;..CMDBUF SO THAT IT.. JMP DOOPT ;..LOOKS AT OPTION FOR DIAL S6: PUSH H LDA CMDBUF+2 LXI H,COMPLIST CALL COMPARE ;COMPARES LIST POINTED TO BY HL.. POP H ;..TO  LDA DISKSAV MOV E,A MVI C,SELDSK CALL BDOS JMP XPRT ; LOGNEW: LDA NFILFLG ORA A JZ NORESET LDA CMDBUF+6 CPI ' ' JNZ SPECIFD MVI C,CURDSK CALL BDOS ADI 'A' SPECIFD: SUI 'A' STA DISKSAV CPI 16 JNC NOTVLD ; IF CPM2X ;I SR7B: MOV A,B STA SAVUSR ; ENDIF ;CPM2X ; CALL ILPRT DB 'Insert disk for drive ',0 LDA DISKSAV ADI 'A' CALL TYPE NOTCR: CALL ILPRT DB CR,LF,'Hit return when ready',0 CALL KEYIN CPI 3 ;CTL-C ABORTS LOGIN JZ XPRT CPI CR JNZ NOT ILPRT DB '++ File not found ++',CR,LF,BELL,0 JMP XPRT ; ERAFILE: LXI D,FCB MVI C,ERASE CALL BDOS CALL ILPRT DB 'File erased',CR,LF,0 JMP XPRT ; SETSPD: CALL ILPRT DB 'Enter character output delay [0(none) - 9(longest delay)]: ',0      CALL NUMGET JNC NOCHG1 STA BYTDLY NOCHG1: CALL SPDMSG CALL ILPRT DB CR,LF,'Enter additional delay after [0-9]: ',0 CALL NUMGET JNC NOCHG2 RLC ;X2 RLC ;X4 STA CRDLY NOCHG2: CALL CRDLYMSG JMP XPRT ; NUMGET: LXI D,CMDBUF CALL,LF DB ' 7=4800, and 8=9600 Baud.' DB CR,LF,LF,'Enter value: ',0 CALL NUMGET CPI 9 JNC NOTVLD STA MSPEED CALL SETTIM2 JMP XPRT ; SETTIM2: CALL SORPTST JNZ SETTIM3 CALL ILPRT DB 'Rate for the S mode time-to-send message is set CMA STA LOCONEXTCHR CALL TOGLOC2 JMP XPRT ; TOGLOC2: CALL ILPRT DB 'Use ',0 LDA LOCONEXTCHR ORA A LDA EXTCHR JZ LOCMSG CALL SHFTYPE DB ' before local command',CR,LF,0 RET ; LOCMSG: CALL SHFTYPE DB ' to send local command to  ' CMC RZ MOV B,A CPI 'N' MVI A,FALSE RZ MOV A,B CPI 'Y' MVI A,TRUE RZ POP PSW ;PRESERVE STACK JMP NOTVLD ; XOFFMSG: CALL ILPRT DB 'XOFF testing ',0 LDA XOFFTST ORA A JNZ XOTSTON CALL ILPRT DB 'NOT ',0 XOTSTON: C INBUFF LDA CMDBUF+2 ;GET NUMBER CPI ' ' RZ NUMCHK: SUI '0' CPI 10 RC POP PSW ;PRESERVE STACK JMP NOTVLD ; SPDMSG: CALL ILPRT DB 'Terminal mode file output delay is 0.',0 LDA BYTDLY CALL GIVNUM CALL ILPRT DB ' seconds per chara to ',0 JMP SETTIM4 SETTIM3: CALL ILPRT DB 'Modem speed is ',0 SETTIM4: JMP BAUDPRT ; SORPTST: LDA SETUPTST MOV B,A LDA PMMIBYTE ORA B RET ; TOGCRC: LDA TOGGLECRC ORA A JZ NOTVLD LDA CKSUMDFLT CMA STA CKSUMDFLT CALL TOremote',CR,LF,0 RET ; TOGLF: LDA TOGGLELF ORA A JZ NOTVLD LDA ADDLF CMA STA ADDLF CALL TOGLF2 JMP XPRT ; TOGLF2: CALL ILPRT DB 'Linefeed ',0 LDA ADDLF ORA A JNZ LFMSG CALL ILPRT DB 'NOT ',0 LFMSG: CALL ILPRT DB 'sent afALL ILPRT DB 'used',0 XONMSG3: CALL ILPRT DB ' in terminal mode file output',CR,LF,0 RET ; XONMSG: CALL ILPRT DB 'XON ',0 LDA XONWAIT ORA A JNZ XONMSG2 CALL ILPRT DB 'NOT ',0 XONMSG2: CALL ILPRT DB 'automatically tested after cter',CR,LF,0 RET ; CRDLYMSG: CALL ILPRT DB 'Additional delay after is 0.',0 LDA CRDLY CALL GIVNUM CALL ILPRT DB ' seconds',CR,LF,0 RET ; GIVNUM: ADD A ;2X CPI 10 MOV B,A JNC NOZERO MVI A,'0' CALL TYPE MOV A,B NOZERO: GCRC2 JMP XPRT ; TOGCRC2: ORA A JNZ CHEKMSG CALL ILPRT DB 'CRC mode set',CR,LF,0 RET ; CHEKMSG: CALL ILPRT DB 'Checksum mode set',CR,LF,0 RET ; TOGBKSP: LDA TOGGLEBK ORA A JZ NOTVLD LDA CONVBKSP CMA STA CONVBKSP CALL Tter ',CR,LF,0 RET ; TOGTXOFF: LDA TOGXOFF ORA A JZ NOTVLD CALL ILPRT DB 'Use XOFF testing? (Y/N): ',0 CALL GETANS JC NOCHG3 STA XOFFTST NOCHG3: CALL XOFFMSG CALL ILPRT DB CR,LF,'Use XON waiting after (Y/N): ',0 CALL GETA',0 JMP XONMSG3 ; SETUPENT: LDA SETUPTST ORA A JZ NOTVLD LXI D,CMDBUF+1 CALL JMP$SETUPR JMP XPRT ; NEWFILE: LDA NFILFLG ORA A JNZ NOFILOPN LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED CPI ' ' JZ NOFILOPN ;IF NO FILE, DON'T PUSH H MOV L,A MVI H,0 CALL DECOUT POP H RET ; SETTIM: CALL SORPTST JNZ NOTVLD CALL ILPRT DB 'Use 0-8 to give baud rate for S mode time-to-send message,' DB CR,LF DB 'where 0=110, 1=300, 2=450, 3=600, 4=710, 5=1200, 6=2400,' DB CROGBKSP2 JMP XPRT ; TOGBKSP2: LDA CONVBKSP ORA A JZ NORUBMSG CALL ILPRT DB 'Backspace is rub',CR,LF,0 RET ; NORUBMSG: CALL ILPRT DB 'Backspace is backspace',CR,LF,0 RET ; TOGLOC: LDA TOGGLELOC ORA A JZ NOTVLD LDA LOCONEXTCHR NS JC NOCHG4 STA XONWAIT NOCHG4: CALL XONMSG LDA XONWAIT ORA A JZ XPRT CMA STA XOFFTST ;DON'T ALLOW BOTH CALL ILPRT DB 'Therefore ',0 CALL XOFFMSG JMP XPRT ; GETANS: LXI D,CMDBUF CALL INBUFF LDA CMDBUF+2 ;GET ANSWER CPI 'ERASE LXI D,FCB3 MVI C,ERASE CALL BDOSRT MVI A,TRUE ;DO NOT ALLOW TERMINAL.. STA NFILFLG ;..SAVE SINCE NO FILE.. CMA ;..SPECIFIED. STA SAVEFLG LXI H,FCB3 CALL INITFCBS LXI H,BOTTRAM SHLD HLSAVE JMP XPRT ; WRTFIL: LDA NFILFLG     CPI TRUE JZ NOFILOPN LDA FCB3+1 ;CHECK THAT FILE WAS REQUESTED CPI ' ' JZ NOFILOPN LHLD HLSAVE CALL NUMRECS ;DISK WRITE ROUTINE AS USED IN.. CALL WRTDSK ;..IN THE INTDSKSV ROUTINE. CALL CLOSE3 MVI A,TRUE STA NFILFLG CMA STA SAVEFLG INX H INX H MVI B,30 CALL MOVE CALL NEWLINE DCR C ;NUMBER OF LINES TO PRINT JZ NUMPRN2 JMP NUMPRN1 ; NEWLINE: ;PUTS CR-LF AT MEMORY POINTED BY 'DE' MVI A,CR ;CR STAX D ;STORE IT MVI A,LF ;LF INX D ;BUMP POINTER STAX D ;STORE LF ? JNZ CLRTST POP PSW ;CLEAN RETURN ADR OFF OF STACK JMP XPRT ; CLRTST: LDA SCRNTEST ORA A JNZ CLRSCRN ; LOTSALF: MVI A,CR CALL TYPE MVI B,12 MVI A,LF LFLOOP: CALL TYPE DCR B JNZ LFLOOP RET ; CURPAR: CALL CLRTST CALL ILPRL: DAD D DCR A JNZ CNTMUL POP D RET ; COMPLIST: DB 6, 'S', 'R', 'T', 'E', 'H', 'L' ILCOMP: INLNCOMP ;A LIB MACRO INBUFF: INBUF ;A LIB MACRO ; ;IF ABOVE ROUTINE DOES NOT LET YOU EDIT IN A PROPER MANNER, ;THEN THE MACRO MAY BE SUBSTITU LXI H,FCB3 CALL INITFCBS ;BLANK OUT FCB SO WRITTEN FILE CAN'T BE ERASED. LXI H,BOTTRAM SHLD HLSAVE JMP XPRT ; NOFILOPN: CALL ILPRT DB '++ No File Open ++',CR,LF,BELL,0 JMP XPRT ; ;THIS ROUTINE DISPLAYS THE PHONE NUMBERS IN THE LIBRARY  INX D ;BUMP POINTER RET ; SPACES: MVI A,20H ;SPACE STAX D INX D ;1 STAX D INX D ;2 STAX D INX D ;3 RET ; NUMPRN2: MVI A,'$' STAX D MVI C,PRINT LXI D,DBUF ;POINT TO TABLE OF NUMBERS TO PRINT CALL BDOS CALL CRLF CALL CRLFT DB ' Current Settings',CR,LF,LF,LF,0 LDA CKSUMDFLT CALL TOGCRC2 LDA LSTTST ORA A JZ NOLST3 CALL LSTMSG NOLST3: CALL SETTIM2 CALL TOGBKSP2 CALL TOGLF2 CALL TOGLOC2 CALL ILPRT DB 'Terminal mode file buffer is ',0 TED FOR THE FOLLOWING ROUTINE: ; ;INBUFF: ; MVI C,RDBUF ; JMP BDOSRT ;BUT BE CAREFUL OF CONTROL-C ; CPMLINE: CMDLINE ;A LIB MACRO DIRLST: DIRLIST ;A LIB MACRO SENDTIM: SENDTIME ;A LIB MACRO BAUDPRT: PRTBAUD ;A LIB MACRO NFILFLG: DB F; NUMPRN: PUSH H CALL CLRTST CALL ILPRT DB ' Library of Phone Numbers of Remote Systems',0 MVI C,13 ;NUMBER OF LINES TO MOVE LXI H,NUMBLIB ;ADDRESS OF SOURCE MEMORY LXI D,DBUF ;ADDRESS OF TARGET MEMORY CALL NEWLINE  POP H JMP XPRT ; COMPARE: MOV B,M ;COMPARES A-REG WITH LIST.. COMPLP: INX H ;..ADDRESSED BY HL. FIRST ELEMENT.. CMP M ;..OF LIST MUST BE NUMBER OF ELEMENTS.. JZ VALID ;..BEING COMPARED. RETURNS WITH.. DCR B ;..CARRY SET IF A-REG DOES NOT. LDA NFILFLG ORA A JZ ACTIVE CALL ILPRT DB 'in',0 ACTIVE: CALL ILPRT DB 'active',CR,LF,'Unused portion of buffer is ',0 CALL GETSPC CALL ILPRT DB ' bytes',CR,LF,0 CALL XOFFMSG CALL XONMSG CALL SPDMSG CALL CRDLYMSG CALL CRLF JALSE ;NORMALLY SET TO FALSE. ALLOWS WRITE TO.. ; ;..MEMORY IN TERMINAL MODE. OPTION: DB 0 ; OPTBL EQU $ ; ANSWFLG: DB 'A' DISCFLG: DB 'D' ORIGFLG: DB 'O' QFLG: DB 'Q' RSEEFLG: DB 'R' SSEEFLG: DB 'S' VSEEFLG: DB 'V' TERMFLG: ;START WITH CRLF STAX D ;+LF INX D ;AND BUMP IT NUMPRN1: INX H ;SKIP PMMI DIALING LETTER INX H ;AND EQUAL SIGN MVI B,30 ;NUMBER OF BYTES TO MOVE CALL MOVE ;MOVE TO BUFFER CALL SPACES ;2 ENTRIES + 3 SPACES = 63 CHARACTERS . JNZ COMPLP ;.. CONTAIN AN ELEMENT IN LIST. STC VALID: RET ; NXTSCRN: CALL ILPRT DB 'HIT any KEY to CONTINUE',0 NOKEY1: CALL STAT ;GET KEYBOARD STATUS JZ NOKEY1 ;KEEP LOOPING UNTIL KEYPRESS CALL KEYIN ;GOBBLE UP KEYPRESS CPI 3 ;QUITMP XPRT ; GETSPC: CALL GETMAX MOV B,A LHLD HLSAVE STC CMC MVI A,0 SBB L MOV L,A MOV A,B SBB H MOV H,A JMP DECOUT ; ;ADJUSTS LOOP COUNTERS FOR VARIOUS CLOCK SPEEDS ; FIXCNT: LDA CLOCK CPI 1 RZ PUSH D PUSH H POP D CNTMU DB 'T' LOCCHFLG: DB 'L' EPARITY: DB '0' ;EVEN PARITY SUB-OPTION ;ONLY AVAILABLE IN 'S' AND 'R' MODES OPARITY: DB '1' ;ODD PARITY SUB-OPTION ;ONLY AVAILABLE IN 'S' AND 'R' MODES BATCHFLG: DB 'B' ;BATCH FLAG (WHY WAS THIS DISABLED IN EAR    LIER VERS?) OPTBE EQU $ RESTROPT: ;MUST BE IN SAME ORDER AS TABLE ABOVE DB 'A','D','O','Q','R','S','V','T','L' DB '0','1','B' ; ;THE NEXT 13 BYTES EQUAL THE NUMBER OF BYTES BETWEEN SECTNOB AND SECTNOE RESTSN: DB 0,0,0,0,0,0 DW DBUF DB 0,0 DB 80H,0 DS 80H DISKNO: DS 1 DISKSAV: DS 1 SAVUSR: DS 1 SENDFLG: DS 1 NBSAVE: DS 2 BGNMS: DS 2 FILECT: DS 1 NAMECT: DS 1 ORIGSAV: DS 1 FTYCNT: DS 1 DS 100 STACK: DS 2 FCB3: DS 33 FCB4: DS 33 FCBBUF: D,0,0,0 ; SECTNOB EQU $ ;START OF TABLE MARKER RCVSNO: DB 0 ;\ SECTNO: DW 0 ; \ ERRCT: DB 0 ; \ ERRCDE: DB 0 ; \ EOFLG: DB 0 ; \ 13 BYTES BETWEEN TABLE MARKERS SECPTR: DW DBUF ; / SECINBF: DB 0 ; / MAXEXT: DB 0 ; / S 15 DBUF EQU $ NAMEBUF EQU DBUF+(DBUFSIZ*1024) ;BUFFER FOR NAMES IN BATCH MODE. ; ;OVERFLOWS ABOVE PROGRAM CODE. ; ; BDOS EQUATES ; RDCON EQU 1 WRCON EQU 2 LSTOUT EQU 5 PRINT EQU 9 RDBUF EQU 10 CONST EQU 11 RESET EQU 13 SELDSK EQU 1RCNT: DW 0 ; / DATAFLG: DB 0 ;/ SECTNOE EQU $ ;END OF TABLE MARKER ; MODCTLB: DB 07FH UARTFLG: DB TRUE UARTCTLB: DB ANSWMOD ;(WAS PREVIOUSLY ORIGMOD) SAVEFLG: DB FALSE LASTBYT1: DB 0 LASTBYT2: DB 0 EXACFLG: DB 0 ECHOFLG: DB FALSE L4 OPEN EQU 15 CLOSE EQU 16 SRCHF EQU 17 SRCHN EQU 18 ERASE EQU 19 READ EQU 20 WRITE EQU 21 MAKE EQU 22 REN EQU 23 CURDSK EQU 25 STDMA EQU 26 USER EQU 32 FILSIZ EQU 35 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32 OCFLG: DB FALSE CKSUMFLG: DB TRUE LISTFLG: DB FALSE LISTMOR: DB FALSE FSTFLG: DB TRUE FIRSTME: DB TRUE ;FIRST SOH RECEIVED SWITCH (ZERO AFTER 1ST SOH) EXITFLG: DB TRUE HLSAVE: DW BOTTRAM HLSAVE1: DW BOTTRAM HLSAVE2: DW BOTTRAM CMDBUF: FCBRNO EQU FCB+32 FCB2 EQU 6CH ; LAST END 100H SK EQU 25 STDMA EQU 26 USER EQU 32 FILSIZ EQU 35 BDOS EQU 5 REIPL EQU 0 FCB EQU 5CH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32                                   !    !    "    "    #    #    $    $    %    %    &    &    '    '    (    (    )    )    *    *    +    +    ,    ,    -    -    .    .    /    /    0    0    1    1    2    2    3    3    4    4    5    5    6    6    7    7    8    8    9    9    :    :    ;    ;    <    <    =    =    >    >    ?    ?    @    @    A    A    B    B    C    C    D    D    E    E    F    F    G    G    H    H    I    I    J    J    K    K    L    L    M    M    N    N    O    O