IMD 1.18: 14/11/2012 14:53:04 cp/m-86 utility programs  CP/M-86 3ȎЎ؎>RYXQ!Q$YPQU2R6>P>YXÉNÀ>VVW^YWZ]QZ]RVZYQ^]]]à uD $t@ <u 9 <u, 2âà uQYQ YQ>t Y<t< s t<u< uÀ u $uñ <$tAQYàMMËRâ ð 'QYÊ tKډ/ &< t 3 36 4 t |IDKD6 Rȋ6 - Y/ "B*AËـ><tًȵDËD Ê"DFB"# ؉DË úBڊ@$"A4<u2Bڠ@ù2CQY á $Ë  'B ڊs?t 3HË ËI;rBR+ӋZñK+sQLKYt :t s\È. N^  S ; RÍIC:uûIË'ICI`sI$QYH u@QYHрŠ$QY Ȋ$يQYR$Y QȈYQZuR><tQSQCS t %;r[CYϋ%CˋC)t;J?t:u C,$uȢ oZѠ3FQ.$""*$Y378td8<t u u:uFڋ;u2BCBCuùهً:rهي1 6 | tڻڱ2Cu ڈ}21!It $t$""1t &$t&Su2twt 2ghZ42B:@r u1=t ?$S,[urIP5=$Ȣ5<s>?$ 3ۉ |y2>=t? t >5t>TuO ÊBdos Err On : $Bad Sector$Select$File R/O$<aa 8LWWz.BDstȎЎ؎V.>uJu uH<tHJÀ>tHðàÈÊtCû&&@ÈGر رmkG_G`]<uM: m&%u &u k>ku?MODEMAPCCMD@ABCDEFGMODEMAPCCMDHIMDM840 A86JKLMNOPQ SQ+۹tY[Ê6P^v ^ P@Ƌ^PPBBPB^F BGv ^ PBFQlBFȊF ȉB] UvvP6`vP]UvvP6bRP4s FR]_ X^_YQVWPX_^Y^ñ&;A]-QP f?w-f㋇L>LtLVVfu]UL`2^ZY[XPQS@C[YXPQS@ jC[YXPSQRD tH @  K8ZY[XPSQR'"d 0 ZY[XR<t0utZ   @+ ~@ mȉXJȉZggL:GwAJ:GwgȴƋXZ:v]àgȴƋXZ:rgu]UJLLT]UTHJHJJ tUrJT]U P P]Y\QUcPrP P>\u PvP>\u P|PpX*GPC>\u PPHJ>Jt6JJ>ctu]Uc1ic1+ʈj>irH]À>k1ujȢjjv P]UFȈFk1u] PhPqP|hPs]U1HDB4PPPp` `,abD`+ȉF]UPPX]UPPI]UPFP8]UPFP%]U PP]U PP]UN؜[Ѝ&S COPYRIGHT (C) DIGITAL RESEARCH, 1981 01/25/82 PFP]UPv]U츀PPv]U^Ov]UPv]UPv]UPv]UPvw]UPvg]UPPV]U P P]Uf~u~t ~u ~t]U~r@P~w@YhXZYP.AP [s Pb212121<s.$ 'v3s,qs v321y3?PPˊ21.H9>CU*ktY]U ]Ur-"]UFȈFpw3pƋ^@$< uppƋ^@$P'puư.Pp >p wpƋ^@$Ppu]UvY:P Pv`]UFȈFj1uP1OM1]U]UM1g]UnP]UM1~Pq]UB-4PD-4d1@X1y3-9>j1t6IPF]U~0s ~9v@]U~As ~Zv@]Uvsv]U~ t~ u~ s ~~v@]U~ar ~~wn F]UFȈFqwb>qur0q㋏F1sF1V>suqƊr^s0q΋^r0qu]UP!Pv6 PPF@P(Pv^G P5]U^GPv.-^]U~u~4>E-Hu A-B-!>E-Du A- B-A- B-D-C-C-C-À20tC-B-8D-sR8-C-:D-wHÊ2E-,0E-< v.E-E-:A-rF-8-A-E-8-C-F-F-s&1]&1'18-(1]UP622P&1Ps&1]Uv3:uYn->q-t-t-Pv-81s 671f661 PZPT641M631Fq-]U>21u8q-:o-t$21uNq-:o-u l-;31t">q-tFo-q-Pv-31t--6p-21P231@31u ~u]UF8.-t.-P]U^G"(-=ui(-7>(-sP^6(-@$P^GP/-t)>/-u^6(-@$(-뿋^PP1밁(-(-^6(-@$/-Fw"/-]U^7L*-*-^;G"s,ƍ@$P,^GPt ^PP-<-;-=- PP1P PP2P122 ]U6-=-s=->:-s)&1<-s :-v3]=-<-2 ]222Ps5]62ds]À>2'uw]&1>2!u2 >2;u>2 t?22 <-s=-]]U>2l-]Un-q-]U]UFp-Fo-,.n-sZ]U졚-]U/6/]UP^G+@PST^G@]U///:FsƋ^0Ist/F]U>&1u4///:Fs"(1/Ɗ*-]U^7. vAv9^G",-=u S|,-F^6,-@$,-@^G" ]U^G"^7h<0r^GP&1u 2:Fu]U>&1u2:Fu>2 u]U P]UvsF#~ tJ-~ uJ-v]UF:J-v P]U^?t 7F]UJ-H-nPQ1PPl1PP1, PPH-P/^:u0/F]U^u ^t<]U^w=P^w/YÊ0>0u^^0^G]U~u~u ~u]U>&1u/>'1u(>2:u!(1^^$ c`]U^P^GF^^7<u-P^Pv^GP#(uv6y3sv'v(Pq]Uv+P`]UtPt]U츘"Ph]UtP]U츘"P]U츼&P]U(P]U+P3P$3PPI-]U젌1sI-I-:1w P% P P,I-]U>I-vc]UI-I-1, 8I-r]U~ u'J-,1+ʈNFȈF&1t&^Pf&1^G'1^G(1^GL622P-Ps;6-^P^G0&1u>2t)>2]UtP0]U>t ]U츘"P]U츼&P]U(P]U+P]U츘"PvgF"Pv"P]U4- 3.->\t \Ȣ.-PVtPP!&PP(PP +PPP]PvP#P]P&PP]P(P^ ]U>j1u y3s]à{3s1=>2u2K-L-J-K-P1P2PPz2*K-1u2*K-1*L-tvPQYK-P1P2PP<>2 t%PM->M-wM-2M-u1*L-tPQYL-P1P1PP1Pz]Uy3 M1s s"$^P^G0<t<t<u]QU^P."^G^G31^G81s51 ^G61^Gy^Pz^t^GC1^G$^GJ1sP^O G>2u^P2P2F222^P62@mP]P+P>e tPeP~P P PQ1P1-1-<r@1-÷u1-Q1P u@Y"sÈ1-Ȋ1-ƇQ1.È1-P~PQ1Px2-3-5->m t/>m$t4-!>2-w@P<$u@Y"r5-5-r>2-t|P0-< t>0-Aut" P621P PP2P21]UM1s H-I-]UM1sApmPP6$13P3P>P7FP3P3P#P]U_-_-_-:\-s/ƋN-V-:v]à_-ƋN-V-:sǰ]ð]U>]-u]à]-1^-\-&^-T !"F""~"]YU(Ps3--<v@ ^PY)Ps%-K[Ps8/s/^P^G^P_s ^P] UPPP"F 0-Hu&>0-Pu( >0-Su +P뷀>0-Fu'TPM0-0-Du w34-2-(j1+k1t3Pz<t4-4-]U>2-t3-0-2-3-0- 0-]UP0-60-_s0-,A^^?v?s4- 4-2-]U6-]U-V-^-R-X-{.X-R-_-_-<wƋR-P-_-u]ËV-\-ȉT-X-R-]-*^-^-]-a]àUF\-FN-FP->\- s&\-㋇R-T-Ê]-T-]Ud-d-d-Ƌ^8t0]Y`-QUj-%^P7^F uF^PFHP] S#j#u###^PPPP->>-u:-4>>- u<-r!>>- u<-<-6>->>- u>- ;-s 6>->->-]U>2 t@P>2 t@Y se2]UF22Os2]U?-?-s?/2PJs 622Ƈ2`-Pe-PIË b-4Pg-P>2 tAP2P"P-NPs6b-l_]Uk-k-k-<sÊ`-:Ru]ð]UN1 M1sy3sy3vD$1]Uw3s ^ ^]U^-C^-FHFÊ-]~u^_ ^P]YU^PPPQhPQQQY"F2@t>2_u?-Fs62i]U;-2@-@-se22<'u@P>2 u@Y"s 62LՀ>2'u'2<'u 622;-&1@-;-&1]UF-P2˷2E-2,D->E-Bu A-B-N>E-Ot>E-Qu A-B-UvY]Ut-P-,s-r-333:-sÊs-r-r-؊-s-:P33:-w#s-3PR6363{3u԰ Po Pi]U>-vg31t--F-s--]U6p-]U>q-t.Pv-t--]U>21 F 2 t@P>2;t@Y ]UsPC]U>21t%3Ps>3u 3^ P|]U>|3u Pe]ø3Pr>3t ]á30>0t |3q]1]U P ]U0O1"M1sM10,17P3]U,10",1P$0XP$0X$ 0F Í3B00>0t%0>0tx 00s 00]U,10>0u ,10B0G0>0u0:0s@0P:0v@Y"]à0:0t@]UB0G0<u]ËB0G$0>F^G]UPPP&1u,>(1u0u0sM1]À>(1u0]U>|3t |3]ðP#]U{3s P030 P P0PRڀ>2t@P>2:t@Y"P62lY"s2,A0sp>2w@PY r4622P0PI.Ps1<0u:0a>0u>0t@0P:0t@Y ]À>0uEB0GD00˷.86D0]6D0]6D0U<t@]8888]UB0G0G0G$00.9>0t@P>0m>0>0t@]sP>0t@Y ]`]Â>0t@P>0u@0>0P6/T]U//-^P/s^G^G^G/]U//v]U//v]U젆3 Í3-0/Pr0[Pas/s6-* 000]U/]U/]Y0QU0P0P>2w@PfY sL"622P&0PPP&0Pؠ0s]600P&0P {{3]UP0]U000:2s2s]ð]Uv3]U츋1P]UP1P]U21.1>&1u?PPl1P؀>2v2622Pt@P>0>0t@B0OPɰt@Y"]&989?9K9^9c9z99]U>0t@]U,1F0,100t]à0:3t0"0000:0s Pk 0蠿0sF0,10]U*1,1s]Ë,1?u]Ë,1]Ux3s,1?urS0P0P,+Ps/0P 0PTs%0:0u0P 0P]Ps]0G u uO@0G]U>&1u9>'1u2^(1^^?t?t^^?t?u]U^?u0O@^?u"0O0O^?u0Ol1P>&1u)]ð Pk]X111UM1s]U1]UN1sN1M11]UM1szN1M1]]UO1]UO1]U0]U000:0sH0PL]U젆30<v00000:s @"x3sm7 PPP.:t4e뙠::::::::::::u:x3s,Ox3]U8Cs-N622P01Psذ P;۰]̰]U01*1]U*10Ê$u@]U03R]UGsPq]U>2u>21t6311P2]U츇3Ps!>3u3}3F&3F31 P]Y 0 000QU51.n*61G181L13191D61A181I131;1061E181K131=161C181J131?1*2*F*Z*ZsPP]Ux3sF0H00]Uvv]U,1]U,1 Í3*0*0]U000:FsƊN^:u0F]U,17i]U,0,0wQ]U,17bro]Up.0.0wG]U[0000G uPТ00s\03 Í30s0tPN0,P,Psـ>3s03띠0]U0000:3s" Í30ÀuGu0Р0rC000:3s4 Í30Gu0t@PwY"s°]ð]U61 0518131]ð$Ps/ 051081061 031sA,3Ps&>3u361 0518131]s P]U671 0z661 0i6611PK2]UR0000sy30vy300}00w"00w]U,2020G+3140O;61u@P640{<t@Y sP2640>2 u20w2P]U6060G;61tP60G+31P>2 u60w2PQ]U,10u{8080G@uG0"0:0t@x3]UK:0s8s.Zss 1sPWPO]U2u3P2P%3P]Uu30P%3P0P02P0P2P}]UP P}3PM]U>&1tF/111:Fs(11Ɗ1^:uaؠ1]U>21u76u3%3P.1Psy30y3]U0^.+y +++,Ps 0 rP5]Uv51]U츇3Ps30<t<t<u]ð]U>&1uA>2v:02I0000:2s 23Y]s 63h]ðP`P:0G0G@u^"0.400&000.$1Т006"00>44440s60]U:0G$00$u@P>0t@Y"]U^G<0O0W0"ш0W"ш0>0u000q0u000Y006.1}3Pǀ>3tc36.1}3PQ6u3%3P.1Pr<6.1}3P1>3uF >3t11sv]U>21u6u3%3P.1Ps z3]ð]U51$ 1F381sN 1 F3613313]U>21t 6.1}3P:]U>5]Uis63G63@]ðP8P2PZ]U;s2>3t+3 t63 636363]ðP0>0w P0uP]UP/]UP$]UP]Ui631v]UA1PI1P;1PP]UC1PJ1P?1PP]UE1PK1P=1P0.50$0$ 0,0t0>0u00 0555F$8F0$0 F 0P>0t6<0>0u6=0~]U>0u]Ã><0u]6<0 ]U0@t0t]ð]ð]U,10^60`P]UT>0>0G01t P] ]U+PsTs PPss]622P01Ps]ðP]U PP".?]]])];]M]_]q]à3s]]à3s]]à3s]]ðP]]]]Pw]UG1PL1P91PP`]UPP]U21..P622Q01QY"s136.1}3P6u3%3P017Yrz3]3Kr#36.1}3]À>3t3(s 6.13Pp4]À>3uk73P>3t@Y s P260@P]U00,1? t)7PP6.6wֺ66660]U~tNn~s*Nf>0u@P~w@Y"s Ft000Nf]U,10{,1760Ph]U,10W]@0@0G06060 E ]x Pxu CxNۊˊﺋӈӜBI t.oKuK<uN2< u< u<u<;t< u< u< tC kj4  Iy؊зں@_F71+F%:&طۺE I   u ~ X< u< u<2uPX*uP2Xkb{uested file not present.$ .A86 file already exists.$ Insufficient space for dictionary.$ Not an .ASM file.$ Checksum failure.$ Can't open source.$ Disk or Directory full.$ Cannot close file.$G000< u < u:d[<:uourCCC7 rathertel 8080. Instead of generating object code for the Intel 8080, the assembler just had to be modified to generate Intel 8086 source code instead. There is no limit to the work which a translator program could undertake. Its simplest assignment is to be less efficient than possible but its reliability makes it worthwhile. Turning to efficiency, it is a temptation to combine Intel 8080 instructions to make use of the extensive addressing combinations of the Intel 8086, or of the additional registers than . If the programmer has made all his BDOS calls in a standard form such as , , or , these calls can be picked out and replaced with . There is really an area which lies in the realm of artifisubstitute Intel 8086 instructions for the corresponding Intel 8080 instructions. As compatibility between the two CPU's was intended from the start, there is almost always a single target instruction with the same parameter structure for every source  available. In this connection, the register si has to be seen as a more natural counterpart of the register pair DE. To exploit this extra convenience requires very careful attention to register usage, which is beyond the scope of the 80T86 programs.  cial intelligence rather than program translation. Suppose, as is often the case in machine language programs, that the program to be translated is an assembler or a compiler. Then, a rote translation will produce a program to handle Intel 8080 code bua, or the linkages to CP/M via address 0001 or 0006 recognized. Our experience is that these are best modified by hand, since they can occur in so many variations. The replacement of tfcb: equ 005CH by org 005CH tfcb rb 0 ;tfcb: equ 005CH]UP]UP]UP]UP]UP]U>21u=j43sj4>21u j4 4sP y43]U4^m4ȋ^8wQ4^4t@Pvv44QY"s 44Â4u4^u]Ut which will run on the Intel 8086, which is probably only half of what is desired. On the one hand, Intel 8080 operation codes included as data will probably confuse the translator except for the unlikely case that they have been included as hexadecim handles the problem quite satisfactorily. If the programmer has used good discipline and placed the CP/M linkages together at the front of his program, an adaptation of this type is quickly made. Don't forget to include an in the pro44<wÊ:Nt 4u4]U44<w6Ê:Nu<r(4:Fuu >2Bu 4uà4]U>&1t]4>'1u4>'1u44(1@]U>&1u>'1t]á(1@]U3@3cv j44 F33]U33cval constants. On the other hand, the program will be built around a whole structure of operation codes and bit patterns which the translator will know nothing about. So, let the would-be translator be warned! Another point to beware in making a transgram too. [end] Key to continue: nation far superior to LU86, by the way). Any particulary lucidF uFF Fv ~FF 3PvV!F޸gPv^;tF=|F=PF^Pv j44F33]U33643P3Ps3?t3643P63>rB363k4Ps]ð]Uv9]Ù>2,u]U>&1u#~u 33>(1w(6(1t~u 3 3.Hj4Qlation is that data areas often begin on special boundaries, to simplify address arithmetic used to consult the data. In translating from the Intel 8080 to the Intel 8086 program lengths will change, so that the positioning of a critical data area may ]$]1]l]4]M]i]q]]]]]]]]ðP;]? ???? ?%?*?/?@?Q?b?b?f?n?s?x?}????????????????UFsհPP.@P}0Pr%PgPXPNPp?P Pd*uHH|HHHHHHHH|HHHHHHHH|HHH]U3H3ÀPC]U3H3ÀP,>2,ṵP>2)tj4]]Uv]Uv]U622P3P:32ȉ33Ù>2:tj4F62also be changed. In short, it requires a good knowledge of the program to be trans- lated, the Intel 8080 machine language, and the Intel 8086 machine language to make a satisfactory transition from one to the other. A program such as 80T86 can simplsts) %!Ph=@H@S@b@b@l@}@@@]U!1Ps)sPvH!1]U!1sk]U>2 t@?.8AP^]ðP]o]]H]ðAA%A*A/A4A]U&1"1<u]À>"1u >2:u]À>"1t>"1u5622P.I Pwj4]ÈIIIIIIIII62.I PAIIIIIˀ>2(u m4]U333n434PPP3P;PdPk4P.PPP4P!4344]U>&1t]622P3P24;ify the transformatiom markedly, but it can hardly be expected to make the transformation completely automatic. The library file 80T86.LBR contains the following files: 80T86.DQC this file 80T86.CNV updated CNVRT version of 80T86 80T86.AQM squ01PCs";,ԡ(1"1>&1u >"1u]ð]À>"1t]ð]U1]131Bz3w3PPl1P3]U>2 t]ð]U>&1u P:>(1wb6(1,Ӏ>2,t(O>&1uH622P3Ps5 P63oӀ>&1u622P3Ps 63K]j4]U>&˰]U>&1u>2,t]]U4s]s j44]]eezed source for Intel 8080 80T86.AQ6 squeezed source for Intel 8086 80T86.COM object program for Intel 8080 80T86.CMD object program for Intel 8086 80X86.AQM extended version for Intel 8080 80X86.AQ6 extended version for Intel 8086 80X86.COM o1u-v~u 6(1 >(1v j476(1'>&1u%622P3PEsFPp63ij4]U>&1u%622P3P sv;634j4]U P.ICPC5C9C=CECfҀ>2,u"\622P3Ps 63?]7? 0<$T%`%Uxbbject program, Intel 8080 80X86.CMD object program, Intel 8086 The difference between 80T86 and 80X86 is that the latter is tailored to the author's programming habits a bit more than the former, in that colons are removed from data declarations andj4]UP]U>&1u>(1w|P6(1 Ҁ>2(ueҀ>&1u;622P3P:rF33363Sр>2(u#р>&1u>(1w6(10р>2)tj4]ѡ33À?u >2)uzу3>2,t]i>]U P]UP]U>21t|j43<==      $  *  9  H   f w  H calls to BDOS made in a particular form are translated. Either could be built up further to suit a particular user or a particular class of programs. In neither case are equivalences defining CP/M's default file control block, the default buffer aresj4^.DP; p.G)P'DDDDDDDDD j4s 4P]U>21u3Ej443sj43.sj4J j4s 4P%]UP]UP]UP]UP           l  ! ( " 7 #    o   up. ; DSEG ; ORG 05CH ;change to 00 when complete template installed ; FCB RB 1 ;default file control block FCBNAME RB 8 FCBTYPE RB 3 RB 3 ;ex,s1,s2 FCBRC RB  BDOS@INR OPENC: ;open file in FCB XOR AL,AL MOV FCBCR,AL ;clear next record to read MOV DX,OFFSET FCB JMPS OPEN BDOS@COND: CALL BDOS  8  9  :  ; '/?  ?  &?  \wsrv 1 ;record count RB 16 FCBCR RB 1 ;current record to read or write RANDREC RW 1 ;random record number RANDOVRF RB 1 ;random record overflow BUFFER RB 128 ;default buffer ; OR AL,AL RET CSELECT: MOV CL,19H ;get current disk number JMPS TO_BDOS ;and ret to caller SETDMA: MOV CL,1AH ;set dma offset function TO_BDOS: JMP ; A bi-directional Type Utility (TU) for CPM86 systems including CCPM. ; ; Written by: Ken Brassler CIS PPN 72345,46 ; ; To generate: ASM86 TU $pz sz ! GENCMD TU DATA[m500] ; ;------------------------------------------------------------------ ; Avai ; End of base page, user data area follows ; ESCF DB 1BH ;escape CLRSCRNF DB 'E' ;clear screen Char. (E=H/Z 29) PWIDTH DW 80 ;screen width PLENGTH DW 24 ;screen BDOS ; ; This moves CX bytes from SI:DS to DI:ES ; MOVE_STRING: CLD ;set forward direction REP MOVSB RET ; ESC0: MOV AL,ESCF CALL DIRCONOUT MOV lable commands: ; Display next page ; <+2 CR> Display two pages ahead ; <+n CR> Display 'n' pages ahead ; <- CR> Display previous page ; <-n CR> Display 'n' pages back ; Display Page 30 length PAGEN DW 1 DCNT DB 0 EOFFLG DB 0 EOTFLG DB 0 SOPPTR DW 0 EOPPTR DW 0 FIRSTRN DW 0 NEXTRN DW 0 ; MSG001 DB 'File not found',CR,LF,EOM MSG002 DB 'That file i AL,CL JMP DIRCONOUT ; GETCOM: MOV BYTE PTR BUFFER,85 MOV DX,OFFSET BUFFER MOV CL,0AH ;read console buffer CALL BDOS MOV BX,OFFSET BUFFER+2 ;start. ; Display Page 'n'. ; ; You can locate the last page by choosing a high number for . ;-------------------------------------------------------------------- ; User changes: ; set CLRSCRNF to the ascii character that cleas empty',CR,LF,EOM ; MIDMARKER DW FILE_BUFFER+2000H EOFMARKER DW FILE_BUFFER+4000H FILE_BUFFER DW 0 ;just a dummy number ; ; Utility procedures ; CSEG ; JMP TYPES ;  of chars XOR CX,CX ;get a 00 MOV CL,BYTE PTR BUFFER+1 ;get byte count in cx JCXZ NO_CHARS XLATE: CMP BYTE PTR [BX],61H JB XLATE1 CMP BYTErs the screen. ; set PWIDTH and PLENGTH to the width and length of your screen. ; note: The display will truncate the line length to 2 chars ; less than the PWIDTH. If you want to try full width make ; PWIDTH = width+2. (BDOS: INT 224 PUSH DS POP ES RET BDOS1: INT 224 POP CX POP BX PUSH DS POP ES RET DASH: MOV AL,'-' CO PTR [BX],7BH JAE XLATE1 AND BYTE PTR [BX],5FH XLATE1: INC BX LOOP XLATE NO_CHARS: MOV [BX],CH ;write 0 zero at end TEST BYTE PTR BUFFER+1,TRUE but you may have problems) ;-------------------------------------------------------------------- ; General notes: ; All wordstar junk characters are filtered out (I think, I don't ; use it). ; There maybe a bug where the display NOUT: PUSH BX PUSH CX MOV DL,AL MOV CL,02H ;conout func JMPS BDOS1 CRLF: MOV AL,LF CALL CONOUT CR_ONLY: MOV AL,CR JMP ;set Z flag if no chars RET ; ; Display number 0 --> 999 ; PAGE_NUMBER: MOV AX,PAGEN CMP AX,10 JB ONE_DIGIT CMP AX,100 JB TWO_DIGIT XOR CX,CX THREE_will halt if a file ; contains a TAB immediately followed by a CRLF. ;----------------------------------------------------------------- ; TRUE EQU 0FFFFH FALSE EQU NOT TRUE ; ;special fcb flags ; ROFILE EQU 9 S CONOUT MESSAGE: ;print string starting at DX until $ PUSH BX PUSH CX MOV CX,9 ;print $ func JMP BDOS1 DIRCONOUT: PUSH BX PUSH CX MDIGIT: CMP AX,100 JB THREE1 SUB AX,100 ;must be 100 or greater INC CL JMPS THREE_DIGIT THREE1: PUSH AX ;save remainder CALL PR ;read only file SYSFILE EQU 10 ;system file flag ; ;special characters ; CR EQU 0DH LF EQU 0AH TAB EQU 09H EOM EQU 24H ;$ ; ; Template for base page of data groOV DL,AL MOV CL,06H ;direct I/O func JMPS BDOS1 BDOS@INR: CALL BDOS MOV DCNT,AL INC AL RET OPEN: MOV CL,0FH ;open JMPS  INT_CL POP AX TWO_DIGIT: XOR CX,CX TWO1: CMP AX,10 JB TWO2 SUB AX,10 ;must be 10 or greater INC CL JMPS TWO1 TWO2: PUSH AX;point to last # for continuity MOV AX,BX ;put it in ax RET CONVERT_ERR: DEC SI ;in case number was forgotten, this XOR AX,AX ;will treat char as next command  CMP DI,EOFMARKER ;is pointer at or beyond end of buff? JAE NEED_MORE ;yes, do refill CMP BYTE PTR [DI],LF JE SCAN2 INC DI JMPS SCAN1 SCAN2: INC D CALL PRINT_CL POP AX ONE_DIGIT: ADD AL,30H JMP CONOUT ;and ret to caller PRINT_CL: MOV AL,CL ADD AL,30H JMP CONOUT ;and ret to  RET ; ; Convert binary number to ascii and print -it- ; PRINT_NUMBER: MOV AX,PWIDTH ;based on page width. MOV CL,2 DIV CL ;width/2 - 3 = # of spaces SUB AX,3 I LOOP SCAN1 SCAN_RET: RET NEED_MORE: SUB SOPPTR,2000H ;move pointer back 8K ADD FIRSTRN,64 ;64 sectors = 8K MOV SI,MIDMARKER ;mid buffer addr MOV DI,OFFcaller ; ; Startins at SI, index SI to next non-blank char, else set Z if end ; of command line. [SI] is returned in AL. ; DEBLANK: ;deblank the input line MOV AL,[SI] CMP AL,0 ;end MOV CX,AX CALL CRLF MOV AL,' ' CENTER: PUSH AX CALL CONOUT POP AX LOOP CENTER CALL DASH CALL PAGE_NUMBER CALL DASH SET FILE_BUFFER ;start of buffer MOV CX,2000H ;move 8K CALL MOVE_STRING ; ; now fill the top 8K, or to eof ; MOV AX,NEXTRN ;pick up next record # MOV RANDREC,AX ;inser of line? JNZ DEBLANK1 RET ;treat end of line as blank DEBLANK1: CMP AL,' ' ;a space? JZ DEBLANK2 ;then skip it RET ;else r JMP CR_ONLY ;and ret to caller ; ; Increment SI to next command char. [SI] is returned in AL. Z set if no ; more characters ; INDEX_POINTER: INC SI JMP DEBLANK ;and ret to caller ; ; Rt in FCB ADD AX,64 ;and update it to new.. MOV NEXTRN,AX ;NEXT RECORD # MOV DX,MIDMARKER ;initial DMA addr MOV CX,64 ;64 sectors=8K CALL RD_RAND_et with SI -> to char DEBLANK2: INC SI JMPS DEBLANK ; ; Get ascii number pointed to by SI. Returns with Z set if no number, and ; SI points to last digit. Continues to acumulate as long as numbers are ; found. Double preciead CX sectors, or to end of file, to initial DMA DX, starting ; at randrec. ; RD_RAND_CX: PUSH CX PUSH DX ;save DMA CALL SETDMA MOV DX,OFFSET FCB MOV CL,21H CX ;do the read RET ; ; Scan back to see if 21 lines remain in buffer. If not, move bottom ; 8K to top 8K, and refill bottom 8K. Update FIRSTRN and NEXTRN. ; SCAN_BACK: CMP FIRSTRN,0 ;is start of file already thsion, number returned in AX. ; GETNUMBER: CMP BYTE PTR [SI],'0' ;at least one number? JB CONVERT_ERR CMP BYTE PTR [SI],'9' JA CONVERT_ERR XOR BX,BX ;set a 0000 CONV ;read random function CALL BDOS POP DX POP CX TEST AL,TRUE ;AL not Z = EOF JNZ END_OF_FILE ADD DX,80H ;bump DMA INC RANDREC ere? JE BACK_RET ;yes, dont scan MOV CX,PLENGTH ;get screen length SUB CX,2 ;is -3 +1 MOV DI,SOPPTR ;get start of current page BACK1: CMP DI,OERT: XOR AX,AX ;get a big zero MOV AL,[SI] ;get first char SUB AL,'0' ;remove ascii bias CMP AL,9 ;should be 0 --> 9 JA END_CONVERT  ;bump record number LOOP RD_RAND_CX ;and keep going RET END_OF_FILE: MOV BX,DX MOV BYTE PTR [BX],1AH MOV EOTFLG,TRUE RET ; ; Scan ahead to see if 41 lines remain @*! COPYRIGHT (C) 1980, DIGITAL RESEARCH  ;out of numbers ; PUSH AX ;save a copy MOV AX,BX ;put previous number in AX MOV CX,10 ;then multiply by 10 MUL CX ;result in DX and AX in buffer. If not, move top ; 8K to bottom of buffer and refill top. SI always points to top of ; current page. ; SCAN_AHEAD: TEST EOTFLG,TRUE ;dont scan if EOF in buffer JNZ SCAN_RET MOV CX,PLENGTH ͎ñ3б QYð Q[ uCS[';20 빱:뵱 뱊бñG'tù رԺ's ñ' V$tȎм$$$&_tUWV%#^_]%#$&$$$ω$#3$'#] û" u%l rPX< t< t < t<t< à" uKD$t8<u:1<t2">#u $$t>#u H&"à" uQYQYQ>$tY"<t< s t<u< uÊNs P^Y@ u "$u 67 t@|:t9 <w<w[9: FF<.uFC365 [ C??u ÿD (tKuÊ< uÌK5 .> u. 0 >,. 0 Q$ТX$9 .> u0 AsA+>&_9 .##!S)r 6ٷ. #<uU###jS$A##4oYPQ'#(#26$6$#>$$YXQ!Q$YPQ(#2$#>$>$YXñ"##ȎS"[PS\+\E+E;v[X++" "<tf#":"s u n i<$tAQY""$&CSQS[Y< u< t<u t͠""Q<u t&K|<u QS"<u$<u["":sG<uK[~<u5Q?Y[SQ tC&QS[YS" t*"" "uC&QS> ;t׋65 tu+: tE>( t5H ؋⹐ \ 7 < t tS[C?. t: u̻( ? u!Ê< t'C,0< suűrrruÀ? uCuûK؊': t$Ȼ9 :t: t Ȼ9 :uà9 <u"|t>D"|DtD"Q8RZY>$t1Q6Y"9DsD8\|t Ts [T t)"7T>$t5H;"wױ7="+,>###;uE# "8t ðÀ>"u "ډ"ð|t.|t\;\v+\[Y&<u <u؎@:s,[&/ ؎bDb?t uLD0? u 0!c_Ë$Î$$ð% %% %"˻"'QYÊ$tP"""ډ #"$"""## tW '> t  > t /.  u(? u ?CuR)uuȊȰ Es u p t bZR$PuzQYAj:e^:[V$< uXP<u $< t 5ŀ s u$XI\UUðTTÃ|tDD"">"u """, "<t<u |uD< u ÃpuS5[T"ÃË%sá$##"$"$"ʱ3 ">$tuMT"p "Q?t$GOQp 3"Ë# # t߻"o$###6"Rȋ6" #JY #T@"#*#Ë$ـ>#tًȵ#Ë# Ê"###"" ؉#Ë$ ú$#ڊ#""##<uu`Z. u!d  tC?YtC5 >( tg'HuL. uJ>( tCetr S#[uCJ<tS[uuE. :u: PtU'765 <=t<_u5F65 u+X:  t:ň/u/'u€YY Ў"$0"&E "8t 0D&ED|tD&&e&>"u &e& ƒv"$$"$"$#<t >#wh##$%$ڊOW[3ۊ؁%$2#ڠ#ù"2CQ$Y á"$$Ë""#B" ڊs "t"*"#Ë$ Ë$";rBR+ӋZñ##sQO#"Yt :t s_È3$ $t')8o G( uW{ '>( u: tȢ9 1 t̠9 >0 t30'u=@t+؎%: S'[7G\'! t t$%#$.#>#GEE)#u >*#tsunD9GrGSyuX:*#sMHuD+9GrG-Su2u-kAu :*#suCn*#G2$ËG"""uσtlutc<uutGE " "$$~û$C:uû$Ë#$C$ds䠦$$QY# u&QYLр"ڊR$Y QȈYQZuR>#tQSQCS t ";r[CYϋ"Cˋ"C#""25 < tN tſ&E.&E.*. ?t.0 (, : uhCMD$$$ SUB8u GDGD3)#### 2*#Ê)##9t!sUG;u E+GE@ܰËG;EtsE+GEEEEEE)##À>)#t#uñ$'#>)#st QD+Gu  Dt;h?t$:u C,$uȢ$oxѠ#EQ."""*$YË$!##$#u!#,DIRSUSERREN TYPEERA DIR NO FILEALL (Y/N)?FILE EXISTSMEMORYQVW*#Ȣ*#*t2ɋ_^YRW3ҵ:*#sD;rЊt _ZRW:*#sD+Gtr;sЊ߰t _ZËGSFF[UQ;r F;FrY] à*#*#+#URQ;uF;FuYQu6$6#NT =t4Ok- t IRQ)sYZ;"sBQRsZY+[Z u̻ñ R$Y[ $u kt UtPSڋ$ RZ ڊڊ/[X:trY NOT AVAILABLEREAD ERROR CANNOT CLOSE NON-SYSTEM FILE(S) EXIST SYSTEM FILE(S) EXIST_ 7*.$P.&'#.#PX.#.&'#XÐ$##$$>$#t u u:uGڋ;u3BCBCu¹هً:rهي #$6$$"U$t$ڱ2Cu ڈy2 # tP|t PD"X" C"V"S%#&Q&&&&&&&##,,,,,,,,,0Z\\]z^ad\at2\at+`ata\a t.%.x9.&%.%u.x9>a>ta:at">_ateaaؠ\aCXaa``]_π>`u%>nfu``d6d F*))__t$ $t""" #t &$t&!u #tut 2"#4# #w#:#r$u t y]# #$(###t%%`;;0@ARSR1.107ȎЎ؎u؎*L-f.pE?  """0/F)*X $y  B@N@O@a:au=Lt7>`u">`u~``0`u*]```u`````aa2bat_>`u V```>`t`(}```>`t:`t``_>_u>_t π>_t9_`Nu``2`t_```>`t؈؉C>$tÈ #>#uE> #u>6#>"3@### #Ê6""C:u###:rP$X<u>#u_Y$ uȢ#H#Q$!ڊ$PC$Ȋ$XC ۳ui ڈ ڊ*u ڊ@@@@E@GBP@ MAddPnnln"*h*$g.䓊䓆=uD械械橰䖨@t  g gb-昻gX-t'`?@uGt'gUjt%j>'gtc<u\<u=1<u62`jj:hr]>}L$,_2_tZ___`_ t.%.x9M.&% .%u.x98_t*)_t]:]t ] 0M`_ðCCÀ>`t>nft>bat>aatba_ >aatba.6; P>_t6_ P>aat I _B*$t_t%_` .0  B@@CX .; À>`tPU`XPX V^V^PX$V^V^Nx /CC u۱ň']ػ```OP0< r, 1 0Z`X%h`T`` 00]`` 00c`[urg" "#$\\$#Gt g#`#$$Ȣ#<s$##$$$À>#`u$"u"3ۉ""$$N{>$t ##<#u#>#t#K$#`$IaÀ>g ug 벻k=ERuG=MAuG=P t juU݋Q!D*EUTBPWk;tRЬCI;uZ;t tsMtC;rߋ_XYJ+͉ ++ڋûHtrZ\ G]û I<u2 t&Z` 00f`Q$Y.`X.`.&`.``Ȏ.`PSQRUVW.`.`&G%tȎ؎`&`X`_^]ZY[ X.`.&`.&`.`X.`.&`.`aȎ.`PSQRUVW.`.`&G%tȎ؎`&`X`_^]ZY[ X.`.&`.&`PQ1 c8Yt[>#`u$G $u#~Z$$$??t??t=$$$$)"&$$J"" nl"$à#jt-jkBû&*ɨuB<s%ӹ:tC-+ڊU$jtQt ]ʈ$]dj.b%.f%.j%.p%.|%.x%.%.%.%.%.Xda>dat`ca`da:caubt(>b(~bbb>btbFEb.%t.x9.%t.%uG.x9 >bt<t6>bubӀ>] t]++Ҋ] *A[׀<t 8t\PQ1c< 59YXX"#À>#t$$>#`uO# t ##>'#uSꡛ$#cuL 6$$ t* : %.%ux*ʋӀt':rċ%ȎػMk(>`au>Yaua:au >]u\<tC\>YatZaZaYa^<t>]t ]]j>Yaut]]au]]u , >]u >dtP*dSfa>fat`ea`fa:eaubu$b bGdGO db< s *b:rÀ>bubGbR8.%.%.x9.&%.x9À>bu bG.9bbbbb haCÀ>bt#=0r =:r<;tW6ddhX&]aQ*aa؊]aG]>a>taaY**P=r==8,Z]at`ZaYa<tYaC>YatX#X]tz^tl^atVWSQbFhagab;>bt)G=;t ;>btAGga>ga FY[_^PVRvtЉFZ^XPVW|a}a>gaugaha>gat#<%u}ab|aga֠|a$<u|a>}at&|a|a.9_^XVQha>gaBdos Err On : $Bad Sector$Select$File R/O$]a@tofuga} uY^VQha>ga} uY^VQha>ga} uY^Vha>gat>gau)<t,<rdD<t,ga~b>dtb;d}bPdbdbX }ItGtp>b&e+*ee6er6eFe>eteeIe1e2eeeCFSڊBF[띹e؊SQKY[6e.%$bu+dbI|bd+IlS>bt+dȡdV>+dȡdHdbI=%>buddbI!dbIX9^Vha>ga=<}86ddt*P*<t d+<t O*dOX^^aÀ>^atOÀ>^atfȎмef.fRPQSUVW.f.f&G%tȎ؎f&fXf_^][YXZ.f.#f.f.&f.&fu(hf&ifkf&lffff>#f*6ef0 0aaùQ Y[pf rf؎frf@ff fcf8fU3@36g3ۊ㋇faa3**#f@tgg33f1#f15#fg7ágfg#f.%.%.%tC.&%jjv%*يtjh*uىuuGhdPssR t~@tjuPj@ÈjipXulVQha>gau* tttt[ bnzY^^aVQha>gau* tttt %6Y^^aaaaa_a_a.;@.;@`a`aÀ>bubGbñ>`u%>nfu``d6pff&w&WÀ>sft *sfQY6ddDofÀ>sft *sfÀ>sfvsf>tfOvtfO6sftfRZf>ufu4+9ufvuffufff=v-f+ff>yft[.;Pnff._B.aBfwfyff>ft Pwff>t;?t3uko>ju uujujٱufkmjhԊj@Èxi`iju uu*䠺u$u*jQj>j[tri t%*D@h>ut7utdqÀ>dtdP6ddVXÀ>dr%dd>dt>dPrdd>drd>dtd>dt ddOddd{PX`>dtd>dPrdd dd:aw.%u:at a.x9.z9 B@@.&rfuyffX.;>}ftonff0._B.aBf{f}ffv>ftP{ff}ffZff>ft Pfuf~JB@@nffuf>ftPfG6dd.YB.>[BRPQ=IB@@JB@@Y^.fB< uu@ uuuthIuu>ut#uhhB<t=!ut3u>ut,t#%jj*ju jhÀ>ut4u%.x9=r PPJPXY.>9u t  B@@`PQd=t= }ddg- PPdXPddP+ddT>dtd1>duofPIdd>du =udYXdPddPdPSdd=P@u@@tQYsGÈfff>f~>>f6>f|/>f'+f;f|f >ft 6f>ff6f>ffÈfڋ`tR>fu Sfy[ffSUf][f>ut->uu&!uuuhuhfkjhÃtڊCÉjÉjûm>uuAjhj1P6j>jjX>utuukjQ>uuGj6j>j؎jhj<u>utuukj#uuuu>dt[u=PtP"P;tG>dPudd0d%=pd -pd.dP+ddd[XSP㋇Ee[ád3d;d|>dt +dddS㋇e[Sظ`rd[PP`@tIBX@@`XV`@tpBdfC&&`6SFfffUf}][RSf[`ËSPX u[ ufQP$ &fXYQPff0 0ࣥfXYVRXS>ftD/ Ĝ V^$$CCNxuٱuu@u@>utuu4uuuuuuuuuuuut=Ȉuu:u/u;uu&uu:u&u:ruuuu>utuu>ur4usuut]j:hu>j:hu5h:ju,u:uu#>utu@@`^^PQ `@tF`YX`P@u tXKB@@@gahaHSP. <.&<.<..<.!<.6#< IB@@JB@@LB@@@ B@@XÃt'RP X AQpY rGZ`@tB@sB@sBPkBX[*V`[Z^ðHKPX V^V^PX$V^V^Nx /CC uرň'RZ RZ$RZPYXP+YXÉfffffff<u <uË6fff\&f1Iut uɺZrhjhj'u<ujuu%j>jj@uu$QuɀtmYu؎j>uuu uu$áu+һ=r-`=Pr+;dsPd+X+dd+PԊ+ËbP.%$e뾊jÊ؀>\t1vAv'}"\:eteejj@uۄu .u>uuuu ˊee\*؊\%tw rr QP+eeX*T&Y<t<teee`ee>eteeSe0e8ee؎r <9wFCIYÀ8fQf#t&fۍjʃvf.uftful&fYQZYDf``:t uBfut uɺZrhm&mtSjhj6jjlMjuuAlkQ.ms@ƀǀYmjjhÈGر jرjjhhhhGhhS<tjjjj:  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ @` @``38 8 8 8 993 99[f4(3=3$49894Av5B5C5D5J+6K7Oa7Pa7m 5M 5>b7lh7Lh7fs h":&XiYi%u&Ziu>ju.>%unh>hrwh>hs hG$hh<u&hW>jt>jth>hsK/Yju"hh jhG$ GjhG$ GÊXiiYii7hs7Hs794140 4B430R81V82Z83b Zi#ihZ÷ñ늟h؀hGPuFPsrRÿXiP@sRssáh h;g*6g9;gr ;g8g:ghhh &g:gtY8g:g@g*gg(CgAg9Agt>Cgv/g.CgAgOOOPOQOROSOT9Agu@g>gAg9Agt Cgg(Cgtxg tn$`<@t Āt#u>Cgt뒀>$gu.>%t6$h>ht*h>ht%go t$`<@uĀth g uggggGgGg%"gtg t $`<@u* ù,64gsg2gAAN`gQYF Dg*iàh 0fhPhàh h!gP&ghȢgAgPģ"g gX$ggg&=g&Cg*H'g$goû g t$`<@uĀt*OWOXOYOZSUBMIT AUTSTRT \  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"#$&0'`()*+ -P./013@4p56790:`;0000=C=CEE?)@@9@ B B LGPH(@ *CI* u"䖨t*)g닟h u*g+=> gtQQ@䢨 uYY9YYSICC> gt梊[> gtQ䢨tY Y)g*䒀> gt 䢨uQ䖨uYY䒨t4gg84g5h+> gt 䢨u  j*k+m-n.o/p0q1r2s3t4u5v6w7x8y9 ?  @DH `$d(h11!`@n@|@@@B @IAJBKCLDE1B1P1bP@ gHHHHHHHH _ P0 HDC H/W ERROR CMD = H STR = H 䖨t4g'h2g*g> gt 䢨 t䠪> gt 䢨u*Ê曋G棊棋G擊擰@؎2 [!22@̢@33##44$$55%%66͛77&ԥ&88*գ*99( ֭(00) ܮ)_-_ _-=+ +@`~ ~QqQQWwWWEeEERrRRTtTTYyYYUuUUIiIIOoOOPpPP[[{{]]}}\\||^^^AaAASsSSDdDDFfFFGgGGHhH EST = H PHN = H LCNH = H LCNL = H LHN = H LSN = H SCNT = HIST = H UST1 = H UST2 = H *** Hard Disk Unit : is Not Available *** HJjJJKkKKLlLL:;::;'""ZzZZXxXXCcCCVvVVBbBBNnNNMmMM,,<<..>>//??CP/M-86 1.1 (1.107:015;D) CAP ALT GR1 GR2 sp:9 / / : SunMonTueWedThuFriSatd UoUkU`UUUUQUQUQUUQUQUUQUQU0  I8ERR0123456789ABCDEF FDC H/W ERROR STATUS 0 = 00H STATUS 1 = 00H STATUS 2 = 00H Type R(Retry) , I(Ignore) , Any Key(Cancel) *** Floppy Disk Drive 0: is No t Ready *** Type R(Retry) , Any Key(Cancel) *** The List Device is Not Ready *** Type R(Retry) , Any Key(Cancel) *** Floppy Disk Drive 0: is Write Protected *** *** Hard disk unit [ , , , ] cylinder read error *** Hard disk unit is not defrUnr7sUnr~sUnrs@?1 @?1 @?1 @?1 ined at the configuration Please reboot from floppydisk . NEC Advanced Personal Computer CP/M-86 Version 1.1 Copyright (C) , Digital Research , Inc. Interrupt Trap Halt ;nUn,nnn;nUn,n#oo;nUn,nRo3o;nUn,nobo?     FFSET FILE_BUFFER JBE NEED_LESS CMP BYTE PTR [DI],LF JE BACK2 DEC DI JMPS BACK1 BACK2: DEC DI LOOP BACK1 BACK_RET: RET NEED_LESS:  MOV EOTFLG,0 ;if it was set, not anymore ADD SOPPTR,2000H ;update page pointer SUB FIRSTRN,64 ;and first record number MOV SI,OFFSET FILE_BUFFER MOV DI,MIDMARKER oopapooqpooq]qoorq4@ MOV CX,2000H CALL MOVE_STRING ; ; now refill the bottom 8K ; MOV AX,FIRSTRN ;get new first record # MOV RANDREC,AX ;and insert in FCB ADD AX,128 ;compute next record # MOV NEXTRN,AX ;and store it ; MOV DX,OFFSET FILE_BUFFER MOV CX,64 ;sectors to read CALL RD_RAND_CX ;do the read RET ; ; Set up pointers to read one pa   Unr$.%蒙Y莙.&%g ge back. ; DEC_PAGE: MOV SI,SOPPTR ;get start of current page CMP SI,OFFSET FILE_BUFFER JBE DEC4 ;hard stop at start of file MOV CX,PLENGTH SUB CX,3  CX,PLENGTH ;# of lines per page SUB CX,3 PAGE1: PUSH CX ;save lines per page count MOV CX,PWIDTH ;get chars per line SUB CX,2 ;room for crlf PAGE2 AND AL,7FH CMP AL,LF JE END_INDEX JMPS INDEX_TO_START END_INDEX: CALL CRLF RET ; EXIT: XOR CX,CX XOR DX,DX INT 224 ;----------- STD ;set reverse direction DEC1: SUB SI,2 ;skip over LF DEC2: LODSB ;AL <-- [SI], DEC SI AND AL,7FH ;strip WS high bit CMP AL,LF : LODSB ;pick up byte, and inc SI AND AL,7FH ;for WS high bits CMP AL,1AH ;is it end of file? JE PR_EOF ;yes CMP AL,LF -------------------------------------------------------- ; Type program begins here ; TYPES: MOV FCB,0 ;erase any disk request CALL OPENC ;open file in FCB JNZ HAVE_FILE MOV  JE DEC3 CMP SI,OFFSET FILE_BUFFER JBE DEC6 ;another hard stop JMPS DEC2 DEC3: LOOP DEC2 ADD SI,2 ;point to first char in line DEC5: ;a line feed? JE PAGE4 ;yes, count it and start new line CMP AL,CR ;a CR? JE PAGE3 ;print it CMP AL,TAB ;a tab? JE TAB_IT  DX,OFFSET MSG001 CALL MESSAGE JMP EXIT HAVE_FILE: TEST FCBRC,TRUE ;is file empty? JNZ NOT_EMPTY MOV DX,OFFSET MSG002 CALL MESSAGE JMP EXIT NO MOV SOPPTR,SI ;page always starts from sopptr DEC PAGEN ;bump page number down MOV EOFFLG,FALSE ;if it scanned, not at eof anymore DEC_RET: RET DEC4: MOV SI,OFFSET FIL ;determine next tab position CMP AL,20H ;another control char? JB PAGE2 ;dont print and dont count PAGE3: CALL CONOUT LOOP PAGE2 ;and dec char count ; ; If iT_EMPTY: MOV RANDREC,0 MOV RANDOVRF,0 MOV DX,OFFSET FILE_BUFFER MOV SOPPTR,DX ;set up cursor MOV CX,16 ;read in 2K initially CALL RD_RAND_CX E_BUFFER MOV SOPPTR,SI ;hard stop at start of file RET DEC6: MOV SI,OFFSET FILE_BUFFER JMPS DEC5 ; ; Move SOPPTR to top of next page and bump page number ; INC_PAGE: MOV SI,St falls thru here, line has been truncated to 78 characters. Move ; SI to start of next line, send CRLF, then reenter loop ; PAGE6: CALL INDEX_TO_START ;advance SI to next line JMPS PAGE5 ; ; Come here when a LF is encou PUSH DX ;DX has next DMA addr CALL PRINT_PAGE ;print first page POP DX TEST EOTFLG,TRUE ;see if end of file reached JNZ COMMAND ;yes, dont read any moreOPPTR ;get start of current page MOV CX,PLENGTH SUB CX,3 CLD ;set forward direction INC1: LODSB ;AL <-- [SI], DEC SI AND AL,7FH ntered to count total # of lines ; PAGE4: CALL CONOUT ;print the LF PAGE5: POP CX ;recover line count LOOP PAGE1 ;until 20 lines JMPS PR_EOF1 ;after MOV CX,112 ;rest of 16K CALL RD_RAND_CX ;do the read MOV AX,RANDREC ;get the next record # MOV NEXTRN,AX ;and store it ; COMMAND: CALL GETCOM  ;strip WS high bit CMP AL,LF JE INC2 CMP AL,1AH ;end of file? JE INC_RET ;dont update anything JMPS INC1 INC2: LOOP INC1 ;for 20 L 20 lines, print page number PR_EOF: POP CX ;eof found before 20 lines PR_EOF1: CALL PRINT_NUMBER RET TAB_IT: MOV DX,PWIDTH SUB DX,2 ;start with same line l ;then get command MOV SI,OFFSET BUFFER+2 JZ NEXT_PAGE ;default is next page CALL DEBLANK CMP AL,'-' ;back n pages JE LAST_PAGE CMP AL,'+' F's INC PAGEN MOV SOPPTR,SI ;print always starts from sopptr RET INC_RET: MOV EOFFLG,TRUE ;set last page flag RET ;and go back ; ; Display 20 lines begength TAB_LOOP: SUB DX,8 ;next tab stop CMP DX,CX ;is it less than current pos? JB NEXT_STOP ;yes, next stop found JMPS TAB_LOOP NEXT_STOP: MOV CX JE NEXT_PAGE ;forward n pages CMP AL,'P' JE ABSOLUTE_PAGE CMP AL,'X' JNE NEXT_PAGE ;all errors default to next page MOV CL,CLRSCRNF CALL inning at SOPPTR, or stop at eof. If EOF found, SOPPTR ; is not updated. ; PRINT_PAGE: MOV CL,CLRSCRNF ;clear the screen CALL ESC0 CLD MOV SI,SOPPTR ;start of current page MOV,DX ;becomes new char count INC CX ;to account for loop dec's CX CMP CX,0 JLE PAGE6 ;error, cut line short JMPS PAGE3 ; INDEX_TO_START: LODSB   ESC0 ;clear screen XOR CX,CX ;all done XOR DX,CX INT 224 ; NEXT_PAGE: TEST BYTE PTR BUFFER+1,TRUE JNZ NP1 ;not a default ONE_PAGE:  ;compute negative increment JMP LAST1 ;and go to it ; ; end  and useful sections of this document probably originated with Gary Novosielski. The Turgid Obfuscation is VVY/{p\;y{ȋQY s MOV AX,1 ;was a default JMPS NP2 NP1: CALL INDEX_POINTER CALL GETNUMBER ;get incremental request JZ ONE_PAGE ;was just a +, default to 1 NP2: MOV ((_|tq%1(ȋ+QY s*/,.AUXȋ[QY s l^L  CX,AX ;load cx with number JCXZ PRINT_IT ;if +0 was entered, reprint current ADVANCE: TEST EOFFLG,TRUE ;are we on last page? JNZ PRINT_IT ;yes, dont scan anymore PUQ@%Kt,&5l$ : û C û H û M wSkh^TJ@=:6zK Y؎rz;stЋQt>ud >*+II D; LAST_PAGE: CALL INDEX_POINTER ;point to number CALL GETNUMBER ;get it if there JNZ LAST1 ;was there MOV AX,1 ;not there, default to -1 LAST1: MOV ectory portion of a pathname, retaining only the 11 character file name for use in the LU directory. (MS-DOS version). Ver 4.02, September 12, 1984. Fixed update function so that it distinguishes between not being able t00-r1 t%< uFtNV@P@ Y^-Gá*+Éááá tPGá t & Q ZRZ' XPX HxPX$'@']É+ˉO CX,AX JCXZ PRINT_IT1 ;if -0, reprint current pg DECLINE: PUSH CX CALL SCAN_BACK CALL DEC_PAGE POP CX LOOP DECLINE PRINT_IT1: CALL PRINT_PAGE o find or read a file (in which case it creates a new directory), and reading a file which is not a library (in which case, it aborts). Prior to this fix, trying to update a file with a .lbr extension, which was not a rNˁsFs t(W+rw>GÉWډtŹMOKK6;r64 t;r;u L7E;tOËM+Wr;s‹ uÃ>0À>YQ󥥥ËFFFF| CALL SCAN_BACK JMP COMMAND ; ; ABSOLUTE_PAGE: CALL INDEX_POINTER ;move to number CALL GETNUMBER ;and get it, if there JZ ABS1 ;not there, default to same pag Library, would destroy it. - 4 - LU86.CMD CP/M VERSION 4.05 October 03, 1984 Ver 4.03, September 25, 1984. Fixed bug that limited input file  ^rOcw|/uÊ u -0*xS1[ ߥ0 t@yـr$s Q*HY t*QـY*2xs) mr /FO**/Ge CMP AX,PAGEN ;compare to current page JA MORE ;it's greater then pagen JB LESS ;it's less then pagen ABS1: JMP PRINT_IT ;must be same page MORE:  list to 30 names.. Now handles 128 names as advertised. Ver 4.04, September 29, 1984. Improved memory allocation error checking in the CP/M version. | | Ver 4.05, October 3, 1984. Added support for MP/M-86 and CCP//G$>Pu>r<Pn t u$0E$,@y ??vCSW^B>*[CS t8P$tȾ>sXtȾ>'uY5~ t/KK/x SUB AX,PAGEN ;compute increment JMP NP2 ;and go to it LESS: MOV BX,AX ;save requested page MOV AX,PAGEN ;get current page SUB AX,BX M | file time and date stamping. Unfortunately, with the CP/M-type | operating systems, you can find out the date of a file, but you | cannot set the time date of a file. Therefore, extracted library | members will not ret  t}|~yuq{ypzx ^                     ( 7  Y j   0  1 IABLEDOUBLE DEFINED LABELUNDEFINED INSTRUCTIONGARBAGE AT END OF LINE - IGNOREDOPERAND(S) MISMATCH INSTRUCTIONILLEGAL INSTRUCTION OPERANDSMISSING INSTRUCTIONUNDEFINED ELEMENT OF EXPRESSIONILLEGAL PSEUDO OPERANDNESTED "IF" ILLEGAL - "IF" IGNOREDILL           h*1* G T t        2  3  SCASWAAADAAAADPUSHFMOVSBWADCjxLODSWADDCMPSWn STOSBzDECAAM REPNZ TESTF{ PUSH REPZ]MOVS STOS"JAJBJCLOOPNE4JEJAEJBELEGAL "IF" OPERAND - "IF" IGNOREDNO MATCHING "IF" FOR "ENDIF"SYMBOL ILLEGALLY FORWARD REFERENCED - NEGLECTEDDOUBLE DEFINED SYMBOL - TREATED AS UNDEFINEDINSTRUCTION NOT IN CODE SEGMENTFILE NAME SYNTAX ERRORNESTED INCLUDE NOT ALLOWEDILLEGAL EXPRESSION  .,  =      $ <L 4 n     EACLCCMCCLDFANDLOOPZAASJGE7 SBBDASCLIJNAJNBNEGaINCJNC$>ESC,JLECBW< MOVSW JNECWD>JPE^JNGJGJL<IN4JO >JP4RLAHFDCALLHJSJELEMENTMISSING TYPE INFORMATION IN OPERAND(S)LABEL OUT OF RANGEMISSING SEGMENT INFORMATION IN OPERANDERROR IN CODEMACROBUILDING** ERROR NO: ** NEAR: "  YNCP/M ASM86 1.1 SOURCE: PAGEEND OF ASSEMBLY. NUMBER OF ERRORS:           4   N  l    NAEfJNBE SALt STOSWCMP RCLCALLFLDSDIVJNLLESF SARJNO RCR REP  SHL(JMP JNP8VHLT JPO\ STCP} SUB*JNS`b STDhpINTp0 RETz SCASBNOP ROL SHRyMUL_ P . USE FACTOR: CP/M 8086 ASSEMBLER VER 1.1 PARAMETER ERROR NO FILE DISK READ ERROR DISK FULL DIRECTORY FULL CANNOT CLOSE SYMBOL TABLE OVERFLOW USER BREAK. OK(Y/N)? END OF PASS 1 END OF PASS 2     0        H*) * ? , T   n        OP ORLOOPNZ SAHFJNGEJZJNLEHXLOCKQ SCASXHXCHG REPE IDIVJMPFh STI|NOT JNZ,MOV RORrLODSBCMPSB4 OUTXOR REPNELOOPEJ RETFhLODS<CMPSDIRET WAITNhPO+-*/ +-    A86 @      ACDEMRSXBWDSdd DPB_offset,dx add CSV_offset,dx add ALV_offset,dx mov di,init_addr ;move code and data into BIOS mov si,offset ini)  )       )  )  & 6 @   P   ` ) p )      PF$IMUL0 RETN` XLATh~INTO~LOOPJMPSJCXZOXas,<nu|NV0@x $4Xr0000LABELSVARIABLESNUMBERS'd A86H86LSTSYM % t_Kdrive mov cx,offset end_Kdrive sub cx,si shr cx,1 inc cx cld rep movs ax,ax mov dx,offset created mov cl,9 int 224 jmpf dword ptr init_addr ;go execute disk initialization routine init_addr dw BIOS_jumptable+100h dw BIOS_segment  )  )       )  )      & ) 6 )  V b       )   Oq           Xَэ&RP~+ɋUVN]0102821100654321  )        n         (    F  ? ,z - -   Z-[-Lx"AHALAXBHBLBPBXCHCLCSCXDBDDDHDIDLDSDWDXEQESGEGTIFLELTNEORRBRSRWSISPSS ANDENDEQUMODNOTORGPTRSEGSHLSHRXOR BYTECSEGDBITDSEGENDMESEGLASTLISTRELBRELWSSEGTYPEWORDDWORDEJECUPP]UR~ĸZXRT\PP!P* PPPPw>uP($PePP\P\P\PF>u'W \P=>u?PV@]U]  {4 5 5        .    ( P  ) _  * n  +     TENDIFMODRMSHORTTITLEIFLISTLENGTHNOLISTOFFSETSEGFIXINCLUDESIMFORMNOIFLISTNOSEGFIXPAGESIZECODEMACROPAGEWIDTHUh"?SsKkTILLEGAL FIRST ITEMMISSING PSEUDO INSTRUCTIONILLEGAL PSEUDO INSTRUCTIONDOUBLE DEFINED VAR  UPFP]U P P]U~ v FA, F0P]UFPF$P]UFPFP]U Pv]Uv]UKPvSP6ZJ]UcP]UPv]UPv]UPv]U6V< tV]U> u]Is>]t> uÈ>u뿀> u]U > w1s  Ƈ    P7 u  > r@" sW <v@" s' COPYRIGHT (C) 1981, DIGITAL RESEARCH [], ERROR: $, LOAD ADDRESS $DISK WRITE$DISK READ$INSUFFICIENT MEMORY TO CREATE CMD FILE $LOAD ADDRESS $ERROR ADDRESS $BYTES READ:$INVALID HEX DIGIT$CHECK SUM ERROR $BYTES READ $RECOPv]UPPz]UPvi]UPvY]UPvI]UPv9]UPv&]UFȈF]u@P> u@Y"r>AuP YNÀ>Mu(P YPP YK딀>XuP YR>BuPY ]RDS WRITTEN $H86CANNOT OPEN SOURCE$CMDNO MORE DIRECTORY SPACE$CANNOT CLOSE FILE$mp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_SETTRK[bx] mov sek_trk[bx],cx ret SETSEC: call adjust cmp byte ptr sek_dsf_F]UP> t]UF,0< vF,A<vF,A ]UFN ]U>w:Fu]u]U\6s(6zTwBsk[bx],10 jz $+7 jmp BIOS_SETSEC[bx] mov sek_sec[bx],cl ret SETDMA: call adjust mov DMA_offset[bx],cx jmp BIOS_SETDMA[bx] READ: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_READ[bx] pushf push ds push es mov es,DMP,uPTPPÙ>tnPfTƇTT]Ubdf|s|h>wLJju,`Z$<:t >uLf@P<Pmh`Z>buZbr@Y"ssh녀>u K>t,>t@ZP; r@Z"P;s@Y"s)ZK>uZ; r+ I|9lslTZH%`d1@L>Pu d1@P`dsKPDE DATA EXTRASTACKX1 X2 X3 X4 8080 NZERONHEADTYPE USERDIR.TXT NSQUEEZE FILES USER 5: 80X86 FILES USER 6: MISC USER 7: ASM86/GENCMD USER 8-16: UNUSED P<wFÃjt3jʁjȉ1P YLPuPuh`jT^<:t >t'PPhZq<u>u >u>v0>s),8w㋇jZu(>k_seg[bx] mov es,dx mov di,ax mov si,DMA_offset[bx] mov ds,DMA_seg[bx] mov cx,64 cld rep movs ax,ax pop es pop ds popf sub ax,ax ret SECTRAN: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_SECTRAN[bx] mov bx,cx t>t@ZP; w@Y"sZ+ jZ8SPE6fP7P\Ps4h|\P]KPPPP8\Pt]UZR;v xPIFX6Z]UZR;r@"sX6ZZ]U츠P ret SETDMAB: call adjust mov DMA_seg[bx],cx jmp BIOS_SETDMAB[bx] inttrap: cli pop ax ;pop old IP, CS, and flags pop ax pop ax or ax,0200h ;enable interrupts on return push ax mov ax,BIOS_segment ;return to WBOOT push ax mov6`TPt6ZFPf1`;Zs u!X6`0` P]U6`:P P]U6zN\Pt4]UzRzdR;w zs]6zRPdA+zZQ]UP<t>vPPh&Ȣu >u끷ZH|9jw0 u|끷S|j,F YK]UV   BIOS_SETSEC DW 0 BIOS_SETDMA DW 0 BIOS_READ DW 0 BIOS_WRITE DW 0 BIOS_LISTST DW 0 BIOS_SECTRAN DW 0 BIOS_SETDMAB DW 0 sek_dsk db 0 sek_sec db 0 sek_trk dw 0 DMA_offset dw 0 DMA_seg dw 0 disk_pages dw 0 disk_seg dw 0 one_twenty_eight  0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITȉXJȉZggL:GwAJ:GwgȴƋXZ:v]àgȴƋXZ:rgu]UJLLT]UTHJHJJ tUrJT]U P P]Y\QUcPrP P>\u PvP>\u P|Pdw 128 DPH_offset dw offset DPH DPH dw 0 ;no sector translation dw 0 dw 0 dw 0 DIRBUF_offset dw offset DIRBUF DPB_offset dw offset DPB CSV_offset dw offset CSV ALV_offset dw offset ALV DIRBUF rs 128 CSV rs 0 ALV rs 32 ;diIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO>\u PPHJ>Jt6JJ>ctu]Uc1ic1+ʈj>irH]À>k1ujȢjjv P]UFȈF256K DPB dw 64 ;SPT BSH db 3 ;BSH 3 4 BLM db 7 ;BLM 7 15 EXM db 0 ;EXM 0 1 DSM dw 0 ;DSM #K-1 (#K/2)-1 DRM dw 63 ;DRM 63 N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP 127 db 0C0h ;AL0 db 0 ;AL1 dw 0 ;CKS dw 0 ;OFF end_Kdrive db 0 end Key to continue: USER 0: CPM, PIP, & OTHER COMMON UTILITIES USER 1: Z80 EMULATOR FILES USER 2: COMMUNICATIONS/MODEMS USER 3: RELOCATABLE ASSEMBLY LANHGUAGE ROUTINES USR 4ER 4: LIBRARY/UNSQUEEZE FILES USER 5: 80X86 FILES USER 6: MISC USER 7: ASM86, GENCMD A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: TYPE USERDIR.TXT$SSEMBLY LANHGUAGE ROUTINES USR 4ER 4: LIBRARY/UNSQUEEZE FILES USER 5: 80X86 FILES USER 6: MISC USER 7: ASM86, GENCMD qs v321y3?PPˊ21.H9>CU*ktY]U ]Ur- CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES  &USR 4ER 4: LIBRARY/UNSQUEEZE FILES$VP"Pq 33:lu]à3:muְ]]UPM1-31P31P$1N1{3|3O151]U1P1w>j1uP1OM1]U]UM1g]UnP]UM1~Pq]UB-4PD-4d1@X1y3-9>j1t6IPUSER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT1USER 3: RELOCATABLE ASSEMBLY LANHGUAGE ROUTINES$USER 2: COMMUNICATIONS/MODEMS$NHGUAGE ROUTINES$*6$13P 3PPP3P 3P%Pt]U{3"v3s {3v3Fs]U~ uc ~ tcv ]Udedd:FsƋ^ee$?]Uv ^ PƋ^NN t7ÊN :Ou%QNP^ PsILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER CUSER 1: Z80 EMULATOR FILES$S$NHGUAGE ROUTINES$+USER 0: CPM, PIP, & OTHER COMMON UTILITIES$INES$N^ N뿰] UFF F+9Bv >P^v ^ P@Ƌ^PPBBPB^F BGv ^ PBFQlBFȊF ȉB] UvvP6`vP]UvvP6bRP4s FR]OMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USERUvvvP6`]U6a^Pv]U6av^P]UvvvP6b\]UFF+9Bvvv6B}FB]UvvPPvo]UHf>f?w-f㋇L>LtLVVfu]UL`   OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER C CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES  PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER CIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES ER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMOUSER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0:   N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES ER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMOUSER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER C CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES ER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPOMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0:  OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER C CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES  PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&  USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER C CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES ER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPOMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0:  OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER C CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES  PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER CIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO   PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER CIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USEROMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMO PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTH 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILIT CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES ER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMOUSER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: N UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER C CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES   ER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIPIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT 1 ;record count RB 16 FCBCR RB 1 ;current record to read or write RANDREC RW 1 ;random record number RANDOVRF RB 1 ;random record overflow BUFFER RB 128 ;default buffer ; A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: ; A bi-directional Type Utility (TU) for CPM86 systems including CCPM. ; ; Written by: Ken Brassler CIS PPN 72345,46 ; ; To generate: ASM86 TU $pz sz ! GENCMD TU DATA[m500] ; ;------------------------------------------------------------------ ; Avai ; End of base page, user data area follows ; ESCF DB 1BH ;escape CLRSCRNF DB 'E' ;clear screen Char. (E=H/Z 29) PWIDTH DW 80 ;screen width PLENGTH DW 24 ;screen CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES lable commands: ; Display next page ; <+2 CR> Display two pages ahead ; <+n CR> Display 'n' pages ahead ; <- CR> Display previous page ; <-n CR> Display 'n' pages back ; Display Page 30 length PAGEN DW 1 DCNT DB 0 EOFFLG DB 0 EOTFLG DB 0 SOPPTR DW 0 EOPPTR DW 0 FIRSTRN DW 0 NEXTRN DW 0 ; MSG001 DB 'File not found',CR,LF,EOM MSG002 DB 'That file iUSER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UT. ; Display Page 'n'. ; ; You can locate the last page by choosing a high number for . ;-------------------------------------------------------------------- ; User changes: ; set CLRSCRNF to the ascii character that cleas empty',CR,LF,EOM ; MIDMARKER DW FILE_BUFFER+2000H EOFMARKER DW FILE_BUFFER+4000H FILE_BUFFER DW 0 ;just a dummy number ; ; Utility procedures ; CSEG ; JMP TYPES ; ILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER Crs the screen. ; set PWIDTH and PLENGTH to the width and length of your screen. ; note: The display will truncate the line length to 2 chars ; less than the PWIDTH. If you want to try full width make ; PWIDTH = width+2. (BDOS: INT 224 PUSH DS POP ES RET BDOS1: INT 224 POP CX POP BX PUSH DS POP ES RET DASH: MOV AL,'-' COOMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A&but you may have problems) ;-------------------------------------------------------------------- ; General notes: ; All wordstar junk characters are filtered out (I think, I don't ; use it). ; There maybe a bug where the display NOUT: PUSH BX PUSH CX MOV DL,AL MOV CL,02H ;conout func JMPS BDOS1 CRLF: MOV AL,LF CALL CONOUT CR_ONLY: MOV AL,CR JMP OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPMwill halt if a file ; contains a TAB immediately followed by a CRLF. ;----------------------------------------------------------------- ; TRUE EQU 0FFFFH FALSE EQU NOT TRUE ; ;special fcb flags ; ROFILE EQU 9 S CONOUT MESSAGE: ;print string starting at DX until $ PUSH BX PUSH CX MOV CX,9 ;print $ func JMP BDOS1 DIRCONOUT: PUSH BX PUSH CX M PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER ;read only file SYSFILE EQU 10 ;system file flag ; ;special characters ; CR EQU 0DH LF EQU 0AH TAB EQU 09H EOM EQU 24H ;$ ; ; Template for base page of data groOV DL,AL MOV CL,06H ;direct I/O func JMPS BDOS1 BDOS@INR: CALL BDOS MOV DCNT,AL INC AL RET OPEN: MOV CL,0FH ;open JMPS  0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITIES USER 0: CPM PIP A& OTHER COMMON UTILITup. ; DSEG ; ORG 05CH ;change to 00 when complete template installed ; FCB RB 1 ;default file control block FCBNAME RB 8 FCBTYPE RB 3 RB 3 ;ex,s1,s2 FCBRC RB    BDOS@INR OPENC: ;open file in FCB XOR AL,AL MOV FCBCR,AL ;clear next record to read MOV DX,OFFSET FCB JMPS OPEN BDOS@COND: CALL BDOS  CALL PRINT_CL POP AX ONE_DIGIT: ADD AL,30H JMP CONOUT ;and ret to caller PRINT_CL: MOV AL,CL ADD AL,30H JMP CONOUT ;and ret to  RET ; ; Convert binary number to ascii and print -it- ; PRINT_NUMBER: MOV AX,PWIDTH ;based on page width. MOV CL,2 DIV CL ;width/2 - 3 = # of spaces SUB AX,3  OR AL,AL RET CSELECT: MOV CL,19H ;get current disk number JMPS TO_BDOS ;and ret to caller SETDMA: MOV CL,1AH ;set dma offset function TO_BDOS: JMP caller ; ; Startins at SI, index SI to next non-blank char, else set Z if end ; of command line. [SI] is returned in AL. ; DEBLANK: ;deblank the input line MOV AL,[SI] CMP AL,0 ;end MOV CX,AX CALL CRLF MOV AL,' ' CENTER: PUSH AX CALL CONOUT POP AX LOOP CENTER CALL DASH CALL PAGE_NUMBER CALL DASH  BDOS ; ; This moves CX bytes from SI:DS to DI:ES ; MOVE_STRING: CLD ;set forward direction REP MOVSB RET ; ESC0: MOV AL,ESCF CALL DIRCONOUT MOV  of line? JNZ DEBLANK1 RET ;treat end of line as blank DEBLANK1: CMP AL,' ' ;a space? JZ DEBLANK2 ;then skip it RET ;else r JMP CR_ONLY ;and ret to caller ; ; Increment SI to next command char. [SI] is returned in AL. Z set if no ; more characters ; INDEX_POINTER: INC SI JMP DEBLANK ;and ret to caller ; ; R AL,CL JMP DIRCONOUT ; GETCOM: MOV BYTE PTR BUFFER,85 MOV DX,OFFSET BUFFER MOV CL,0AH ;read console buffer CALL BDOS MOV BX,OFFSET BUFFER+2 ;startet with SI -> to char DEBLANK2: INC SI JMPS DEBLANK ; ; Get ascii number pointed to by SI. Returns with Z set if no number, and ; SI points to last digit. Continues to acumulate as long as numbers are ; found. Double preciead CX sectors, or to end of file, to initial DMA DX, starting ; at randrec. ; RD_RAND_CX: PUSH CX PUSH DX ;save DMA CALL SETDMA MOV DX,OFFSET FCB MOV CL,21H  of chars XOR CX,CX ;get a 00 MOV CL,BYTE PTR BUFFER+1 ;get byte count in cx JCXZ NO_CHARS XLATE: CMP BYTE PTR [BX],61H JB XLATE1 CMP BYTEsion, number returned in AX. ; GETNUMBER: CMP BYTE PTR [SI],'0' ;at least one number? JB CONVERT_ERR CMP BYTE PTR [SI],'9' JA CONVERT_ERR XOR BX,BX ;set a 0000 CONV ;read random function CALL BDOS POP DX POP CX TEST AL,TRUE ;AL not Z = EOF JNZ END_OF_FILE ADD DX,80H ;bump DMA INC RANDREC  PTR [BX],7BH JAE XLATE1 AND BYTE PTR [BX],5FH XLATE1: INC BX LOOP XLATE NO_CHARS: MOV [BX],CH ;write 0 zero at end TEST BYTE PTR BUFFER+1,TRUE ERT: XOR AX,AX ;get a big zero MOV AL,[SI] ;get first char SUB AL,'0' ;remove ascii bias CMP AL,9 ;should be 0 --> 9 JA END_CONVERT  ;bump record number LOOP RD_RAND_CX ;and keep going RET END_OF_FILE: MOV BX,DX MOV BYTE PTR [BX],1AH MOV EOTFLG,TRUE RET ; ; Scan ahead to see if 41 lines remain  ;set Z flag if no chars RET ; ; Display number 0 --> 999 ; PAGE_NUMBER: MOV AX,PAGEN CMP AX,10 JB ONE_DIGIT CMP AX,100 JB TWO_DIGIT XOR CX,CX THREE_ ;out of numbers ; PUSH AX ;save a copy MOV AX,BX ;put previous number in AX MOV CX,10 ;then multiply by 10 MUL CX ;result in DX and AX in buffer. If not, move top ; 8K to bottom of buffer and refill top. SI always points to top of ; current page. ; SCAN_AHEAD: TEST EOTFLG,TRUE ;dont scan if EOF in buffer JNZ SCAN_RET MOV CX,PLENGTH DIGIT: CMP AX,100 JB THREE1 SUB AX,100 ;must be 100 or greater INC CL JMPS THREE_DIGIT THREE1: PUSH AX ;save remainder CALL PR POP CX ;recover new number ADD AX,CX ;and add it in MOV BX,AX ;and save it INC SI JMP CONVERT END_CONVERT: DEC SI  ;get screen length SUB CX,3 ;leave room for number ROL CX,1 ;times two ADD CX,1 ;and one more MOV DI,SOPPTR ;use di as a pointer SCAN1: INT_CL POP AX TWO_DIGIT: XOR CX,CX TWO1: CMP AX,10 JB TWO2 SUB AX,10 ;must be 10 or greater INC CL JMPS TWO1 TWO2: PUSH AX;point to last # for continuity MOV AX,BX ;put it in ax RET CONVERT_ERR: DEC SI ;in case number was forgotten, this XOR AX,AX ;will treat char as next command    CMP DI,EOFMARKER ;is pointer at or beyond end of buff? JAE NEED_MORE ;yes, do refill CMP BYTE PTR [DI],LF JE SCAN2 INC DI JMPS SCAN1 SCAN2: INC Dcord # MOV NEXTRN,AX ;and store it ; MOV DX,OFFSET FILE_BUFFER MOV CX,64 ;sectors to read CALL RD_RAND_CX ;do the read RET ; ; Set up pointers to read one painning at SOPPTR, or stop at eof. If EOF found, SOPPTR ; is not updated. ; PRINT_PAGE: MOV CL,CLRSCRNF ;clear the screen CALL ESC0 CLD MOV SI,SOPPTR ;start of current page MOVI LOOP SCAN1 SCAN_RET: RET NEED_MORE: SUB SOPPTR,2000H ;move pointer back 8K ADD FIRSTRN,64 ;64 sectors = 8K MOV SI,MIDMARKER ;mid buffer addr MOV DI,OFFge back. ; DEC_PAGE: MOV SI,SOPPTR ;get start of current page CMP SI,OFFSET FILE_BUFFER JBE DEC4 ;hard stop at start of file MOV CX,PLENGTH SUB CX,3  CX,PLENGTH ;# of lines per page SUB CX,3 PAGE1: PUSH CX ;save lines per page count MOV CX,PWIDTH ;get chars per line SUB CX,2 ;room for crlf PAGE2SET FILE_BUFFER ;start of buffer MOV CX,2000H ;move 8K CALL MOVE_STRING ; ; now fill the top 8K, or to eof ; MOV AX,NEXTRN ;pick up next record # MOV RANDREC,AX ;inser STD ;set reverse direction DEC1: SUB SI,2 ;skip over LF DEC2: LODSB ;AL <-- [SI], DEC SI AND AL,7FH ;strip WS high bit CMP AL,LF : LODSB ;pick up byte, and inc SI AND AL,7FH ;for WS high bits CMP AL,1AH ;is it end of file? JE PR_EOF ;yes CMP AL,LF t in FCB ADD AX,64 ;and update it to new.. MOV NEXTRN,AX ;NEXT RECORD # MOV DX,MIDMARKER ;initial DMA addr MOV CX,64 ;64 sectors=8K CALL RD_RAND_ JE DEC3 CMP SI,OFFSET FILE_BUFFER JBE DEC6 ;another hard stop JMPS DEC2 DEC3: LOOP DEC2 ADD SI,2 ;point to first char in line DEC5: ;a line feed? JE PAGE4 ;yes, count it and start new line CMP AL,CR ;a CR? JE PAGE3 ;print it CMP AL,TAB ;a tab? JE TAB_IT CX ;do the read RET ; ; Scan back to see if 21 lines remain in buffer. If not, move bottom ; 8K to top 8K, and refill bottom 8K. Update FIRSTRN and NEXTRN. ; SCAN_BACK: CMP FIRSTRN,0 ;is start of file already th MOV SOPPTR,SI ;page always starts from sopptr DEC PAGEN ;bump page number down MOV EOFFLG,FALSE ;if it scanned, not at eof anymore DEC_RET: RET DEC4: MOV SI,OFFSET FIL ;determine next tab position CMP AL,20H ;another control char? JB PAGE2 ;dont print and dont count PAGE3: CALL CONOUT LOOP PAGE2 ;and dec char count ; ; If iere? JE BACK_RET ;yes, dont scan MOV CX,PLENGTH ;get screen length SUB CX,2 ;is -3 +1 MOV DI,SOPPTR ;get start of current page BACK1: CMP DI,OE_BUFFER MOV SOPPTR,SI ;hard stop at start of file RET DEC6: MOV SI,OFFSET FILE_BUFFER JMPS DEC5 ; ; Move SOPPTR to top of next page and bump page number ; INC_PAGE: MOV SI,St falls thru here, line has been truncated to 78 characters. Move ; SI to start of next line, send CRLF, then reenter loop ; PAGE6: CALL INDEX_TO_START ;advance SI to next line JMPS PAGE5 ; ; Come here when a LF is encouFFSET FILE_BUFFER JBE NEED_LESS CMP BYTE PTR [DI],LF JE BACK2 DEC DI JMPS BACK1 BACK2: DEC DI LOOP BACK1 BACK_RET: RET NEED_LESS: OPPTR ;get start of current page MOV CX,PLENGTH SUB CX,3 CLD ;set forward direction INC1: LODSB ;AL <-- [SI], DEC SI AND AL,7FH ntered to count total # of lines ; PAGE4: CALL CONOUT ;print the LF PAGE5: POP CX ;recover line count LOOP PAGE1 ;until 20 lines JMPS PR_EOF1 ;after MOV EOTFLG,0 ;if it was set, not anymore ADD SOPPTR,2000H ;update page pointer SUB FIRSTRN,64 ;and first record number MOV SI,OFFSET FILE_BUFFER MOV DI,MIDMARKER  ;strip WS high bit CMP AL,LF JE INC2 CMP AL,1AH ;end of file? JE INC_RET ;dont update anything JMPS INC1 INC2: LOOP INC1 ;for 20 L 20 lines, print page number PR_EOF: POP CX ;eof found before 20 lines PR_EOF1: CALL PRINT_NUMBER RET TAB_IT: MOV DX,PWIDTH SUB DX,2 ;start with same line l MOV CX,2000H CALL MOVE_STRING ; ; now refill the bottom 8K ; MOV AX,FIRSTRN ;get new first record # MOV RANDREC,AX ;and insert in FCB ADD AX,128 ;compute next reF's INC PAGEN MOV SOPPTR,SI ;print always starts from sopptr RET INC_RET: MOV EOFFLG,TRUE ;set last page flag RET ;and go back ; ; Display 20 lines beg ength TAB_LOOP: SUB DX,8 ;next tab stop CMP DX,CX ;is it less than current pos? JB NEXT_STOP ;yes, next stop found JMPS TAB_LOOP NEXT_STOP: MOV CX JE NEXT_PAGE ;forward n pages CMP AL,'P' JE ABSOLUTE_PAGE CMP AL,'X' JNE NEXT_PAGE ;all errors default to next page MOV CL,CLRSCRNF CALL  SUB AX,PAGEN ;compute increment JMP NP2 ;and go to it LESS: MOV BX,AX ;save requested page MOV AX,PAGEN ;get current page SUB AX,BX ,DX ;becomes new char count INC CX ;to account for loop dec's CX CMP CX,0 JLE PAGE6 ;error, cut line short JMPS PAGE3 ; INDEX_TO_START: LODSB  ESC0 ;clear screen XOR CX,CX ;all done XOR DX,CX INT 224 ; NEXT_PAGE: TEST BYTE PTR BUFFER+1,TRUE JNZ NP1 ;not a default ONE_PAGE:  ;compute negative increment JMP LAST1 ;and go to it ; ; end  AND AL,7FH CMP AL,LF JE END_INDEX JMPS INDEX_TO_START END_INDEX: CALL CRLF RET ; EXIT: XOR CX,CX XOR DX,DX INT 224 ;----------- MOV AX,1 ;was a default JMPS NP2 NP1: CALL INDEX_POINTER CALL GETNUMBER ;get incremental request JZ ONE_PAGE ;was just a +, default to 1 NP2: MOV -------------------------------------------------------- ; Type program begins here ; TYPES: MOV FCB,0 ;erase any disk request CALL OPENC ;open file in FCB JNZ HAVE_FILE MOV  CX,AX ;load cx with number JCXZ PRINT_IT ;if +0 was entered, reprint current ADVANCE: TEST EOFFLG,TRUE ;are we on last page? JNZ PRINT_IT ;yes, dont scan anymore PU2@&GPVCXP- ;XU 4 ເ u*_ <u. <uO 2 tw *+C DX,OFFSET MSG001 CALL MESSAGE JMP EXIT HAVE_FILE: TEST FCBRC,TRUE ;is file empty? JNZ NOT_EMPTY MOV DX,OFFSET MSG002 CALL MESSAGE JMP EXIT NOSH CX CALL SCAN_AHEAD CALL INC_PAGE ;move pointers ahead 1 page POP CX LOOP ADVANCE ; PRINT_IT: CALL PRINT_PAGE CALL SCAN_AHEAD JMP COMMAND ? v?0r?9w.&0 uD . ?kt.=vPQX=v.......+2@&W.>t -@+.++w N&W&>%%.>t&&G+.>Z&W.-% C&CCÉGG.ZT_EMPTY: MOV RANDREC,0 MOV RANDOVRF,0 MOV DX,OFFSET FILE_BUFFER MOV SOPPTR,DX ;set up cursor MOV CX,16 ;read in 2K initially CALL RD_RAND_CX ; LAST_PAGE: CALL INDEX_POINTER ;point to number CALL GETNUMBER ;get it if there JNZ LAST1 ;was there MOV AX,1 ;not there, default to -1 LAST1: MOV %G+&+&+&$+&:+&G+&+&+&+&+&>&&G+&. .1.;.=.?.A.>Z+A ..Z&@0 u t0Kú<  PUSH DX ;DX has next DMA addr CALL PRINT_PAGE ;print first page POP DX TEST EOTFLG,TRUE ;see if end of file reached JNZ COMMAND ;yes, dont read any more CX,AX JCXZ PRINT_IT1 ;if -0, reprint current pg DECLINE: PUSH CX CALL SCAN_BACK CALL DEC_PAGE POP CX LOOP DECLINE PRINT_IT1: CALL PRINT_PAGE      RAMDISK 1.1     Context Sensitive Inc. Seattle, Washington (206) NEC-0301   $  Thank you for MOV CX,112 ;rest of 16K CALL RD_RAND_CX ;do the read MOV AX,RANDREC ;get the next record # MOV NEXTRN,AX ;and store it ; COMMAND: CALL GETCOM  CALL SCAN_BACK JMP COMMAND ; ; ABSOLUTE_PAGE: CALL INDEX_POINTER ;move to number CALL GETNUMBER ;and get it, if there JZ ABS1 ;not there, default to same pag choosing RAMDISK from Context Sensitive Inc.  This program creates a pseudo disk drive using part of the random access memory (RAM) of your computer. Your computer has kbytes of memory available for progra ;then get command MOV SI,OFFSET BUFFER+2 JZ NEXT_PAGE ;default is next page CALL DEBLANK CMP AL,'-' ;back n pages JE LAST_PAGE CMP AL,'+' e CMP AX,PAGEN ;compare to current page JA MORE ;it's greater then pagen JB LESS ;it's less then pagen ABS1: JMP PRINT_IT ;must be same page MORE:  m execution. Most programs require less than 64 kbytes, so any remaining memory would otherwise be unused. The main advantage of using a RAM disk is its speed. The main drawback is that it is not permaneeletes all files and removes the drive $[.-.+P=wȿX-wۺ".# t..# t..1.# t..%.# t..$.'..# t..).'.%.$./ .-{{TXَэ&PUVN]0102821100654321nt. Each time the computer is turned off or CP/M-86 rebooted using the CTRL-FNC-BREAK sequence, all files stored on the RAM disk are deleted and the RAM disk itself is eliminated. Therefore be sure ڋ@+w.# t..%.$./ .-‹.'.)@+..# t..).!XXX P@P%Pϐ3CU]UF]Ð{.츀P5PPw>5t@("s P|&=0r -PP(s "PI5rto save all modified files on a permanent disk at the end of every session with the computer. In an emergency press the reset button behind the rubber stopper in the key- board to return to CP/M-86 without erasing the RA@?* #)!"%(s *P>5w`P s PPO>+=t >+_tMPX> u?>t52 sP\P$P]@(5-P >u%> uPP#P!M disk.  Press any key to continue...$ The RAM disk created by this program is called drive K. Drive K is used the same way as any other disk drive. To list the directory of files,>v PP0므>t!%s>+,t>+ t PP>+,t@%>u>u>u>r> w s PP>t">u">"'w P"u> uPz %sP7UPP]UP type:  DIR K: (Initially drive K is empty and this command will give the NO FILE message.) To copy programs and data files to drive K, type:  PIP K:=filenameP]UPF$Px]U P P]U PvW]Uv]U4 P4P1]U PP"]U PP]UPv]UPv3]UPv3]U>3u]Ê3ˀ`:u]ðPP3]UPv3].typ To select drive K as the default drive, just type:  K: in response to the CP/M-86 prompt.  Press any key to continue...$ To create the RAM disk, typeUPP3]UPvo]UPv_3]UPvL3]UPv93]UPv&3]UPP]UPv3]U PP]U PFP]U6]U6]U6]U!Pv]U"Pv]U:  RAMDISK nnn where nnn is the number of kbytes of memory to allocate for drive K. Remember, this must be less than kbytes. $ $  A size must be specified for RAMD#Pv]U$Pvx]UFȈF3u PP#]UtP,Њ"s3>3u PP"-"."/"0"1"2P93PPPH]U#s% RAMDISK drive K not created - it already exists  CTRL-FNC-BREAK deletes all files and removes the drive $  RAMDISK drive K has been created ( kbytes)  CTRL-FNC-BREAK d u]6:Pd' &'sP3t PP͠rP;sjP;t@@r]á]á;r]Us1-3ta>3t PP:t >uPUТ& "s PP$6]Áj]U~ r>t:wgs PFPsR!&"$s#Ps*%s]á&"$sE5 ss 6+%"s]à!s ]U3PhPP*3u$]À>3u>3u%u뷰PPCEOZau!<Na (1/8/82) CP/M-86 PIP VERS 1.1 DISK READ$DISK WRITE$VERIFY$INVALID DESTINATION$INVALID SOURCE$USER ABORTED$BAD PARAMETER$INVALID USER NUMBER$INVALID FORMAT$HEX RECORD CHE. v?PFPp-;rF6:ӈ ]U~ u>uva28r(*>t  P/~ u]U~t@"s F0P]UFPF$P]U8t@]U Pdh\P >3u@ P; r@Y"s  ؀>3u>u P\Ps]á @ 3$@PPPPPPrts=2 s&s>uPW#]UCKSUM$FILE NOT FOUND$START NOT FOUND$QUIT NOT FOUND$INVALID HEX DIGIT$CLOSE FILE$UNEXPECTED END OF HEX FILE$INVALID SEPARATOR$NO DIRECTORY SPACE$INVALID FORMAT WITH SPARCE FILE$ =.:;,<> _[]OUTPRNLSTAXOCONAXIINPNULEOFERROR: $ -'''P66>u :P  P ]U젾s~ tg)sD~ t>>t"<u<:r  P>tP)~ uv~ u)]U~ar ~zwf_F]U~Ar ~ZwN F]U< w(Ê t< u.P6u]U?P>3t33$@PPPs ]ư]U:u :u6]U젶:5r ]à6]U+< t]U>+ t]YQUG% + , $$$$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$COPYING -$REQUIRES CP/M-86$CP/M-86 PIP VERSION 1.1$. PP*u;r"s>t 67PP* PP$ sCs **> t@ss2<u]ðPPis&s 6]às 6>,#s>, u+G$>wƇup,6+js#>,r]À>+*uPw+Ѐ>+:t>,u<G,A<v]6+s>+[uqG% ]>,t]> wi<]à]U>tȢ<u/ ])>tƊ6]<u]Â>t%6Is맂>t6s ]]]UFFƊ6u 6:u]U+s;v@֋P:t@Y"rȀ>uG%^<[u]Àu]À>+[uc^>,u],>+.u- +PDs>, r]À>+*u P{QӀ>+[uG%G ]]U> wF:uu]U,w@"$]À>+t@]U>:t#>us]ðPP6>u"s&>:u@P>u@Y"sWXM:P66}k>t ZRt PP,Ɗ+?u ]U+?,:Fs]Uc++< t@+P]t@Z rAv>+ tİPP뾀>+St>+Qu1+<t@P>+ t@Y r+9+,0< v#+,0< w ݠ??Y[ð-SQб SQ SQбñ2|\ ñàU 3Ɋ?]U,0< w]à,A<v PP,A ]UP]UPY ]UPY ]U>t PP>t PP]UtP4 P>3u PPpP>3t}PsUsL>3Yuu<v PP'G$v+]?ar?{s'_C/á= r+=dr3=dr-dPX3= r- PX0B0;<u< tF<0r&<9w!33,0< wPù YFNN3á- PXeFQR\!ZYu €}Ë  u!> ;>;@P>3Nu@Y"sP"P3р>3YtPP]&&P+PPPPP" -" ." /" 0 " 1" 2 PsP]U-:P:X% s = tGGÁ.  @69= }@9@Ã>t> =v = tOO   .@=>9 Z}=@)Ë6 =v-$< t=v6  þ=6 þ=6 $< t<t 6  nterrupt BDOSBP EQU 24A0H ;bdos data page base \ MONTH EQU 24C0H ;month location in bdos \ DAYS EQU 24C3H ;days location in bdos \ using the proper system YEARS EQU 24C6H ;years location in bdos > call will eliminaea all HOURS EQU 2GISTERS UNCHANGED ; FFCBFN: CALL FCBFN ;CALL NEAR PROCEDURE RETF ;RETURN FAR FCBFN: PUSH ES PUSH SI PUSH DI PUSH CX PUSH AX PUSHF MOV AX,DS MOV ES,AX ;SET ES: TO DS: MOV SI,0 MOV DI,DX MOV BYTE PTR 0 [BX],0 MOV AL,[DI] Ê6 Q$<t"< t< t< t< rZ)PYYJË;rA~Ϭ$< t(33\?u ku $ }=  RKZ u p}t <-tK<+tFCB ADDRESS ; BX-->STRING TO CONVERT ; DS:=>BOTH DX AND BX ; CALL FSCAN:NEAR ; ;EXIT WITH: ; AL=0 AND Z FLAG SET MEANS NO ERROR OCCURRED DURING SCAN ; AH IS DESTROYED. ; DIRECTION FLAG IS CLEARED ; BX=>LAST CHARACTER SCANNED (THE ONE THAT TITLE 'CLINE - SAVE COMMAND LINE IN INTERNAL BUFFER' PUBLIC CLINE CSEG ;BX-->POINTS TO COMMAND LINE (USUALLY DS:0080H) ;EXIT WITH BX-->POINTING TO LINE IN HERE WITH NULL TERMINATOR CLINE: PUSH SI PUSH DI PUSH ES MOV SI,DS MOV ES,SI PROPERLY FORMATTED. THE FILE STRING IS CONSTRUCTED ;IN THE USER BUFFER AND THE FIRST BYTE CONTAINS THE NUMBER OF ;BYTES IN THE FILE STRING. ;PROGRAMMED BY A. L. BENDER, M. D. ;NEUROLOGICAL SERVICES, INC. ;336 CENTER AVENUE ;WESTWOOD NJ 07675 ;THI STOPPED THE SCAN) ; DX=>POINTS TO YOUR FCB AS ON ENTRY ; ALL OTHER REGISTERS EXCEPT PSW ARE PRESERVED ; AL=NON ZERO AND ZFLAG CLEAR MEANS ERROR DURING SCAN ; ; SCAN STOPS ON COMMA, SEMICOLON, EQUALS SIGN, BLANK, CARRIAGE ; RETURN, LEFT BRACKET, LESPUSH CX PUSHF CLD MOV CL,BYTE PTR 0 [BX] ;COUNT OF CHARS IN LINE MOV CH,0 LEA SI,1[BX] ;GET START OF STRING MOV DI,OFFSET THISBFR ;INTERNAL BUFFER MOV BX,DI ;SET ADDRESS OF CLINE BUFFER REP MOVSB ;MOVE THE STRING TO HERE MOV BYTE PTR [S IS IN PUBLIC DOMAIN AND MAY BE USED BY ALL BUT NEVER SOLD ;OR INCORPORATED IN SOFTWARE TO BE SOLD OR DISRIBUTED FOR PROFIT. ; ; ;CALL: ; BX-->ADDRESS OF USER BUFFER TO STORE FILE NAME ; DX-->ADDRESS OF USER'S FCB ; CALL FCBFN ;NEAR CALL ;OR CALS THAN SIGN, ZERO (NULL). ; ON EXIT THE FCB IS ALL SET UP TO USE (THE BODY IS ZEROIZED ; AND THE FILENAME, DISK AND EXTENSION ARE SET FOR USE) ; ; YOU MAY WISH TO MAKE THIS A "FAR" PROCEDURE. TO DO THIS YOU ; MUST CALL IT FSCAN END EXTERNALIZE IT ":FDI],0 ;PUT TERMINATOR ON STRING POPF POP CX POP ES POP DI POP SI RET DSEG THISBFR RB 128 ;CLINE BUFFER END L FFCBFN ;FAR CALL ; ; IN EITHER CASE DS: MUST BE SET TO DATA SEGMENT OF BOTH ; ON EXIT: ; THE STRING IS IN THE USER'S BUFFER. ; THE NUMBER OF BYTES IN THE STRING IS IN THE FIRST BYTE OF THE BUFFER ; BX->UNDISTURBED ; DX->UNDISTURBED ; ALL OTHER RE AR". CHANGE THE ; RETURN FOLLOWING THE LABEL "EXIT" TO "RETF" RATHER THAN "RET" ; ; THIS SUBROUTINE USES NO OTHER SUBROUTINES. ; ; FCBLEN EQU 36 ;SIZE OF FILE CONTROL BLOCK FNAMEL EQU 8 ;LENGTH OF FILENAME (PRIMARY NAME) FEXTL EQU 3 ;LENGTH OF FILYTE PTR 0 [BX] CALL TERM JZ DONE ;FINISHED WITH SCAN JMPS ERROR ;SCAN ENDED IMPROPERLY SPCH: CMP AL,'*' JNZ SPCH1 ;NOT ASTERISK CALL STAR INC BX MOV AL,BYTE PTR 0 [BX] CALL TERM JZ DONE JMPS ERROR SPCH1: CALL TERM JNZ FX2 ;NOT Tet from beginning of o.s. to fix ; dx = # of bytes offset from beginning of o.s. to fix ; ds: = segment where we expect to find bye86, if loaded ; es: = operating system segment MEMFIX: PUSH CX ;save segment # for new i/o calls SUB CX,SYSSEGE EXTENSION FNLEN EQU FNAMEL+FEXTL FSPEC EQU FNLEN+1 ;FILE AND DISK SIZE FSCAN: PUSH CX PUSH ES PUSH SI PUSH DI CLD MOV AX,DS MOV ES,AX MOV CX,(FCBLEN-FSPEC)/2 ;SOZE OF FCB TO BE ZEROED MOV DI,DX ;FCB ADDRESS ADD DI,FSPEC ;START OF ERMINATOR, JUST STORE IT JMPS DONE ;SCAN TERMINATED ;CHECK FOR CHARACTER WHICH WILL TERMINATE D:F.E PROCESSING TERM: CMP AL,',' ;CHECK FOR COMMA SEPARATOR JZ T1 ;NOPE TEST AL,AL ;CHECK FOR NULL (END OF STRING MARK) JZ T1 ;NOPE CMP AL,' ' ;rationalize segment # to 40h (operating sys) MOV AX,CX ;\ MOV CL,4 ; > compute offset relative to 40h SHL AX,CL ;/ MOV DX,AX CALL MOVEIT ;move routines low memory POP DS ;put segment # in ds MOV CX,DX ; and offset in cx MOV AX,(OFFSFCB BEYOND FN XOR AX,AX REP STOSW ;ZERO FCB MOV DI,DX MOV CX,FSPEC/2 MOV AX,' ' ;BLANK OUT FILE NAME IN FCB REP STOSW MOV SI,DX MOV BYTE PTR 0 [SI],0 ;ZERO DISK INDICATOR CMP BYTE PTR 1[BX],':' ;LOOK FOR EXPLICIT DISK JNE NODISK  ;TEST BLANK JZ T1 ;EXIT IF BLANK CMP AL,0DH ;CARRIAGE RETURN? JZ T1 ;NOPE FALL THRU CMP AL,';' ;SEMICOLON? JZ T1 CMP AL,'=' ;EQUAL SIGN? JZ T1 CMP AL,'[' JZ T1 CMP AL,'<' T1: RET ;RETURN WITH FLAGS SET ;CONVERT THE '*' TO P TITLE 'INITIALIZE FCB' PUBLIC INITFCB NAME 'INITFCB' ; ;INITFCB - INITIALIZES THE FCB TO ZERO BUT DOES NOT DISTURB THE DISK ; DESIGNATOR OR FILENAME AND EXTENSION. ;ON ENTRY DX-->FCB (MUST BE IN DATA SEGMENT) ;ON EXIT NO REGISTERS ARE DISTURBED ;NONE MOV AL,BYTE PTR 0 [BX] ;GET START OF STRING CALL UPPERCASE ;TRANSLATE TO UPPER CASE JNZ ERROR ;ERROR... NOT A LETTER SUB AL,'A'-1 ;FORM DISK ID MOV BYTE PTR 0 [SI],AL ;SAVE DISK ID INC BX ;PASS ':' INC BX ; NODISK: MOV CX,FNAMEROPER NUMBER OF ??? IN FCB STAR: MOV AL,'?' ;CONVERT '*' TO '???..' IN FN OR FEXT INC SI ;MAKE SI POINT TO STAR FIELD MOV DI,SI REP STOSB ;REPEATEDLY STORE ? IN FCB MOV SI,DI ;MAKE SI POINT TO PROPER SPOT IN FCB RET ;CX=COUNT OF REMAINDEFCB IS CLEARED AS ABOVE. ; CSEG FCBLEN EQU 36 ;SIZE OF FCB FNLENGTH EQU 12 ;COMPLETE FILENAME DESIGNATOR SIZE INITFCB: PUSH AX PUSHF ;PRESERVE DIRECTION FLAG PUSH CX PUSH DI PUSH ES MOV AX,DS ;MAKE EXTRA SEGMENT POINT TO DATA SEGMENTL ;FILE NAME SIZE NOD1: MOV AL,BYTE PTR 0 [BX] ;GET FIRST CHARACTER OF FILE NAME CALL UPPERCASE ;TRANSLATE TO UC JNZ NOTLET ;NOT A LETTER - SPECIAL NOD2: INC SI INC BX ;MOVE POINTERS ALONG MOV BYTE PTR 0 [SI],AL ;PUT CHARACTER IN FCB LOOP R OF FCB FIELD UPPERCASE: CMP AL,'A' JC LESS ;LESS THAN CAPITAL A CMP AL,'Z'+1 JNC NOTAZ ;NOT A-Z, MAY NEED CONVERSION LETR: XOR AH,AH ;SIGNAL LETTER FOUND (Z=1 ON RETURN) RET ;EXIT TO USER NOTAZ: CMP AL,'a' ;CHECK a-z JC LESS ;DONT MOV ES,AX MOV CX,FCBLEN-FNLENGTH/2 XOR AX,AX ;MAKE A=0 MOV DI,DX ;DX-->FCB ADDRESS ADD DI,FNLENGTH ;PASS FILE NAME CLD REP STOSW POP ES ;RESORE EVERYTHING POP DI POP CX POPF POP AX RET ;RETURN IN THIS SEGMENT END NOD1 ;LOOP THRU FILE NAME NOD3: MOV AL,BYTE PTR 0 [BX] ;GET NEXT CHARACTER IN IMAGE CMP AL,'.' ;MUST BE PERIOD OR TERMINATOR JZ FEXT ;FILE EXTENSION CALL TERM ;CHECK FOR TERMINATOR JZ DONE ;TERMINATOR ERROR: MOV AL,1 ;IMPROPER FILE SYNTAX  CONVERT CMP AL,'z'+1 JNC LESS ;NOT a-z, DONT CONVERT IT AND AL,01011111B ;MASK UC BIT OUT JMPS LETR ;LETTER RETURN LESS: OR AH,1 ;INDICATE NON LETTER RET ;RETURN TO USER END ,AX ; MOV BX,(OFFSET PTCHFA) - (OFFSET CONSTE) ; MOV DS:[BX],AX ; MOV BX,(OFFSET PATCH1) - (OFFSET CONSTE) ; MOV AX,[BX] ; ADD AX,DX ;the following routines MOV DS:[BX],AX ;set up the pointers MOV BX,BCONST ;to the old and new MOV DX,(OFF JMPS EXIT DONE: XOR AL,AL EXIT: OR AL,AL POP DI POP SI POP ES POP CX RET ;RETURN TO USER PROGRAM NOTLET: CMP AL,'*' ;IS IT ASTERISK? JZ NOL1 ;YES CMP AL,'.' ;FIND PERIOD? JZ FEXT ;YERP ->PROCESS EXTENSION CALL TERM ;CHECK F to avail mem length ; cx = segment # of next available memory (lower bound) ; dx = length of moved portion in paragraphs ; es: = operating system segment SETSEG: PUSH DX MOV CX,AX MOV AX,SYSSEG MOV ES,AX ADD DX,CX MOV ES:[BX],DX POPSET CONSTE)-(OFFSET CONSTE) ;bios routines. fixit MOV AX,(OFFSET CON1)-(OFFSET CONSTE) ;computes the offset CALL FIXIT ;from the old jump to MOV BX, BCONIN ;the new jump and MOV DX,(OFFSET CONINE)-(OFFSET CONSTE) ;writes it in the old MOV AX,(OOR TERMINATOR CHARACTER JZ DONE ;FINISHED SCAN JMPS NOD2 NOL1: INC BX ;POINT TO NEXT CHARACTER IN STRING CALL STAR ;CONVERT *-->??? JMPS NOD3 ;KILL REMAINDER OF FILENAME PROCESSING FEXT: MOV CX,FEXTL ;SET FOR MAX 3 CHARACTER EXTENSION INC DX ADD BX,2 MOV AX,ES:[BX] SUB AX,DX MOV ES:[BX],AX RET ; memfix - move the necessary portions of bye86 and patch required jumps ; in 'BIOS' ; ; enter: ax = ? ; bx = offset in segment 40 to avail mem length ; cx = segment # of next FFSET CON2)-(OFFSET CONSTE) ;bios jump location. CALL FIXIT ;it then computes the MOV BX, BCONOUT ;offset from the new MOV DX,(OFFSET CONOUTE)-(OFFSET CONSTE) ;location to the loca- MOV AX,(OFFSET CON3)-(OFFSET CONSTE) ;tion the old jump took CA BX ;PASS THE '.' MOV SI,FNAMEL ;BIAS FOR EXTENSION ADD SI,DX ;ADD FCB START (FORM LOC OF EXTENSION) FX1: MOV AL,BYTE PTR 0 [BX] CALL UPPERCASE JNZ SPCH ;SPECIAL CHARACTER FX2: INC BX INC SI FX3: MOV BYTE PTR 0 [SI],AL LOOP FX1 MOV AL,Bavailable memory (lower bound) ; dx = length of moved portion in paragraphs ; es: = operating system segment ; exit: (after moveit) ; ax = (pop) seg # next avail mem ; bx = offset in segment 40 to avail mem length ; cx = # of paragraphs offs LL FIXIT ;and saves it in the MOV CX,(OFFSET CON2A) - (OFFSET CON1) ;new routine. MOV BX,(OFFSET CON1) - (OFFSET CONSTE) + 1 ; ** this routine MOV AX,DS:[BX] ;computes the offset SUB AX,CX ;for the call at loca- MOV BX,(OFFSET CON2A) - (OFFSET  PvX^P6j XD3RPRP PvX^P6j XtXRP/XZ^_+RPFPpP/U PvX^P6j XtX u6 PvX^P6j XtDD PvX^P6j Xt[DD PvX^P6j XtX u PvX^P6j XtX uPPT PvF]Ív]Ë]'vLDDFF=u PvX^P6j X]r'3FF;;|6P PvX^P6j X^;tF]Ív]Ë]'FF=tPKDD3]øPvKFF=tvPK3]CONSTE) + 1 ;tion con2a of the new MOV DS:[BX],AX ;routines in low memory RET ; routine to patch 3 bios jump locations - enter with bx = offset ; (relative to 400h) of 'BIOS' jump instruction in 'BX', and offset ; (relative to beginning of availX^P6j XtX u6 PvX^P6j XtDD PvX^P6j XtDD PvX^P6j XD3RPRP PvX^P6j XtXRPz.XZ^_+RPvTY[ӉTvP PvX^P6j X^;t vP PvX^P6j X^;tPRP6;D6;FDDVFVF3;6;6;vaKF uvXRPvTY[ӉT;F3FF;Fr*6;vƊPP;vvVv6;6;P^;u36;>DDp;PPJPJDDPJDDPc?DD7JJJ6G7VvVvVu)^;t PwODDvv,F=|o5P/PP[?P[DD[P[DDP[DDP[DD vvvv踍P`SvvvPMS].$3V^;|p;PP(S]øFF;;|3P PvX^P6j X^;tFP PvX^P6j XtV-FPPRPFPpGFF=tFPPR:RP 6;3PPP3P~P; PvX^P6j XtVv RPvv$ PvX^P6j Xt XZRPRPvvXZ^_RP# PvX^P6j XtXZ PvX^P6j Xt; PvX^P6j X33V6j,3PvF^;|8PIDD3P^>P[DDPy[DDPp[DDIPg[DDnP^[DDPU[DD(Pv4Fv4Vp;P p;PDD3P.Pp;PS~;^;uP6~;  uA~; u'PZDDPZDD%PZDDPODDVPp;P ^F=([PZDDvPZPZDDPvX^P6j Xt XRP,XZVF⸀RP PvX^P6j XtXRP,XZVF3Pvv6;NK3;RPvvXZ^_;u;w 6;X3RPvvXZ^_;u;w 6;X3RP vvXZRPXZFv6;6;Q;F3FދvVvX^;r*6;vDD$P PvX^P6j XtX3P PvX^P6j XtX6j,t PvX^P6j XtX3P PvX^P6j XtX PvX^P6j Xt3 PvX^P6j Xt3 PvX^P6j Xt3 PvX^P6j Xt3v23FF;;|VPvX^P6p,XV; DD^;u!PvX^P6p,XVEP$XPvX^P6p,XV`PXPvX^P6p,XV DD3VPvX^P6p,XV DD^;t vD]23Vz^;|p;PtPW]3gRP PvX^P6j Xt XRP)XZVFRP PvX^P6j XtXRP)XZVF3Pvv6;?H3;RPvvXZ^_;u;w%6;X3RPvvXZ^_;u;w 6;X3RP vvXZRPXZFv6;6;N;F3FF;Fr*6;RP PvX^PXtX3RP XZV։FԸRPvvXZ^_;u;w6;X3RPvvXZ^_;u;w 6;X3RP vvXZRPXZFv6;vFPv6;6;LF^;t F;Fu46;9DDp;PaKDDp;PPEPEDDPe:DDvXFF;;|VPvX^P6p,XVN DD^;u!PvX^P6p,XVP7WPvX^P6p,XVPWPvX^P6p,XV DDvk(]+2VF3FFF3V^;|p;PPV]Íp;PPV6j tX uPVvƊPT;vvXRPvTY[+ӉTPv6;v]TF^;t F;FuQv;BDDPvX^P6p,XVSDDPvX^P6p,XVPMPMDDPBDD6;3PSP3PS;vADD3P6j tX^;ƸtH4;RPvԋTY[+ӉT PvX^P6j X3 PvX^PXt PvX^P6j XtX PvX^P6j XtVFPLRPRPvvXZ^_RP PvX^P6j Xt XZ PvX^PXt PvX^P6j XtX PvX^PXtDDP}VDD -PqVDD3FF;;|3P PvX^P6j X^;tkFP PvX^P6j XtV|F u^ PvX^P6j Xt PvX^P6j Xt RP PvX^P6j XtXRPA0SPU PvX^P6j Xt PvX^P6j Xt; u!6;V PvX^P6j XtX^;u;PSMDDaPJMDDPvX^P6p,XV{P*Mv6;;ADD]R(FPvBFPFPP3FF;;|o3P PvX^P6j X^;tAFP PvX^P6j XtV3VFPFPBP^;t  PvX^P6j XtX PvX^PXt PvX^P6j XtX PvX^PXt PvX^P6j XtX PvX^PXt PvX^P6j XtX PvX^PXDP PvX^P6j XtX PvX^P6j Xt3 PvX^P)vvPv ^^Ɓ0FvF]Ë]v uvP@DDPvXv]_(3FF=$|vv3vvVv)vVvPFPP.^;ƸtH]Ë]FFv u vƊPv3]Ë] PK&DDFv4v4X3F3PP0DD^;t]øFF;|g!VFPX4^;tWF=tk PPXXFPX4VvP8XXFPX4VDD u*6j Xt3 PvX^P6j Xt3vʋvm7DDFPHDDFP! P]mPp;PB;;=t]þ V P6j V6; C^;u6;7DD]ø PP6j tX^^ t3; P;^F;=p;P/ PBX]v u.vƊPvƊ^;u3]]Ë]t P6n,4XYFP6n,tXYFP6n,tXYFFFFF]Ë] PPF^#YP6n,XPPF^#YP6n,tXPPF^#YP6n,tFPX4VPXXFPX4V`P`PZ.DDt"6:VFPX4P#X^;t<FPX4P"X"6"APP$!vPP$ ut! uPPa$]3P6j ^;t P^ P6j tVF u3P6j t X^;t3P6j tX^;up;Pj PB]ËvVv6 V6;B^;up;P PA]3P6j tX^;ƸtH4;3F PF^ƉF6j tXF3P6j tX6j F3FX]vDD6n,t6n,t6n,4J PY9]v*DD6l,tXlP6l,46l,tY P&9]cPvY3FFF;Fr7Pv^ t3 umPnPvYPv,^ t3 umPnPvY+PF^ P ^;t3!P P ^^Pv^P6v3P"P4DDP.DDPPXX^;t]Ë=}]Í"PPX4V3FPP#v3FF;F|FF;|FPFF;F|(vvƊPqGFvv3PVGP3PLGF6j tF; uF;Fu PADD6; PA]Ë]: 3; P@DDPPP6;56;DD;;=};=t]þV;^ tP^P6l,tXvX+FP6l,tX3PV6l,tX^ t^;ƸtH uP#3PdV6l,tX^ t^;ƸuHPX uH tP#3PV6l,tX^ t^;ƸtHPXF6l,t6l,XFFPPvX^P6 XX46l,4X^;5FPPvX^P6 XXPX4VFP8X4V u^,4VF^;tEFFF;|0FPX4VFPXXvpvXv;vPvX3]Ë] 3FFF= |E Vvv^;t-vvPv;Pp;P55;;=t]Í6j tV PV P6;X^^ tP6j tX6j 3FF;;|} PvX^P6j XtV P33P PvX^P6j XtX3P PvX^P6j Xt X PvX^P6j Xvw3F P646l,Y+v6l,tF]3FF6l,t^VF^;~9VF^ t umPnPvYvPPF^^+Ƌ]Ë](6l,4XF3PV6l,tX^ t^;ƸtHFF6l,tF^;|4FPPvX^PPvXXv Vv ^;uvPvX. FF= |E Vvv^;t-vvPvPvXXvvv3F]Ë] 'VvF^;t3]ÍvƊF u,*VF^;t?VF;X^F3P6j tX6j F3FF;F|(vvƊPNEFvv3P3EP3P)EF6j tFF u.6l,DD6n,& DDP6j tXP6j tX ]Ë]P6j tX^F6l,DD6n,DD;P6j tXZP6j6 XX4vYvF]Ë]F u]þVvDD^;t6n,bDD6l,DDPvtX]Ë]L3PvXv3v3vViP)v4DD] 3PvXv3v3v3vVPk)3Pv^;t]3]Ë]:Vv^;uG:Vv^;t.FPvA^;tPvY3]D:Vv^;u.FPvA^;tPvY3]ÍvƊF u?VF^;t7vƊF u tX3F3P6j tX6j F3FF;F|(vvƊPJDFvv3P/DP3P%DF6j tF3PRP6;7vVv6j V6;D^;u ! P=DD6;1DD]:Vv^;t vF.Vv^;t-^;t3Pv^;t3Pv^;tvViP)PvX#V PPPvY^#^^PvXPvX#V PPPvY^#^^PvtXPvX#V PPPvY^#^^&& < s\sns<u< t#< t(< t< s߻ N$uC2 <t   <tSRQ3FF= |vv3v]'3FF= |vv vvv33FF= |n3Vv^;tvv C.Vv^;tvFvP@BDDPvvXvv]Ë]FF=uGvPPvtX]"0V3P P?(^;|]ËFP6;X4F޸ PvVvދ4V3VvVfP'^;t]Ív4X uPvX#V PPPvY^#^^P6n,XPvX#V PPYZ[2SQPбX< r#Pu>r<Pn t u$0E$,@y ??vCSW^B>*[CS t8P$tȾ>sXtȾ>'uY5~ t/KK/xFOy]q%uZDV u0E(%Ay-AxC6B*/F/F/F/F/F/F//s6't떋W@[ $tF*VVY/{p\;y{ȋQY s'JuBBӋCCCCӃ t-%:u:u t2r ðÇ ^P.$YQ S[^ P.$CC^CC ^CC6 P.$ -N2$2Ȫ%þ2$2ȪF_|tq%1(ȋ+QY s*/,.AUXȋ[QY s l^L $ Ȫà<s tyÿN-yȈ/þÊ'P'rC'$'Fá u' ĈGäÿ'''''''ËCC$ud >*+II Du 5Ë uK[XS$v+ y؀r *tyú'ډ[[SS'YZRQ u2 u YoNN<#u~<$u~<$ui$<*u f<*tT*<.uW<#.u2g<-u"A<00-r1 t%< uFtNV@P@ Y^-Gá*+Éááá tPGá t & Q ZRZ' XPX HxPX$'@']É+ˉO#t<.-u°2H<\u t] <#t<,u<.u<#u<^u<-u u.7Cu tȢ t t uc,@t s2rNˁsFs t(W+rw>GÉWډtŹMOKK6;r64 t;r;u L7E;tOËM+Wr;s‹ uÃ>0À>YQ󥥥ËFFFF|  t tű<r,Ŋ*ŢyL%L2&%,@*ňڻ ڰuWt  u Ȋ*<s0Kusr t u* uVtQ tB<s8*Z_YQSCCӀ t[=;:2CuK29<V< t<+t <-u<B<0t<.u&9sТ9<uf <0uޠ<Ȣ<tF* tBCC*B]*SCCZSʺBX< t*Ë t# xSta*:s'_CXSQCCZZSXHHÉOYEIQPMKCEAtBG9O8I.t/ىK<\uKFMCCS"[rM;G~+SI t+۬<#u":$_A<s $:P. XĞt CC:tp2. \u$`ȵޞS! 5. . [ \u/ S\ 2\ޞ$ZB4 hP0X. Where: FN.FT is the filename and filetype     QRSб[ZY2 u2<tú Test aborted by control-C $&CBußPX$'@'dTU ٷ[õsuúK[UNUSED]BADNo; 29-Jul-85 fixed code at CLCSUB to prevent int 0, same ver 7.5-E ; 21-Jul-85 revised for 32 bit mult/div in GTLSEC and CLCSUB routines ; changed to rev 7.5-E. WHAT A MESS.... ; 29-Mar-85 relaxed for CCP/M ver 4.1 and up changed to -D ver ; 8-11-84 re$ bad blocks found $vsed for PC_MODE support renamed DU-V75C.A86 ; 04/15/84 revised to correct minor bugs - renamed DU-V75B.A86 ; ; DU.ASM V7.5 Revised 1/23/81 ( CP/M-80 version ) ; DISK UTILITY - By Ward Christensen ; ; DU-75A.A86 is a CP/M-86 translation of the CP/M-80 version. ; ; The original translation came from the SLICER USER GROUP ; disk #2, via Micro Cornucopia, PO Box 223, Bend, OR ; It did not indicate the name of the translator who should ; be thanked for his work. That version appeared as DU-75.A8x FINDBAD - Ver 1.0, Bad Sector Lockout Utility ------- Universal Version for CP/M-86 ------- Type CTL-C to abort $Z6 ; ; See DU77.DOC for description and detailed instructions. ; See original issue ver 7.5 for history of changes and authors ; NOTE: see below for change in multiple cmd symbol. ; ; 03/05/84 by H.M. Van Tassell, (201)-755-5372 ; 120 Hill Hollow  3tH ~ t ກ \ u<rQѱY 2&C&7Cډޞ&C&?%2.>> PHdrive push ax ;drive and multi-sector count push itrack ;track # push isector ;sector # = 0 push idmaseg ;sector buffer DMA segment push idmaoff ;sector buffer DMA offset call getsu ;set up DS-SYSDAT and ES-UDA mov ax,bx ;set,CR XCHG BX,DX MOV [BX],AL XCHG BX,DX MOV BX,OFFSET INBUF JMP PRMPTI ; PRMPTR: XOR AL,AL MOV QFLAG,AL CALL RDBUF ; PRMPTI: MOV AL,255 MOV BYTE PTR TOGO,AL ;LOOP COUNT FOR "/" MOV BYTE PTR TOGO+1,AL ; PROMPT EQU $ SETSTK: MOV SYSHF TABLE <<< mov dx,offset toobig ; 128 = 0 1024 = 3 mov cl,9 ; 256 = 1 2048 = 4 int 224 ; 512 = 2 4096 = 5 jmp exit buf_ok: ret sect_to_mem: ;------------ ; ENTRY: itrack & isector specified ; EXIT: sector is in memory,  I/O function into AX callf BIOS_ENTRY ;call indirect the BIOS ;AL,BL = return status add sp,10 ;restore stack pop es ;restore original ES pop ds ;ditto for DS ret ;====== getsu: ;====== ; entry: DS = local data seg ; exit:P, OFFSET STACK XOR AL,AL ;ZERO 2-UP PRINT MOV TWOUP,AL ;..SWITCH MOV AL,1 MOV FTSW,AL ;TELL SEARCH NOT TO INCR PUSH BX MOV BX,OFFSET BASE +100H MOV BUFAD,BX ;FOR RDBYTE POP BX CALL CTLCS ;ABORT? JZ PRMPTR ;..YES, READ BUFFER ; ;Do does read if required ; AX BX = 0 if no error ; mov ax,itrack ;get track cmp ax,0 ! jnz not_zero cmp ax,1 ! jmps no_match not_zero: mov bx,isector ;and sector numbers cmp ax,trk_sect ! jne no_match ;if same as last time cmp bx,trk_sec DS = SYSDAT seg, ES=UDA seg (for call to XIOS) mov ax,udaaddr ;get the saved value or ax,ax ;set flags jz get_ds_es ;uninitialized, go get DS and ES mov es,ax ;we've been here before, so load regs mov ds,sysaddr ret get_ds_ewe have to position in directory after find? MOV AL,FINDFL OR AL,AL JZ L@00005 JMP POSDIR ;POSITION IN DIRECTORY L@00005: MOV AL,BYTE PTR [BX] CMP AL,CR JZ PRMPTR CMP AL,'!' ;LOGICAL CR? PUSHF INC BX POPF JZ PROMPT CALL UPCASE t+2 ;then sector is in memory no_match: mov trk_sect,ax ;save for next time mov trk_sect+2,bx mov ax,0 ! mov bx,ax ;clear AX BX registers je got_sect ;if not in memory, then mov bx,BIO_READ ;signal a read call biosiopb ;read a physics: ;this is the initial call ;--------- cmp cpm_version,CCPM_31 ;is it CCP/M-86 version 1431+? jb get_ds_es10 ;or version 1031 get_ds_es14: ;use this for CCP/M-86 version 1431 ;---------- mov cl,P_PDADR ;will return Process Desc Addr inMOV DUMTYP,AL ;TYPE OF DUMP (A,D,H) ; ;Command dispatcher ; CMP AL,'+' JNZ L@00008 JMP PLUS L@00008: ; CMP AL,'-' JNZ L@00009 JMP MINUS L@00009: ; CMP AL,'=' JNZ L@00010 JMP SEARCH L@00010: ; CMP AL,'<' JNZ L@00011 JMP SAVal sector got_sect: ret read_sector31: ;reads a logical record from disk to buffer ;------------- ; call sect_to_mem ;get sector push si ! push di ! push es cld ! mov es,dmaseg ;setup user dma segment mov di,dmaoff ;where to copy 128 by BX int 224 ;...and SYStem DATa seg in ES mov ax,es:P_UDA[bx] ;grab UDA_seg jmps com_su ;jmp to common get_ds_es10: ;use this with CP/M-86 version 1031 ;---------- mov cl,DRV_DPB ;will return SYStem DATa seg in ES int 224 mov ax,esE L@00011: ; CMP AL,'>' JNZ L@00012 JMP RESTOR L@00012: ; CMP AL,'#' JNZ L@00013 JMP STATS L@00013: ; CMP AL,'?' JNZ L@00014 JMP HELP L@00014: ; CMP AL,'A' JNZ L@00015 JMP DUMP L@00015: ; CMP AL,'C' JNZ L@00016 JMP Cte record mov si,rec_offset ;record offset into sector buffer mov cl,7 ! shl si,cl ;times 128 add si,offset sector_buf ;points to start of record mov cx,128/2 ;move 128 bytes rep movsw ;so do the move pop es ! pop di ! pop si ret :UDA_seg ;grab UDA_seg ;fall thru to common com_su: ;this is common to both versions mov sysaddr,es ;save system data segment (SYSDAT) push es mov udaaddr,ax ;save for UDS_seg for future calls mov es,ax ;get UDA_seg into ES pop HG L@00016: ; CMP AL,'D' JNZ L@00017 JMP DUMP L@00017: ; CMP AL,'F' JNZ L@00018 JMP POSFIL L@00018: ; CMP AL,'G' JNZ L@00019 JMP POS L@00019: ; CMP AL,'H' JNZ L@00020 JMP DUMP L@00020: ; CMP AL,'L' JNZ L@00021 JMP LOwrite_sector31: ;writes a physical sector ;-------------- ; call sect_to_mem push si ! push di ! push es ! push ds mov ds,dmaseg ;source of user data to copy mov si,dmaoff ;into sector buffer cld ! mov es,idmaseg ;setup for sector buffer dds ;get SYSDAT into DS ret ;----------------------------------------------------------------------- ; CLOCK DB 1 ;<---PUT NON-ZERO HERE FOR 4 MHZ CLOCK ; PASTCK: MOV AX,CS MOV DS,AX MOV SS,AX MOV ES,AX MOV SP,OFFSET STACK call cpGIN L@00021: ; CMP AL,'M' JNZ L@00022 JMP MAP L@00022: ; CMP AL,'N' JNZ L@00023 JMP NEWDSK L@00023: ; CMP AL,'P' JNZ L@00024 JMP PRNTFF L@00024: ; CMP AL,'Q' JNZ L@00025 JMP QUIET L@00025: ; CMP AL,'R' JNZ L@00026 JMma segment mov di,rec_offset ;record offset into sector buffer mov cl,7 ! shl di,cl ;times 128 add di,offset sector_buf ;points to start of record mov cx,128/2 ;move 128 bytes rep movsw ;so do the move pop ds ! pop es ! pop di ! pop si mchk ;make sure right version, do setup ; HELLO: CALL ILPRT DB CR,LF,'DISK UTILITY ver 7.5-E',CR,LF DB 'For CP/M-86 & CCP/M-86 ver 3.1-4.1',CR,LF DB CR,LF DB 'Type ? for help, X or ESC Quits' DB CR,LF,0 CALL GETSTP ;SET UP PARAMETERS MOV P DOREAD L@00026: ; CMP AL,'S' JNZ L@00027 JMP POS L@00027: ; CMP AL,'T' JNZ L@00028 JMP POS L@00028: ; CMP AL,'U' ;******CP/M 2.x ONLY****** JNZ L@00029 JMP USER L@00029: ; CMP AL,'V' JNZ L@00030 JMP VIEW L@00030: ; CMPAKE UP FOR PREV INX D XCHG BX,DX MOV TOGO,BX MOV AL,BH ;ALL DONE? OR AL,BL XCHG BX,DX ;GET BACK INBUF PTR JZ L@00038 JMP PROMPT ;NO, KEEP GOING L@00038: JMP PRMPTR ;ALL DONE ; ;Set CP/M 2.x user number ; USER: CALL DECIN ;GET REQUEST11 IT IS 10 BYTES AX8: ADD BX,AX MOV BX,ES:[BX] ;GET DPB PTR ; SELSKP: CALL LOGIT MOV BX,SYSTRK ;RESET TRACK AND SECTOR XCHG BX,DX ; TO DIRECTORY CALL SETTRK ; ON EVERY MOV DX,OFFSET 1 ; LOGIN CALL SETSEC ; CHANGE MOV BX,PHYSEC ;THIS L AL,'W' JNZ L@00031 JMP DORITE L@00031: ; CMP AL,'X' JNZ L@00032 QUIT: CALL ILPRT DB 'Confirm Quiting (Y/N)? ',0 CALL CONIN CALL UPCASE CMP AL,'Y' JE EXIT CALL CRLF JMP PRMPTR ; EXIT: MOV CL,0 MOV DL,0 JMP BDOS ;RETUED USER NO. MOV AL,DL CMP AL,32 ;VALID? JNAE L@00040 JMP WHAT L@00040: MOV AL,DH OR AL,AL JZ L@00041 JMP WHAT L@00041: MOV UNUM,DL ;SAVE IT MOV CL,SUSER PUSH BX ;SAVE CHAR POINTER CALL BDOS ;SET USER NO. POP BX JMP PROMPT ; OGIC WILL TELL MOV AL,BH ; IF FIRST SEC OR AL,BL ; IS PHYSICAL 0 MOV FIRST0,AL cmp byte ptr cpm_version,31h ;if ver 31 then jb no_set_0 ;use first sector=1 mov first0,1 no_set_0: CALL CLCSUB POP BX ; LGNODK: CALL NORITE RET ;RN TO CP/M 86 L@00032: ; CMP AL,'Z' JNZ L@00033 JMP SLEEP L@00033: ; CMP AL,'/' JNZ L@00034 JMP REPEAT L@00034: ; WHAT: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '?',0 JMP PRMPTR ; ;Memory full error ; MEMFUL: XOR AL,AL;Toggle print flag ; PRNTFF: MOV AL,PFLAG XOR AL,1 MOV PFLAG,AL JMP PROMPT ; ;Sleep routine, in tenths of a sec ; SLEEP: CALL HEXIN ;GET COUNT IF ANY MOV AL,DL ;ANY? OR AL,AL JNZ SLEPLP MOV DL,10 ; SLEPLP: MOV CX,OFFSET 10000 MOV  ;Read in the disk directory ; REDDIR: PUSH BX CALL NORITE ;POSITIONING LOST MOV BX,SYSTRK MOV CURTRK,BX MOV BX,OFFSET 1 MOV CURSEC,BX MOV BX,DRM ;GET DIR SIZE FROM DPB INC BX ; MAKE 1-RELATIVE CALL ROTRHL CALL ROTRHL ;DIVIDE BY 4 (4 N MOV QFLAG,AL CALL ILPRT DB '+++ Out of memory +++' DB CR,LF,0 JMP PRMPTR ; ;Print disk statistics ; STATS: PUSH BX CALL ILPRT DB 'Disk Information:',CR,LF DB 'Tracks:',9,9,0 MOV BX,MAXTRK INC BX CALL DEC CALL ILPRT DB CR,LF,AL,CLOCK OR AL,AL JZ SLEEP2 MOV CX,OFFSET 32000 ; SLEEP2: DEC CX MOV AL,CH OR AL,CL JNZ SLEEP2 PUSH DX CALL CTLCS POP DX JNZ L@00045 JMP PRMPTR L@00045: DEC DL JNZ SLEPLP JMP PROMPT ; ;Check for control-C or S ; CTLCS: AMES/SECTOR) MOV CX,BX MOV DX,OFFSET DIRECT ;DMA ADDR ; RDIRLP: PUSH CX PUSH DX MOV CX,DX MOV AL,0F0H ;FORCE MEMORY CMP AL,DH JAE L@00053 JMP MEMFUL L@00053: CALL SETDMA MOV BX,CURTRK XCHG BX,DX CALL SETTRK MOV BX,CURSEC XCHG'Sec/trk:',9,0 MOV BX,SPT CALL DEC CALL ILPRT DB CR,LF,'Grpsize:',9,0 MOV AL,BLM INC AL MOV BL,AL MOV BH,0 CALL DEC CALL ILPRT DB ' (sectors per group)',CR,LF DB 'Tot grps:',9,0 MOV BX,DSM CALL DEC CALL ILPRT DB CR,LF,'Dir eCALL CONST OR AL,AL JNZ GETC OR AL,1 ;NO CHAR, RETN NZ RET ; GETC: CALL CONIN and al,5fh cmp al,'Q' ;a Q will quit jz quit_ret AND AL,1FH ;ALLOW ASCII CMP AL,'S'-40H JNZ L@00048 CALL CONIN L@00048: CMP AL,'['-40H ;AN ESCAPE WILL BX,DX CALL SETSEC CALL READ CALL NXTSEC POP DX POP CX MOV BX,OFFSET 80H ADD BX,DX XCHG BX,DX DEC CX MOV AL,CH OR AL,CL JNZ RDIRLP MOV CX,OFFSET BASE +80H CALL SETDMA POP BX RET ; ;Map the directory ; MAP: CALL REDDIR ;Rntries:',9,0 MOV BX,DRM INC BX CALL DEC CALL ILPRT DB CR,LF,'Sys tracks:',9,0 MOV BX,SYSTRK CALL DEC CALL CRLF POP BX JMP PROMPT ; ;The following command resets the disk ;system thru CP/M, and may be usable for ;changing the disk de QUIT JZ QUIT_RET CMP AL,'C'-40H ;AND SO WILL ^C QUIT_RET: RET ;0 SET IF CTL-C,esc ; ;Find our way at initialization ; GETSTP: MOV CL,SUSER ;GET USER NUMBER MOV DL,0FFH ;GET USER CALL BDOS MOV UNUM,AL ;SET USER NUMBER MOV CL,GETEAD IN DIRECTORY MOV CL,0 ;INIT START GRP # MOV AL,AL0 ;READ DIR GRP BITS CALL COLECT ;COLLECT COUNT OF DIR GRPS.. MOV AL,AL1 ;..IN REGISTER C CALL COLECT MOV CH,0 ;BC NOW HAS A DEFAULT START GRP # CALL HEXIN PUSH BX ;SAVE INBUF PTR MOV Ansity or format. ;This can only be done if your BIOS resets ;the auto-density select parameters at ;every track-zero access. ; NEWDSK: PUSH BX MOV CL,RESETDK CALL BDOS MOV AL,DRIVE MOV CL,AL POP BX CALL SELECT JMP PROMPT ; ;Quite mode DSK CALL BDOS ;GET CURNT DSK MOV CL,AL ; WE HAVE TO SELECT JMP SELECT ; TO GET THE DPH ; LOGIN: CALL DOLOG JMP PROMPT ; DOLOG: MOV AL,BYTE PTR [BX] ;DISK REQ? MOV DX,OFFSET 0 CMP AL,CR JNZ L@00049 JMP LGNODK L@00049: CMP AL,'!' JL,DL ;GET START OR AL,DH ;NOTHING? JZ MAPDF ;..YES, DFLT MOV CX,DX ; MAPDF: CALL HEXB MOV AL,'-' CALL TYPEOUT CALL GETGRP ;GET GRP(C) TO HL ; MAPCNT: INC CX ;NEXT GRP # PUSH BX MOV BX,DSM ;GET HIGHEST GRP # INC BX ;PLUS 1 FOR COMPAR ; QUIET: MOV QFLAG,AL ;NOW QUIET JMP PROMPT ; ;Repeat buffer contents ; REPEAT: CALL DECIN ;NN SPECIFIED? MOV AL,DH OR AL,DL JZ NNN ;NO. MOV BX,TOGO INC BX ;TEST FOR FIRST TIME MOV AL,BH OR AL,BL ;WAS IT 0FFFFH? JNZ NNN ;NO: COUNNZ L@00050 JMP LGNODK L@00050: CALL UPCASE INC BX SUB AL,'A' MOV CL,AL ; SELECT: PUSH BX MOV AL,CL ;put drive in AL push cx ;save drive mov dl,0 ;indicate first select CALL SEL ;SELECT DISK THRU BIOS MOV AL,BH OR AL,BL pop cx ISON MOV AL,BL ;WHEN BC REACHES DSM+1.. CMP AL,CL ;..THEN WE HAVE EXCEEDED.. JNZ MAPC1 ;.. THE DISK CAPACITY.. MOV AL,BH CMP AL,CH ; MAPC1: POP BX JZ MAPEND ;.. AND WE ARE DONE PUSH BX CALL GETGRP ;GET ANOTHER POP DX ;SEE IF SAME CALLTING XCHG BX,DX ;GET COUNT MOV TOGO,BX ;SET COUNT ; NNN: MOV BX,TOGO XCHG BX,DX MOV BX,OFFSET INBUF ;READY TO REPEAT INC DX ;TEST FOR 0FFFFH MOV AL,DH OR AL,DL JNZ L@00037 JMP PROMPT ;CONTINOUS L@00037: DEC DX ;COUNT DOWN DEC DX ;M JNZ L@00052 JMP WHAT ;SELECT ERROR L@00052: MOV DRIVE,CL ;REMEMBER LATER WHERE WE ARE ; MOV AX,ES:[BX] ;GET THE SECTOR TABLE PTR MOV SECTBL,AX MOV AX,8 ;IN VER 31 OFFSET IS 8 CMP BYTE PTR CPM_VERSION,31H JAE AX8 MOV AX,10 ;BUT IN VER   CTLCS JZ MAPND2 MOV AL,DH CMP AL,BH JNZ MAPDIF MOV AL,DL CMP AL,BL JZ MAPCNT ;SAME, CONTINUE ; ;Different file encountered MAPDIF: DEC CX CALL HEXB INC CX XCHG BX,DX CALL MAPNAM JMP MAPDF ; ;End of map ; MAPEND: DEC CX ;L2: INC BX ;POINTING INTO DM FIELD CALL GRPCMP ;COMPARE BC GP # AGAINST 1 DM FLD JZ GETGOT ;JUMP IF FOUND ONE DEC DL ;ELSE COUNT DOWN JNZ GETGL2 ;GO TEST SOME MORE ; GETGNF: POP BX ;NOT THIS ONE MOV DX,OFFSET 32 ;SO GO TO NEXT ADD BX,DX L HEX CALL CRLF JMP CLCGRP ; ;Get value from input buffer ; GETVAL: MOV AL,BYTE PTR [BX] CMP AL,'<' ;HEX ESCAPE? JZ L@00082 RET ;NO, RETURN L@00082: ;"<<" means one "<" INC BX MOV AL,BYTE PTR [BX] CMP AL,'<' JNZ L@00083 RET L@000GET LAST CALL HEXB CALL MAPNAM POP BX CALL CRLF ; ;End of map - reposition to previous group ; MAPND2: PUSH BX MOV BX,GROUP XCHG BX,DX JMP POSGP2 ; ;Print file name pointed to by HL ; MAPNAM: CALL SPACE MOV AL,BH OR AL,BL ;NONE?  XCHG BX,DX MOV BX,FILECT ;THERE IS LIMIT TO EVERYTHING DEC BX MOV FILECT,BX MOV AL,BH OR AL,BL XCHG BX,DX ;RE-ALIGN JNZ GETGLP ; ;Group is not allocated to any file MOV BX,OFFSET 0 ;SAY SO RET ; ;Found the file ; GETGOT: POP BX 83: ;Got hex PUSH DX CALL HEXIN ;GET VALUE CMP AL,'>' ;PROPER DELIM? MOV AL,DL ;GET VALUE POP DX JZ L@00084 JMP WHAT ;ERROR L@00084: RET ; ;Read a byte at a time ; RDBYTE: PUSH BX MOV AL,FTSW ;FIRST READ? OR AL,AL JNZ READ1 MO JZ NONAME MOV AL,BYTE PTR [BX] ;SEE IF ALLOC ; cmp al,20h ! je noname ; cmp al,21h ! je noname CMP AL,0E5H ;FREE? MOV AL,' ' JNZ MPNSP1 MOV AL,'[' ; MPNSP1: CALL TYPEOUT PUSH BX ;SAVE POINTER MOV AL,BYTE PTR [BX] CALL HEX ;SHOW USER NURET ; ;Save the current sector ; SAVE: MOV AL,WRFLG OR AL,AL JNZ L@00074 JMP BADW ;NONE TO SAVE L@00074: PUSH BX MOV BX,OFFSET BASE +80H MOV DX,OFFSET SAVBUF MOV CH,128 CALL MOVE MOV AL,1 ;..SHOW MOV SAVEFL,AL ;..SAVED EXISTS POV BX,BUFAD MOV AL,BL OR AL,AL ;IN BUFFER? JS NORD ;YES, SKIP READ ; ;Have to read CALL NXTSEC ; READ1: XOR AL,AL MOV FTSW,AL ;NOT FIRST READ MOV BX,CURSEC XCHG BX,DX CALL SETSEC MOV BX,CURTRK XCHG BX,DX CALL SETTRK CALL READ MBER CALL SPACE INC BX ;SKIP USER BYTE PUSH CX MOV CH,8 CALL MAPN2 MOV AL,'.' CALL TYPEOUT MOV CH,3 CALL MAPN2 POP CX CALL SPACE MOV AL,BYTE PTR [BX] ;GET EXT CALL HEX POP BX MOV AL,BYTE PTR [BX] CMP AL,0E5H MOV AL,' ' JP BX JMP PROMPT ; ;Restore the current sector ; RESTOR: MOV AL,SAVEFL OR AL,AL JZ NOSAVE ;NONE TO SAVE PUSH BX MOV BX,OFFSET SAVBUF MOV DX,OFFSET BASE +80H MOV CH,128 CALL MOVE POP BX JMP PROMPT ; NOSAVE: XOR AL,AL MOV QFLAG,AL CALL CLCSUB MOV BX,OFFSET BASE +80H ; NORD: MOV AL,BYTE PTR [BX] INC BX MOV BUFAD,BX POP BX RET ; ;View the file in ASCII starting at ;current sector, stepping thru the disk ; VIEW: MOV AL,WRFLG OR AL,AL JNZ L@00087 JMP BADDMP L@00NZ MPNSP2 MOV AL,']' ; MPNSP2: CALL TYPEOUT ;")" IF ERASED FILE JMP FLIP ; NONAME: CALL ILPRT DB ' ++FREE++ ',0 ; FLIP: MOV AL,TWOUP XOR AL,1 MOV TWOUP,AL JNZ L@00064 JMP CRLF L@00064: ; DELIM: MOV AL,':' CALL TYPEOUT  CALL ILPRT DB '++NO "<" SAVE COMMAND ISSUED' DB CR,LF,0 JMP PRMPTR ; ;Move (HL) to (DE) length in B ; MOVE: MOV AL,BYTE PTR [BX] XCHG BX,DX MOV [BX],AL XCHG BX,DX INC BX INC DX DEC CH JNZ MOVE RET ; MOVEFROMBIOS: MOV AL,ES:087: CALL HEXIN ;GET DISPL IF ANY PUSH BX MOV AL,DL OR AL,AL JNZ VIEWLP INC DL ;DFLT=1 ; VIEWLP: MOV BX,OFFSET BASE +80H ;TO DATA ; VEWCHR: CALL CTLCS JZ VEWEND MOV AL,BYTE PTR [BX] CMP AL,1AH JZ VEWEOF AND AL,7FH CMP AL,7EH JJMP SPACE ; ;Print name, length in B ; MAPN2: MOV AL,BYTE PTR [BX] AND AL,7FH ;STRIP POSSIBLE 2.x ATTRIBUTE BIT INC BX CMP AL,' ' ;PRINTABLE? JNAE MAPN2H ;..NO, IN HEX CMP AL,7EH ;7E IS LEADIN ON SOME CRTS JNAE MAPN2A ; MAPN2H: CALL BHEX BYTE PTR [BX] XCHG BX,DX MOV [BX],AL XCHG BX,DX INC BX INC DX DEC CH JNZ MOVEFROMBIOS RET ; NORITE: XOR AL,AL ;GET 0 MOV WRFLG,AL ;CAN'T WRITE NOW RET ; ;No match in search, try next char ; SRNOMT: POP BX CALL CTLCS ;ABORT? JAE VIEWHX ;SHOW RUBOUT AND TILDE AS HEX CMP AL,' ' JAE VIEWPR CMP AL,CR JZ VIEWPR CMP AL,LF JZ VIEWPR CMP AL,TAB JZ VIEWPR ; VIEWHX: MOV AL,BYTE PTR [BX] ;NOT ASCII...PRINT AS CALL BHEX JMP VIEWNP ; VIEWPR: CALL TYPEOUT ; VIE JMP MAPN2Z ; MAPN2A: CALL TYPEOUT ; MAPN2Z: DEC CH JNZ MAPN2 RET ; ;Find which file group (BC) belongs to ; GETGRP: MOV BX,DRM ;MAX DIR ENTRY # INC BX ;MAKE 1-RELATIVE MOV FILECT,BX MOV BX,OFFSET DIRECT ; GETGLP: PUSH BX ;SAVE POINTERNZ SEARCH ;...YES MOV BX,OFFSET INBUF MOV BYTE PTR [BX],CR JMP CLCGRP ;SHOW WHERE STOPPED ; ;Search for character string ; SEARCH: PUSH BX ;SAVE STRING POINTER ; SRCHL: CALL RDBYTE ;GET A BYTE MOV CH,AL ;SAVE IT MOV AL,BYTE PTR [BX] ;CHECK WNP: INC BL JNZ VEWCHR DEC DL JZ VEWEND PUSH DX ;SAVE COUNT CALL NXTSEC MOV BX,CURSEC XCHG BX,DX CALL SETSEC MOV BX,CURTRK XCHG BX,DX CALL SETTRK CALL READ POP DX ;RESTORE COUNT JMP VIEWLP ; VEWEOF: CALL ILPRT DB CR,LF,TAB,' TO NAME MOV AL,BYTE PTR [BX] ;PICK UP user number cmp al,20h ! je getgnf ;user must be <20h cmp al,21h ! je getgnf ; MOV DX,OFFSET 14 ;NOW GET RECORD COUNT ADD BX,DX ; S2 PORTION .. MOV AL,BYTE PTR [BX] ; IS 0 IN CP/M 1.4 CMP AL,0E5H JZ NEXT MATCH CHAR. CMP AL,'<' ;WILL IT BE HEX? MOV AL,CH ;RESTORE DISK CHAR JZ SRCHL1 AND AL,7FH ;NEXT CHAR IS ASCII...STRIP BIT 7 ; SRCHL1: LAHF XCHG AL,AH PUSH AX XCHG AL,AH CALL GETVAL ;GET SEARCH VALUE MOV CH,AL POP AX XCHG AL,AH ++EOF++',CR,LF,0 ; VEWEND: POP BX CALL CRLF JMP CLCGRP ; ;Dump in hex or ASCII ; DUMP: MOV AL,WRFLG OR AL,AL JNZ DUMPOK ; BADDMP: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++Can''t dump, no sector read.',CR,LF,0 ; EXPL: XOR AL,AL MOVGETGNF AND AL,0FH MOV DL,AL INC BX MOV AL,BYTE PTR [BX] OR AL,DL JZ GETGNF MOV DL,16 ;FIRST SET FOR 8-BIT GRPS MOV AL,BYTE PTR DSM+1 OR AL,AL JZ SMALGP MOV DL,8 ;NOPE, BIG GROUPS ; SMALGP: MOV DH,AL ;SAVE GRP SIZE INDICATOR ; GETG SAHF CMP AL,CH ;MATCH? JNZ SRNOMT ;NO MATCH INC BX MOV AL,BYTE PTR [BX] ;DONE? CMP AL,CR JZ SREQU CMP AL,'!' JNZ SRCHL ; ;Got match SREQU: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '= AT ',0 MOV AL,BYTE PTR BUFAD AND AL,7FH CAL  QFLAG,AL CALL ILPRT DB 'Use G command following F,',CR,LF DB 'or R or S following T',CR,LF,0 JMP PRMPTR ; DUMPOK: MOV AL,BYTE PTR [BX] CMP AL,'!' JZ DUMPDF ;DFLT CMP AL,CR JNZ DMPNDF ; ;Use default DUMPDF: MOV CX,OFFSET BASE +80H MSETSEC CALL READ XOR AL,AL MOV NOTPOS,AL ;POSITIONED OK ; CLCGRP: CALL CLCSUB JMP INQ ; ;Calculate group from track and sector ; CLCSUB: push bx mov ax,CURTRK mov bx,SYSTRK cmp bx,ax ! ja a_systrack sub ax,SYSTRK a_systrack: xor d CALL BDOS INC AL JNZ FLOK MOV DIRPOS,AL ;GRP 0 IF NOT FOUND CALL ILPRT DB '++FILE NOT FOUND',CR,LF,0 POP BX JMP PROMPT ; FLOK: DEC AL MOV DIRPOS,AL ;SAVE POS. IN DIR AND AL,3 MOV BL,AL MOV BH,0 ADD BX,BX ADD BX,BX ADD BX,BXOV DX,OFFSET 0FFH JMP DUMP1 ; DMPNDF: CALL DISP MOV CX,DX CMP AL,CR JZ DUMP1 CMP AL,'!' JZ DUMP1 INC BX ;SKIP ',' CALL DISP ; ;BC = start, DE = end ; DUMP1: PUSH BX ;SAVE COMMAND POINTER MOV BX,CX ; DUMPLP: MOV AL,BL AND AL,7FH x,dx mul SPT ;TRK*SPT=hi bits in DX lo bits in AX mov bx,CURSEC dec bx add ax,bx ;add in cursec - 1 adc dx,0 divide1: mov bx,1 mov cl,BSH shl bx,cl ;BX = 2^BSH div bx ;DX:AX=((CURTRK-SYSTRK)*SPT+CURSEC-1)/(2^BSH) mov group,ax ;AX=q ADD BX,BX ADD BX,BX MOV DX,OFFSET BASE +80H ADD BX,DX MOV DX,OFFSET 32 XCHG BX,DX ADD BX,DX XCHG BX,DX MOV AL,'D' MOV DUMTYP,AL JMP DUMPLP ;WHICH POPS H ; MVNAME: MOV AL,BYTE PTR [BX] CMP AL,'.' JZ MVIPAD CMP AL,CR JZ PAD  CALL HEX CALL SPACE CALL SPACE MOV AL,DUMTYP CMP AL,'A' JZ DUMPAS PUSH BX ;SAVE START ; DHEX: MOV AL,BYTE PTR [BX] CALL HEX MOV AL,BL AND AL,3 CMP AL,3 JNZ L@00104 CALL SPACE L@00104: MOV AL,BL AND AL,7 CMP AL,7 JNZ L@0uotent, DX=remainder mov GRPDIS,dl pop bx ret ; ;Position in the dorectory after a find ;(Does not work in CP/M-2.x) ; POSDIR: PUSH BX ;SAVE INBUF MOV BX,WORD PTR BSH XOR AL,AL MOV FINDFL,AL ;CANCEL POS REQ MOV AL,DIRPOS ;GET POSITION  CMP AL,'!' JZ PAD CALL UPCASE XCHG BX,DX MOV [BX],AL XCHG BX,DX INC BX INC DX DEC CH JNZ MVNAME MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00135 RET L@00135: CMP AL,'!' JNZ L@00136 RET L@00136: INC BX CMP AL,'.' JNZ L@000105 CALL SPACE L@00105: MOV AL,DL CMP AL,BL JZ DPOP INC BX MOV AL,BL AND AL,0FH JNZ DHEX ; DPOP: CALL CTLCS JNZ L@00108 JMP PRMPTR L@00108: MOV AL,DUMTYP CMP AL,'H' JZ DNOAS ;HEX ONLY POP BX ;GET START ADDR ; DUMPAS: CALL RCR AL,1 RCR AL,1 LAHF XCHG AL,AH PUSH AX XCHG AL,AH AND AL,BH MOV GRPDIS,AL POP AX XCHG AL,AH SAHF ; POSDLP: RCR AL,1 DEC BL JNZ POSDLP AND AL,1 ;GET GROUP MOV BL,AL ;SETUP FOR POSGP2 MOV BH,0 MOV GROUP,BX XCHG BX,DX 137 RET L@00137: JMP WHAT ; MVIPAD: INC BX ; PAD: MOV AL,' ' XCHG BX,DX MOV [BX],AL XCHG BX,DX INC DX DEC CH JNZ PAD RET ; PLUS: MOV DX,OFFSET 1 ;DFLT TO 1 SECT MOV AL,BYTE PTR [BX] ;GET NEXT CHAR CMP AL,CR ;CR? JZ PLUSGO ; ASTER ; DCHR: MOV AL,BYTE PTR [BX] AND AL,7FH CMP AL,' ' JNAE DPER CMP AL,7EH JNAE DOK ; DPER: MOV AL,'.' ; DOK: CALL TYPEOUT MOV AL,DL CMP AL,BL JZ DEND INC BX MOV AL,BL AND AL,0FH JNZ DCHR ; DEND: CALL ASTER CALL CRLF  JMP POSGP2 ;POSITION TO IT ; POSGPH: CALL HEXIN ; POSGRP: PUSH BX MOV BX,DSM CALL SUBDE POP BX JAE L@00127 JMP OUTLIM L@00127: XCHG BX,DX MOV GROUP,BX XCHG BX,DX XOR AL,AL MOV GRPDIS,AL PUSH BX ; POSGP2: CALL GTKSEC CALL S.. YES, DFLT TO 1 CMP AL,'!' JZ PLUSGO CALL HEXIN ;GET # MOV AL,DH OR AL,DL JNZ L@00141 JMP WHAT L@00141: ; PLUSGO: CALL NXTSEC DEC DX ;MORE TO GO? MOV AL,DH OR AL,DL JNZ PLUSGO ;..YES ; ;Ok, incremented to sector. Setup and rea PUSH DX CALL CTLCS POP DX JNZ L@00114 JMP PRMPTR L@00114: MOV AL,DL CMP AL,BL JZ L@00115 JMP DUMPLP L@00115: POP BX JMP PROMPT ; DNOAS: POP CX CALL CRLF MOV AL,DL CMP AL,BL JZ L@00116 JMP DUMPLP L@00116: POP BX JMP PETTRK XCHG BX,DX inc dx CALL SETSEC CALL READ XOR AL,AL MOV NOTPOS,AL ;NOW POSITIONED POP BX JMP INQ ; GTKSEC: MOV BX,DX ;BX = number of blocks mov cl,BSH mov ax,1 shl ax,cl ;AX=2^BSH xor dx,dx ;clear DX register mul bx d ; PLUSMI: PUSH BX MOV BX,CURSEC XCHG BX,DX CALL SETSEC MOV BX,CURTRK XCHG BX,DX CALL SETTRK POP BX CALL READ JMP CLCGRP ; MINUS: MOV DX,OFFSET 1 ;SET DFLT MOV AL,BYTE PTR [BX] ;GET CHAR CMP AL,CR ;CR? JZ MINGO ;.. YES, DFLT=1 ROMPT ; ;Position ; POS: LAHF XCHG AL,AH PUSH AX XCHG AL,AH MOV AL,BYTE PTR [BX] CMP AL,'!' JZ POSINQ CMP AL,CR JNZ POSOK ; POSINQ: POP AX XCHG AL,AH SAHF JMP INQ ; POSOK: POP AX XCHG AL,AH SAHF CMP AL,'T' JZ POSTKD ;AX*BX=hi 16 bits in DX, lo in AX xor bx,bx mov bl,GRPDIS add ax,bx ;add in GRPDIS adc dx,0 ;with carry into DX ; ;Divide by nbr of sectors, quotient=track, remainder=sector ;NOTE for O/S = ver 3.1+, SPT is in 128 byte units, not phy sectors ;  CMP AL,'!' JZ MINGO CALL HEXIN ;..NO, GET ## MOV AL,DH OR AL,DL JNZ L@00145 JMP WHAT L@00145: ; MINGO: PUSH BX MOV BX,CURSEC DEC BX MOV AL,BH OR AL,BL JNZ MINOK MOV BX,CURTRK MOV AL,BH OR AL,BL JNZ SEASH MOV BX,MAXTRK ;CMP AL,'S' JZ POSSCD CMP AL,'G' JNZ L@00121 JMP POSGPH L@00121: JMP WHAT ; POSTKD: CALL DECIN ; POSTRK: PUSH BX MOV BX,MAXTRK CALL SUBDE POP BX JAE L@00122 JMP OUTLIM L@00122: CALL SETTRK CALL NORITE ;TRACK DOESN'T READ MOV  divide2: div Word Ptr SPT ;DX:AX/SPT=AX(quotent)=track, DX(remainder)=sector add ax,SYSTRK ;add in track offset mov bx,dx ;and get stuff into proper registers mov dx,ax ;for the return or bx,bx ;don't allow a zero sector number ret ; POSFIL:WRAP TO END OF DISK MOV CURTRK,BX MOV BX,MAXSEC JMP MINOK ; SEASH: DEC BX MOV CURTRK,BX MOV BX,SPT ; MINOK: MOV CURSEC,BX POP BX DEC DX MOV AL,DH OR AL,DL JNZ MINGO JMP PLUSMI ; ;Go to next sector ; NXTSEC: PUSH BX PUSH DXAL,1 MOV NOTPOS,AL ;SHOW NOT POSITIONED JMP CLCGRP ; POSSCD: CALL DECIN MOV AL,DH OR AL,DL JNZ L@00123 JMP WHAT ;DON'T ALLOW SECTOR 0 L@00123: ; POSSEC: PUSH BX MOV BX,SPT CALL SUBDE POP BX JAE L@00124 JMP WHAT L@00124: CALL  CALL NORITE MOV AL,1 MOV FINDFL,AL ;SO WE POSITION LATER MOV DX,OFFSET FCB XOR AL,AL ;LOGGED IN DISK XCHG BX,DX MOV [BX],AL XCHG BX,DX INC DX MOV CH,8 CALL MVNAME MOV CH,3 CALL MVNAME MOV DX,OFFSET FCB MOV CL,SRCHF PUSH BX   MOV BX,CURSEC INC BX XCHG BX,DX MOV BX,SPT CALL SUBDE XCHG BX,DX JAE NEXTOK MOV BX,CURTRK INC BX XCHG BX,DX MOV BX,MAXTRK CALL SUBDE JAE TRASK MOV DX,OFFSET 0 ;WRAP TO START OF DISK ; TRASK: XCHG BX,DX MOV CURTRK,BX MOV BL@00164: JMP WHAT ; ;Change hex ; CHGHCM: INC BX ; CHGHEX: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00165 JMP PROMPT L@00165: CMP AL,'!' JNZ L@00166 JMP PROMPT L@00166: CMP AL,',' ;DELIM? JZ CHGHCM PUSH DX MOV HEXAD,BX ;IN CASE IN CMP AL,1bh ! je il_abort ;escape CMP AL,'Q'-40h ! je il_abort ;^Q CMP AL,'C'-40h ! je il_abort ;^C=ABORT? JMPS L@00180 IL_ABORT: JMP PRMPTR L@00180: JMP ILPNX ; ILPOK: CALL TYPEOUT ; ILPNX: INC BX MOV AL,BYTE PTR [BX] OR AL,AL X,OFFSET 1 ; NEXTOK: MOV CURSEC,BX POP DX POP BX RET ; ;Tell what group, displacement, track, sector, physical sector ; INQ: CALL INQSUB JMP PROMPT ; ;Position inquiry subroutine ;Executed via: G S or T (with no operands) ; INQSUB: PUSH 'THRU' CALL HEXIN ;POSITIONS TO DELIM MOV AL,DL ;GET VALUE POP DX ;..ADDR LAHF XCHG AL,AH PUSH AX XCHG AL,AH ;SAVE VALUE XCHG BX,DX MOV AL,[BX] XCHG BX,DX ;GET OLD CALL HEX ;ECHO IN HEX POP AX XCHG AL,AH SAHF ;GET NEW XCHG BX, JNZ ILPLP INC BX POP SI XCHG BX,SI PUSH SI RET ; ;DISP calls HEXIN, and validates a sector ;displacement, then converts it to an address ; DISP: CALL HEXIN LAHF XCHG AL,AH PUSH AX XCHG AL,AH ;SAVE DELIMITER MOV AL,DH OR AL,AL BX MOV BX,SYSTRK XCHG BX,DX MOV BX,CURTRK CALL SUBDE JNAE NOGRP CALL ILPRT DB 'G=',0 MOV BX,GROUP MOV CH,BH MOV CL,BL CALL HEXB MOV AL,':' CALL TYPEOUT MOV AL,GRPDIS CALL HEX MOV AL,',' CALL TYPEOUT ; NOGRP: CALL ILPRT DX MOV [BX],AL XCHG BX,DX ;SAVE NEW MOV AL,CL ;SEE IF 'THRU' OR AL,AL JZ CHHNTH ;..NO. CMP AL,DL ;..YES, DONE? JNZ L@00169 JMP PROMPT L@00169: MOV BX,HEXAD ;..NO: MORE ; CHHNTH: INC DL JNZ CHGHEX MOV AL,BYTE PTR [BX] CMP AL,CR JNZ BADISP MOV AL,DL OR AL,AL JS BADISP ADD AL,80H ;TO POINT TO BUFFER AT BASE+80H MOV DL,AL MOV DH,BASE/256 POP AX XCHG AL,AH SAHF ;GET DELIM RET ; BADISP: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++BAD DISPLACEMENT (NOT 0-7F)'  DB ' T=',0 MOV BX,CURTRK CALL DEC CALL ILPRT DB ', S=',0 MOV BX,CURSEC CALL DEC CALL ILPRT DB ', PS=',0 MOV BX,PHYSEC CALL DEC CALL CRLF POP BX RET ; CHG: MOV AL,BYTE PTR [BX] ;GET TYPE (HEX, ASCII) CALL UPCASE LAHF XCHG JNZ L@00171 JMP PROMPT L@00171: CMP AL,'!' JNZ L@00172 JMP PROMPT L@00172: JMP WHAT ; DOREAD: MOV AL,NOTPOS OR AL,AL JNZ CANTRD CALL READ JMP PROMPT ; CANTRD: XOR AL,AL MOV QFLAG,AL ;NOT QUIET CALL ILPRT DB '++Can''t read - n DB CR,LF,0 JMP PRMPTR ; HEXIN: MOV DX,OFFSET 0 MOV AL,BYTE PTR [BX] CMP AL,'#' ;DECIMAL? JZ HDIN ;MAKE DECIMAL ; HINLP: MOV AL,BYTE PTR [BX] CALL UPCASE CMP AL,CR JNZ L@00185 RET L@00185: CMP AL,'!' JNZ L@00186 RET L@00186: AL,AH PUSH AX XCHG AL,AH ;SAVE "H" OR "A" INC BX CALL DISP ;GET, VALIDATE DISP TO DE INC BX MOV CX,OFFSET 0 ;SHOW NO 'THRU' ADDR CMP AL,'-' ;TEST DELIM FR. DISP JNZ CHGNTH ;NO THRU PUSH DX ;SAVE FROM CALL DISP ;GET THRU INC BX ;SKIP Eot positioned',CR,LF DB 'Position by:',CR,LF DB 9,'Track then Sector, or',CR,LF DB 9,'Group',CR,LF,0 JMP PROMPT ; DORITE: CALL WRITE JMP PROMPT ; BHEX: LAHF XCHG AL,AH PUSH AX XCHG AL,AH MOV AL,'<' CALL TYPEOUT POP AX XCHG AL,AHCMP AL,',' JNZ L@00187 RET L@00187: CMP AL,'-' ;'THRU'? JNZ L@00188 RET L@00188: CMP AL,'>' JNZ L@00189 RET L@00189: INC BX CMP AL,'0' JAE L@00190 JMP WHAT L@00190: CMP AL,'9'+1 JNAE HINNUM CMP AL,'A' JAE L@00192 JMP WND DELIM MOV CX,DX ;BC = THRU POP DX ;GET FROM JMP CHGAH ; CHGNTH: CMP AL,',' JZ L@00153 JMP WHAT L@00153: ; CHGAH: POP AX XCHG AL,AH SAHF CMP AL,'H' JNZ L@00154 JMP CHGHEX L@00154: CMP AL,'A' JZ L@00155 JMP WHAT L@00155:  SAHF CALL HEX MOV AL,'>' CALL TYPEOUT RET ; HEXB: MOV AL,BYTE PTR DSM+1 OR AL,AL JZ HEXX MOV AL,CH CALL HEX ; HEXX: MOV AL,CL ; HEX: LAHF XCHG AL,AH PUSH AX XCHG AL,AH RCR AL,1 RCR AL,1 RCR AL,1 RCR AL,1 CALL NIBBL HAT L@00192: CMP AL,'F'+1 JNAE L@00193 JMP WHAT L@00193: SUB AL,7 ; HINNUM: SUB AL,'0' XCHG BX,DX ADD BX,BX ADD BX,BX ADD BX,BX ADD BX,BX ADD AL,BL MOV BL,AL XCHG BX,DX JMP HINLP ; HDIN: INC BX ;SKIP '.' ; DECIN: MOV DX,; ;Change ASCII CHGALP: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00156 JMP PROMPT L@00156: CMP AL,'!' JNZ L@00157 JMP PROMPT L@00157: XCHG BX,DX MOV AL,[BX] XCHG BX,DX CMP AL,' ' JNAE CHGAHX CMP AL,7EH JAE CHGAHX JMP CHGA2 ; C POP AX XCHG AL,AH SAHF ; NIBBL: AND AL,0FH CMP AL,10 JNAE HEXNU ADD AL,7 ; HEXNU: ADD AL,'0' JMP TYPEOUT ; ;Decimal output routine ; DEC: PUSH CX PUSH DX PUSH BX MOV CX,-OFFSET 10 MOV DX,-OFFSET 1 ; DECOU2: PUSHF ADD BX,CXOFFSET 0 ; DINLP: MOV AL,BYTE PTR [BX] CALL UPCASE CMP AL,CR JNZ L@00194 RET L@00194: CMP AL,'!' JNZ L@00195 RET L@00195: CMP AL,',' JNZ L@00196 RET L@00196: CMP AL,'-' ;'THRU'? JNZ L@00197 RET L@00197: INC BX CMP AL,'0'HGAHX: CALL BHEX JMP CHGA3 ; CHGA2: CALL TYPEOUT ; CHGA3: MOV BACK,BX ;IN CASE "THRU" CALL GETVAL ;ASCII OR XCHG BX,DX MOV [BX],AL XCHG BX,DX ;UPDATE CHAR INC BX ;TO NEXT INPUT CHAR ;See if 'THRU' requested MOV AL,CL OR AL,AL J RCR SI,1 POPF RCL SI,1 PUSHF INC DX POPF JNAE DECOU2 MOV CX,OFFSET 10 ADD BX,CX XCHG BX,DX MOV AL,BH OR AL,BL JZ L@00177 CALL DEC L@00177: MOV AL,DL ADD AL,'0' CALL TYPEOUT POP BX POP DX POP CX RET ; SPACE: MOV JAE L@00198 JMP WHAT L@00198: CMP AL,'9'+1 JNAE L@00199 JMP WHAT L@00199: SUB AL,'0' PUSH BX MOV BH,DH MOV BL,DL ADD BX,BX ADD BX,BX ADD BX,DX ADD BX,BX ADD AL,BL MOV BL,AL MOV AL,BH ADC AL,0 MOV BH,AL XCHG BX,DX Z CHANTH CMP AL,DL ;DONE?.. JNZ L@00161 JMP PROMPT ;..YES L@00161: MOV BX,BACK ; CHANTH: INC DL JZ L@00162 JMP CHGALP L@00162: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00163 JMP PROMPT L@00163: CMP AL,'!' JNZ L@00164 JMP PROMPT  AL,' ' JMP TYPEOUT ; ASTER: MOV AL,'*' JMP TYPEOUT ; ;Inline print routine ; ILPRT: POP SI XCHG BX,SI PUSH SI ; ILPLP: CALL CTLCS ;ABORT? JNZ L@00178 JMP PRMPTR L@00178: MOV AL,BYTE PTR [BX] CMP AL,1 ;PAUSE? JNZ ILPOK CALL CON POP BX JMP DINLP ; ;Read in a console buffer full ; RDBUF: ;PRINT PROMPT AS DU nnA: CALL ILPRT DB CR,LF,'DU ',0 ;SAY WHO WE ARE MOV AL,UNUM CMP AL,0 ! JZ DONT_0 MOV BL,AL ;DISPLAY USER NUMBER MOV BH,0 CALL DEC ;PRINT IN DECIMAL T ; CONIN: PUSH CX PUSH DX PUSH BX CALL BCONIN ;GET CONSOLE CHAR FROM BIOS POP BX POP DX POP CX RET ; ;Console out with TAB expansion ; Enter: char in AL ; TYPEOUT: PUSH CX PUSH DX PUSH BX MOV CL,AL ;FOR OUTPUT ROUTINE CMP ALNORITE JMP PRMPTR ; SETDMA: CALL DMA ;SET UP DMA FOR BIOS MOV CX,CS ;SET DMA SEGMENT FOR BIOS JMP SETDMAB ; ; READ: MOV AL,1 MOV WRFLG,AL PUSH BX CALL DSKREAD ;READ DISK THRU BIOS OR AL,AL JZ READOK XOR AL,AL MOV QFLAG,AL CALDONT_0: MOV AL,DRIVE ;GET DRIVE NUMBER ADD AL,'A' ;CONVERT TO ASCII CALL TYPEOUT CALL ILPRT ;PRINT THE PROMPT DB ': ',0 ; RDBF1: MOV BX,OFFSET INBUF MOV CH,0 ; RDBLP: CALL CONIN MOV CL,AL ;SAVE FOR BS TEST ; ;Evaluate control charact,TAB JNZ TYPE2 ; TYPTAB: MOV AL,' ' CALL TYPEOUT MOV AL,TABCOL AND AL,7 JNZ TYPTAB JMP TYPRET ; ;Filter out control characters to ;prevent garbage during view of file ; TYPE2: CMP AL,' ' JAE TYPEQ CMP AL,CR JZ TYPEQ CMP AL,LF JL ILPRT DB '++READ failed, sector may be invalid++' DB CR,LF,0 ; READOK: POP BX RET ; WRITE: MOV AL,WRFLG OR AL,AL JNZ PWRITE ; BADW: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++CANNOT WRITE UNLESS READ ISSUED' DB CR,LF,0 JMP EXPL ;ers ; CMP AL,'U'-40H JNZ L@00200 JMP RDCTLU L@00200: ; CMP AL,CR JZ RDCR ; CMP AL,'H'-40H JZ RDBS ; CMP AL,7FH JZ RDBS ; CMP AL,'R'-40H JZ RDCTLR ; CMP AL,'X'-40H JZ RDCTLX CMP AL,'['-40H JNE NO_QUIT JMP QUIT NO_NZ TYPNCR ; TYPEQ: MOV AL,QFLAG OR AL,AL VCONOT: JNZ L@00218 PUSH CX CALL BCONOUT ;CONSOLE OUT THRU BIOS POP CX L@00218: ; ;Update column used in tab expansion MOV AL,CL ;GET CHAR CMP AL,CR JNZ TYPNCR MOV AL,0 MOV TABCOL,AL JMP PWRITE: PUSH BX MOV CL,1 ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED CALL DSKWRITE ;WRITE DISK OR AL,AL JZ WRITOK XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++WRITE failed++',CR,LF,0 ; WRITOK: POP BX RET ; ;Help ; HELP: CALL ILPRT QUIT: ; CMP AL,' ' JNAE RDBLP ; MOV BYTE PTR [BX],AL INC BX INC CH JS FULL CALL TYPEOUT JMP RDBLP ; FULL: DEC CH PUSHF DEC BX POPF MOV AL,'*' ;SIGNAL WE'RE FULL CALL TYPEOUT JMP RDBLP ; ;Got CR ; RDCR: MOV BYTE PTR [BX], TYPLST ; TYPNCR: CMP AL,' ' ;CTL CHAR? JNAE TYPLST ;..NO CGANGE IN COL MOV AL,TABCOL INC AL MOV TABCOL,AL ; TYPLST: MOV AL,PFLAG AND AL,1 JZ L@00221 CALL LISTOUT ;FROM C REG. L@00221: ; TYPRET: POP BX POP DX POP CX RET ; LISTDB 'Operands in brackets [...] are optional' DB CR,LF DB 'Numeric values: ''n'' are decimal, ''x'' hex' DB CR,LF,CR,LF DB '+[n] step in [n] sectors;' DB CR,LF DB '-[n] step out [n] sectors' DB CR,LF DB '# print disk parameters for AL ;SAVE IT CALL TYPEOUT ;ECHO IT MOV AL,LF ;ECHO.. CALL TYPEOUT ;..LF MOV BX,OFFSET INBUF RET ; ;Got DELETE or BS, echo if BS ; RDBS: XOR AL,AL ;AT FRONT.. OR AL,CH ;..OF LINE? JZ RDCTLU ;.. YES, ECHO ^U DEC BX DEC CH MOV AL,CL COUT: ;enter char in CL mov dl,cl ;put char in DL mov cl,L_WRITE ;write to default list device CALL BDOS ;LIST TO PRINTER THRU BDOS RET ; HOME: PUSH BX CALL BHOME ;HOME DRIVE THRU BIOS POP BX RET ; ;Set track # in DE ; SETTRK: PUSH BX curr drive.' DB CR,LF DB '=xxx search for ASCII xxx from curr sector.' DB CR,LF DB ' Caution: upper/lower case matters.' DB CR,LF DB ' Use for hex:' DB CR,LF DB ' To find "IN AL,0C0h" use: = or' DB CR,MP AL,'H'-40H ;BS? JZ BACKUP ;ECHO THE BS MOV AL,BYTE PTR [BX] ;ECHO.. CALL TYPEOUT ;..DELETED CHAR JMP RDBLP ; BACKUP: CALL WIPER JMP RDBLP ; RDCTLX: INC CH ; RDCX1: DEC CH JZ RDBF1 CALL WIPER JMP RDCX1 ; WIPER: PUSH CX PUSH DX  MOV BX,MAXTRK CALL SUBDE POP BX JNAE OUTLIM XCHG BX,DX MOV CURTRK,BX XCHG BX,DX MOV CX,DX PUSH BX CALL TRK ;SET TRACK THRU BIOS POP BX RET ; SETSEC: PUSH BX PUSH DX MOV BX,SYSTRK XCHG BX,DX MOV CURSEC,BX MOV BX,CURTRK LF DB ' "(tab)H,0(CR)(LF)" use: =<9>H,0' DB CR,LF DB '< save current sector into mem. buff.' DB CR,LF DB '> restore saved sector' DB CR,LF DB '? give help' DB CR,LF DB 'A[ff,tt] ASCII dump' DB CR,LF,CR,LF DB PUSH BX MOV DX,OFFSET BSMSG ;BACKSPACE, SPACE, BACKSPACE MOV CL,PRINT CALL BDOS POP BX POP DX POP CX RET ; BSMSG DB BS,' ',BS,'$' ; ;Got CTL-R, retype ; RDCTLR: MOV BYTE PTR [BX],CR CALL CRLF MOV BX,OFFSET INBUF MOV CH,0 ; RDCRCALL SUBDE POP CX MOV BX,CX JAE NOTSYS MOV AL,FIRST0 ;SEE IF FIRST SEC 0 OR AL,AL JNZ GSTSEC ;NO, JUMP AWAY DEC BX ;YES, SO DECREMENT JMP GSTSEC ; REQUESTED, THEN GO ; NOTSYS: MOV BX,SECTBL XCHG BX,DX DEC CX CALL BSECTTRAN MOV AL '(Type SP bar to continue)' DB 1,CR,LF,CR,LF DB 'C Change:' DB CR,LF DB ' CHaddr,byte,byte... (hex)' DB CR,LF DB ' or CAaddr,data... (Ascii)' DB CR,LF DB ' Allowed for imbedded hex.' DB CR,LF DB ' or CHfromL: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00211 JMP RDBLP L@00211: CALL TYPEOUT INC CH INC BX JMP RDCRL ; ;Got CTL-U or backup to beginning of line. ; RDCTLU: MOV AL,'^' CALL TYPEOUT MOV AL,'U' CALL TYPEOUT JMP RDBUF ; CRLF: MOV ,BYTE PTR SPT+1 ;IF SPT<256 (HI-ORD = 0) OR AL,AL ; THEN FORCE 8-BIT TRANSLATION JNZ VSCTR1 ; ELSE KEEP ALL 16 BITS MOV BH,AL VSCTR1: GSTSEC: MOV PHYSEC,BX cmp byte ptr cpm_version,31h jb aint31 mov bx,cursec ;version 31 does it's own xla-thru,byte e.g. ch0-7f,e5' DB CR,LF DB ' or CAfrom-thru,byte' DB CR,LF DB 'D[ff,tt] Dump (hex+ASCII)' DB CR,LF DB 'Fn.t Find file' DB CR,LF DB 'Gnn CP/M Allocation Group nn' DB CR,LF DB 'H[ff,tt] hex dump' DB CR,LF DBAL,CR CALL TYPEOUT MOV AL,LF JMP TYPEOUT ; UPCASE: CMP AL,60H JNB L@00212 RET L@00212: AND AL,5FH ;MAKE UPPER CASE RET ; CONST: PUSH CX PUSH DX PUSH BX CALL BCONST ;GET CONSOLE STATUS USING BIOS CALL POP BX POP DX POP CX REte, use cursec aint31: MOV CX,BX CALL SEC ;SET SECTOR THRU BIOS POP BX RET ; OUTLIM: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++not within tracks 0-',0 PUSH BX MOV BX,MAXTRK CALL DEC POP BX CALL ILPRT DB '++' DB CR,LF,0 CALL   'L Log in drive' DB CR,LF DB 'Lx Log in drive x' DB CR,LF DB 'M[nn] Map [from group nn]' DB CR,LF,CR,LF DB '(Type SP bar to continue)' DB 1,CR,LF,CR,LF DB 'N New disk' DB CR,LF DB 'P Toggle printer switch' DB CR,L ; MLDONE: POP DX POP CX RET ; ;Routine to fill in disk params ;with every drive change ; LOGIT: cmp byte ptr cpm_version,31h ;if it's ver 31 the select jae logcal ;routine done moved DPB MOV DX,OFFSET DPB ; THEN MOVE TO LOCAL MOitrack rw 1 ;track number (first track=0) isector rw 1 ;sector number (first sector=0) idmaseg rw 1 ;dma segment for sector buffer idmaoff dw offset sector_buf ;dma offset for sector buffer dmaseg rw 1 ;dma segment for data dmaoff rw 1 ;dF DB 'Q Quiet mode (no msgs)' DB CR,LF DB 'R Read current sector' DB CR,LF DB 'Snn Sector nn' DB CR,LF DB 'Tnn Track nn' DB CR,LF DB 'Unn Set User nn for Find command' DB CR,LF DB 'V[nn] View [nn] ASCII sectors' V CH,DPBLEN ; WORKSPACE CALL MOVEFROMBIOS ; LOGCAL: MOV BX,OFFSET GRPDIS MOV AL,BYTE PTR [BX] PUSH AX MOV AL,BLM MOV BYTE PTR [BX],AL PUSH BX MOV BX,DSM XCHG BX,DX CALL GTKSEC MOV MAXSEC,BX XCHG BX,DX MOV MAXTRK,BX POP BX Pma offset for data trk_sect dw 0ffffh,0 ;number of track/sector in memory sec_xlat_tbl dw 0 ;address of BIOS xlat table rec_offset dw 0 ;logical record offset into phy sec ; data storage for Disk Parameter Block (DPB) ; dpb rs 0 ;17 byteDB CR,LF DB 'W Write current sector' DB CR,LF DB 'X Exit program' DB CR,LF DB 'Z[nn] Sleep [nn tenths]' DB CR,LF DB '/[nn] Repeat [nn (decimal) times]' DB CR,LF,CR,LF DB '(Type SP bar to continue)' DB 1,CR,LF,CR,LF DB 'CanOP AX MOV BYTE PTR [BX],AL RET ; ; DATAOFFSET EQU OFFSET$ DSEG ORG DATAOFFSET ; ; ; RW 200 STACK RW 1 ;LOCAL STACK ; ;Temporary storage area ; BUFAD DW BASE +100H ;FORCES INITIAL READ HEXAD DW 0 ;TO RE-FETCH A VALUE TOGO DW 0FFFFH ;Rs of storage ; SPT rw 1 BSH rb 1 BLM rb 1 EXM rb 1 DSM rw 1 DRM rw 1 AL0 rb 1 AL1 rb 1 CKS rw 1 SYSTRK rw 1 PHYSHF rb 1 ;not in CP/M-86 ver 1.1 PHYMSK rb 1 ; " " " " " ; ;End of disk parameter block wvmsg db 13,1cel a function with ESC or Ctl-C.' DB CR,LF DB 'Suspend output with S or Ctl-S.' DB CR,LF DB 'Separate commands with "!".' DB CR,LF DB ' Example: g0' DB CR,LF DB ' +!d!z#20!/' DB CR,LF DB ' would step in, dump, sleep 2EPEAT COUNT (FFFF=CONT) TWOUP DB 0 PFLAG DB 0 ;1=PRINT GROUP DW 0 GRPDIS DB 0 SAVEFL DB 0 CURTRK DW 0 CURSEC DW 1 PHYSEC DW 1 TABCOL DB 0 FILECT DW 0 DIRPOS DB 0 FINDFL DB 0 ;1=MUST POSITION AFTER FIND FTSW DB 1 ;SEARCH W/O INCREMENT NOTPOS D0,'Only CP/M-86 ver 1.1 & 3.1 Plus ' db 'and CCP/M ver 3.1-4.1 are Supported$' mpmsg db 13,10,'THE MP/M OPERATING SYSTEM IS NOT SUPPORTED$' toobig db 13,10,'SECTOR SIZE TOO BIG - ABORTING$' sector_buf rs 2048 ;------------------------------- sec, ' DB CR,LF DB ' and repeat until control-c typed.' DB CR,LF DB 'All "nn" usage except "/", "T", and "S" are' DB CR,LF DB ' HEX. Use #nn for decimal.' DB CR,LF,CR,LF DB 'See DU.DOC for complete examples.' DB CR,LF,CR,LFB 1 ;INITIALLY NOT POSITIONED WRFLG DB 0 ;MAY NOT WRITE UNTIL '+', '-', ; OR 'G' COMMAND QFLAG DB 0 ;QUIET? (0=NO) FIRST0 DB 0 ;SETS TO 0 IF FIRST SEC # IS 0 UNUM DB 0 ;USER NUMBER DRIVE DB 0 MAXTRK DW 0 MAXSEC DW 0 SECTBL DW 0 ;POINTER TO SECT------------------- ; SAVBUF RS 128 INBUF RS 128 ; ;Directory read in here; also search work area ; WORK EQU $ DIRECT EQU $ END ,0 JMP PROMPT ; ;******************************** ;* * ;* Utility Subroutines * ;* * ;******************************** ; GRPCMP: MOV AL,CL INC DH DEC DH JZ CMP8 CMP AL,BYTE PTR [BX] PUSHF INC BX POPF JZ L@00231 RET L@0OR SKEW TABLE ; BACK RW 1 ;TO BACK UP IN "CA0-7F,X" DUMTYP RS 1 ; ;-------------------------------------------------- bios_call_tbl rw 1 ;address of bios call table goes here table11 dw offset select_disk11 ;direct bios calls for cp/m-11 dw 0231: MOV AL,CH ; CMP8: CMP AL,BYTE PTR [BX] RET ; ;2's complement HL ==> HL ; NEG: NOT BX PUSHF INC BX POPF RET ; ;HL/2 ==> HL ; ROTRHL: OR AL,AL MOV AL,BH RCR AL,1 MOV BH,AL MOV AL,BL RCR AL,1 MOV BL,AL RET ; ;Colloffset set_track11 dw offset set_dmaseg11 dw offset set_dmaoff11 dw offset set_sector11 dw offset read_sector11 dw offset write_sector11 dw offset sector_xlat11 dw offset home_disk11 table31 dw offset select_disk31 ;direct bios callsect the number of '1' bits ;in A as a count in C ; COLECT: MOV CH,8 ; COLOP: RCL AL,1 JAE COSKIP INC CL ; COSKIP: DEC CH JNZ COLOP RET ; ;HL-DE ==> HL ; SUBDE: SUB BX,DX RET ; ;Quick Kludge multiply ;HL=DE ==> HL ; MULT: PUSH CX for cp/m-31 dw offset set_track31 dw offset set_dmaseg31 dw offset set_dmaoff31 dw offset set_sector31 dw offset read_sector31 dw offset write_sector31 dw offset sector_xlat31 dw offset home_disk31 bpb rs 0 ;bios parameter block PUSH DX XCHG BX,DX MOV CX,DX MOV AL,CH OR AL,CL JNZ MULCON MOV BX,OFFSET 0 ;FILTER SPECIAL CASE JMP MLDONE ; OF MULTIPLY BY 0 ; MULCON: DEC CX MOV DX,BX ; MULTLP: MOV AL,CH OR AL,CL JZ MLDONE ADD BX,DX DEC CX JMP MULTLP  bpb_func rb 1 ;for direct bios call 50 bpb_cx rw 1 bpb_dx rw 1 cpm_version dw 0 ;cpm version sysaddr dw 0 ;SYSDAT addr udaaddr dw 0 ;process UDA addr imcnt db 1 ;multi-sector count (preset to 1) idrive rb 1 ;drive number (a:=0)   jkTREEDIR CQM7TREEDIR DOC8 vTREEDIR.COM tv !"#$%&'()*+,-./0C4GfmFbi,ԲԟˡLIIb#7:FGalH@(Vy kأLηa6ěI~(Njfy= mu6IIb#7:FGa' jP=|;{q>-EwB=?Q'.ho칠 Bi`y#<3Q8 ^%y]ςpGt3X^ET #ҁQ5/- n,$n,=kBס քʽf(612XAaN^s5ݯԴnCM+7]eԯ t7)j:n]ѽGCZ)t5Ec@ф9kS.=ț)mi.HQT7IJzHyc&$XAAAa.HqUt#`v5ݏ>́1Gxr]|Q(1|?23456789:;<=>?@ABCDEFGHIJKLMNOPQRST.殫`x{`LFW@`ddF B^P}$1]VPP]11+((zA0wa]|(:3Ego11+((zA0wMaVGZBNPo9}w'I/~A,qs62^[%\N@FC&@8޶u9!6e D!($eS;1dJV^e-3YIUFJt'Ԋ* VP7 t4ԷyR*^-=1Fx#ovN%!ԊQ ]G 6՘P+F1Gi[Ɛ/W~SPg7-ΐտIFi=<-Z^b`o7?qۄc]|N2!mS ?wmԴ1Cj @'^d=5&II)/RP`dT7+((>)*(@jeK1ԭ9ğg]ijC%/f=jCjC+}{<ѥ\ёVx1T;BUb[kWӊ[ڋْYPRR05BHQ+Z1ԭ5?}EwL$Zъ! +Zъn5AԉKE{54 _: caU>=]1-) bYWD!SOL7Zk~d36N~ޣ/|~p/V$1.tN|'֗<灏aoqZ[ D4\rUVx1ԭƽ0RR)N JE>ʨo1ԭNaK`ee"|8q6qB,X#Vb-o,KxN2J2's}21ӧh>,m '}rP5Nr> תF26R4+Y՘o9!CYOdg~>1P7#7yaHٺr3Cjě )cpBR{vnLKMxl3JAip[r&S]#lh "X)8{@RgY%s.(ze\8J+BF|͢Ts=8T#Q $v3җK}fR(pihXQB30*# lkgeVTPM umܪ>lZ=՗?u0}zI$nT$j~91_Hv KA̓#orLxق;:λh>ƒ;f ՘(DV@ 8TaNra.Hq:)u;{$`NvqJ12*QY uSv(sQ᎘{h>,m Q|B.R#2R<T]Hl#eʊlCLF{O3qDVJ wr*rpG^ a)3^hd1 qp86.upvq5.bJ"B.oN 7SR"P,(3f_nGzR|9 .n:텁ʈBRM-_;'^~p΃߬[#Q@v0^#QoPqeiR8#] }mDypV@\k}h3Ji/RFsS lGI:EuHAu/LqAte7qgw^,m[]ծޢb_[λi>ƒ{>8XxÍGV-=zKO'Cɸŭ|][cmCpwPc8S=: 7./,œ3p$p$p$pś'+|{ |aƩVCje=tC^Å)ki:ql[,O_NWzEYW&~0qhk' 7a?ܯxۺba@ aCnZ~O _ٺa߄~:h-!4+!Ɩ&\ s߄{*+M7[SaIb[oln#XPmgaT(()I(b;(" _Q%=`- ZpG82k1p6ۧ;8c`%h1RmQ1sZpǁi+h`-FxcFbp {$m+ &=?|3J'9­oٺ4DmC$ںD #nkʞ(n>Эy29ߎ+j+^ 8ey"T~!9CCP-mYgPYaiijCmz٣LηawL@\UyqF[ْ3S.=k4rTWIt"#GGw?P;\#aѶn+b;\DHIEFfGk1?t σ5\rpH +ck5ASe@g9y ;f 5':hDj:r98A̱]`MW9lID er -2 =;oÏo7bo#9y Uj:)}{Au߼HQR'.`N}RM``ngᬠ!/K! #p+#XfRˌ XfC05!5[ g'|@v5 qp(xax-?1QXˆ~ #@5c!1fiV@ju%!BBtw޳>h5uiy)ɋ;'~短ka(sub†̱NV5fp}R̩Sk9V3v5\o2o&AȁcC!oiy+o8͗udž|`[`ḵ։6g dwR޷6SN\ %)3k5A}9>tΨ D nV|v}>w^Q~~xF۾cww_b<'?n=k'v}oπݤXkz)pz@yqݴrI)߬Zgv{ܾ'/'/ ׬7h߲ lXa=6rCxؗ;labCxǘ1Ꮁvc?2ccM;/Yo7wqncp؏s zBoX&ᅬ >drFBOrJB_rRB[(Q o{]67bVғPe:[N+51b.%\sQ)29fK%PUWm螇rJf)OhPNJyC9#%rT .o;mb[erwͤ!ix'uwiπIRb[(xX#GNpǁEDx(4LnitR365UTZ/a29ߎ3opGt7f2$5*`Qpak5tj~D`3Kt7ʖb&Lc?{z|`^ S>L]e}瓾Ĵw2>~:ѧ/LwbK xIATtd LF@ tHb T73 R 9aZT73FA XA=>]뀌Ș}HsTI swFZU+[!5D3 vȍL6d$ZۚԞlR~ۤhM&n77vSt04~_ljmkRdS{Im5';{/hZ$xl|@Z|eo9O˷h?ld7Ul,gS+(_u0uǑ[ϙ3k^X3SS y ؃πRP0CPSVWW^3؎W_E %E%] VW_^D %  DEËE E E E uE7E tm ]]]]E ueUUU )]WUFtF uv~JyvDv~;3rNˁsFs t(W+rw>GÉWډtŹMOKK6;r64 t;r;u L7E;tOËM+Wr;s‹ uÀ>0À>YQ󥥥ËFFFF|r~pv{>Ѻq$>vj2Zc{Z7ѻ |uv"/xٳ^x~Y'}z?f)'._A,~2'~|荇>n=Z|y~k E?C$F1Gi[Ɛ/W~SPg7-ΐտIFi=<-Z^b`o7?qۄcSSSSSS_Nj, . t. .CCsCCt֋F-0@FFދF3FF܋!~]_" " " " WUF uv~FuFFF F} vi[Y3PPPPQS vT5Qv~;rwNNOO ^rOcw|44/uÊ u -40*xS!1[ !ߥ40 t@yـr!!$2s Q*HY t*QـY*!2x"s) (m"r /FO**/G TREEDIR Tree directory for MSDOS V2.xx. usage: TREEDIR [directory] If the directory is omitted, the tree starts with the root directory. Use TREEDIR . to start from the current directory. This program combines v~FFGGvFFYċF-?)FF1F~Cv~]_ ܊o w y2y:}ĹW9Wu KK$t w$t$t2 ܉G_ttt4^XZ[YU]MQSRP_D3۹%uPPP8PRS3PD/G!$>Pu>2r<Pn t u$0E$,@y ??vCS4"W^B>2*[CS t8P$tȾ">2sXtȾ)>2'24uY5~  t/KK/xTREE and DIR to produce a directory of all files in each directory along with date, time and file size. Totals are given for each directory, which includes the totals of any subdirectories. This program was primarily writt%-?=#=|)D-8yT\D 3E_Xˎ& A.2 UWFVv~ u y ؃ y ރS 3SN;w r;w+@N^Yt tu t؃FV _] vFOv]q%uZDS u0E(%Ay-Ax4C2)62B*/F/F/F/F/F/F//s62')4t떋W@[ $tF*en to display the actual space used on the hard disk for each directory, and the amount of space needed to copy to a diskette. This is due to the allocation cluster of MSDOS: files on diskette are allocated in increments of 1024 byt UF fF FfF FfFV ] v û< Wg؎Ћ&>  O3  D UFP t5x t/PVP ±$'@'Nuӱ 9nvnX@ &B ^3^.U+;&> v^.PF^;rPv'JuBBӋCCCCӃ t-%:u:u t2r ðÇ ^P.$YQ S[^P.$CC^CC ^CC6P.$ -N2$2Ȫ%þ2$2ȪFes while files on the hard disk (10 MB) are in 4096 byte chunks. The program requires DOS 2.0 or higher, since it doesn't make any sense otherwise. Future versions will probably include sorts and hidden files and options l;;hPaZW\Xm>ȸ$; sy ̻x$ Ȫà<s tyÿN-yȈ/þÊ'P'rC'$'Fá u' ĈGäÿ'''''''ËCC$ȸ$; s3PP`/;Ȼ:QY#s -0@;Ȼ[QY#s -7`;Ȼ{QZY#s -U;x !.@;|+۠ t8,Ax4@ȿuO$uܠ yۋYQ5CCCC0 y8YQ󥥥~tvËfË+Ntx@@H2&5 5Hఙ'y@#!S[̡PXFF= tvP0DDPvX3FFvv uF=|vPvXPvvX.Vvv^;tPvY*Vvv^;t&F;F|vPvX? v^vv3]ËGtw VU v22XP+>> y 0 ;y 7غS>uNf ~>*Y؎r;sَЋQ>ut >*+II + F00-u !-$5Ë uK[XS$v+ y؀r *tyú$ډ9[[SS$9YZRQN; u2<K u Y;mNNX<#u~<$u|<$ui$X<*u d<*tT*<.uU<#.u2Mg<-u"?<F%1FF0CP3PPP!FV^ t؃]^Ëܸ1GVUF tFuv~vv~~D+EtyEȻYKKyً3x CC$CCE y3CC1W^~FuF]^^XZ^X33SS^XZr3 t%< uFtNV@P@ Y^-Gá*+Éáà *á  tPGùZD t  & Q ZRZ' XHHHPX HpyPX$'@'UÉ+ˉO #t<.-u°B2MHB<\u thD D<#t<,uLM<.u<<#u><^u@<-uC4Y u.?A7CuM tȢEB tB t@ Auc,@t s2SRsޞZ7[S St#RCCZYS/CCBI uZ[C7SxB tQRޞ[CS}[Sk[ڋˋ*rDO[[/CCSޞ։[u< rP|X*d*Ë*Ê[6NUMERAL TOO HIGH IN NUMBER ANSWER = ?M t?L tű<r,ŊM*ŢEyL%W2LBCY&%M?,@*ňBڻC ڰuUt ?E?>@ u AȊ*<s0 Kusr  tE u*CB uVtQ? tBM<s8Z*Z_YQSCCӀ t[2CuK2V< t<+t <-uB<0t<.u&sТ<uf <0uޠȢТ<? 0uc< t,-tur$rȊ u*Ŋ蠎@ŋ2SںL<+t!<-u يȵه$4s⠑ tЊЊПB[C7à uȢC<0s<:s$ÊC7*ŠƇsyÊ uÊshûbADIR 4Ȼ? y?q2L<Ȱ.sl;< t?@ uA>:s2*Ţ>/4 t>x)>@ t@EA; u y-ű/, y  0C t 2CB; tà=;ú$9 u>;t>Jt=SNScٞڞڻsޞ֊RSSQڋSQr)x'SCC룒ZYZYZ[[à LS SR t5 t9Sڋ;_uZ[R[tr 2ðVt݇Lև;t#SR;r[ t x؀'_St *[P;XùCA[SCC>;u! t CS[J[ uÊr4J uY;SN:HډFXTtUP tB;CCTV[*;\*SCCZSʺ;X< t*Ë t# xSta*:s'_CXSQCCZZSXHHÉYQPMKMtB98:t/ى<\uKFCS"[r;~+SPR t+۬<#u" 3 ȜX.[.&YP.Y.[.[..YUVN]U]UX^P6;X4F uF]øo P P5PFDD]PF^+PDDFPvtX^# uN PvtX^# uv0DDVv4VP^;@PvtY @PvtX^# uP3PX]Ë]3FF v~ Pv]UPvZ]UPvZ]UPv]UPv]UPv]UPvpZ]UFȈFZuNX uv~3F v}X u3]ËF=|3]ËF udF=FP~Av, u F'vv} P8vX u Fv, ukPvY* P]U>v\P&t]ȴÊ< u&66<9v6055<9v 504,a<s&_]U9Pt@ P ]U2  r T <u@P> u@Y"r> t׀> $uI$ <$te ,0 < vz FP6 XvFX u5FP6 XxFpvPvYPvDX u Fv, ukPvYFP6 XvX u5FP6 XFPvY+PD > t  `rWs6 뇀> ^u,A <v PS P6 jπ> t@ 6 T2]U [ < t@P> t@Y s ]ð]U [ u ]U2@2=vQ PF2 <}vi P]UvKX u# PFv,3P~vFvFv4X@PvXv;v5; PuvX uP[vX u3PvVPvYF uv~vvF9P,Y9PP>Zu PzQ t3 ƇƇ$> t,  ø9P>Zu P(]U2H2Ê]ÎӍ&0.6$@6 ]Ë]F F v2X u"v~vƸ-F=|tvƸ0vƸ.vvYF=|vvY+3F3Vv^;|vƸ0rvFF0PvX vv001 $$$$ SUB copyright(c) 1977, digital research $Error On Line $SUBNo 'SUB' File Present$Disk Write Error$Command Buffer ,~v, uF uvƸ.v, uIv^FF0PvX 9vv-A~/v3VF+F ^ t3]Ë]v u%Pv^;t_F-Pv4^;ƸtHF Overflow$Command Too Long$Parameter Error$Invalid Control Character$Directory Full$Cannot Close, Read/Only?$u vvF0PF^;u F*Pv^;tv 4XFvF3FvPDD u-0PvƊX+V PvX^^ƉF.Pv^;ƸtHF uv*Pv^;tv 4XFvF3F PvދYvFށP\PvP\^ƉF܍\PDDF썆\FFF9FF*F FFF FFދF u)F Fvt4vXZTFF EF=|v 4XRPvXZTv 4X3R;tPv4tY Vv4VFP-^;lvt vtDDPvtX uEPvtvtVFPFP6;XXPvtX5^# u F uv4V#P3RPv4t#t!XZY[RPvtXZTPvtX^@PO^&Q^&S^&U^&W^&Y^&U &PvXZTvލ\Pvt4F u2\F3RPvt4XZ^_;u;r v܁vDDFF uPvXVF^;rbPF^PPvX^PPvX^PF^Ɓ^+Pv0PPF^+FPvPF^ƉFPF^PPvX^# uvttXZ uv4t!,\t4XZvtVP!v4V!P3FF=|(Pvtv^;t vFRPvtTY[ӉTF]ËF u!v4 u v4VDDvDD]Ë]PvtX^# uPPvX^PF^^+ƁPPvX^PPvX^PF^^+PPF+F^PvX.\FvzDDFv 4XFv[DDFF uF;FrFF3Ftv FܸF3FZFFܸF3FFC^csdDxXuUoObBfPvtX^# uPv4^;tqvtvtV P PPvt Pvt^Pvt Xvt XPvtX hv4VDDPvtXPvtX^# u Pvt^;tvt vt  vt egizog\TIA6.`^F uF;FwF u-Vv܊^;t 0PF^;t,Pv4vvЃv,v,vVv,^;wPvVvvЃF;FwvvY+3FvvvvЃF uF]øRPvtt XZY[F3FFF=|vttPvX^RPvtt XZ^_^_;u;rPvX^Pvt^PPFF3RPv4t!XZTv4V!PFF=t F=t-3PPPvX^Pvt^Pt3 u(v, uPvVvvЃvPv4vvЃc]n4F̍v4^Fv4,X ux Pv̊^;t Pv̊^;t PvX6APv̊^;sZPv̊^;v Pv̊Yv́4XwF F u vF u@PvtY PvX^Pvt Xvtt vttXZ^_+RPvt X^_;u;w&vtt vttXZ^_+RPvt XZ] PvtX^# uLvtvt X^;|vt vtXvt XPvX~ F҉FЉFθF̸FPv4^^ƉFv4,X uv̊ u<Pv̊^;t F́F<>Pv̊^;t F́FFPv4^VF^ƉXF=} P P Pv̊ uv́4Xv,4XRPvtt XZ^_RPvttXZ^_;u;r*vt XRPvtt XZ^_RPvtXZT3Fvt PvX^^;|PvX^Pvt^PPvXRPRPvtt XZY[s^_RPv4t!XZTv4V"P u@PvtY vv́4X+ F̸>PvЊ^;tvЁ4X F̸P Pv ^;uPvv ^;uP Pv ^;u P PP PFԉXFPvϸP ]3F3FF=|)FP6;X4 u vYPvtY#]縱 PPvVvP.bPu PPnP]UNV]\vvX^Fv F uPvvF]Ë]PF^P}DD u]vDDFPvtX5^# u v4VDDvF=tPPQFF uPv5^#PvtXVvDD^;:Vv^;t'3FF=|3FF=|/PvX^P6 XvPvvP:DD^;t vF=t(PvX#VPvX^P6 Xt u vtVDDvDD3PPvX^P6;XX3]Ë]Pvvo]Ë]l3FF=|,FP6;X4 uvDDvvDD] PvY+P&DDF3FvVF^;|KPFFPv FF=|VPvދYvP\PvP\^ƉF܍v܋ƸEF=|v܋Ƹ-F؉Fv܋Ƹ+v޸y Pv6\PQ DDF썆\FF uFF Fv~FF 3PvVF޸PvދF^^PvVD^;tPvtY PvX^P6 XDPvXPPvtX^#^;t/Pv4^;tvt vt vt vPvtX5^# uvDDPvX uF uv4VPwPPvtX^#^ & PvPvX^;tvv3F u F]3]Ë]zFFFv uv4^PdFF uFPvY F uFF uFPvY Vawrb ƋFFPvX3]Ë]PPF^^#ƉF6;Fv4F uvVvtX^;sPF^PvtX^;sMPvX^PF^ƁFv4VvXPvtX+F^+PvtXFPvX vtXFv4VvX FFSF ut X@PvtX^# uPFPX]Ë]Ӌvtvt X^;}Kvtvt Xv[DDvtXRPvt TY[ӉTvt 3Pvt Xvt X uPvtX5^# u-vt 3vDDvt X u vt  PvtY vt _FPRPFFPvFF=u F=t3PFFPvqFVF=tF=uPRPvF=u F]ø]Ë]vVvFP.bP]Ë]PvY+v4VF^;PF^P F u%FPvtXFPvXPvYF]Ë]U؎v~N;rNO]Z۸PvvG]Ë]?ۍvVvP.bP]Ë]$v6DDFPvtX^# u P PPDD3FvVvX^;r3VvDPvtXF]u P PQPb6;Fv4 uvVv4^;r v4Fv4VvXFPvXPvtX^PF^ƁPF^;t+PvtX^PvtYv4VvXFFv4FPvtX^PF^ƁPF^;t(PvtX^PvDF^;|vƋFvPvtX^# uF=tvt ,v,nF= tR3VvDDF^;|JF= tv 0vtFPvtY F= t@PvtX^# uPFPX]Ë]ٸPvlu86: wildexp error. memory?LU86 Ver%s, %s; 4.0503 Oct 84T. Jennings, Paul Homchick Use: lu86 -[tlaeudr] lbrfile afn afn afn... Where [] is one of: t | l List of files in LBR file, a Extract all files fromtYv4VvX]v u-FPv4^^;tv,4X]]Ë]aFP0^;ƸvH uH uP9PF^;ƸvH uHPX]Ë]v/DDFPvtX^# u 3ҋ]øPvtY#F Pvt XRPvtX^# uPvtY#vD]Ëvt vt X^;} PvtX^# uvZDDPvtX^# uOvtvt X^;t*vtXRPvt TY[ӉTvt 3vt X uvt 3vDDvt vt X^;}]Ëvt P the LBR file, e Extract file(s) from LBR file, u Add to or create LBR file, (wildcards ok) d Delete a file from LBR file, r Reorganize the LBR file. ".LBR" is assumed for the library file type. .LBRlu86: Error- illegal filetypvvtt XZ^_^_׉VFvvXZVFvt XRPvtt XZ^_RPvttXZ^_;u;r*vt XRPvtt XZ^_RPvtXZTvvvttXZ^_׉VF3ҋ]{aNvt X u$vtt vvXZ^_vtX]Ë]P6> 4X^Pv^+PF^;s3]Í6< 46> 4X^+ƉFv6> YF]Ë]U؎~NF]Bvv4VvPvX^PvYPv4X]؍vVvvV_P݃]Ë]FFv4^ ue for library file. If a filetype is supplied, it must be ".LBR". If no filetype is supplied, ".LBR" is assumed. .LBRlu86: Program only allows 128 input names, and %d names are present. Please cut down on size of input list. lu86: Not;u;r9vt XRPvtt XZ^_RPvvXZ^_;u;sR PvtX^# uvQDDRPvvXZ^_##RPvt XZTvt 3vNDDvtt vvXZ^_+RPvt XZvt vt X^;vt vt XvvXZ]Ë]߸Pv,4Xv4^Pv4^X uF]Ë]׋vPv^;t+v4^ u]Ív4XvPv^;r]ø]Ë]!FFv4^Pv4^X uF]Ë]v4XFv4^ enough memory lu86: No command given. lu86: Not a command: %c. Error: cant create new directory Updating existing file %s Adding new file %s Error: LBR file: %s, not found Deleting %s %s not in library Error: LBR file: %s, not found Library: %sRPv]Ë]*FP!PF^ƉFXF =|RPvvXZ^_;u;r FvvXZ؃VFRPv XRPvvXZ؃RPgލ9 ^YƉƊPv,4^XF ؙRPFu5XZU ujvvXZVF3RPv X3 uPF+F^ t3]Ë]֍v4,X uvPv^;t+v4^ u]Ív4XPF^;t]ËvPv^;r]ø]Ë]֊FPA^;~ ZPF^;~ PvYF]Ë]ՊF Filename Bytes Index CRC --- Created --- --- Updated --- Filename Bytes Index CRC directory %8lu %8u %04x %-12s %8lu %8u %04x%19s %7lu bytes used;%5u active entries; %5u deleted; %5u empty. Error: LBR file: %sRPvvdݍ9 ^YƉƊPv,4^Xv X3RPFu5(XZU uF u-Pv,4^XP!PF^+F^ t3FFPvvF]Ë]#P%PF u:Pv^;tHvPDDFF=A}F=PPa^;~ zPF^;~PvYF]Ë]vdF u]vPFvoF u]ø]Ë]UF^s!]v.DDFPvtX^# u P PPDDPvtX^# uv3, not found Extracting: %s Error: cant create %s lu86: Error during file write to %s Disk is full, or no directory space ^ Warning: Bad CRC value. File is questionable. Error: LBR file: %s, not found Extracting: %s Error: cant ~F@PvXgPvY P PvtV5vVPvtVD uvVPvt V& uF]v\DD3]Ë]8v4Fv ubvƊP:DDFF=.t8F=!|]ËF uv,vFvVvX^;r^ Vv^;tPvtX^# u Pv4VvƊPv4Vv3FvVvX^;rX Vv^;tPvtX^# u v PtvvƊP\vvt vt X^;vt v create %s lu86: Error during file write to %s Disk is full, or no directory space ^ Warning: Bad CRC value. File is questionable. %s not in library No room in directory Cant find %s lu86: Error during file write to %s, diuZõuދ.oCt9 ** There may be text in the memory buffer ** ** It will be lost unless NOL or WRT commands are used ** .ȻQ KuuuCC GxCqC<.C.C ~ Single Letter .t."B - Toggle printer Z.%! - Start copy into buffer .# - Stop copy into buffer Start & Stop may be toggled as often as desired. A ":" at start of line indicates buffer is open. XOFF automatically used to stosk is full, or no directory space. Reorganize library to remove garbage at end. lu86: Error getting filestamp. Error: cant find library Old library has %u slots, %d free. lu$$$$$$.tmpNot enough room in new directory Copying %s lu86: Error durCommands H - Display this information ? - Display current settings T - Terminal mode E - Terminal mode with echo L - Terminal mode with local echo For capturing text use T(or E or L) FILENAME.TYP and Start & Stop toggles descrip input when writing full buffer to disk, XON sent to resume. .$ - Transfer ASCII file to remote .  .&u3 - Send local control character to remote 7 - Next character will be used for local control u Drive Aing file write to %s Disk is full, or no directory space lu$$$$$$$.tmpDirectory error: %s is bad or not an LBR file %s is not a Library. Directory error: is %s an LBR file? Warning: Directory CRC error. Directory seems to have %d bed on subsequent screen. R - Receive CP/M file using Christensen Protocol S - Send CP/M file using Christensen Protocol Command is: R(or S) FILENAME.TYP R and S can use the following subcommands: B - Bulk transfer using wild1 LU86.CMD CP/M VERSION 4.05 October 03, 1984 NAME lu86 - create and maintain a Novosielski library file. SYNOPSIS lu86 option lbr_file_name[.lbr] [ file ] ... entries. Number of slots (3 - 255, 0 to abort): . .LBR close error: library may be trashed %02d:%02d:%02d %02d/%02d/%02d *.*BAD FILE$%03dcon: TOO MANY ARGS$warw REDIRECTION ERROR$c ABORT:- FREE$READ$WRITE$J i/!! ]< ueLCBCR\t?t C? tSv\J[CCCt ~ DESCRIPTION Library Utility 86 (LU86) is a program to allow combining multilple files into one larger file. It will run on all 16 bit versions of CP/M, MP/M and CCP/M. Version 4.05 replaces all prior vers NO CORE$ $$@Y@@חA7yACnF?O8M30HwZ?sOuW ?{Gz?-C6?:0yE>ؗҜ<2#I9 LDIR FOO (.LBR may be omitted) $'>' can be used to create a file of the directory list. -t (Table) A synonym for -l: also produces a directory list. -a Extracts all files from th$uZnot Rpresent Ì.0I.2I[؎м0ISyog.0D.oC.Cc.pC< tUm u .C.oC.oC.<t RSZ WRT - Write memory buffer to disk file 0 Local Commands while in Terminal Mode .  - Exit to command mode . tu.! - Transmit string Must be followed by number of string (0-9) or L to display list of strings   library will be updated with files from the command line file list. If the library does not exist, it will be created. Wildcards may be used when specifying the f library to it. Reorganization gets rid of unused space lost to delete and duplicate filename update operations. If you are dealing with a large library and a.0 do not have CRC words. The CRC calculation is supressed for earlier libraries. LIBRARY FORMAT The entire library file and each of its members are conceptually organized into "sectors", each sector ile. When a file is added to a library, the time and date file stamp is read and stored in the library | directory. LU86 uses the following path to find | re using floppies, you might not have room on the default disk to reorganize the library file. In this case, put the disk containing the existing lbrbeing 128 bytes long. Each sector of the file belongs to at most one library member. Each member comprises a whole number of sectors. The last sector of a member may, however, be logically declared as a "Short Sector".  the time and date of a file: the 'update' stamp, | the 'create' stamp, the current time and date. If a file to be added already exists in the library, LU86 will delete th file you want to reorganize in one drive, and put a floppy disk with a lot of room and lu86.exe in another drive. For an example let us assume your lbr file is on B: (B:biglbr Although it physically contains 128 bytes, a Short Sector contains one or more "pad" bytes at the end for the purpose of maintaining the structure of the library file as a whole. A member may have as few ase existing libary member, and add the new file to the end of the library. In terms of directory usage and library space used, this is the same as adding a .lbr), and lu86 and room is on A:. Log in drive A: and reorgainze the library thusly: A>lu86 -r b:biglbr This will open biglbr.lbr on  0 sectors. Members may be referred to by a name of up to 8 characters, and an extension of up to 3 characters. The naming rules are identical to those for the naming of CP/M-80 disk files. Members must be  completely new member. - 1 - LU86.CMD CP/M VERSION 4.05 October 03, 1984 Prior versions of 16-bit LU and LU86 would re-use drive B:, and put the reorganized result on the default disk, in this case, drive A:. Whenever a new member is added to a library, a value called the CRC (Cyclic Redundancy Check)  uniquely named; any given combination of name and extension may identify at most one member. The start and end points of each member are defined by the pointers in a "directory entry" for the member. There ar deleted directory entries when performing an add/update operation. LU86 v4.x will not re-use deleted directory entries, and requires a reorgaword is calculated and stored in the member's directory entry. When the member is extracted from the library, the calculation is done again, and compared with the saved value. If the two values do not match, it is an indicae no embedded start or end marks separating the members. All sectors between the start and end sectors of a member belong to that member. The members need not appear in the library in the same order that theirnization to reclaim deleted directory entries. This was done to provide an indication of unused space in the lbr file. If the -l or -t command shows deleted directory entrition that the member was damaged in some way while it was in the library. The extract will still be performed, but a message warning that the extracted copy is questionable will be displayed.  directory entries appear in the directory. The directory information in an LU style library is contained in the same file as the data files, or members. The amount of space to be allocated to the directory must be specifiedes, then the lbr file contains unused 'lost' space. -d Delete a file from a library. This tags the specified member entrie(s) as deleted, and 'l This feature is especially valuable for libraries which have been created on another system and transmitted by phone (possibly several times) before you receive them. It helps insure that the extracted files are fa by the user when a new library is created, but can be changed when the file is reorganized. The size of each LU directory entry is 32 bytes, which means each four directory entries take up one 128-byte 'sectoroses' the space that had been allocated for the deleted member(s). -r Reorganize the library file by creating a new file, and copying active members of the old ithful reproductions of the files - 2 - LU86.CMD CP/M VERSION 4.05 October 03, 1984 originally inserted. Members added by LU86 versions prior to 4 ' of the library file. The LU directory uses one entry for control information itself, so the number of directory 'sectors' needed for a library of m members is (m + 1) / 4, rounded up to the next whole number. and have renamed the effort to LU86. LU86, ver 4.x is a 'C' program, and is compiled with version | 1.33C of the Computer Innovations C86 compiler. This document replaces a document of the same name, dated  The user need not be concerned with this discussion, as directory size is calculated by the program. All directory sizes are input and output in terms of entries, each entry being a potential member file. The pro September 12, 1984. Changes are highlighed with a "|" in the left margin. CHANGE HISTORY Ver 4.0, September 3, 1984. Original release. Ver 4.01, September 10, 1984. Fixed add routines to exclude the dirgram adjusts directory size to an integral number of sectors. MISFEATURES (BUGS) Ideally, wildcards would work with the -l (or -t) -d and -e commands, but currently do not. ectory portion of a pathname, retaining only the 11 character file name for use in the LU directory. (MS-DOS version). Ver 4.02, September 12, 1984. Fixed update function so that it distinguishes between not being able t - 3 - LU86.CMD CP/M VERSION 4.05 October 03, 1984 Options may not be stacked or be specified more than one at a time. One execution of LU86, one option. Wildcao find or read a file (in which case it creates a new directory), and reading a file which is not a library (in which case, it aborts). Prior to this fix, trying to update a file with a .lbr extension, which was not a rd expansion of the -u input list is limited to 128 filenames. Wildcard expansion is not supported for pathnames (MS-DOS version). ACKNOWLEDGEMENTS Gary Novosielski designed the LU format Library, would destroy it. - 4 - LU86.CMD CP/M VERSION 4.05 October 03, 1984 Ver 4.03, September 25, 1984. Fixed bug that limited input file  and wrote the first programs supporting 'LBR' files. He has continued to maintain and improve the LU format by distributing a file of the offical LU format definition. The current version of this definition is  list to 30 names.. Now handles 128 names as advertised. Ver 4.04, September 29, 1984. Improved memory allocation error checking in the CP/M version. | | Ver 4.05, October 3, 1984. Added support for MP/M-86 and CCP/ contained in LUDEF5.DOC. Interested users are directed to that file for more complete information on the LU format. Large portions of this document are excerpts from the file LU300.DOC, which documents the operatioM | file time and date stamping. Unfortunately, with the CP/M-type | operating systems, you can find out the date of a file, but you | cannot set the time date of a file. Therefore, extracted library | members will not ret$$$Ix3FFFVvVvV^;t%PP513P-DDvVF^;t3PP 13Pq-DD636:6n of the CP/M version of LU (an implemenation far superior to LU86, by the way). Any particulary lucid and useful sections of this document probably originated with Gary Novosielski. The Turgid Obfuscation is ain the lu86 time and date. Paul J. Homchick Chimitt Gilman Homchick, Inc. One Radnor Station, Suite 300 Radnor, PA 19087 33FFF=v, uv44F:Vv^;t F udvP2DD uA3Vv^;t)vP>DDP6XP=P9F vQP9-Vv^;tv4 uvPtz~ u probably mine. This program had its genesis in the UNIX progam LAR.C. LAR was rendered into C that mortal compilers could understand by Tom Jennings, who renamed the source to LU.C. I used LU as a base  - 5 - Key to continue:  z ugPP/P<,DDL~~ uz uPP/P,DDrn]2F uF=v4 u FFFFmF=|SPPP(/PP/PP /2PP.WPP.FPPg"v3FF;F|FF;|FPFPX4VFP8X4V u^,4VF^;tEFFF;|0FPX4VFPXXvpvXv;vPvX3SRP_D3۹%uPPP8PRS3PD%-?=#=|)D-8yT\D 3E_Xˎ& A.2 UWFVv~ u y ؃ y ރS 3SN;w r;w+@N^YPT+DD3FF;F|#FPvX4V*DDFv3PF^;ƸuHP +DD]T33PPv -^;tvPP].]þvV6DD^;u!vPP0.6*DD]6DD6S,DDPX3V]Ë] 3FFF= |E Vvv^;t-vvPvPvXXv Vv ^;uvPvX. FF= |E Vvv^;t-vvPvPvXXvvv3F]Ë]t tu t؃FV _] v UF fF FfF FfFV ] v ûWg؎Ћ&>rtO3I  UF t5x t/PV±$'@'Nuӱ 9nvnX&^3^Ɗ^;u3PP:PP:6^DD=| =}!vPP~-6.*DD]Í663;|K6DDPP6XX6DDPP6XXPvvƊF u,*VF^;t?VF^;t]3]Ë]:Vv^;uG:Vv^;t.FPvA^;tPvY3]D:Vv^;u.FPvA^;tPvY3]ÍvƊ.U+;&v^.PF^;rPvX^P6X4F uF]øP PPFDD]3FF0_vY~aX uvBn~G3F8(v"X u3]ËF=|3]ËF udF=FPPP,3PPPd+^;tPPP,V^;uuY= t~ u!6P,6,+= tz u6R,x6(DD6(DD6(DD;u!vPP+F u?VF^;t7vƊF u .VF^;u3]*VF^;tavF uv.VF^;tvF uv.VF^;t'vƊPF^;t3]v u 0~v, u@Fvv" Pv4X u Fv, ukPvYFP6XBv]Ë]PPvVPF^+P^;uFF]Ë]PvY+v4VF^;u^P PP,6Fv4 uvVv4^;r v4Fv4VvXFPvXPvtX^PF^ƁPF^;t+Pvt 4XFvwDDFF uF;FrFF3Ftv FܸF3FZFFܸF3FFCcsdDxXuUoObBfegizog\TIA6.`^F uF;FwF u-Vv܊^;t 0PF^;t,Pv4vtXPvtX^# u Pvt^;tvt vt  vt ]øRPvtt XZY[F3FFF=|vttPvX^RPvtt XZ^_^_;u;rPvX^Pvt^PPFF3RPv4t!XZX^PvtYv4VvXFFv4FPvtX^PF^ƁPF^;t(PvtX^PvtYv4VvX]tFPA^;ƸvH uH uPZPF^;ƸvH uHPX uH tPGFPa^;ƸvH uH uPzPF^;vvЃv,v,vVv,^;wPvVvvЃF;FwvvY+3FvvvvЃF uF u(v, uPvVvvЃvPv4vvЃc]4F̍v4^Tv4V!PiFF=t F=t-3PPPvX^Pvt^P13F F u vF u@PvtY PvX^Pvt Xvtt vttXZ^_+RPvt X^_;u;w&vtt vttXZ^_+RƸvH uHPX uHPX]Ë]FP0^;ƸvH uH uP9PF^;ƸvH uHPX]Ë]FPa^;ƸvH uH uPzPF^;ƸvH uHPX]Ë]AFPA^;ƸvH uH uPZPF^;ƸvH uHPX]Ë]Fv4,X ux Pv̊^;t Pv̊^;t PvX6APv̊^;sZPv̊^;v Pv̊Yv́4XwPvX+F҉FЉFθF̸FPv4^^ƉFv4,X uv̊ u<Pv̊^;t FPvt XZ] PvtX^# uLvtvt X^;|vt vtXvt XRPvtt XZ^_RPvttXZ^_;u;r*vt XRPvtt XZ^_RPvtXZT3Fvt PvX^^;|PvX^Pvt^PPvXRPvDDFPvtX^# u 3ҋ]øPvtY#F Pvt XRPvvvtt XZ^_^_׉VFvvXZVFvt XRPvtt XZ^_RPvttXZ^_;u;r*vt XRPvtt XZ^_RPvtXZTvvvttXZ^_F<>Pv̊^;t F́FFPv4^VF^ƉXF=}0P P PGv̊ uv́4Xv,4Xv́4X+@F̸>PvЊ^;tvЁ4XBF̸PDPv ^;uPvv ^;uPFRPvtt XZY[K^_RPv4t!XZTv4V"P@ u@PvtY vYPvtY#]UNV]vvvX^Fv F uPvvF]Ë]7PF^PDD u]v+DDFPvtX5^ ׉VF3ҋ][aNvt X u$vtt vvXZ^_;u;r9vt XRPvtt XZ^_RPvvXZ^_;u;sR PvtX^# uvYDDRPvvXZ^_##RPvt XZTvt 3vVDDvtt vvXZ^_4^ uv,4Xv4^Pv4^X uF]Ë]FFv4^Pv4^X uF]Ë]ov4XFv4^ uPF+F^ t3]Ë]&֊FPA^;~ ZPF^;~ PvYFOy]q%uZDV u0E(%Ay-AxC6B*/F/F/F/F/F/F//s6't떋W@[ $tF*+RPvt XZvt vt X^;vt vt XvvXZ]Ë]*FP!PF^ƉFXF =|RPvvXZ^_;u;r FvvXZ؃VFRPv XRPvvXZ؃RPgݍ~^YƉƊPv,4^XF ؙRPFuF]Ë]ՊFPa^;~ zPF^;~PvYF]Ë]vDDFPvtX^# ujP PP(DDPvtX^# uv3FvVvX^;r^ Vv^;tPvtX^# u Pv4VvƊPv4Vx'JuBBӋCCCCӃ t-%:u:u t2r ðÇ ^P.$YQ S[^ P.$CC^CC ^CC6 P.$ -N2$2Ȫ%þ2$2ȪF5XZU ujvvXZVF3RPv X3RPvvd܍~^YƉƊPv,4^Xv X3RPFu5(XZU uF u-Pv,4^XP!PF^+F^ t3FFPvvF]Ë]#P%PF u:Pvv3FvVvX^;rX Vv^;tPvtX^# u v PtvvƊP\vvt vt X^;vt vt X@PvtX^# uPFPX]Ë]*ԋvtvt X^;}Kvtvt XvDDvt$ Ȫà<s tyÿN-yȈ/þÊ'P'rC'$'Fá u' ĈGäÿ'''''''ËCC$ %s wbusq: can't create %s usq: bad checksum in %s *.*BAD FILE$%03dcon: TOO MANY ARGS$ t tű<r,Ŋ*ŢyL%L2&%,@*ňڻ ڰuWt  u Ȋ*<s0Kusr t u* uVtQ tB<s8FPX]Ë]ظPvtX^# uPvtY#vD]Ëvt vt X^;} PvtX^# uvDDPvtX^# uOvtvt X^;t*vtXRPvt TY[ӉTvt 3vt X uvt 3vVDDvt vt X^;}warw REDIRECTION ERROR$cFREE$READ$WRITE$4 NO CORE$ $$@Y@@חA7yACnF?O8M30HwZ?sOu?{Gz?-C6?:0yE>ؗҜ<2#I9PZ܃]Ë]FFv?$@$@CONCONRDRPUNPRN0123456789ABCDEF Ptr PMMIMODEM ;is modem a PMMI? OR AL,AL ;set flags JNZ LA24 RET ;no, return LA24: MOV AL,Byte Ptr OPARITY ;ge Ȼ yf2Ȱ.sa t? u:s2*Ţ$ tx t@E  u y-ű/, y  0 t 2 tàú'ډڊ u  uSQS$ٞڞڻ!ޞ֊RSSQڋSQr)x'SCC@ZYZYZ[[@à LSSR t5 t9{Sڋs;_uZ[R[tr 2ðJt݇@և;t#SR;r[ t x؀'_St *[P/XùCA[SCC u% t CS[J[ uÊr/ u YSN:ډtF* tBCC*B]*SCCZSʺBX< t*Ë t# xSta*:s'_CXSQCCZZSXHHÉOYEIQPMKCEAtBG9O8I.t/ىK<\uKFMCCS"[rM;G~+SIer library MOV CX,LIBLEN ;length of library entry MOV AL,DL ;number of times to library length to BX OR AL,AL ;set flags JZ DIAL11 ; DIAL10: MOV AL,Byte Ptr [BX] ;get first char of selected lib entry OR AL,AL ;set flags JNZ LA2 JMP D t+۬<#u">> PHdrive push ax ;drive and multi-sector count push itrack ;track # push isector ;sector # = 0 push idmaseg ;sector buffer DMA segment push idmaoff ;sector buffer DMA offset call getsu ;set up DS-SYSDAT and ES-UDA mov ax,bx ;set,CR XCHG BX,DX MOV [BX],AL XCHG BX,DX MOV BX,OFFSET INBUF JMP PRMPTI ; PRMPTR: XOR AL,AL MOV QFLAG,AL CALL RDBUF ; PRMPTI: MOV AL,255 MOV BYTE PTR TOGO,AL ;LOOP COUNT FOR "/" MOV BYTE PTR TOGO+1,AL ; PROMPT EQU $ SETSTK: MOV SYSHF TABLE <<< mov dx,offset toobig ; 128 = 0 1024 = 3 mov cl,9 ; 256 = 1 2048 = 4 int 224 ; 512 = 2 4096 = 5 jmp exit buf_ok: ret sect_to_mem: ;------------ ; ENTRY: itrack & isector specified ; EXIT: sector is in memory,  I/O function into AX callf BIOS_ENTRY ;call indirect the BIOS ;AL,BL = return status add sp,10 ;restore stack pop es ;restore original ES pop ds ;ditto for DS ret ;====== getsu: ;====== ; entry: DS = local data seg ; exit:  P, OFFSET STACK XOR AL,AL ;ZERO 2-UP PRINT MOV TWOUP,AL ;..SWITCH MOV AL,1 MOV FTSW,AL ;TELL SEARCH NOT TO INCR PUSH BX MOV BX,OFFSET BASE +100H MOV BUFAD,BX ;FOR RDBYTE POP BX CALL CTLCS ;ABORT? JZ PRMPTR ;..YES, READ BUFFER ; ;Do  MOV QFLAG,AL CALL ILPRT DB '+++ Out of memory +++' DB CR,LF,0 JMP PRMPTR ; ;Print disk statistics ; STATS: PUSH BX CALL ILPRT DB 'Disk Information:',CR,LF DB 'Tracks:',9,9,0 MOV BX,MAXTRK INC BX CALL DEC CALL ILPRT DB CR,LF,AL,CLOCK OR AL,AL JZ SLEEP2 MOV CX,OFFSET 32000 ; SLEEP2: DEC CX MOV AL,CH OR AL,CL JNZ SLEEP2 PUSH DX CALL CTLCS POP DX JNZ L@00045 JMP PRMPTR L@00045: DEC DL JNZ SLEPLP JMP PROMPT ; ;Check for control-C or S ; CTLCS: we have to position in directory after find? MOV AL,FINDFL OR AL,AL JZ L@00005 JMP POSDIR ;POSITION IN DIRECTORY L@00005: MOV AL,BYTE PTR [BX] CMP AL,CR JZ PRMPTR CMP AL,'!' ;LOGICAL CR? PUSHF INC BX POPF JZ PROMPT CALL UPCASE 'Sec/trk:',9,0 MOV BX,SPT CALL DEC CALL ILPRT DB CR,LF,'Grpsize:',9,0 MOV AL,BLM INC AL MOV BL,AL MOV BH,0 CALL DEC CALL ILPRT DB ' (sectors per group)',CR,LF DB 'Tot grps:',9,0 MOV BX,DSM CALL DEC CALL ILPRT DB CR,LF,'Dir eCALL CONST OR AL,AL JNZ GETC OR AL,1 ;NO CHAR, RETN NZ RET ; GETC: CALL CONIN and al,5fh cmp al,'Q' ;a Q will quit jz quit_ret AND AL,1FH ;ALLOW ASCII CMP AL,'S'-40H JNZ L@00048 CALL CONIN L@00048: CMP AL,'['-40H ;AN ESCAPE WILLMOV DUMTYP,AL ;TYPE OF DUMP (A,D,H) ; ;Command dispatcher ; CMP AL,'+' JNZ L@00008 JMP PLUS L@00008: ; CMP AL,'-' JNZ L@00009 JMP MINUS L@00009: ; CMP AL,'=' JNZ L@00010 JMP SEARCH L@00010: ; CMP AL,'<' JNZ L@00011 JMP SAVntries:',9,0 MOV BX,DRM INC BX CALL DEC CALL ILPRT DB CR,LF,'Sys tracks:',9,0 MOV BX,SYSTRK CALL DEC CALL CRLF POP BX JMP PROMPT ; ;The following command resets the disk ;system thru CP/M, and may be usable for ;changing the disk de QUIT JZ QUIT_RET CMP AL,'C'-40H ;AND SO WILL ^C QUIT_RET: RET ;0 SET IF CTL-C,esc ; ;Find our way at initialization ; GETSTP: MOV CL,SUSER ;GET USER NUMBER MOV DL,0FFH ;GET USER CALL BDOS MOV UNUM,AL ;SET USER NUMBER MOV CL,GETE L@00011: ; CMP AL,'>' JNZ L@00012 JMP RESTOR L@00012: ; CMP AL,'#' JNZ L@00013 JMP STATS L@00013: ; CMP AL,'?' JNZ L@00014 JMP HELP L@00014: ; CMP AL,'A' JNZ L@00015 JMP DUMP L@00015: ; CMP AL,'C' JNZ L@00016 JMP Cnsity or format. ;This can only be done if your BIOS resets ;the auto-density select parameters at ;every track-zero access. ; NEWDSK: PUSH BX MOV CL,RESETDK CALL BDOS MOV AL,DRIVE MOV CL,AL POP BX CALL SELECT JMP PROMPT ; ;Quite mode DSK CALL BDOS ;GET CURNT DSK MOV CL,AL ; WE HAVE TO SELECT JMP SELECT ; TO GET THE DPH ; LOGIN: CALL DOLOG JMP PROMPT ; DOLOG: MOV AL,BYTE PTR [BX] ;DISK REQ? MOV DX,OFFSET 0 CMP AL,CR JNZ L@00049 JMP LGNODK L@00049: CMP AL,'!' JHG L@00016: ; CMP AL,'D' JNZ L@00017 JMP DUMP L@00017: ; CMP AL,'F' JNZ L@00018 JMP POSFIL L@00018: ; CMP AL,'G' JNZ L@00019 JMP POS L@00019: ; CMP AL,'H' JNZ L@00020 JMP DUMP L@00020: ; CMP AL,'L' JNZ L@00021 JMP LO ; QUIET: MOV QFLAG,AL ;NOW QUIET JMP PROMPT ; ;Repeat buffer contents ; REPEAT: CALL DECIN ;NN SPECIFIED? MOV AL,DH OR AL,DL JZ NNN ;NO. MOV BX,TOGO INC BX ;TEST FOR FIRST TIME MOV AL,BH OR AL,BL ;WAS IT 0FFFFH? JNZ NNN ;NO: COUNNZ L@00050 JMP LGNODK L@00050: CALL UPCASE INC BX SUB AL,'A' MOV CL,AL ; SELECT: PUSH BX MOV AL,CL ;put drive in AL push cx ;save drive mov dl,0 ;indicate first select CALL SEL ;SELECT DISK THRU BIOS MOV AL,BH OR AL,BL pop cx GIN L@00021: ; CMP AL,'M' JNZ L@00022 JMP MAP L@00022: ; CMP AL,'N' JNZ L@00023 JMP NEWDSK L@00023: ; CMP AL,'P' JNZ L@00024 JMP PRNTFF L@00024: ; CMP AL,'Q' JNZ L@00025 JMP QUIET L@00025: ; CMP AL,'R' JNZ L@00026 JMTING XCHG BX,DX ;GET COUNT MOV TOGO,BX ;SET COUNT ; NNN: MOV BX,TOGO XCHG BX,DX MOV BX,OFFSET INBUF ;READY TO REPEAT INC DX ;TEST FOR 0FFFFH MOV AL,DH OR AL,DL JNZ L@00037 JMP PROMPT ;CONTINOUS L@00037: DEC DX ;COUNT DOWN DEC DX ;M JNZ L@00052 JMP WHAT ;SELECT ERROR L@00052: MOV DRIVE,CL ;REMEMBER LATER WHERE WE ARE ; MOV AX,ES:[BX] ;GET THE SECTOR TABLE PTR MOV SECTBL,AX MOV AX,8 ;IN VER 31 OFFSET IS 8 CMP BYTE PTR CPM_VERSION,31H JAE AX8 MOV AX,10 ;BUT IN VER P DOREAD L@00026: ; CMP AL,'S' JNZ L@00027 JMP POS L@00027: ; CMP AL,'T' JNZ L@00028 JMP POS L@00028: ; CMP AL,'U' ;******CP/M 2.x ONLY****** JNZ L@00029 JMP USER L@00029: ; CMP AL,'V' JNZ L@00030 JMP VIEW L@00030: ; CMPAKE UP FOR PREV INX D XCHG BX,DX MOV TOGO,BX MOV AL,BH ;ALL DONE? OR AL,BL XCHG BX,DX ;GET BACK INBUF PTR JZ L@00038 JMP PROMPT ;NO, KEEP GOING L@00038: JMP PRMPTR ;ALL DONE ; ;Set CP/M 2.x user number ; USER: CALL DECIN ;GET REQUEST11 IT IS 10 BYTES AX8: ADD BX,AX MOV BX,ES:[BX] ;GET DPB PTR ; SELSKP: CALL LOGIT MOV BX,SYSTRK ;RESET TRACK AND SECTOR XCHG BX,DX ; TO DIRECTORY CALL SETTRK ; ON EVERY MOV DX,OFFSET 1 ; LOGIN CALL SETSEC ; CHANGE MOV BX,PHYSEC ;THIS L AL,'W' JNZ L@00031 JMP DORITE L@00031: ; CMP AL,'X' JNZ L@00032 QUIT: CALL ILPRT DB 'Confirm Quiting (Y/N)? ',0 CALL CONIN CALL UPCASE CMP AL,'Y' JE EXIT CALL CRLF JMP PRMPTR ; EXIT: MOV CL,0 MOV DL,0 JMP BDOS ;RETUED USER NO. MOV AL,DL CMP AL,32 ;VALID? JNAE L@00040 JMP WHAT L@00040: MOV AL,DH OR AL,AL JZ L@00041 JMP WHAT L@00041: MOV UNUM,DL ;SAVE IT MOV CL,SUSER PUSH BX ;SAVE CHAR POINTER CALL BDOS ;SET USER NO. POP BX JMP PROMPT ; OGIC WILL TELL MOV AL,BH ; IF FIRST SEC OR AL,BL ; IS PHYSICAL 0 MOV FIRST0,AL cmp byte ptr cpm_version,31h ;if ver 31 then jb no_set_0 ;use first sector=1 mov first0,1 no_set_0: CALL CLCSUB POP BX ; LGNODK: CALL NORITE RET ;RN TO CP/M 86 L@00032: ; CMP AL,'Z' JNZ L@00033 JMP SLEEP L@00033: ; CMP AL,'/' JNZ L@00034 JMP REPEAT L@00034: ; WHAT: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '?',0 JMP PRMPTR ; ;Memory full error ; MEMFUL: XOR AL,AL;Toggle print flag ; PRNTFF: MOV AL,PFLAG XOR AL,1 MOV PFLAG,AL JMP PROMPT ; ;Sleep routine, in tenths of a sec ; SLEEP: CALL HEXIN ;GET COUNT IF ANY MOV AL,DL ;ANY? OR AL,AL JNZ SLEPLP MOV DL,10 ; SLEPLP: MOV CX,OFFSET 10000 MOV !  ;Read in the disk directory ; REDDIR: PUSH BX CALL NORITE ;POSITIONING LOST MOV BX,SYSTRK MOV CURTRK,BX MOV BX,OFFSET 1 MOV CURSEC,BX MOV BX,DRM ;GET DIR SIZE FROM DPB INC BX ; MAKE 1-RELATIVE CALL ROTRHL CALL ROTRHL ;DIVIDE BY 4 (4 NMBER CALL SPACE INC BX ;SKIP USER BYTE PUSH CX MOV CH,8 CALL MAPN2 MOV AL,'.' CALL TYPEOUT MOV CH,3 CALL MAPN2 POP CX CALL SPACE MOV AL,BYTE PTR [BX] ;GET EXT CALL HEX POP BX MOV AL,BYTE PTR [BX] CMP AL,0E5H MOV AL,' ' JP BX JMP PROMPT ; ;Restore the current sector ; RESTOR: MOV AL,SAVEFL OR AL,AL JZ NOSAVE ;NONE TO SAVE PUSH BX MOV BX,OFFSET SAVBUF MOV DX,OFFSET BASE +80H MOV CH,128 CALL MOVE POP BX JMP PROMPT ; NOSAVE: XOR AL,AL MOV QFLAG,ALAMES/SECTOR) MOV CX,BX MOV DX,OFFSET DIRECT ;DMA ADDR ; RDIRLP: PUSH CX PUSH DX MOV CX,DX MOV AL,0F0H ;FORCE MEMORY CMP AL,DH JAE L@00053 JMP MEMFUL L@00053: CALL SETDMA MOV BX,CURTRK XCHG BX,DX CALL SETTRK MOV BX,CURSEC XCHGNZ MPNSP2 MOV AL,']' ; MPNSP2: CALL TYPEOUT ;")" IF ERASED FILE JMP FLIP ; NONAME: CALL ILPRT DB ' ++FREE++ ',0 ; FLIP: MOV AL,TWOUP XOR AL,1 MOV TWOUP,AL JNZ L@00064 JMP CRLF L@00064: ; DELIM: MOV AL,':' CALL TYPEOUT  CALL ILPRT DB '++NO "<" SAVE COMMAND ISSUED' DB CR,LF,0 JMP PRMPTR ; ;Move (HL) to (DE) length in B ; MOVE: MOV AL,BYTE PTR [BX] XCHG BX,DX MOV [BX],AL XCHG BX,DX INC BX INC DX DEC CH JNZ MOVE RET ; MOVEFROMBIOS: MOV AL,ES: BX,DX CALL SETSEC CALL READ CALL NXTSEC POP DX POP CX MOV BX,OFFSET 80H ADD BX,DX XCHG BX,DX DEC CX MOV AL,CH OR AL,CL JNZ RDIRLP MOV CX,OFFSET BASE +80H CALL SETDMA POP BX RET ; ;Map the directory ; MAP: CALL REDDIR ;RJMP SPACE ; ;Print name, length in B ; MAPN2: MOV AL,BYTE PTR [BX] AND AL,7FH ;STRIP POSSIBLE 2.x ATTRIBUTE BIT INC BX CMP AL,' ' ;PRINTABLE? JNAE MAPN2H ;..NO, IN HEX CMP AL,7EH ;7E IS LEADIN ON SOME CRTS JNAE MAPN2A ; MAPN2H: CALL BHEX BYTE PTR [BX] XCHG BX,DX MOV [BX],AL XCHG BX,DX INC BX INC DX DEC CH JNZ MOVEFROMBIOS RET ; NORITE: XOR AL,AL ;GET 0 MOV WRFLG,AL ;CAN'T WRITE NOW RET ; ;No match in search, try next char ; SRNOMT: POP BX CALL CTLCS ;ABORT? JEAD IN DIRECTORY MOV CL,0 ;INIT START GRP # MOV AL,AL0 ;READ DIR GRP BITS CALL COLECT ;COLLECT COUNT OF DIR GRPS.. MOV AL,AL1 ;..IN REGISTER C CALL COLECT MOV CH,0 ;BC NOW HAS A DEFAULT START GRP # CALL HEXIN PUSH BX ;SAVE INBUF PTR MOV A JMP MAPN2Z ; MAPN2A: CALL TYPEOUT ; MAPN2Z: DEC CH JNZ MAPN2 RET ; ;Find which file group (BC) belongs to ; GETGRP: MOV BX,DRM ;MAX DIR ENTRY # INC BX ;MAKE 1-RELATIVE MOV FILECT,BX MOV BX,OFFSET DIRECT ; GETGLP: PUSH BX ;SAVE POINTERNZ SEARCH ;...YES MOV BX,OFFSET INBUF MOV BYTE PTR [BX],CR JMP CLCGRP ;SHOW WHERE STOPPED ; ;Search for character string ; SEARCH: PUSH BX ;SAVE STRING POINTER ; SRCHL: CALL RDBYTE ;GET A BYTE MOV CH,AL ;SAVE IT MOV AL,BYTE PTR [BX] ;CHECK L,DL ;GET START OR AL,DH ;NOTHING? JZ MAPDF ;..YES, DFLT MOV CX,DX ; MAPDF: CALL HEXB MOV AL,'-' CALL TYPEOUT CALL GETGRP ;GET GRP(C) TO HL ; MAPCNT: INC CX ;NEXT GRP # PUSH BX MOV BX,DSM ;GET HIGHEST GRP # INC BX ;PLUS 1 FOR COMPAR TO NAME MOV AL,BYTE PTR [BX] ;PICK UP user number cmp al,20h ! je getgnf ;user must be <20h cmp al,21h ! je getgnf ; MOV DX,OFFSET 14 ;NOW GET RECORD COUNT ADD BX,DX ; S2 PORTION .. MOV AL,BYTE PTR [BX] ; IS 0 IN CP/M 1.4 CMP AL,0E5H JZ NEXT MATCH CHAR. CMP AL,'<' ;WILL IT BE HEX? MOV AL,CH ;RESTORE DISK CHAR JZ SRCHL1 AND AL,7FH ;NEXT CHAR IS ASCII...STRIP BIT 7 ; SRCHL1: LAHF XCHG AL,AH PUSH AX XCHG AL,AH CALL GETVAL ;GET SEARCH VALUE MOV CH,AL POP AX XCHG AL,AH ISON MOV AL,BL ;WHEN BC REACHES DSM+1.. CMP AL,CL ;..THEN WE HAVE EXCEEDED.. JNZ MAPC1 ;.. THE DISK CAPACITY.. MOV AL,BH CMP AL,CH ; MAPC1: POP BX JZ MAPEND ;.. AND WE ARE DONE PUSH BX CALL GETGRP ;GET ANOTHER POP DX ;SEE IF SAME CALLGETGNF AND AL,0FH MOV DL,AL INC BX MOV AL,BYTE PTR [BX] OR AL,DL JZ GETGNF MOV DL,16 ;FIRST SET FOR 8-BIT GRPS MOV AL,BYTE PTR DSM+1 OR AL,AL JZ SMALGP MOV DL,8 ;NOPE, BIG GROUPS ; SMALGP: MOV DH,AL ;SAVE GRP SIZE INDICATOR ; GETG SAHF CMP AL,CH ;MATCH? JNZ SRNOMT ;NO MATCH INC BX MOV AL,BYTE PTR [BX] ;DONE? CMP AL,CR JZ SREQU CMP AL,'!' JNZ SRCHL ; ;Got match SREQU: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '= AT ',0 MOV AL,BYTE PTR BUFAD AND AL,7FH CAL CTLCS JZ MAPND2 MOV AL,DH CMP AL,BH JNZ MAPDIF MOV AL,DL CMP AL,BL JZ MAPCNT ;SAME, CONTINUE ; ;Different file encountered MAPDIF: DEC CX CALL HEXB INC CX XCHG BX,DX CALL MAPNAM JMP MAPDF ; ;End of map ; MAPEND: DEC CX ;L2: INC BX ;POINTING INTO DM FIELD CALL GRPCMP ;COMPARE BC GP # AGAINST 1 DM FLD JZ GETGOT ;JUMP IF FOUND ONE DEC DL ;ELSE COUNT DOWN JNZ GETGL2 ;GO TEST SOME MORE ; GETGNF: POP BX ;NOT THIS ONE MOV DX,OFFSET 32 ;SO GO TO NEXT ADD BX,DX L HEX CALL CRLF JMP CLCGRP ; ;Get value from input buffer ; GETVAL: MOV AL,BYTE PTR [BX] CMP AL,'<' ;HEX ESCAPE? JZ L@00082 RET ;NO, RETURN L@00082: ;"<<" means one "<" INC BX MOV AL,BYTE PTR [BX] CMP AL,'<' JNZ L@00083 RET L@000GET LAST CALL HEXB CALL MAPNAM POP BX CALL CRLF ; ;End of map - reposition to previous group ; MAPND2: PUSH BX MOV BX,GROUP XCHG BX,DX JMP POSGP2 ; ;Print file name pointed to by HL ; MAPNAM: CALL SPACE MOV AL,BH OR AL,BL ;NONE?  XCHG BX,DX MOV BX,FILECT ;THERE IS LIMIT TO EVERYTHING DEC BX MOV FILECT,BX MOV AL,BH OR AL,BL XCHG BX,DX ;RE-ALIGN JNZ GETGLP ; ;Group is not allocated to any file MOV BX,OFFSET 0 ;SAY SO RET ; ;Found the file ; GETGOT: POP BX 83: ;Got hex PUSH DX CALL HEXIN ;GET VALUE CMP AL,'>' ;PROPER DELIM? MOV AL,DL ;GET VALUE POP DX JZ L@00084 JMP WHAT ;ERROR L@00084: RET ; ;Read a byte at a time ; RDBYTE: PUSH BX MOV AL,FTSW ;FIRST READ? OR AL,AL JNZ READ1 MO JZ NONAME MOV AL,BYTE PTR [BX] ;SEE IF ALLOC ; cmp al,20h ! je noname ; cmp al,21h ! je noname CMP AL,0E5H ;FREE? MOV AL,' ' JNZ MPNSP1 MOV AL,'[' ; MPNSP1: CALL TYPEOUT PUSH BX ;SAVE POINTER MOV AL,BYTE PTR [BX] CALL HEX ;SHOW USER NURET ; ;Save the current sector ; SAVE: MOV AL,WRFLG OR AL,AL JNZ L@00074 JMP BADW ;NONE TO SAVE L@00074: PUSH BX MOV BX,OFFSET BASE +80H MOV DX,OFFSET SAVBUF MOV CH,128 CALL MOVE MOV AL,1 ;..SHOW MOV SAVEFL,AL ;..SAVED EXISTS PO! V BX,BUFAD MOV AL,BL OR AL,AL ;IN BUFFER? JS NORD ;YES, SKIP READ ; ;Have to read CALL NXTSEC ; READ1: XOR AL,AL MOV FTSW,AL ;NOT FIRST READ MOV BX,CURSEC XCHG BX,DX CALL SETSEC MOV BX,CURTRK XCHG BX,DX CALL SETTRK CALL READ 0105 CALL SPACE L@00105: MOV AL,DL CMP AL,BL JZ DPOP INC BX MOV AL,BL AND AL,0FH JNZ DHEX ; DPOP: CALL CTLCS JNZ L@00108 JMP PRMPTR L@00108: MOV AL,DUMTYP CMP AL,'H' JZ DNOAS ;HEX ONLY POP BX ;GET START ADDR ; DUMPAS: CALL RCR AL,1 RCR AL,1 LAHF XCHG AL,AH PUSH AX XCHG AL,AH AND AL,BH MOV GRPDIS,AL POP AX XCHG AL,AH SAHF ; POSDLP: RCR AL,1 DEC BL JNZ POSDLP AND AL,1 ;GET GROUP MOV BL,AL ;SETUP FOR POSGP2 MOV BH,0 MOV GROUP,BX XCHG BX,DX  CALL CLCSUB MOV BX,OFFSET BASE +80H ; NORD: MOV AL,BYTE PTR [BX] INC BX MOV BUFAD,BX POP BX RET ; ;View the file in ASCII starting at ;current sector, stepping thru the disk ; VIEW: MOV AL,WRFLG OR AL,AL JNZ L@00087 JMP BADDMP L@00 ASTER ; DCHR: MOV AL,BYTE PTR [BX] AND AL,7FH CMP AL,' ' JNAE DPER CMP AL,7EH JNAE DOK ; DPER: MOV AL,'.' ; DOK: CALL TYPEOUT MOV AL,DL CMP AL,BL JZ DEND INC BX MOV AL,BL AND AL,0FH JNZ DCHR ; DEND: CALL ASTER CALL CRLF  JMP POSGP2 ;POSITION TO IT ; POSGPH: CALL HEXIN ; POSGRP: PUSH BX MOV BX,DSM CALL SUBDE POP BX JAE L@00127 JMP OUTLIM L@00127: XCHG BX,DX MOV GROUP,BX XCHG BX,DX XOR AL,AL MOV GRPDIS,AL PUSH BX ; POSGP2: CALL GTKSEC CALL S087: CALL HEXIN ;GET DISPL IF ANY PUSH BX MOV AL,DL OR AL,AL JNZ VIEWLP INC DL ;DFLT=1 ; VIEWLP: MOV BX,OFFSET BASE +80H ;TO DATA ; VEWCHR: CALL CTLCS JZ VEWEND MOV AL,BYTE PTR [BX] CMP AL,1AH JZ VEWEOF AND AL,7FH CMP AL,7EH J PUSH DX CALL CTLCS POP DX JNZ L@00114 JMP PRMPTR L@00114: MOV AL,DL CMP AL,BL JZ L@00115 JMP DUMPLP L@00115: POP BX JMP PROMPT ; DNOAS: POP CX CALL CRLF MOV AL,DL CMP AL,BL JZ L@00116 JMP DUMPLP L@00116: POP BX JMP PETTRK XCHG BX,DX inc dx CALL SETSEC CALL READ XOR AL,AL MOV NOTPOS,AL ;NOW POSITIONED POP BX JMP INQ ; GTKSEC: MOV BX,DX ;BX = number of blocks mov cl,BSH mov ax,1 shl ax,cl ;AX=2^BSH xor dx,dx ;clear DX register mul bx AE VIEWHX ;SHOW RUBOUT AND TILDE AS HEX CMP AL,' ' JAE VIEWPR CMP AL,CR JZ VIEWPR CMP AL,LF JZ VIEWPR CMP AL,TAB JZ VIEWPR ; VIEWHX: MOV AL,BYTE PTR [BX] ;NOT ASCII...PRINT AS CALL BHEX JMP VIEWNP ; VIEWPR: CALL TYPEOUT ; VIEROMPT ; ;Position ; POS: LAHF XCHG AL,AH PUSH AX XCHG AL,AH MOV AL,BYTE PTR [BX] CMP AL,'!' JZ POSINQ CMP AL,CR JNZ POSOK ; POSINQ: POP AX XCHG AL,AH SAHF JMP INQ ; POSOK: POP AX XCHG AL,AH SAHF CMP AL,'T' JZ POSTKD ;AX*BX=hi 16 bits in DX, lo in AX xor bx,bx mov bl,GRPDIS add ax,bx ;add in GRPDIS adc dx,0 ;with carry into DX ; ;Divide by nbr of sectors, quotient=track, remainder=sector ;NOTE for O/S = ver 3.1+, SPT is in 128 byte units, not phy sectors ; WNP: INC BL JNZ VEWCHR DEC DL JZ VEWEND PUSH DX ;SAVE COUNT CALL NXTSEC MOV BX,CURSEC XCHG BX,DX CALL SETSEC MOV BX,CURTRK XCHG BX,DX CALL SETTRK CALL READ POP DX ;RESTORE COUNT JMP VIEWLP ; VEWEOF: CALL ILPRT DB CR,LF,TAB,'CMP AL,'S' JZ POSSCD CMP AL,'G' JNZ L@00121 JMP POSGPH L@00121: JMP WHAT ; POSTKD: CALL DECIN ; POSTRK: PUSH BX MOV BX,MAXTRK CALL SUBDE POP BX JAE L@00122 JMP OUTLIM L@00122: CALL SETTRK CALL NORITE ;TRACK DOESN'T READ MOV  divide2: div Word Ptr SPT ;DX:AX/SPT=AX(quotent)=track, DX(remainder)=sector add ax,SYSTRK ;add in track offset mov bx,dx ;and get stuff into proper registers mov dx,ax ;for the return or bx,bx ;don't allow a zero sector number ret ; POSFIL:++EOF++',CR,LF,0 ; VEWEND: POP BX CALL CRLF JMP CLCGRP ; ;Dump in hex or ASCII ; DUMP: MOV AL,WRFLG OR AL,AL JNZ DUMPOK ; BADDMP: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++Can''t dump, no sector read.',CR,LF,0 ; EXPL: XOR AL,AL MOVAL,1 MOV NOTPOS,AL ;SHOW NOT POSITIONED JMP CLCGRP ; POSSCD: CALL DECIN MOV AL,DH OR AL,DL JNZ L@00123 JMP WHAT ;DON'T ALLOW SECTOR 0 L@00123: ; POSSEC: PUSH BX MOV BX,SPT CALL SUBDE POP BX JAE L@00124 JMP WHAT L@00124: CALL  CALL NORITE MOV AL,1 MOV FINDFL,AL ;SO WE POSITION LATER MOV DX,OFFSET FCB XOR AL,AL ;LOGGED IN DISK XCHG BX,DX MOV [BX],AL XCHG BX,DX INC DX MOV CH,8 CALL MVNAME MOV CH,3 CALL MVNAME MOV DX,OFFSET FCB MOV CL,SRCHF PUSH BX  QFLAG,AL CALL ILPRT DB 'Use G command following F,',CR,LF DB 'or R or S following T',CR,LF,0 JMP PRMPTR ; DUMPOK: MOV AL,BYTE PTR [BX] CMP AL,'!' JZ DUMPDF ;DFLT CMP AL,CR JNZ DMPNDF ; ;Use default DUMPDF: MOV CX,OFFSET BASE +80H MSETSEC CALL READ XOR AL,AL MOV NOTPOS,AL ;POSITIONED OK ; CLCGRP: CALL CLCSUB JMP INQ ; ;Calculate group from track and sector ; CLCSUB: push bx mov ax,CURTRK mov bx,SYSTRK cmp bx,ax ! ja a_systrack sub ax,SYSTRK a_systrack: xor d CALL BDOS INC AL JNZ FLOK MOV DIRPOS,AL ;GRP 0 IF NOT FOUND CALL ILPRT DB '++FILE NOT FOUND',CR,LF,0 POP BX JMP PROMPT ; FLOK: DEC AL MOV DIRPOS,AL ;SAVE POS. IN DIR AND AL,3 MOV BL,AL MOV BH,0 ADD BX,BX ADD BX,BX ADD BX,BXOV DX,OFFSET 0FFH JMP DUMP1 ; DMPNDF: CALL DISP MOV CX,DX CMP AL,CR JZ DUMP1 CMP AL,'!' JZ DUMP1 INC BX ;SKIP ',' CALL DISP ; ;BC = start, DE = end ; DUMP1: PUSH BX ;SAVE COMMAND POINTER MOV BX,CX ; DUMPLP: MOV AL,BL AND AL,7FH x,dx mul SPT ;TRK*SPT=hi bits in DX lo bits in AX mov bx,CURSEC dec bx add ax,bx ;add in cursec - 1 adc dx,0 divide1: mov bx,1 mov cl,BSH shl bx,cl ;BX = 2^BSH div bx ;DX:AX=((CURTRK-SYSTRK)*SPT+CURSEC-1)/(2^BSH) mov group,ax ;AX=q ADD BX,BX ADD BX,BX MOV DX,OFFSET BASE +80H ADD BX,DX MOV DX,OFFSET 32 XCHG BX,DX ADD BX,DX XCHG BX,DX MOV AL,'D' MOV DUMTYP,AL JMP DUMPLP ;WHICH POPS H ; MVNAME: MOV AL,BYTE PTR [BX] CMP AL,'.' JZ MVIPAD CMP AL,CR JZ PAD  CALL HEX CALL SPACE CALL SPACE MOV AL,DUMTYP CMP AL,'A' JZ DUMPAS PUSH BX ;SAVE START ; DHEX: MOV AL,BYTE PTR [BX] CALL HEX MOV AL,BL AND AL,3 CMP AL,3 JNZ L@00104 CALL SPACE L@00104: MOV AL,BL AND AL,7 CMP AL,7 JNZ L@0uotent, DX=remainder mov GRPDIS,dl pop bx ret ; ;Position in the dorectory after a find ;(Does not work in CP/M-2.x) ; POSDIR: PUSH BX ;SAVE INBUF MOV BX,WORD PTR BSH XOR AL,AL MOV FINDFL,AL ;CANCEL POS REQ MOV AL,DIRPOS ;GET POSITION "  CMP AL,'!' JZ PAD CALL UPCASE XCHG BX,DX MOV [BX],AL XCHG BX,DX INC BX INC DX DEC CH JNZ MVNAME MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00135 RET L@00135: CMP AL,'!' JNZ L@00136 RET L@00136: INC BX CMP AL,'.' JNZ L@00 DB ' T=',0 MOV BX,CURTRK CALL DEC CALL ILPRT DB ', S=',0 MOV BX,CURSEC CALL DEC CALL ILPRT DB ', PS=',0 MOV BX,PHYSEC CALL DEC CALL CRLF POP BX RET ; CHG: MOV AL,BYTE PTR [BX] ;GET TYPE (HEX, ASCII) CALL UPCASE LAHF XCHG JNZ L@00171 JMP PROMPT L@00171: CMP AL,'!' JNZ L@00172 JMP PROMPT L@00172: JMP WHAT ; DOREAD: MOV AL,NOTPOS OR AL,AL JNZ CANTRD CALL READ JMP PROMPT ; CANTRD: XOR AL,AL MOV QFLAG,AL ;NOT QUIET CALL ILPRT DB '++Can''t read - n137 RET L@00137: JMP WHAT ; MVIPAD: INC BX ; PAD: MOV AL,' ' XCHG BX,DX MOV [BX],AL XCHG BX,DX INC DX DEC CH JNZ PAD RET ; PLUS: MOV DX,OFFSET 1 ;DFLT TO 1 SECT MOV AL,BYTE PTR [BX] ;GET NEXT CHAR CMP AL,CR ;CR? JZ PLUSGO ;AL,AH PUSH AX XCHG AL,AH ;SAVE "H" OR "A" INC BX CALL DISP ;GET, VALIDATE DISP TO DE INC BX MOV CX,OFFSET 0 ;SHOW NO 'THRU' ADDR CMP AL,'-' ;TEST DELIM FR. DISP JNZ CHGNTH ;NO THRU PUSH DX ;SAVE FROM CALL DISP ;GET THRU INC BX ;SKIP Eot positioned',CR,LF DB 'Position by:',CR,LF DB 9,'Track then Sector, or',CR,LF DB 9,'Group',CR,LF,0 JMP PROMPT ; DORITE: CALL WRITE JMP PROMPT ; BHEX: LAHF XCHG AL,AH PUSH AX XCHG AL,AH MOV AL,'<' CALL TYPEOUT POP AX XCHG AL,AH.. YES, DFLT TO 1 CMP AL,'!' JZ PLUSGO CALL HEXIN ;GET # MOV AL,DH OR AL,DL JNZ L@00141 JMP WHAT L@00141: ; PLUSGO: CALL NXTSEC DEC DX ;MORE TO GO? MOV AL,DH OR AL,DL JNZ PLUSGO ;..YES ; ;Ok, incremented to sector. Setup and reaND DELIM MOV CX,DX ;BC = THRU POP DX ;GET FROM JMP CHGAH ; CHGNTH: CMP AL,',' JZ L@00153 JMP WHAT L@00153: ; CHGAH: POP AX XCHG AL,AH SAHF CMP AL,'H' JNZ L@00154 JMP CHGHEX L@00154: CMP AL,'A' JZ L@00155 JMP WHAT L@00155:  SAHF CALL HEX MOV AL,'>' CALL TYPEOUT RET ; HEXB: MOV AL,BYTE PTR DSM+1 OR AL,AL JZ HEXX MOV AL,CH CALL HEX ; HEXX: MOV AL,CL ; HEX: LAHF XCHG AL,AH PUSH AX XCHG AL,AH RCR AL,1 RCR AL,1 RCR AL,1 RCR AL,1 CALL NIBBL d ; PLUSMI: PUSH BX MOV BX,CURSEC XCHG BX,DX CALL SETSEC MOV BX,CURTRK XCHG BX,DX CALL SETTRK POP BX CALL READ JMP CLCGRP ; MINUS: MOV DX,OFFSET 1 ;SET DFLT MOV AL,BYTE PTR [BX] ;GET CHAR CMP AL,CR ;CR? JZ MINGO ;.. YES, DFLT=1 ; ;Change ASCII CHGALP: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00156 JMP PROMPT L@00156: CMP AL,'!' JNZ L@00157 JMP PROMPT L@00157: XCHG BX,DX MOV AL,[BX] XCHG BX,DX CMP AL,' ' JNAE CHGAHX CMP AL,7EH JAE CHGAHX JMP CHGA2 ; C POP AX XCHG AL,AH SAHF ; NIBBL: AND AL,0FH CMP AL,10 JNAE HEXNU ADD AL,7 ; HEXNU: ADD AL,'0' JMP TYPEOUT ; ;Decimal output routine ; DEC: PUSH CX PUSH DX PUSH BX MOV CX,-OFFSET 10 MOV DX,-OFFSET 1 ; DECOU2: PUSHF ADD BX,CX CMP AL,'!' JZ MINGO CALL HEXIN ;..NO, GET ## MOV AL,DH OR AL,DL JNZ L@00145 JMP WHAT L@00145: ; MINGO: PUSH BX MOV BX,CURSEC DEC BX MOV AL,BH OR AL,BL JNZ MINOK MOV BX,CURTRK MOV AL,BH OR AL,BL JNZ SEASH MOV BX,MAXTRK ;HGAHX: CALL BHEX JMP CHGA3 ; CHGA2: CALL TYPEOUT ; CHGA3: MOV BACK,BX ;IN CASE "THRU" CALL GETVAL ;ASCII OR XCHG BX,DX MOV [BX],AL XCHG BX,DX ;UPDATE CHAR INC BX ;TO NEXT INPUT CHAR ;See if 'THRU' requested MOV AL,CL OR AL,AL J RCR SI,1 POPF RCL SI,1 PUSHF INC DX POPF JNAE DECOU2 MOV CX,OFFSET 10 ADD BX,CX XCHG BX,DX MOV AL,BH OR AL,BL JZ L@00177 CALL DEC L@00177: MOV AL,DL ADD AL,'0' CALL TYPEOUT POP BX POP DX POP CX RET ; SPACE: MOVWRAP TO END OF DISK MOV CURTRK,BX MOV BX,MAXSEC JMP MINOK ; SEASH: DEC BX MOV CURTRK,BX MOV BX,SPT ; MINOK: MOV CURSEC,BX POP BX DEC DX MOV AL,DH OR AL,DL JNZ MINGO JMP PLUSMI ; ;Go to next sector ; NXTSEC: PUSH BX PUSH DXZ CHANTH CMP AL,DL ;DONE?.. JNZ L@00161 JMP PROMPT ;..YES L@00161: MOV BX,BACK ; CHANTH: INC DL JZ L@00162 JMP CHGALP L@00162: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00163 JMP PROMPT L@00163: CMP AL,'!' JNZ L@00164 JMP PROMPT  AL,' ' JMP TYPEOUT ; ASTER: MOV AL,'*' JMP TYPEOUT ; ;Inline print routine ; ILPRT: POP SI XCHG BX,SI PUSH SI ; ILPLP: CALL CTLCS ;ABORT? JNZ L@00178 JMP PRMPTR L@00178: MOV AL,BYTE PTR [BX] CMP AL,1 ;PAUSE? JNZ ILPOK CALL CON MOV BX,CURSEC INC BX XCHG BX,DX MOV BX,SPT CALL SUBDE XCHG BX,DX JAE NEXTOK MOV BX,CURTRK INC BX XCHG BX,DX MOV BX,MAXTRK CALL SUBDE JAE TRASK MOV DX,OFFSET 0 ;WRAP TO START OF DISK ; TRASK: XCHG BX,DX MOV CURTRK,BX MOV BL@00164: JMP WHAT ; ;Change hex ; CHGHCM: INC BX ; CHGHEX: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00165 JMP PROMPT L@00165: CMP AL,'!' JNZ L@00166 JMP PROMPT L@00166: CMP AL,',' ;DELIM? JZ CHGHCM PUSH DX MOV HEXAD,BX ;IN CASE IN CMP AL,1bh ! je il_abort ;escape CMP AL,'Q'-40h ! je il_abort ;^Q CMP AL,'C'-40h ! je il_abort ;^C=ABORT? JMPS L@00180 IL_ABORT: JMP PRMPTR L@00180: JMP ILPNX ; ILPOK: CALL TYPEOUT ; ILPNX: INC BX MOV AL,BYTE PTR [BX] OR AL,AL X,OFFSET 1 ; NEXTOK: MOV CURSEC,BX POP DX POP BX RET ; ;Tell what group, displacement, track, sector, physical sector ; INQ: CALL INQSUB JMP PROMPT ; ;Position inquiry subroutine ;Executed via: G S or T (with no operands) ; INQSUB: PUSH 'THRU' CALL HEXIN ;POSITIONS TO DELIM MOV AL,DL ;GET VALUE POP DX ;..ADDR LAHF XCHG AL,AH PUSH AX XCHG AL,AH ;SAVE VALUE XCHG BX,DX MOV AL,[BX] XCHG BX,DX ;GET OLD CALL HEX ;ECHO IN HEX POP AX XCHG AL,AH SAHF ;GET NEW XCHG BX, JNZ ILPLP INC BX POP SI XCHG BX,SI PUSH SI RET ; ;DISP calls HEXIN, and validates a sector ;displacement, then converts it to an address ; DISP: CALL HEXIN LAHF XCHG AL,AH PUSH AX XCHG AL,AH ;SAVE DELIMITER MOV AL,DH OR AL,AL BX MOV BX,SYSTRK XCHG BX,DX MOV BX,CURTRK CALL SUBDE JNAE NOGRP CALL ILPRT DB 'G=',0 MOV BX,GROUP MOV CH,BH MOV CL,BL CALL HEXB MOV AL,':' CALL TYPEOUT MOV AL,GRPDIS CALL HEX MOV AL,',' CALL TYPEOUT ; NOGRP: CALL ILPRT DX MOV [BX],AL XCHG BX,DX ;SAVE NEW MOV AL,CL ;SEE IF 'THRU' OR AL,AL JZ CHHNTH ;..NO. CMP AL,DL ;..YES, DONE? JNZ L@00169 JMP PROMPT L@00169: MOV BX,HEXAD ;..NO: MORE ; CHHNTH: INC DL JNZ CHGHEX MOV AL,BYTE PTR [BX] CMP AL,CR " JNZ BADISP MOV AL,DL OR AL,AL JS BADISP ADD AL,80H ;TO POINT TO BUFFER AT BASE+80H MOV DL,AL MOV DH,BASE/256 POP AX XCHG AL,AH SAHF ;GET DELIM RET ; BADISP: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++BAD DISPLACEMENT (NOT 0-7F)' QUIT: ; CMP AL,' ' JNAE RDBLP ; MOV BYTE PTR [BX],AL INC BX INC CH JS FULL CALL TYPEOUT JMP RDBLP ; FULL: DEC CH PUSHF DEC BX POPF MOV AL,'*' ;SIGNAL WE'RE FULL CALL TYPEOUT JMP RDBLP ; ;Got CR ; RDCR: MOV BYTE PTR [BX], TYPLST ; TYPNCR: CMP AL,' ' ;CTL CHAR? JNAE TYPLST ;..NO CGANGE IN COL MOV AL,TABCOL INC AL MOV TABCOL,AL ; TYPLST: MOV AL,PFLAG AND AL,1 JZ L@00221 CALL LISTOUT ;FROM C REG. L@00221: ; TYPRET: POP BX POP DX POP CX RET ; LIST DB CR,LF,0 JMP PRMPTR ; HEXIN: MOV DX,OFFSET 0 MOV AL,BYTE PTR [BX] CMP AL,'#' ;DECIMAL? JZ HDIN ;MAKE DECIMAL ; HINLP: MOV AL,BYTE PTR [BX] CALL UPCASE CMP AL,CR JNZ L@00185 RET L@00185: CMP AL,'!' JNZ L@00186 RET L@00186: AL ;SAVE IT CALL TYPEOUT ;ECHO IT MOV AL,LF ;ECHO.. CALL TYPEOUT ;..LF MOV BX,OFFSET INBUF RET ; ;Got DELETE or BS, echo if BS ; RDBS: XOR AL,AL ;AT FRONT.. OR AL,CH ;..OF LINE? JZ RDCTLU ;.. YES, ECHO ^U DEC BX DEC CH MOV AL,CL COUT: ;enter char in CL mov dl,cl ;put char in DL mov cl,L_WRITE ;write to default list device CALL BDOS ;LIST TO PRINTER THRU BDOS RET ; HOME: PUSH BX CALL BHOME ;HOME DRIVE THRU BIOS POP BX RET ; ;Set track # in DE ; SETTRK: PUSH BX CMP AL,',' JNZ L@00187 RET L@00187: CMP AL,'-' ;'THRU'? JNZ L@00188 RET L@00188: CMP AL,'>' JNZ L@00189 RET L@00189: INC BX CMP AL,'0' JAE L@00190 JMP WHAT L@00190: CMP AL,'9'+1 JNAE HINNUM CMP AL,'A' JAE L@00192 JMP WMP AL,'H'-40H ;BS? JZ BACKUP ;ECHO THE BS MOV AL,BYTE PTR [BX] ;ECHO.. CALL TYPEOUT ;..DELETED CHAR JMP RDBLP ; BACKUP: CALL WIPER JMP RDBLP ; RDCTLX: INC CH ; RDCX1: DEC CH JZ RDBF1 CALL WIPER JMP RDCX1 ; WIPER: PUSH CX PUSH DX  MOV BX,MAXTRK CALL SUBDE POP BX JNAE OUTLIM XCHG BX,DX MOV CURTRK,BX XCHG BX,DX MOV CX,DX PUSH BX CALL TRK ;SET TRACK THRU BIOS POP BX RET ; SETSEC: PUSH BX PUSH DX MOV BX,SYSTRK XCHG BX,DX MOV CURSEC,BX MOV BX,CURTRK HAT L@00192: CMP AL,'F'+1 JNAE L@00193 JMP WHAT L@00193: SUB AL,7 ; HINNUM: SUB AL,'0' XCHG BX,DX ADD BX,BX ADD BX,BX ADD BX,BX ADD BX,BX ADD AL,BL MOV BL,AL XCHG BX,DX JMP HINLP ; HDIN: INC BX ;SKIP '.' ; DECIN: MOV DX, PUSH BX MOV DX,OFFSET BSMSG ;BACKSPACE, SPACE, BACKSPACE MOV CL,PRINT CALL BDOS POP BX POP DX POP CX RET ; BSMSG DB BS,' ',BS,'$' ; ;Got CTL-R, retype ; RDCTLR: MOV BYTE PTR [BX],CR CALL CRLF MOV BX,OFFSET INBUF MOV CH,0 ; RDCRCALL SUBDE POP CX MOV BX,CX JAE NOTSYS MOV AL,FIRST0 ;SEE IF FIRST SEC 0 OR AL,AL JNZ GSTSEC ;NO, JUMP AWAY DEC BX ;YES, SO DECREMENT JMP GSTSEC ; REQUESTED, THEN GO ; NOTSYS: MOV BX,SECTBL XCHG BX,DX DEC CX CALL BSECTTRAN MOV ALOFFSET 0 ; DINLP: MOV AL,BYTE PTR [BX] CALL UPCASE CMP AL,CR JNZ L@00194 RET L@00194: CMP AL,'!' JNZ L@00195 RET L@00195: CMP AL,',' JNZ L@00196 RET L@00196: CMP AL,'-' ;'THRU'? JNZ L@00197 RET L@00197: INC BX CMP AL,'0'L: MOV AL,BYTE PTR [BX] CMP AL,CR JNZ L@00211 JMP RDBLP L@00211: CALL TYPEOUT INC CH INC BX JMP RDCRL ; ;Got CTL-U or backup to beginning of line. ; RDCTLU: MOV AL,'^' CALL TYPEOUT MOV AL,'U' CALL TYPEOUT JMP RDBUF ; CRLF: MOV ,BYTE PTR SPT+1 ;IF SPT<256 (HI-ORD = 0) OR AL,AL ; THEN FORCE 8-BIT TRANSLATION JNZ VSCTR1 ; ELSE KEEP ALL 16 BITS MOV BH,AL VSCTR1: GSTSEC: MOV PHYSEC,BX cmp byte ptr cpm_version,31h jb aint31 mov bx,cursec ;version 31 does it's own xla JAE L@00198 JMP WHAT L@00198: CMP AL,'9'+1 JNAE L@00199 JMP WHAT L@00199: SUB AL,'0' PUSH BX MOV BH,DH MOV BL,DL ADD BX,BX ADD BX,BX ADD BX,DX ADD BX,BX ADD AL,BL MOV BL,AL MOV AL,BH ADC AL,0 MOV BH,AL XCHG BX,DX AL,CR CALL TYPEOUT MOV AL,LF JMP TYPEOUT ; UPCASE: CMP AL,60H JNB L@00212 RET L@00212: AND AL,5FH ;MAKE UPPER CASE RET ; CONST: PUSH CX PUSH DX PUSH BX CALL BCONST ;GET CONSOLE STATUS USING BIOS CALL POP BX POP DX POP CX REte, use cursec aint31: MOV CX,BX CALL SEC ;SET SECTOR THRU BIOS POP BX RET ; OUTLIM: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++not within tracks 0-',0 PUSH BX MOV BX,MAXTRK CALL DEC POP BX CALL ILPRT DB '++' DB CR,LF,0 CALL POP BX JMP DINLP ; ;Read in a console buffer full ; RDBUF: ;PRINT PROMPT AS DU nnA: CALL ILPRT DB CR,LF,'DU ',0 ;SAY WHO WE ARE MOV AL,UNUM CMP AL,0 ! JZ DONT_0 MOV BL,AL ;DISPLAY USER NUMBER MOV BH,0 CALL DEC ;PRINT IN DECIMAL T ; CONIN: PUSH CX PUSH DX PUSH BX CALL BCONIN ;GET CONSOLE CHAR FROM BIOS POP BX POP DX POP CX RET ; ;Console out with TAB expansion ; Enter: char in AL ; TYPEOUT: PUSH CX PUSH DX PUSH BX MOV CL,AL ;FOR OUTPUT ROUTINE CMP ALNORITE JMP PRMPTR ; SETDMA: CALL DMA ;SET UP DMA FOR BIOS MOV CX,CS ;SET DMA SEGMENT FOR BIOS JMP SETDMAB ; ; READ: MOV AL,1 MOV WRFLG,AL PUSH BX CALL DSKREAD ;READ DISK THRU BIOS OR AL,AL JZ READOK XOR AL,AL MOV QFLAG,AL CALDONT_0: MOV AL,DRIVE ;GET DRIVE NUMBER ADD AL,'A' ;CONVERT TO ASCII CALL TYPEOUT CALL ILPRT ;PRINT THE PROMPT DB ': ',0 ; RDBF1: MOV BX,OFFSET INBUF MOV CH,0 ; RDBLP: CALL CONIN MOV CL,AL ;SAVE FOR BS TEST ; ;Evaluate control charact,TAB JNZ TYPE2 ; TYPTAB: MOV AL,' ' CALL TYPEOUT MOV AL,TABCOL AND AL,7 JNZ TYPTAB JMP TYPRET ; ;Filter out control characters to ;prevent garbage during view of file ; TYPE2: CMP AL,' ' JAE TYPEQ CMP AL,CR JZ TYPEQ CMP AL,LF JL ILPRT DB '++READ failed, sector may be invalid++' DB CR,LF,0 ; READOK: POP BX RET ; WRITE: MOV AL,WRFLG OR AL,AL JNZ PWRITE ; BADW: XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++CANNOT WRITE UNLESS READ ISSUED' DB CR,LF,0 JMP EXPL ;ers ; CMP AL,'U'-40H JNZ L@00200 JMP RDCTLU L@00200: ; CMP AL,CR JZ RDCR ; CMP AL,'H'-40H JZ RDBS ; CMP AL,7FH JZ RDBS ; CMP AL,'R'-40H JZ RDCTLR ; CMP AL,'X'-40H JZ RDCTLX CMP AL,'['-40H JNE NO_QUIT JMP QUIT NO_NZ TYPNCR ; TYPEQ: MOV AL,QFLAG OR AL,AL VCONOT: JNZ L@00218 PUSH CX CALL BCONOUT ;CONSOLE OUT THRU BIOS POP CX L@00218: ; ;Update column used in tab expansion MOV AL,CL ;GET CHAR CMP AL,CR JNZ TYPNCR MOV AL,0 MOV TABCOL,AL JMP#  PWRITE: PUSH BX MOV CL,1 ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED CALL DSKWRITE ;WRITE DISK OR AL,AL JZ WRITOK XOR AL,AL MOV QFLAG,AL CALL ILPRT DB '++WRITE failed++',CR,LF,0 ; WRITOK: POP BX RET ; ;Help ; HELP: CALL ILPRT cel a function with ESC or Ctl-C.' DB CR,LF DB 'Suspend output with S or Ctl-S.' DB CR,LF DB 'Separate commands with "!".' DB CR,LF DB ' Example: g0' DB CR,LF DB ' +!d!z#20!/' DB CR,LF DB ' would step in, dump, sleep 2EPEAT COUNT (FFFF=CONT) TWOUP DB 0 PFLAG DB 0 ;1=PRINT GROUP DW 0 GRPDIS DB 0 SAVEFL DB 0 CURTRK DW 0 CURSEC DW 1 PHYSEC DW 1 TABCOL DB 0 FILECT DW 0 DIRPOS DB 0 FINDFL DB 0 ;1=MUST POSITION AFTER FIND FTSW DB 1 ;SEARCH W/O INCREMENT NOTPOS DDB 'Operands in brackets [...] are optional' DB CR,LF DB 'Numeric values: ''n'' are decimal, ''x'' hex' DB CR,LF,CR,LF DB '+[n] step in [n] sectors;' DB CR,LF DB '-[n] step out [n] sectors' DB CR,LF DB '# print disk parameters for  sec, ' DB CR,LF DB ' and repeat until control-c typed.' DB CR,LF DB 'All "nn" usage except "/", "T", and "S" are' DB CR,LF DB ' HEX. Use #nn for decimal.' DB CR,LF,CR,LF DB 'See DU.DOC for complete examples.' DB CR,LF,CR,LFB 1 ;INITIALLY NOT POSITIONED WRFLG DB 0 ;MAY NOT WRITE UNTIL '+', '-', ; OR 'G' COMMAND QFLAG DB 0 ;QUIET? (0=NO) FIRST0 DB 0 ;SETS TO 0 IF FIRST SEC # IS 0 UNUM DB 0 ;USER NUMBER DRIVE DB 0 MAXTRK DW 0 MAXSEC DW 0 SECTBL DW 0 ;POINTER TO SECTcurr drive.' DB CR,LF DB '=xxx search for ASCII xxx from curr sector.' DB CR,LF DB ' Caution: upper/lower case matters.' DB CR,LF DB ' Use for hex:' DB CR,LF DB ' To find "IN AL,0C0h" use: = or' DB CR,,0 JMP PROMPT ; ;******************************** ;* * ;* Utility Subroutines * ;* * ;******************************** ; GRPCMP: MOV AL,CL INC DH DEC DH JZ CMP8 CMP AL,BYTE PTR [BX] PUSHF INC BX POPF JZ L@00231 RET L@0OR SKEW TABLE ; BACK RW 1 ;TO BACK UP IN "CA0-7F,X" DUMTYP RS 1 ; ;-------------------------------------------------- bios_call_tbl rw 1 ;address of bios call table goes here table11 dw offset select_disk11 ;direct bios calls for cp/m-11 dw LF DB ' "(tab)H,0(CR)(LF)" use: =<9>H,0' DB CR,LF DB '< save current sector into mem. buff.' DB CR,LF DB '> restore saved sector' DB CR,LF DB '? give help' DB CR,LF DB 'A[ff,tt] ASCII dump' DB CR,LF,CR,LF DB0231: MOV AL,CH ; CMP8: CMP AL,BYTE PTR [BX] RET ; ;2's complement HL ==> HL ; NEG: NOT BX PUSHF INC BX POPF RET ; ;HL/2 ==> HL ; ROTRHL: OR AL,AL MOV AL,BH RCR AL,1 MOV BH,AL MOV AL,BL RCR AL,1 MOV BL,AL RET ; ;Colloffset set_track11 dw offset set_dmaseg11 dw offset set_dmaoff11 dw offset set_sector11 dw offset read_sector11 dw offset write_sector11 dw offset sector_xlat11 dw offset home_disk11 table31 dw offset select_disk31 ;direct bios calls '(Type SP bar to continue)' DB 1,CR,LF,CR,LF DB 'C Change:' DB CR,LF DB ' CHaddr,byte,byte... (hex)' DB CR,LF DB ' or CAaddr,data... (Ascii)' DB CR,LF DB ' Allowed for imbedded hex.' DB CR,LF DB ' or CHfromect the number of '1' bits ;in A as a count in C ; COLECT: MOV CH,8 ; COLOP: RCL AL,1 JAE COSKIP INC CL ; COSKIP: DEC CH JNZ COLOP RET ; ;HL-DE ==> HL ; SUBDE: SUB BX,DX RET ; ;Quick Kludge multiply ;HL=DE ==> HL ; MULT: PUSH CX for cp/m-31 dw offset set_track31 dw offset set_dmaseg31 dw offset set_dmaoff31 dw offset set_sector31 dw offset read_sector31 dw offset write_sector31 dw offset sector_xlat31 dw offset home_disk31 bpb rs 0 ;bios parameter block-thru,byte e.g. ch0-7f,e5' DB CR,LF DB ' or CAfrom-thru,byte' DB CR,LF DB 'D[ff,tt] Dump (hex+ASCII)' DB CR,LF DB 'Fn.t Find file' DB CR,LF DB 'Gnn CP/M Allocation Group nn' DB CR,LF DB 'H[ff,tt] hex dump' DB CR,LF DB PUSH DX XCHG BX,DX MOV CX,DX MOV AL,CH OR AL,CL JNZ MULCON MOV BX,OFFSET 0 ;FILTER SPECIAL CASE JMP MLDONE ; OF MULTIPLY BY 0 ; MULCON: DEC CX MOV DX,BX ; MULTLP: MOV AL,CH OR AL,CL JZ MLDONE ADD BX,DX DEC CX JMP MULTLP  bpb_func rb 1 ;for direct bios call 50 bpb_cx rw 1 bpb_dx rw 1 cpm_version dw 0 ;cpm version sysaddr dw 0 ;SYSDAT addr udaaddr dw 0 ;process UDA addr imcnt db 1 ;multi-sector count (preset to 1) idrive rb 1 ;drive number (a:=0)  'L Log in drive' DB CR,LF DB 'Lx Log in drive x' DB CR,LF DB 'M[nn] Map [from group nn]' DB CR,LF,CR,LF DB '(Type SP bar to continue)' DB 1,CR,LF,CR,LF DB 'N New disk' DB CR,LF DB 'P Toggle printer switch' DB CR,L ; MLDONE: POP DX POP CX RET ; ;Routine to fill in disk params ;with every drive change ; LOGIT: cmp byte ptr cpm_version,31h ;if it's ver 31 the select jae logcal ;routine done moved DPB MOV DX,OFFSET DPB ; THEN MOVE TO LOCAL MOitrack rw 1 ;track number (first track=0) isector rw 1 ;sector number (first sector=0) idmaseg rw 1 ;dma segment for sector buffer idmaoff dw offset sector_buf ;dma offset for sector buffer dmaseg rw 1 ;dma segment for data dmaoff rw 1 ;dF DB 'Q Quiet mode (no msgs)' DB CR,LF DB 'R Read current sector' DB CR,LF DB 'Snn Sector nn' DB CR,LF DB 'Tnn Track nn' DB CR,LF DB 'Unn Set User nn for Find command' DB CR,LF DB 'V[nn] View [nn] ASCII sectors' V CH,DPBLEN ; WORKSPACE CALL MOVEFROMBIOS ; LOGCAL: MOV BX,OFFSET GRPDIS MOV AL,BYTE PTR [BX] PUSH AX MOV AL,BLM MOV BYTE PTR [BX],AL PUSH BX MOV BX,DSM XCHG BX,DX CALL GTKSEC MOV MAXSEC,BX XCHG BX,DX MOV MAXTRK,BX POP BX Pma offset for data trk_sect dw 0ffffh,0 ;number of track/sector in memory sec_xlat_tbl dw 0 ;address of BIOS xlat table rec_offset dw 0 ;logical record offset into phy sec ; data storage for Disk Parameter Block (DPB) ; dpb rs 0 ;17 byteDB CR,LF DB 'W Write current sector' DB CR,LF DB 'X Exit program' DB CR,LF DB 'Z[nn] Sleep [nn tenths]' DB CR,LF DB '/[nn] Repeat [nn (decimal) times]' DB CR,LF,CR,LF DB '(Type SP bar to continue)' DB 1,CR,LF,CR,LF DB 'CanOP AX MOV BYTE PTR [BX],AL RET ; ; DATAOFFSET EQU OFFSET$ DSEG ORG DATAOFFSET ; ; ; RW 200 STACK RW 1 ;LOCAL STACK ; ;Temporary storage area ; BUFAD DW BASE +100H ;FORCES INITIAL READ HEXAD DW 0 ;TO RE-FETCH A VALUE TOGO DW 0FFFFH ;R# s of storage ; SPT rw 1 BSH rb 1 BLM rb 1 EXM rb 1 DSM rw 1 DRM rw 1 AL0 rb 1 AL1 rb 1 CKS rw 1 SYSTRK rw 1 PHYSHF rb 1 ;not in CP/M-86 ver 1.1 PHYMSK rb 1 ; " " " " " ; ;End of disk parameter block wvmsg db 13,1Version 1.1, (C) Copyright March 1982, By Bill Bolton, Software Tools, Sydney, Australia**** File Open Error **** $**** File Read Error **** $ Sorry, you need CP/M-86 Version 1.0 or later to run PAGE !$ End of Input File Reached IRET and return to the program, effectively making all unplanned ; interrupts (such as arithmetic exceptions and pressing the keyboard ; reset button) invisible. This program causes any such interrupt ; to perform a warm boot, returning the user to the0,'Only CP/M-86 ver 1.1 & 3.1 Plus ' db 'and CCP/M ver 3.1-4.1 are Supported$' mpmsg db 13,10,'THE MP/M OPERATING SYSTEM IS NOT SUPPORTED$' toobig db 13,10,'SECTOR SIZE TOO BIG - ABORTING$' sector_buf rs 2048 ;-------------------------------[0m$ed L4A10: CALL OUT_MODDATP ;otherwise send the character CALL LOGLP1 ;check for echo character and display it LAHF  CP/M prompt. BIOS_segment equ 0040h BIOS_jumptable equ 2500h cseg org 100h mov dx,offset T_GETSEGT ;get available memory size for messages mov cl,50 int 224 mov ax,BIOS_segment mov es,ax mov ax,es:3[bx] mov cl,6 ;convert from------------------- ; SAVBUF RS 128 INBUF RS 128 ; ;Directory read in here; also search work area ; WORK EQU $ DIRECT EQU $ END ;next location in message INC BX SAHF JMPS LOGLP ;get next character ;..... ; ; LOGLP1: CALL JMP_INMODEM ;get the echo character JNB L4A11 CALL JMP_INMODEM ;if none, try once more L4A11: JNB L4A12 RET ;if no character don't try to pages to kbytes shr ax,cl push ax mov bx,offset h1_size+2 call binasc pop ax push ax mov bx,offset h4_size+2 call binasc pop ax mov bx,offset nm_size+2 call binasc mov dx,offset company_name ;print company name message mov cl,9 send JNZ TNLP2 MOV BX,Word Ptr NBSAVE ;get name MOV DX, FCB ;move it to FCB XCHG BX,DX MOV CH,12 CALL MOVE XCHG BX,DX MOV Word Ptr NBSAVE,BX ;addressof next name MOV BX, Offset FILECT ;count files found INC Byte Ptr [BX] JM print L4A12: AND AL,7FH ;strip off any parity JMP STYPE ;display the character, then return ;..... ; ; ; Check for exit character ; EXITTEST: CALL STAT ;anything on keyboard? JNZ L4A13 RET L4A13: CALL KEYIN ;get it, then M int 224 mov bx,80h ;check command buffer mov cl,[bx] ; if no command tail was entered, or cl,cl ; display help screens jnz RD04 mov dx,offset help1 mov cl,9 int 224 mov cl,1 int 224 cmp al,ctrl_C jnz $+5 jmp exit1 mov dPS TNLP2 ;..... ; ; NEXTNM: MOV BX, Offset NAMECT ;count names found DEC Byte Ptr [BX] JNZ TNLP1 MOV BX, Offset NAMEBUF ;save start of buffer MOV Word Ptr NBSAVE,BX MOV AL,Byte Ptr FILECT CMP AL,64+1 ;no more than 64 transfers JNB L4A9 OV CH,AL ;save to protect the 'A' reg. ; EXITTST1: MOV AL,EXITCHR ;exit character CMP AL,CH ;asking to exit to menu? JZ L4A14 RET ;if not, back to work L4A14: POP BX ;clear the stack from 'CALL' JMPS EXITMENU ;exit to the menu ;.x,offset help3 mov cl,9 int 224 mov cl,1 int 224 cmp al,ctrl_C jnz $+5 jmp exit1 mov dx,offset help4 jmp exit RD04: mov dx,offset T_SELDSK ;see if drive already exists mov cl,50 int 224 or bx,bx jz RD05 mov dx,offset I_exists RET L4A9: MOV AL,64 ;only transfer first 64 MOV Byte Ptr FILECT,AL RET ;..... ; ; ; Tells when buffer is opened/closed for memory save to write on disk ; BUFMSG: CALL ILPRT DB CR,LF,'** Memory buffer ',0 MOV AL,Byte Ptr SAVEFLG OR AL21 title 'RAMDISK - A Memory-Based Virtual Drive' ; THIS PROGRAM IS HEREBY PLACED IN THE PUBLIC DOMAIN, ; AND MAY BE FREELY COPIED AND DISTRIBUTED. ; program: RAMDISK ; ; created by Context Sensitive Inc. ; 4200 Auro jmp exit RD05: mov bx,80h ;get allocation size from command buffer mov cl,[bx] sub ch,ch sub ax,ax RD10: inc bx ;convert ascii digits to binary cmp byte ptr [bx],' ' jbe RD20 cmp byte ptr [bx],'0' jb RD21 cmp byte ptr [bx],'9' && < s\sns<u< t#< t(< t< s߻ N$uC2 <t   <tSRQra Ave. N. ; Seattle, WA 98103 ; (206) 632-0301 ; ; version: 1.1 October 28, 1983 ; author: Ron Blanford ; ; The handler code for the RAM disk takes approximately 250h bytes, ; or just over 1/2 kbyte. In versionsja RD21 mul ten mov dl,byte ptr [bx] sub dl,'0' add ax,dx RD20: loop RD10 RD21: or ax,ax ;make sure size specification is in range jnz RD30 mov dx,offset nosize jmp exit RD30: mov CBOOT_overlay,1 ;if nnnK entered, then put handlers YZ[2SQPбX< r#256K, then change parameters jbe RD45 ; to block at 2048 mov byte ptr BSH,4 ; rather than default 1024 mov byte ptr BLM,15 mov byte ptr EXM,1 mov word ptr DRM,127 shr ax,1 mov cl,7x ;set up interrupt handler mov es,ax ; by replacing normal IRET mov di,es:.0 ; with JMP to my handler mov ax,es:.2 mov es,ax mov al,0E9h ;JMP instruction mov es:[di],al inc di mov ax,offset inttrap add ax,dx sub ax,di mov es:[le for program execution.' db cr,lf,' Most programs require less than 64 kbytes, so any remaining' db cr,lf,' memory would otherwise be unused.' db cr,lf db cr,lf,' The main advantage of using a RAM disk is its sp RD45: mov word ptr DSM,ax dec word ptr DSM shl ax,cl mov disk_pages,ax RD50: mov dx,offset T_GETSEGT ;see if enough memory exists mov cl,50 int 224 mov ax,BIOS_segment mov es,ax mov dx,es:3[bx] ;number of pages available cmp CBOOT_odi],ax add dx,2 ;change local addresses to new location mov adj_offset,dx add DPH_offset,dx add DIRBUF_offset,dx add DPB_offset,dx add CSV_offset,dx add ALV_offset,dx mov di,init_addr ;move code and data into BIOS mov si,offset inieed. The' db cr,lf,' main drawback is that it is not permanent. Each time the' db cr,lf,' computer is turned off or CP/M-86 rebooted using the' db cr,lf,' CTRL-FNC-BREAK sequence, all files stored on theverlay,1 jz RD55 mov ax,offset end_Kdrive ;this code puts the RAMDISK handlers sub ax,offset init_Kdrive ; at the beginning of the TPA mov cl,4 ; rather than overlaying CBOOT code. shr ax,cl inc ax sub dx,ax RD55: sub dx,disk_pages jt_Kdrive mov cx,offset end_Kdrive sub cx,si shr cx,1 inc cx cld rep movs ax,ax mov dx,offset created mov cl,9 int 224 jmpf dword ptr init_addr ;go execute disk initialization routine init_addr dw BIOS_jumptable+100h dw BIOS_segment  RAM disk' db cr,lf,' are deleted and the RAM disk itself is eliminated. Therefore' db cr,lf,' be sure to save all modified files on a permanent disk at' db cr,lf,' the end of every session with the computer. In an ea RD60 mov dx,offset nomem jmp exit RD60: mov es:3[bx],dx ;save new TPA length mov di,es:.BIOS_jumptable+1 add di,BIOS_jumptable+3 cmp CBOOT_overlay,1 jz RD65 mov di,es:1[bx] ;this code puts the RAMDISK handlers add es:1[bx],ax ;  ; BINASC converts an unsigned binary number to ascii representation. ; Input registers: ax = number to convert ; bx = ptr to memory location ; for least significant digit binasc: mov byte ptr [bx],'0' mov cx,10 ba10: mov dx,0 ;comergency' db cr,lf,' press the reset button behind the rubber stopper in the key-' db cr,lf,' board to return to CP/M-86 without erasing the RAM disk.' db cr,lf db esc,'[25;1H',esc,'[21m Press any key to continue...',at the beginning of the TPA mov ax,es ; rather than overlaying CBOOT code. sub di,ax mov cl,4 shl di,cl RD65: mov init_addr,di add dx,es:1[bx] mov disk_seg,dx mov bx,BIOS_jumptable+18h ;move BIOS jumptable to local table mov di,offset nvert ax to ascii div cx or ax,ax jnz ba15 or dx,dx jz ba20 ba15: or dl,'0' mov byte ptr [bx],dl ;store ascii digit in display area dec bx jmps ba10 ba20: ret exit1: mov dx,offset abort_msg exit: mov cl,9 int 224 mov dx,0 mov clesc,'[m$' help3 db esc,'[7;1H',esc,'[J' db cr,lf,' The RAM disk created by this program is called drive K.' db cr,lf,' Drive K is used the same way as any other disk drive. To' db cr,lf,' list the directory ofBIOS_HOME ; after converting from relative mov cx,10 ; to absolute addressing RD70: inc bx mov ax,es:[bx] inc bx inc bx add ax,bx mov [di],ax inc di inc di loop RD70 mov dx,init_addr ;move my entry points to BIOS jump table sub ,0 int 224 eject ctrl_C equ 03h cr equ 0Dh lf equ 0Ah esc equ 1Bh ten dw 10 CBOOT_overlay db 1 ;1=overlay CBOOT code, 0=use part of TPA T_SELDSK db 9 ;direct BIOS call for disk selection dw 10 dw 0 T_GETSEGT db 18 ;direct B files, type:' db cr,lf,esc,'[23m DIR K:',esc,'[20m' db cr,lf,' (Initially drive K is empty and this command will give the' db cr,lf,' NO FILE message.) To copy programs and data files to' db cr,lfdx,2 sub dx,offset init_Kdrive mov di,BIOS_jumptable+18h inc di mov ax,offset HOME add ax,dx sub ax,di mov es:[di],ax add di,3 mov ax,offset SELDSK add ax,dx sub ax,di mov es:[di],ax add di,3 mov ax,offset SETTRK add ax,dx sIOS call for memory extents dw 0 dw 0 company_name db esc,'[1;1H',esc,'[J',cr,lf,' ',esc,'[2;3m ',esc,'[3;23m' db ' RAMDISK 1.1 ' db esc,'[2m ',esc,'[m',cr,lf,' ',esc,'[2;4m ',es,' drive K, type:' db cr,lf,esc,'[23m PIP K:=filename.typ',esc,'[20m' db cr,lf,' To select drive K as the default drive, just type:' db cr,lf,esc,'[23m K:',esc,'[20m' db cr,lf,' iub ax,di mov es:[di],ax add di,3 mov ax,offset SETSEC add ax,dx sub ax,di mov es:[di],ax add di,3 mov ax,offset SETDMA add ax,dx sub ax,di mov es:[di],ax add di,3 mov ax,offset READ add ax,dx sub ax,di mov es:[di],ax add dc,'[4;20m' db ' Context Sensitive Inc. Seattle, Washington (206) NEC-0301 ' db esc,'[2m ' db esc,'[m',cr,lf,'$' help1 db cr,lf,esc,'[19m' db cr,lf,' Thank you for choosing RAMDISK from Context Sensitive Inc.' db cr,lf,esc,'[n response to the CP/M-86 prompt.' db cr,lf db esc,'[25;1H',esc,'[21m Press any key to continue...',esc,'[m$' help4 db esc,'[7;1H',esc,'[J' db cr,lf,' To create the RAM disk, type:' db cr,lf,esc,'[23m RAMDi,3 mov ax,offset WRITE add ax,dx sub ax,di mov es:[di],ax add di,6 ;skip list status jump mov ax,offset SECTRAN add ax,dx sub ax,di mov es:[di],ax add di,3 mov ax,offset SETDMAB add ax,dx sub ax,di mov es:[di],ax sub ax,a20m' db cr,lf,' This program creates a pseudo disk drive using part of the' db cr,lf,' random access memory (RAM) of your computer. Your computer' db cr,lf,' has ' h1_size db ' ' db ' kbytes of memory availab$ ISK nnn',esc,'[20m' db cr,lf,' where nnn is the number of kbytes of memory to allocate for' db cr,lf,' drive K. Remember, this must be less than ' h4_size db ' ' db ' kbytes.' db cr,lf,esc,'[m$' abort_msg db 0Bh,esc,'[mA_seg[bx] mov di,DMA_offset[bx] mov ax,sek_trk[bx] mov cl,6 shl ax,cl add al,sek_sec[bx] mul one_twenty_eight[bx] mov cl,12 shl dx,cl add dx,disk_seg[bx] mov ds,dx mov si,ax mov cx,64 cld rep movs ax,ax pop es pop ds popf    DaPPP*'P*F=unPDPFƋ4V F^;tFƋ4VFP`*-TP\PF',esc,'[J$' nosize db cr,lf,esc,'[19m' db cr,lf,' A size must be specified for RAMDISK drive K' db cr,lf,esc,'[21m' db cr,lf,' for example: ''RAMDISK 128'' allocates 128K of memory' db esc,'[m',cr,lf,'$' nomem  sub ax,ax ret WRITE: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_WRITE[bx] pushf push ds push es mov ax,sek_trk[bx] mov cl,6 shl ax,cl add al,sek_sec[bx] mul one_twenty_eight[bx] mov cl,12 shl dx,cl add dx,disƋ4V F^;tFƋ4V^P*nP*vv >]VFVFVFPv F^;uF=uPvY#vt4TXZRPRPvvGXZ^_;u;t xPe)RPRPvvX db cr,lf,esc,'[19m' db cr,lf,' RAMDISK drive K not created - not enough memory' db cr,lf,esc,'[21m' db cr,lf,' Your computer only has ' nm_size db ' ' db ' kbytes of memory available' db esc,'[m',cr,lf,'$' k_seg[bx] mov es,dx mov di,ax mov si,DMA_offset[bx] mov ds,DMA_seg[bx] mov cx,64 cld rep movs ax,ax pop es pop ds popf sub ax,ax ret SECTRAN: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_SECTRAN[bx] mov bx,cx Z^_;u;t zP0)F= }F=|vv gFPIvv Qv-P vt4TXZ/vt4TXZQ vPz }P(Pv ^;tP(PvvPT(vvI_exists db cr,lf,esc,'[19m' db cr,lf,' RAMDISK drive K not created - it already exists' db cr,lf,esc,'[21m' db cr,lf,' CTRL-FNC-BREAK deletes all files and removes the drive' db esc,'[m',cr,lf,'$' created db cr,lf ret SETDMAB: call adjust mov DMA_seg[bx],cx jmp BIOS_SETDMAB[bx] inttrap: cli pop ax ;pop old IP, CS, and flags pop ax pop ax or ax,0200h ;enable interrupts on return push ax mov ax,BIOS_segment ;return to WBOOT push ax movPD(vvP4(]CP#(P(P(P(DP'vP'P']ËGtw VU vJF%1FF0CP3PPP!FV^ t؃]^Ëܸ1GVUF tFuv~vv~~D,esc,'[19m' db cr,lf,' RAMDISK drive K has been created (' cr_size db ' ' db ' kbytes)' db cr,lf,esc,'[21m' db cr,lf,' CTRL-FNC-BREAK deletes all files and removes the drive' db esc,'[m',cr,lf,'$' title ax,BIOS_jumptable+3 push ax iret adjust: nop ;all variables to be offset db 0BBh ; by the amount the program moved adj_offset dw 0 ;this is a MOV BX,nnnn instruction ret eject BIOS_HOME DW 0 BIOS_SELDSK DW 0 BIOS_SETTRK DW 0 +EtyEȻYKKyً3x CC$CCE y3CC1W^~FuF]^^XZ^X3SS y ؃πRP0CPSVW~^Z^XZ^X3R3SSP0CPSVWW^3؎W_E %E% 'RAMDISK initialization and handler code' eject init_Kdrive: call adjust mov es,disk_seg[bx] mov ax,disk_pages[bx] init1: push ax ;format the disk area mov cx,8000h cmp ax,1000h ja init2 mov cl,3 shl ax,cl mov cx,ax init2: mov d BIOS_SETSEC DW 0 BIOS_SETDMA DW 0 BIOS_READ DW 0 BIOS_WRITE DW 0 BIOS_LISTST DW 0 BIOS_SECTRAN DW 0 BIOS_SETDMAB DW 0 sek_dsk db 0 sek_sec db 0 sek_trk dw 0 DMA_offset dw 0 DMA_seg dw 0 disk_pages dw 0 disk_seg dw 0 one_twenty_eight ] VW_^D %  DEËE E E E uE7E tm ]]]]E ueUUU )]WUFtF uv~JyvDv~;3SSSSSS_ǣD . t. .CCsCCt֋F-0@FFދF3FF܋!i,0 mov ax,0E5E5h cld rep stos ax mov ax,es add ax,1000h mov es,ax pop ax sub ax,1000h ja init1 mov dx,0 mov cl,0 int 224 HOME: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_HOME[bx] ret SELDSK: call adjust dw 128 DPH_offset dw offset DPH DPH dw 0 ;no sector translation dw 0 dw 0 dw 0 DIRBUF_offset dw offset DIRBUF DPB_offset dw offset DPB CSV_offset dw offset CSV ALV_offset dw offset ALV DIRBUF rs 128 CSV rs 0 ALV rs 32 ;di~]_" " " " WUF uv~FuFFF F} vi[Y3PPPPQS vT5Qv~;rwNNOOv~FFGGvFFYċF-?)FF1F~Cv~]_  mov byte ptr sek_dsk[bx],cl cmp cl,10 jz $+7 jmp BIOS_SELDSK[bx] mov bx,DPH_offset[bx] ret SETTRK: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_SETTRK[bx] mov sek_trk[bx],cx ret SETSEC: call adjust cmp byte ptr sek_dsk size: <256K >256K DPB dw 64 ;SPT BSH db 3 ;BSH 3 4 BLM db 7 ;BLM 7 15 EXM db 0 ;EXM 0 1 DSM dw 0 ;DSM #K-1 (#K/2)-1 DRM dw 63 ;DRM 63 ܊o w y2y:}ĹW9Wu KK$t w$t$t2 ܉G_ttt4^XZ[YU]MQSRP_D3۹%uPPP8PRS3PD%-?=#=|)D-8yT\D 3E_Xˎ& Ask[bx],10 jz $+7 jmp BIOS_SETSEC[bx] mov sek_sec[bx],cl ret SETDMA: call adjust mov DMA_offset[bx],cx jmp BIOS_SETDMA[bx] READ: call adjust cmp byte ptr sek_dsk[bx],10 jz $+7 jmp BIOS_READ[bx] pushf push ds push es mov es,DM 127 db 0C0h ;AL0 db 0 ;AL1 dw 0 ;CKS dw 0 ;OFF end_Kdrive db 0 end Key to continue: the current file WRERR1: CALL ERXIT ;also will reset stack DB '++ DISK FULL, SAVING PARTIAL FILE ++','$' ;..... ; ; ; I% .2 UWFVv~ u y ؃ y ރS 3SN;w r;w+@N^Yt tu t؃FV _] v UF fF FfF FfFV ] v ûWg؎Ћ&>\FVF uFF Fv4^(~0FF PvVF޸PvދF^^PvVwPvދYvFށP\PvP\^ƉF܍\PF썆\FFF9FF*F FFF FFދF uv4V#PPv4t#t!XZYuRPvtXZTPZPvtX^# uvttXZ uv4t!,\t4XZvtVPv4V!PFPYPF^;|1PvVvt^ƉƊ^;t v4XPYPF^+ƙRPvtO3 $0 t5x t/PV0±$'@'Nuӱ 9nvnX &"^3^.U+;&v^.PF^;r PvX^P6^ƉƋ4F uF]øP PPJ]FFcv]~e,F Fv4^t4vXZTPZFF KF=|!v 4^4XRPvXZTPZv 4^4X3RPvXZTPZvލ\Pvt4^\FvFv 4^4XFvFF uF;FrFFFwv 4XFܸFFTY[ӉTF]ËF u#v4 u v4V2v)]Ë]PvtX^# u6PvtX^# uPv4^;tPvtXvtV P PPPvt XPvtƊ^Pvt X Pvt XX uvFZ~KF+v%X u]ËF=|]ËF udF=F~v,4X uFvv Pv5X u Fv4,X uoPvY[FFܸFFFCcsdDxXuUoObBfegewod\F uF;FwF u-Pv܊^;t 0PF^;t.Pv4vvЃv,4Xv,4XvVv4,X^;wPvVvvЃF;Pvt^ƉXv4V~PvtXPvtX^# u PvtƊ^;t% PvtXPvt X Pvt X]øPvtt XZY!RFZFFF=|vttPYPvX^RPvtt XZ^_^_vV7^Ɖ@v:X u7vV^ƉF&PvY Fv4,X uoPvYvV^ƉvVX u7vV7^ƉFPvYPv_X u#FwvvY+FvvvvЃF uF u)v4,X uPvVvvЃv4XPv4vvЃ]4F̍v4^Fv4,X ux Pv̊^;t Pv̊^;t PvX6AP;u;rPYPvX^Pvt^PPkFF3RPv4t!XZTPZv4V!P>FF=t F=t=PPYPPYPvX^Pvt^PF F u v4XF u@PvtY PNFF[Lv4XF؉FF uv-~vv F]Ë]F Fv{X u#v~-Pv4^XF=|z0Pv4^X.Pv4^XvvYF=|vvY+Fv̊^;sZPv̊^;v Pv̊Yv́4XwPvXF҉FЉFθF̸FPv4^^ƉFv4,X uv̊ u<Pv̊^;t F́F<>Pv̊^;t F́FFPv4^VF^ƉXF=}YPvX^Pvt X]L PvtX^# ugvtvt X^;|Pvt vt^ƉXvt XRPvtt XZ^_RPvttXZ^_;u;r.vt XRPvtt XZ^_RPvtXZTPZFvt PYPvX^^;|PYPvPv4X^;|0Pv4^Xsv"DFF0Pv4^Xv#vW~v,4X uF u.Pv4^Xv4,X uHvFF0Pv4^Xzvvn~pPvP P Pv̊ uv́4Xv,4Xv́4X+F̸>PvЊ^;tvЁ4XF̸PPv? ^;uPvv% ^;uPPv ^;uP PPEPFԉXFPvP ]X^Pvt^PPvXRPPvtt XZY^_RPv4t!XZTPZv4V"PA u@PvtY v4XIPvtY#]UNV]vvX^FvB F uPvvF]Ë]|PF^PXPF+F ^ t3]Ë]Iv ug%Pv^;t7F-Pv4^^;ƸtHF u v4XvF0PF^;u F*Pv^;tv 4^4XFv4XEFvP u*0Pv4^^+P PvXfFFF=|,vV6^ƉƋ4 u v4XF=tPPKFF uPv4X5^#PvtXPv^;:PFƊ^;tFFF=|5FF=|@vVPvX^P^ƉƉ^ u]voFPvtX5^# u v4V0vt u vtVv PPvX^P6^ƉX]Ë]FF=|0vV6^ƉƋ4 u v,v4XvJ]PF^+PFPvtX^^^ƉF.Pv^;ƸtHF uv4X*Pv^;tv 4^4XFv4XEFvP/ u*0Pv4^^+P PvX^^ƉFlPvP^;ƸtHF u v4XvP8F uFF Fv4ƉƊPvVF^ƉƊP^;t v4XF=t*PF^#PPvX^P^ƉƊD^;tPvtY PvX^P^ƉƊDPvXPPvtX^#^;t3Pv4^;tPvtX PvtX PvtX v# uO PvtX^# u vPv4VPd^;@PvtY @PvtX^# uPPX]Ë]FPPvVPF^+P5 ^;uFF]Ë]FFFv uv4^PdF^M~UFF PvVF޸gPv^;tF=|F=PF^PvVvPvދYvP\PvP\^ƉFܸEPv4^XF=|-Pv4^XF؉F+Pv4^Xv޸Pv1\PFF썆4XPvtX5^# uvv[PvX uF uv4VPMPv4VFP6^;PYPvtXvtgPvtX ufPvtvtVFPvV6^ƉXPvtX5^# u F u% F uFPvY F uFF uFPvY awrb _FPRPFFPvnFF=u F=t3PFFPv<FVF=tF=utXFPvXPvYF]Ë]U؎v~N;rNO]ލvVvP~/P]Ë]vFvvPF^+PnPF^;u]øPPPF^+PBP^;u]ø]Ë]v݃FPvtX^# uOutput file flush error %ld characters processed %ld characters were deleted %ld soft hyphens replaced Usage: SCRUB d:file1 d:file2 Where: file1 = source file, (* and ? not allowed) file2 = destination file, (* and ? not allowed) d: = oPRPvF=u F]ø]Ë]0PPvVPF^+P ^;uFF]Ë]PvY+v4VF^;uP PP|6VFv4 uvVv4^;r v4Fv4VvXFPvXPvtX^ P PPsFvVvX^;rPvF^;|FPv4^Xv4XPvtX^# uF=t+PvtXPvtY v,4XvF= tZPvF^;|PF= t PFX2FPvtXptional drive identifier i.e. SCRUB A:FOOBAR.WST B:FUBAR.DOC BAD FILE$%03dcon: TOO MANY ARGS$warw REDIRECTION ERROR$cFREE$ READ$WRITE$6% NO CORE$ $$@Y@@חA7yACnF?O8M 0HwZ۾sOuPF^ƁPF^;t+PvtX^PvtYv4VvXFFv4FPvtX^PF^ƁPF^;t(PvtX^PvtYv4VvX]FP0^;ƸvH uH uP9PF^;ƸvH uHPX]Ë]zvFPvtY F= t@PvtX^# uPFPX]Ë]ܸPvtX^# uPvtY#vD]Ëvt vt X^;} PvtX^# u vfPvtX^# uRvtvt X^;t-vtXRPvt TY[?yGz?(C6?30yE>ؗҜ<#I9D2F[%nd( ??$@$@$@CONCONRDRPUNPRN0123456789ABCDEFPvtX^# u 3ҋ]øPvtY#F Pmvt XRPvvvtt XZ^_^_׉VFPvvXZVF?vvvttXZ^_׉VF3ҋ]Evt X u$vtt vvXZ^_;u;r9vt XRPvtt XTPvt Xvt X uPvt Xvvt vt X^;}]Ëvt 4vt^ƉƊ]Ë]vV4XF^;s]Í44X^+ƉFvƋYF]Ë]U؎~NF]vv4Vv5PvX ; ABORTL: MOV CH,1 ;1-second delay to clear input CALL RECV JNB ABORTL MOV AL,CANCEL ;show you are cancelling CALL SEND ; ABORTW: MOV CH,1 ;1-second delay to clear input CALL RECV JNB ABORTW MOV AL,' ' CALL SEND MOV AL,'B' ;tuZ^_RPvvXZ^_;u;sp PvtX^# u vPYP^5RPvvXZ^_##RPvt XZTPZPvt Xvvtt vvXZ^_+RPvt XZvt vt X^;vt vt XvvXZ]Ë]{*FP!PF^PvYPv4X]DڍvVvvVc.Pރ]Ë])v4XFv4^ uPF+F^ t3]Ë]يFPA^;~ ZPF^;~ PvYF]Ë]يFPa^;~ zPF^;~PvYF]Ë]i TITLE 'UPPERCASE FUNCTION' PUBLIC CAPS CSEG ;CAPITALIZE AL CAPS: CMP AL,'a' JL RETURN CMP AL,'z' JG RETURN AND AL,01011111B RETURN: RET END ^ƉFXF =|RPvvXZ^_;u;r FvvXZ؃VFRPv XRPvvXZ؃RP3%^YƉƊPv,4^XF ؙRPFu5]XZU ujvvXZVF3RPv X3RPvv0%^YƉƊPv,4v{كFPvtX^# uP PqP؃PvtX^# uwFvVvX^;r^ Pv^;tPvtX^# u Pv4Vv4^Pv4Vv4XFvVvX^;rX Pv^;tPvtX^# u? CMP AL,'R' JNZ L5A32 JMP RCVSABT ;if yes, cancel the unfinished file L5A32: CALL ILPRT DB CR,LF,LF,'++ FILE CANCELLED ++',CR,LF,BELL,0 JMP DONETCA ;..... ; ; ; Increment the record count ; INCRRNO:PUSH BX MOV BX,Word Ptr RECDNO ^Xv X3RPFu5XZU uF u-Pv,4^XP!PF^+F^ t3FFPvvF]Ë]P%PF u:PFƊ^;tIvPFF=A}F=P~F@PvXgPvY v Ptvv4^P]v4Xvt vt X^;vt vt X@PvtX^# uPFPX]Ë]׋vtvt X^;}Ovtvt XvlvtXRPvt TY[ӉTPvt XPvt Xvt X uPv ;get record number LAHF ;bump it INC BX SAHF MOV Word Ptr RECDNO,BX ;store it MOV AL,BL POP BX RET ;..... ; ; ; First check for any wild cards and disallow, just to be safe. Do not ; want a group of files being accidently erased P PvtVvVPvtVF uvVPvt V( uF]v ]Ë]v4Fv udv4^P"FF=.t:F=!|]ËF uv,4XFPv4^XFPvX]tX5^# u3Pvt Xv,vt X u Pvt X PvtY FPvt 4vt^ƉX]. ; ERASFIL:MOV BX, FCB ;file name is stored here MOV CH,11 ;maximum of 11 chars for filename.ext ; ERASFIL1: INC BX ;next location in file name MOV AL,Byte Ptr [BX] ;get the char. CMP AL,'?' ;check for any wild card chars. JZ ERRORW Ë]bPPF^^#ƉF6VFv4F uvVvtX^;sPF^PvtX^;sMPvX^PF^ƁFv4VvXPvtX+F^+PvtXFPvX vtXFv4VvX FFSF uPF^PF u%FPv WordStar file Scrubber Version %d.%d Bill Bolton, Software Tools r Cannot find file %s w Can't open %s Working * &  ;error if one is found DEC CH ;number of tries left JNZ ERASFIL1 ;if not zero, keep checking MOV AL,Byte Ptr BATCHFLG ;don't ask for erase.. OR AL,AL ;..in multi-file mode,.. JZ NOASK ;..just do it. MOV DX, FCB MOV CL,SRCHF INT 2H CX PUSH DX MOV CL,SETDMA INT 224 MOV DX, FCB MOV CL,READ INT 224 POP DX POP CX OR AL,AL JZ RDRECOK DEC AL JZ REOF CALL ERXIT DB '++ FILE READ ERROR ++','$' ; RDRECOK:MOV BX,128 LAHF ADD BX,DX RCR SI,1 SAHF RCL SI,1m special storage area and compare RET ;return with flag set for the compare ;..... ; ; ; Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage ; characters on the line. For example, having just sent a record, cal- ; ling RECVDG24 INC AL JNZ L5A33 RET ;file erased ok, return L5A33: CALL ILPRT ;otherwise make sure it'S OK DB 'File exists - erase? (Y/N): ',BELL,0 CALL KBDCHR CMP AL,'Y' JZ L5A34 JMP MENU ;if not a 'Y' do not erase L5A34: CALL CRLF ;ot XCHG BX,DX INC CL CALL DSKSIZ ;establish buffer size JZ RDBFULL JMPS RDRECLP ;... ; ; REOF: MOV AL,1 MOV Byte Ptr EOFLG,AL MOV AL,CL ; ; ; Buffer full or received "End Of File (EOF)" ; RDBFULL:MOV Byte Ptr RECINBF,AL MOV BX, Off will delete any line noise induced characters LONG before ; the ACK/NAK would be received. ; RECVDG: CALL CKCHAR ;catch any garbage characters ; RECV: PUSH DX ; ; ; Get back quickly to gobble 2nd character if TIMFLG is set by the GETNM ; routinherwise erase the file ; NOASK: MOV DX, FCB MOV CL,ERASE INT 224 RET ;..... ; ; ERRORW: POP BX ;restore stack from "call ERASFIL" CALL ILPRT DB '++ NO WILDCARDS ALLOWED FOR TEXT FILES ++' DB CR,LF,BELL,0 JMP MENU ;..... ; ; BLKFILset BUFFER MOV Word Ptr RECPTR,BX MOV CL,SETDMA MOV DX, Offset TBUF INT 224 JMP RDRECD ;..... ; ; ; Write a record ; WRRECD: MOV BX,Word Ptr RECPTR XCHG BX,DX MOV BX,128 CALL MOVE128 XCHG BX,DX MOV Word Ptr RECPTR,BX ;new recoe - or just step through quickly after the first wait for 'SOH' ; in the 'SOHLUP' routine. ; MSEC: PUSH BX MOV BX, Offset TIMFLG MOV DL, Byte Ptr [BX] INC DL MOV BX,Word Ptr QUIKTIM JZ DOQUIK MOV BX,Word Ptr TIMVAL ; DOQUIK: XCHG BX,DX PE:CALL ILPRT ;no file named for send or receive DB '++ NO FILE SPECIFIED ++',CR,LF,BELL,0 JMP MENU ;..... ; ; MAKEFIL:MOV DX, FCB MOV CL,MAKE INT 224 INC AL JZ L5A35 RET L5A35: CALL ERXIT DB '++ ERROR -- Can''t open file ++',CR,LF rd pointer MOV AL,Byte Ptr RECINBF ;increment 'RECORDS IN BUFFER' count INC AL MOV Byte Ptr RECINBF,AL MOV CL,AL ;store the record count for now CALL DSKSIZ ;establish buffer size JZ WRBLOCK RET ;buffer not full, return ; ; ; WriOP BX ; MWTI: CALL RCVREADY JZ MCHAR MOV AL,DH OR AL,DL LAHF DEC DX SAHF JNZ MWTI DEC CH JNZ MSEC POP DX CALL CKABORT STC RET ;..... ; ; ; Get the character from the modem, but filter out 'ACK' and '.' chars. ; if recieving DB '++ Directory is perhaps full ++','$' ; CNREC: MOV CL,FILSIZ ;compute file size function in cp/m 2.x MOV DX, FCB ;point to file control block INT 224 MOV BX,Word Ptr .FCB+33 ;get record count MOV Word Ptr RCNT,BX ;store it MOV BX,0 ;zte a block to disk ; WRBLOCK:MOV AL,Byte Ptr RECINBF ;get the number of records in the buffer OR AL,AL JNZ L5A40 RET ;if zero, don't try to move to disk L5A40: MOV CL,AL ;otherwise store in 'C' reg. MOV DX,Offset BUFFER ;start of buffe a file name. ('FILTRFLG' is set by the 'GETNM' routine.) ; MCHAR: CALL IN_MODDATP ;get the character that is waiting POP DX LAHF ;save the character for later use also XCHG AL,AH PUSH AX XCHG AL,AH CMP AL,ACK ;see if it is 'ACK' JZ ero 'BX' MOV Word Ptr .FCB+33,BX ;reset random record in FCB RET ;..... ; ; OPENFIL:XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV DX, FCB MOV CL,OPEN INT 224 INC AL JZ L5A36 JMP SENDTIME ;send transfer time, # of records, etc. L5A36: CALLr to move to disk ; DSKWRT: PUSH CX PUSH DX PUSH BX MOV CL,SETDMA INT 224 MOV CL,WRITE MOV DX, FCB INT 224 POP BX POP DX POP CX OR AL,AL JZ L5A41 JMP WRERR ;error if disk is full L5A41: MOV BX,128 ;add in another page AISACK CMP AL,'.' ;see if it is a period JNZ DOUPD ;neither, so update 'CRC' ; ISACK: PUSH BX PUSH DX MOV BX,Offset FLTRFLG ;see if need to each 'ACK' or period MOV DL,Byte Ptr [BX] INC DL POP DX POP BX JZ MWTI ;yes, so do i ERXIT ;file did not open DB '++ FILE NOT FOUND ++','$' ;..... ; ; CLOSFIL:MOV DX, FCB ;get the file name MOV CL,CLOSE INT 224 ; close the file INC AL JZ L5A37 RET L5A37: JMP ERXIT1 ;no file to close, exit ;..... ; ; ; UpdatDD BX,DX XCHG BX,DX DEC CL ;one less record left to move to disk JNZ DSKWRT XOR AL,AL MOV Byte Ptr RECINBF,AL ;zero the 'RECORDS IN BUFFER' count MOV BX, Offset BUFFER ;reset location to next buffer start MOV Word Ptr RECPTR,BX RET ;.t ; DOUPD: CALL CRCUPD ;calculate 'CRC' ADD AL,CL MOV CL,AL MOV AL,Byte Ptr RSEEFLG OR AL,AL JZ MONIN MOV AL,Byte Ptr VSEEFLG OR AL,AL JNZ NOMONIN MOV AL,Byte Ptr DATAFLG OR AL,AL JZ NOMONIN ; MONIN: POP AX ;get the character e record read ; RDRECD: MOV AL,Byte Ptr RECINBF ;decrement 'RECORDS IN BUFFER' count DEC AL MOV Byte Ptr RECINBF,AL JS RDBLOCK MOV BX,Word Ptr RECPTR ;find where last move stopped MOV DX,128 CALL MOVE128 ;move 128 characters MOV Wo.... ; ; ; Determine if the buffer size is for file transfer or for ASCII capture ; to disk then compare with current record length ; DSKSIZ: MOV AL,Byte Ptr XFLG ;see if transferring files now OR AL,AL MOV AL,CL ;get the current record cagain XCHG AL,AH SAHF LAHF ;resave it for later use also XCHG AL,AH PUSH AX CALL CKABORT ;show the character on the CRT ; NOMONIN:CALL CKABORT POP AX ;get the character back once more XCHG AL,AH OR AL,AL ;reset the carry flag rd Ptr RECPTR,BX ;store new address for next move RET ;..... ; ; ; Buffer empty so read in another block from the disk ; RDBLOCK:MOV AL,Byte Ptr EOFLG CMP AL,1 STC JNZ L5A38 RET L5A38: MOV CL,0 MOV DX, Offset BUFFER ; RDRECLP:PUSount JZ DSKSIZ1 ;if yes, exit MOV AL,CL CMP AL,BUFSIZ*8 ;buffer size for ASCII capture to disk RET ;return with flag set for the compare ;... ; ; DSKSIZ1:MOV AL,Byte Ptr SAVSIZ ;get the file transfer buffer size.. CMP AL,CL ;..fro&  RET ;return with the character and flag set ;..... ; ; ; Send a character to the modem ; SEND: PUSH AX MOV AL,Byte Ptr SSEEFLG OR AL,AL JZ MONOUT MOV AL,Byte Ptr VSEEFLG OR AL,AL JNZ NOMONOT MOV AL,Byte Ptr DATAFLG OR AL,AL JZ Nfile name JMPS LOADMSG ;loop for another character ;..... ; ; PERIOD: MOV AL,Byte Ptr [BX] CMP AL,' ' ;is file type empty? JZ FTRNMSG0 ;go if so MOV AL,'.' ;else put period in message MOV SI,DX MOV [SI],AL INC DX DEC CH JMPS LO JMP MENU ;if yes, go to command mode L6A4: MOV AL,Byte Ptr JMPCMD ;requesting return to command mode? OR AL,AL JNZ L6A5 JMP MENU ;if yes go to command mode L6A5: CALL CRLF ;turn up a new line JMP TERM ;otherwise return to terminaOMONOT ; MONOUT: POP AX PUSH AX CALL SHOW ; NOMONOT:POP AX PUSH AX CALL CRCUPD ;update the 'CRC' calcuation ADD AL,CL MOV CL,AL ; SENDW: CALL SENDRDY JNZ SENDW POP AX JMP OUT_MODDATP ;send character to modem, done ;..... ; ; ADMSG ;..... ; ; FTRNMSG0: CALL ILPRT DB CR,LF ; FTRNMSG RS 12 DB 0 CALL ILPRT DB ' Transferred',CR,LF,LF,BELL,0 ; NMSTRNS:MOV AL,Byte Ptr .FCB ;save drive no. MOV Byte Ptr DISKNO,AL MOV BX, FCB ;blank out file control blocks Cl mode ;..... ; ; DONETCD:CALL ILPRT DB CR,LF,'<< DISCONNECTED >>',BELL,CR,LF,0 CALL JMP_GOODBYE ;set 'DTR' low for 300 ms. MOV AL,Byte Ptr PMMIMODEM OR AL,AL JZ L6A6 CALL JMP_DISCONNT L6A6: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-typ; Waits for the first character received while waiting to send a file. ; If a character is not received in one second, it loops again until a ; char. is received or it times out. The count is set for two minutes ; before timeout. This gives the receivALL INITFCB MOV AL,Byte Ptr DISKNO ;put drive number back MOV Byte Ptr .FCB,AL MOV BX,Offset RESTSN ;restore record numbers.. MOV DX,Offset RECDNOB ;..for new file transfer. MOV CH,(Offset RECDNOE)-(Offset RECDNOB) ;routine also done in menu.e modem? OR AL,AL JZ L6A7 CALL JMP_DISCONNT ;if yes, disconnect L6A7: JMP MENU0 ;back to command line ;..... ; ; MOVEFCB:MOV BX, FCB+16 MOV DX, FCB MOV CH,16 CALL MOVE XOR AL,AL MOV Byte Ptr .FCBSNO,AL MOV Byte Ptr .FCBEXT,AL ing station ample time to name ; a file, etc. ; WAITNAK:CALL ILPRT DB 'Waiting ready signal',CR,LF,0 CALL CRLF ; WAITNLP:CALL CKABORT MOV CH,1 ;wait up to 1 second for a character CALL RECV CMP AL,CANCEL ;want to quit? JNZ L5A42 JMP  CALL MOVE CALL SENDNOW ;insures last character is finished CALL CKCHAR ;catch any echo characters on line MOV AL,Byte Ptr SENDFLG ;goes to either send or.. OR AL,AL ;..receive file, depending.. JZ L6A1 JMP SENDFIL2 ;..upon which roRET ;..... ; ; SHOW: CMP AL,LF JZ CTYPE CMP AL,CR JZ CTYPE CMP AL,9 JZ CTYPE CMP AL,' ' JB SEEHEX CMP AL,7FH JB CTYPE ; SEEHEX: LAHF XCHG AL,AH PUSH AX MOV AL,'(' CALL CTYPE POP AX XCHG AL,AH SAHF CALL HEXO MOV AL,ABORT L5A42: CMP AL,CRC ;'CRC' request? JZ WAITCRC ;yes, go set 'CRC' flag CMP AL,NAK JZ WAITCHK DEC DL JNZ WAITNLP JMP ABORT ;... ; ; WAITCRC:CALL ILPRTQ DB 'CRC request received',CR,LF,0 MOV AL,1 MOV Byte Ptr CRCFLAG,AL ;mutine set.. L6A1: JMP RCVFIL1 ;..the flag in multi-file mode. ;..... ; ; DONETC: CALL CKABORT ;slight delay for next message CALL ILPRT DB CR,LF,'[Transfer completed]',CR,LF,BELL,0 ; DONETCA:MOV AL,Byte Ptr XITFLG ;special 'X' flag set')' JMPS CTYPE ;..... ; ; CTYPE: PUSH CX PUSH DX PUSH BX MOV DL,AL MOV CL,WRCON INT 224 POP BX POP DX POP CX RET ;..... ; ; CRLF: LAHF XCHG AL,AH PUSH AX MOV AL,CR CALL STYPE MOV AL,LF CALL STYPE POP AX XCHG AL,Aake sure in 'CRC' mode then RET ;..... ; ; WAITCHK:MOV AL,Byte Ptr BATCHFLG ;in batch mode? OR AL,AL JNZ L5A43 RET L5A43: CALL ILPRTQ DB 'Got checksum request',CR,LF,0 RET ;..... ; ; WAITCHK1: CALL ILPRTQ DB 'Name NAK received'? OR AL,AL JNZ L6A2 JMP BYEBYE ;if yes, disconnect and reboot L6A2: MOV AL,Byte Ptr DISCFLG ;normal 'D' flag set? OR AL,AL JZ DONETCD ;if yes, disconnect, get next command ; DONETCB:CALL JMP_NOPARITY ;reset to no parity XOR AL,AL H SAHF RET ;..... ; ; STAT: PUSH CX PUSH DX PUSH BX ; VSTAT: MOV DL,0FEH ; Direct Console I/O Status function flag MOV CL,6 INT 224 POP BX ; vois la POP DX POP CX OR AL,AL RET ;..... ; ; KEYIN: PUSH CX PUSH DX PUSH BX ,CR,LF,0 RET ;..... ; ; ; Finished with the file transfer ; DONE: MOV AL,Byte Ptr BATCHFLG ;in batch mode? OR AL,AL JZ L5A44 JMP DONETC ;exit if not L5A44: MOV AL,Byte Ptr QFLG OR AL,AL JNZ L5A45 JMP NMSTRNS L5A45: MOV CH,12  MOV Byte Ptr CRCFLAG,AL ;reset back to checksum MOV Byte Ptr FIRSTME,AL ;reset first-time 'SOH' flag MOV Byte Ptr FSTFLG,AL ;reset multi-file trans MOV Byte Ptr NFILFLG,AL ;turn off the memory save for disk file MOV Byte Ptr SAVEFLG,A ; VKEYIN: MOV DL,0FFH ; KEYIN FLAG FOR direct CONSOLE I?O MOV CL,6 INT 224 OR AL,AL JZ VKEYIN POP BX ;..by 'INITADR' routine POP DX POP CX RET ;..... ; ; STYPE: LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX ;zero out FTRNMSG MOV BX,(Offset FTRNMSG) MOV AL,0 ; ZEROLP: MOV Byte Ptr [BX],AL INC BX DEC CH JNZ ZEROLP MOV CH,12 ;put file name in FTRNMSG MOV BX, FCB+1 MOV DX,(Offset FTRNMSG) ; LOADMSG:MOV AL,4 ;start of file type? CMP AL,CL ;stop memory save in term routine. MOV AL,Byte Ptr VSEEFLG ;view flag set? OR AL,AL JNZ DONETCC ;if not, exit NOT AL MOV Byte Ptr QFLG,AL ;VSEEFLG also sets the QFLG MOV Byte Ptr VSEEFLG,AL ;reset the flag ; DONETCC:MOV BX, ; VTYPE: MOV DL,AL ; Direct Conout requirtes Char in DL MOV CL,6 INT 224 POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ; ; Get a character from the keyboard, convert to upper-case if needed, ; and show on CRT ; KBDCHH JZ PERIOD ;put in period if so MOV AL,Byte Ptr [BX] CMP AL,' ' ;don't put in space JZ SKPSP MOV SI,DX ;store in FTRNMSG MOV [SI],AL INC DX ; SKPSP: INC BX DEC CH MOV AL,CH OR AL,AL ;end of file name? JZ FTRNMSG0 ;display  Offset QFLG ;in quiet mode? MOV AL,Byte Ptr [BX] OR AL,AL MOV Byte Ptr [BX],'Q' ;reset the flag to normal JNZ L6A3 JMP MENU ;if yes, go back to command line L6A3: MOV AL,Byte Ptr ABORTFLG ;come here from a timeout? OR AL,AL JZ L6A4 ' R: CALL KEYIN ;get a keyboard character CALL UCASE ;convert to upper case if needed CALL STYPE ;show on CRT RET ;..... ; ; UCASE: CMP AL,61H ;changes lower case character.. JNB L6A8 RET ;..in 'A'reg. to upper case. L6A8: CMP ALhen resturns to command mode ; ERXIT: POP DX CALL PRTMSG MOV AL,BELL CALL STYPE CALL CRLF ; ERXIT1: MOV AL,1 MOV Byte Ptr ABORTFLG,AL ;shows an unintentional abort MOV AL,Byte Ptr BATCHFLG ;in batch mode? OR AL,AL JZ L6A12 JMP DON command line addressed by 'DE' registers (max # characters in ; line in 'DE', number of characters in line in DE+1, line starts in ; DE+2) into FCB addressed by 'BX' registers. The FCB should be at least ; 33 bytes in length. The command line buffer ,7AH+1 ;see if more than small 'Z' JNAE L6A9 RET L6A9: AND AL,5FH RET ;..... ; ; DECOUT: LAHF XCHG AL,AH PUSH AX PUSH CX PUSH DX PUSH BX MOV CX,-10 MOV DX,-1 ; DECOU1: ADD BX,CX INC DX JB DECOU1 MOV CX,10 ADD BX,CX XETCB ;if not, exit L6A12: JMP ABORT ;abort other computer ;..... ; ; ; Exits directly to CP/M ; EXIT: MOV AL,Byte Ptr OLDUSER ;get original user number back MOV DL,AL CALL SETUSER MOV CL,SETDMA MOV DX, ofFSET TBUF ;restore originalmust have a maximum length ; at least one more than the greatest number of characters that will be ; needed. CMDLINE:LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX CALL INITIAL ;fills FCBs with blanks and nulls XCHG BX,DX CHG BX,DX MOV AL,BH OR AL,BL JZ L6A10 CALL DECOUT L6A10: MOV AL,DL ADD AL,'0' CALL CTYPE POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ; ;----> DHXOUT: - double precision hex output routine ; DHXOUT: PUSH BX  buffer area INT 224 MOV CX,1A00H ;a little delay timer ; EXIT1: DEC CX ;one less loop to make MOV AL,CH OR AL,CL JNZ EXIT1 ;loop again till both are zero CALL CKCON ;catch any extra keyboard characters MOV AL,Byte Ptr NFILFLG ;sa ;get start of command line in hl. INC BX ;address # bytes in cmd line. MOV DL,Byte Ptr [BX] ;load de pair with # bytes. MOV DH,0 INC BX ADD BX,DX ;point to byte after last char.. MOV Byte Ptr [BX],CR ;..in cmd line and store delimiter. PLAHF XCHG AL,AH PUSH AX MOV AL,BH ;get ms byte CALL HEXO ;output high order byte MOV AL,BL ;get ls byte CALL HEXO ;output low order byte POP AX XCHG AL,AH SAHF POP BX RET ;..... ; ; ; Prints a hex value in 'A' on the CRT ving for a disk file? OR AL,AL JZ L6A13 CALL WRTFIL1 ;if yes, close the file L6A13: EXIT2: MOV CL,0 ;if not, reboot MOV DL,0 INT 224 ;..... ; ; ; Catch any extra keyboard characters coming through BDOS ; CKCON: MOV CL,CONST ;see OP BX ;restore BX and DE. POP DX PUSH DX PUSH BX INC DX ;address start of command. INC DX CALL DRIVE ; NAME1: MOV CL,8 ;transfer first filename to FCB. CALL TRANS CMP AL,CR JZ DONEL CMP AL,' ' ;if space, then start of.. JZ N; HEXO: LAHF XCHG AL,AH PUSH AX XCHG AL,AH RCR AL,1 RCR AL,1 RCR AL,1 RCR AL,1 CALL NIBBL POP AX XCHG AL,AH ; NIBBL: AND AL,0FH CMP AL,10 JB ISNUM ADD AL,7 ; ISNUM: ADD AL,'0' ;add in ASCII bias JMP CTYPE ;..... ; ; ;if any characters waiting INT 224 OR AL,AL JNZ L6A15 RET ;if not, exit L6A15: MOV CL,RDCON ;otherwise get the character INT 224 XOR AL,AL ;discard the character JMPS CKCON ;see if any others ;..... ; ; MOVE128:MOV CH,128 ; MAME2 ;..second filename. POP BX ;filetype must be after.. PUSH BX ;..eighth byte of name. MOV CX,9 ADD BX,CX MOV CL,3 ;transfer type of first file CALL TRANS CMP AL,CR JZ DONEL ; NAME2: MOV SI,DX ;eat multiple spaces.. MOV AL, Displays the control-characters shown in the menu ; SHFTYPE:LAHF XCHG AL,AH PUSH AX CALL ILPRT DB 'CTL-',0 POP AX XCHG AL,AH ADD AL,40H ;convert binary to ASCII chars. CALL STYPE ;show on the CRT JMPS ILPRT ;..... ; ; ; Write OVE: MOV AL,Byte Ptr [BX] MOV SI,DX MOV [SI],AL LAHF INC BX SAHF LAHF INC DX SAHF DEC CH JNZ MOVE RET ;..... ; ; ; Sends the character in 'A' to the modem ; SENDCHR:CALL SENDNOW ;wait until modem is ready for character MOV A[SI] CMP AL,' ' ;..between names. JNZ NAME3 INC DX JMPS NAME2 ; NAME3: POP BX ;second name starts in 16th byte. PUSH BX ;point BX to this byte. MOV CX,16 ADD BX,CX CALL DRIVE MOV CL,8 CALL TRANS CMP AL,CR JZ DONEL POP BX a string of characters to the CRT ; ILPRT: POP SI ; ILPRT1: LODS BYTE PTR [SI] ;get the character OR AL,AL ;see if a "0" for end of string JZ ILPRT2 ;if yes, all done CALL CTYPE ;show on CRT JMPS ILPRT1 ; ILPRT2: PUSH SI ;restore theL,CH ;get the original character back JMP OUT_MODDATP ;send the character to modem, return ;..... ; ; ; Initializes CP/M file control blocks AT 5CH and 6CH ; SETFCB: MOV DX, Offset CMDBUF MOV BX, FCB JMPS CMDLINE ;..... ; ; ; Adjusts loo ;second type starts in 25th byte. PUSH BX MOV CX,25 ADD BX,CX MOV CL,3 CALL TRANS ; DONEL: POP BX PUSH BX INC BX ;point to 1st char of 1st name in FCB CALL SCANL ;check for * (ambiguous names) POP BX PUSH BX MOV CX,17 ;..to 1 address RET ;..... ; ; ; Write a string of characters unless in the Quiet mode ; ILPRTQ: POP SI ; ILPRTQ1:LODS Byte Ptr [SI] ;get the character OR AL,AL ;see if a "0" for end of string JZ ILPRTQ2 ;if yes, all done MOV BL,Byte Ptr p counter for the selected clock speed. Returns with delay ; in 'BX'. ; FIXCNT: MOV AL,Byte Ptr CLOCK ;get the user's clock speed PUSH DX ;save the current 'DE' value PUSH BX POP DX ;get same value into 'DE' as in 'BX' ; CNTMUL: LAHF st char of second name in FCB ADD BX,CX CALL SCANL POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ; ; Subroutines for CMDLINE section ; INITIAL:PUSH BX ;initializes FCB with 1 null (for first drive).. PUSH CX ;..11 bQFLG OR BL,BL JZ ILPRTQ1 CALL CTYPE ;show on CRT if not in quiet mode JMPS ILPRTQ1 ; ILPRTQ2:PUSH SI ;restore the address RET ;..... ; ; PRTMSG: MOV CL,PRINT ;print the string INT 224 RET ;..... ; ; ; Displays error statement t ;add 'DE' to 'BX' ADD BX,DX RCR SI,1 SAHF RCL SI,1 DEC AL ;one less to go JNZ CNTMUL POP DX ;restore current 'DE', delay in 'BX' RET ;..... ; ; ;======================================================================= ; ; Loads a' lanks, 4 nulls, 1 null (for 2nd drive).. MOV Byte Ptr [BX],0 ;..11 blanks, and 4 nulls. LAHF INC BX SAHF MOV CH,11 MOV AL,' ' CALL INITFILL MOV CH,5 XOR AL,AL CALL INITFILL MOV CH,11 MOV AL,' ' CALL INITFILL MOV CH,4 XOR AL,Aypassed, if you wish this feature, put ; JMP DIRLIST2 instead of JMP DIRLIST3 in the eighth line. The ; current disk (plus the A: drive) will then reset each DIR re- ; quest. You can also reset the disk with the LOG command when ; when inserting a dift end of line or.. ; ;..LAST FILENAME NOFENCE:POP BX POP DX POP AX XCHG AL,AH SAHF JMPS DIRLOOP ;..... ; ; ; Determine storage remaining on default drive ; STORAGE: CALL CRLF MOV CL,DSKPAR ;current disk parameter block INT 224 L CALL INITFILL POP CX POP BX RET ;..... ; ; INITFILL: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ INITFILL RET ;..... ; ; DRIVE: INC DX ;check 2nd byte of filename. if it.. MOV SI,DX ;..is a ":", then drive was spferent one. This saves a reset each time ; DIR might be requested. ; DIRLIST:CALL GETDISK ADD AL,'A' ;change to ascii MOV Byte Ptr DRNAME,AL ;show for drive name MOV Byte Ptr ACTDRV,AL ;show for space remaining on drive ; DIRLIST1: JMPS DIR ADD BX,2 MOV AL,ES: BYTE PTR [BX] ;Get Block Shift Factor MOV BSHIFTF,AL INC BX ;bump to block mask MOV AL,ES: BYTE PTR [BX] ;get it MOV BMASK,AL ADD BX,2 MOV DX,ES: WORD PTR [BX] ;get max block number MOV Word Ptr BMAX,DX ;put it away ecified.. MOV AL,[SI] DEC DX CMP AL,':' JNZ DEFDR ;..else zero for default drive .. MOV SI,DX ;..('INIT' put zero) MOV AL,[SI] AND AL,5FH SUB AL,40H ;calculate drive (A=1, B=2,...).. MOV Byte Ptr [BX],AL ;..and place it in FCB. LALIST3 ; DIRLIST2: MOV CL,RESET ;13 reset disk system (resetdk) INT 224 ; ; ; Directory list routine ; DIRLIST3: MOV DX, Offset CMDBUF ;put command line in FCBb.. MOV BX, FCB ;..addressed by BX-reg.. CALL CMDLINE ;..and then... MOV B MOV CL,DSKALL ;address of CP/m Allocation vector INT 224 XCHG BX,DX ;get its length MOV BX, Word Ptr BMAX INC BX MOV CX,0 ;initialize block count to zero GSPBYT: PUSH DX ;save allocation address XCHG BX,DX MOV AL,ES: BYTE PTR [BX] HF ;address first byte of.. INC DX SAHF LAHF ;..in command line,.. INC DX SAHF ; DEFDR: LAHF ;..and name field in FCB INC BX SAHF RET ;..... ; ; TRANS: MOV SI,DX ;transfer from command line to FCB.. MOV AL,[SI] INC DX X, Offset FCB4 CALL INITFCB MOV AL,Byte Ptr .FCB2 ;get drive number MOV Byte Ptr FCB4,AL MOV AL,Byte Ptr .FCB2+1 CMP AL,' ' ;if a space (blank) get all names LAHF XCHG AL,AH PUSH AX JNZ L6A19 CALL QSTMARK L6A19: POP AX XCHG AL,AH XCHG BX,DX MOV DL,8 ;set to process 8 blocks GSPLUP: RCL AL,1 ;test bit JC NOTFRE INC CX NOTFRE: MOV DH,AL ;save bits DEC BX MOV AL,BL OR AL,BH JZ ENDALC ;quit if out of blocks MOV AL,DH ;restore bits DEC DL ;count dow ;..up to number of chars specified.. CMP AL,CR ;..by 'C' reg. keep scanning field.. JNZ L6A16 RET ;..without transfer until a delimiting.. L6A16: CMP AL,'.' ;..field char such as '.', blank, or.. JNZ L6A17 RET ;..CR (for end of comm SAHF JZ L6A20 CALL MOVNAME ;else move name into FCB L6A20: CALL DRIVEL MOV CL,SETDMA MOV DX, TBUF INT 224 MOV AL,Byte Ptr NOOFCOL ;number of columns into 'A' reg. MOV Byte Ptr NAMECT,AL ;CRLF after 'NOOFCOL' number of columns n 8 bits JNZ GSPLUP ;do another bit POP DX ;bump to next count.... INC DX ;...of allocation vector JMP GSPBYT ;process it ; ENDALC: POP DX ;clear allocation vector pointer from stack MOV BX,CX ;copy block to bx MOV AL,Byte Ptr Bmand line). L6A17: CMP AL,' ' JNZ L6A18 RET L6A18: DEC CL JS TRANS ;once c-reg is less than zero, keep.. MOV Byte Ptr [BX],AL ;..reading cmd line but do not.. INC BX ;..transfer to FCB. JMPS TRANS ;... ; ; SCANL: MOV CH,8 ;scan  MOV DX, Offset FCB4 MOV CL,SRCHF ;do first search INT 224 INC AL ;0FFH --> 0 if no file(s) found JNZ DIRLOOP CALL ILPRT DB '++ FILE NOT FOUND ++',0 JMP STORAGE ;still show storage on default drive ; DIRLOOP:CALL GETADD LAHF ;poiSHIFTF ;get block shift factor SUB AL,3 ;convert from record to K JZ PRTFREE ;skip shifts of 1K blocks FREKLP: ADD BX,BX ;multiply blocks by 'K per block' DEC AL JNZ FREKLP ; PRTFREE:CALL DECOUT ;(# of free k bytes now in 'BX') MOV Dfile name addressed by BX. ; TSTNAM: MOV AL,Byte Ptr [BX] CMP AL,'*' ;if '*' found, fill in rest of field.. JZ FILL1 ;..with '?' for ambiguous name. INC BX DEC CH JNZ TSTNAM JMPS TSTTYP ;... ; ; FILL1: CALL FILL ; TSTTYP: MOV CH,3 nt to first letter of filename INC BX SAHF MOV DX,(Offset PRTNAME) MOV CX,8 CALL MOVER LAHF INC DX SAHF MOV CX,3 CALL MOVER CALL ILPRT ; PRTNAME DB ' ','.',' ',0 ; 8 spaces, period, 3 spaces ; NEXTSR: MOV DX, oFFSET FCB4X,(Offset FREEMSG) JMP PRTMSG ;..... ; ; ; Subroutines for 'DIRLIST' section ; QSTMARK:MOV AL,'?' ;if blank in FCB, put in 11 ?'S. MOV CH,11 MOV BX, oFFSET FCB4+1 ; QSTLP: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ QSTLP R ;scan and fill type field for name.. ; TSTTYPL:MOV AL,Byte Ptr [BX] ;..specified above. CMP AL,'*' JZ FILL2 LAHF INC BX SAHF DEC CH JNZ TSTTYPL RET ;..... ; ; FILL2: CALL FILL RET ;..... ; ; FILL: MOV Byte Ptr [BX],'?' ;routine MOV CL,SRCHN ;do next search INT 224 INC AL ;if 0FFH --> 0 then.. JZ STORAGE ;..directory-read finished. LAHF XCHG AL,AH PUSH AX PUSH DX PUSH BX MOV AL,Byte Ptr NAMECT DEC AL MOV Byte Ptr NAMECT,AL ;name count updated ORET ;..... ; ; MOVNAME:MOV BX, FCB2+1 MOV DX, Offset FCB4+1 MOV CX,11 CALL MOVER RET ;..... ; ; GETADD: DEC AL ;un-do the inr above ADD AL,AL ;times 32 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,TBUF ;add buffer offset  transfers '?'. LAHF INC BX SAHF DEC CH JNZ FILL RET ;======================================================================= ; ; LISTS DIRECTORY AND GIVES FREE SPACE REMAINING ON THE REQUESTED DRIVE. ; ; ; Disk system reset - currently b AL,AL JNZ L6A21 CALL CRLF ;terminate line of file names L6A21: JNZ FENCE MOV AL,Byte Ptr NOOFCOL ;restart columns-per-line count MOV Byte Ptr NAMECT,AL JMPS NOFENCE ;fence not needed ; FENCE: CALL ILPRT DB ' : ',0 ;fence if not a(  MOV BL,AL MOV BH,0 RET ;..... ; ; DRIVEL: MOV AL,Byte Ptr FCB4 ;if no drive, use OR AL,AL ;default drive in drname. JZ PRNTHD LAHF XCHG AL,AH PUSH AX XCHG AL,AH DEC AL MOV DL,AL MOV CL,SELDSK INT 224 POP AX XCHG AL;compare count to maximum JNB L6A27 JMP ALERTL ;if maximum, ring bell and wait for cr. L6A27: XCHG BX,DX ;restore buffer pointer to 'BX' MOV Byte Ptr [BX],CH ;put inputted character in buffer MOV AL,CH ;output it CMP AL,EXITCHR ;exit chestore.. PUSH DX ;..stack MOV CH,Byte Ptr [BX] ;save maximum in 'B' LAHF ;point to first.. INC BX SAHF LAHF ;..buffer byte. INC BX SAHF MOV AL,' ' ; CLEARL: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ CLEARL RET,AH ADD AL,40H ;make 1=a, 2=b, etc., and.. MOV Byte Ptr DRNAME,AL ;..overwrite default stored below. MOV Byte Ptr ACTDRV,AL ; PRNTHD: CALL ILPRT DB 'Drive ' ; DRNAME DB ' :',CR,LF,0 RET ;..... ; ; ; Initialized storage ; FREEMSG DB 'karacter? JNZ L6A28 JMP INBUFR ;if yes, all done L6A28: CMP AL,20H ;printing character? JNAE L6A29 CALL STYPE ;if yes, print it L6A29: LAHF ;bump pointer INC BX SAHF JMPS INBUFB ;get next character ;... ; ; DELETE: XCHG B ;..... ; ; ;======================================================================= ; ; In-line compare. Compares string addressed by 'DE' to string after ; call (ends with zero). Return with carry set means strings not the ; same. All register bytes free on drive ' ACTDRV DB ' :',CR,LF,'$' ; ; ; Uninitialized storage ; BMAX Rb 2 ;highest block number on drive BMASK Rb 1 ;rec/blk - 1 BSHIFTF Rb 1 ;number of shifts to multiply by rec/blk ;..... ; ; ;=============================X,DX ;save buffer pointer in 'DE' POP BX ;address beginning of buffer PUSH BX ;restore stack INC BX ;address count field MOV AL,Byte Ptr [BX] SUB AL,1 ;decrease count MOV Byte Ptr [BX],AL JB NODEL ;don't delete past beginning of bs except 'A'-reg are unaffected. ; INLNCOMP: POP BX ;point 'SI' to 1st char. PUSH DX ; ILCOMPL:MOV AL,Byte Ptr [BX] ;'BX' points to in-line string. OR AL,AL ;end of string if zero. JZ SAME MOV SI,DX MOV AL,[SI] CMP AL,Byte Ptr [BX] ========================================== ; ; Duplicates 'READ BUFFER' routine same as CP/M function 10, but does ; not use CTL-C (reason for the routine). Does allow controls U, R, E ; and H (BACKSPACE). Outputs bell if the input is greater than thuffer XCHG BX,DX ;restore buffer pointer to 'BX' DEC BX ;point to last byte inputted MOV AL,Byte Ptr [BX] ;get character being deleted MOV Byte Ptr [BX],' ' ;restore blank CMP AL,' ' ;see if non-printing character JB DELETE1 ;if yesJNZ NOTSAME INC BX INC DX JMPS ILCOMPL ;... ; ; NOTSAME:XOR AL,AL ;if not same, finish thru.. ; NSLP: INC BX ;..string so return will.. CMP AL,Byte Ptr [BX] ;..go to instruction after.. JNZ NSLP ;..string and not remainder of string. e ; buffer. ; INBUF: LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH BX PUSH CX PUSH DX ;'DE' registers must be pushed last ; INBUFA: CALL CLEARBUF ;clear the buffer area POP DX ;get address of buffer on retries PUSH DX ;restore stack , skip the CRT backup MOV AL,BKSP CALL STYPE ;true erase if 08H MOV AL,' ' CALL STYPE MOV AL,BKSP CALL STYPE DELETE1: JMP INBUFB ;..... ; ; MORE DB '12345' ;5 bytes extra from DELETE routine fix ; NODEL: INC Byte Ptr [BX] ;do STC ; SAME: POP DX LAHF ;avoids a NOP instruction.. INC BX SAHF PUSH BX ;..when returning. RET ;..... ; ; ;======================================================================= ; ; Multi-file access subroutine. Allows processing XOR AL,AL LAHF ;address count field INC DX SAHF MOV SI,DX ;initialize with a zero in count byte MOV [SI],AL LAHF INC DX SAHF XCHG BX,DX ;address first buffer byte with 'BX' ; INBUFB: CALL KEYIN ;(waits for char) CALL UCASE n't leave count negative XCHG BX,DX ;restore pointer to 'BX' MOV AL,BELL ;says can go no further CALL STYPE JMP INBUFB ;..... ; ; INBUFO: MOV AL,'#' ;announces the line has been removed CALL STYPE CALL CRLF JMP INBUFA ;..... ; ;  of multiple files ; (i.e., *.ASM) from disk. Builds the correct name in the FCB each time ; it is called. The command is used in programs to process single or ; multiple files. The FCB is set up with the next name, ready to do ; normal processing ( ;convert to upper case if needed CMP AL,CR ;is it (enter command)? JNZ L6A24 JMP INBUFR ;if so, then return. L6A24: CMP AL,08H ;CTL-H backspaces over deleted character JZ DELETE CMP AL,7FH ;is it a delete? JZ DELETE CMP A RETYPE: POP DX PUSH DX LAHF ;point to current number.. INC DX SAHF MOV SI,DX ;..of characters. MOV AL,[SI] MOV CH,AL MOV AL,'#' CALL STYPE CALL CRLF MOV AL,CH ;test if zero input OR AL,AL JNZ CTLRLP JMP INBUFB ;... ; open, read, etc.) when routine is called. Carry is ; set if no more names are found. MFNAME: PUSH CX PUSH DX PUSH BX MOV CL,SETDMA MOV DX, TBUF INT 224 POP BX POP DX POP CX XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV AL,Byte Ptr MFFLG1 L,'U'-40H ;is it a CTL-U? JNZ L6A25 JMP INBUFO ;output #, CR, LF, and start over L6A25: CMP AL,'R'-40H ;CTL-R retypes line JNZ L6A26 JMP RETYPE L6A26: ; INBUFC: MOV CH,AL ;save inputted character XCHG BX,DX ;save 'BX' in 'DE' POP ; CTLRLP: LAHF INC DX SAHF MOV SI,DX MOV AL,[SI] CALL STYPE DEC CH JNZ CTLRLP JMP INBUFB ;..... ; ; ALERTL: MOV AL,BELL ;alarm for full buffer CALL STYPE DEC Byte Ptr [BX] XCHG BX,DX JMP INBUFB ;..... ; ; PCRLF: CALL CRLOR AL,AL JNZ MFNAME1 MOV AL,1 MOV Byte Ptr MFFLG1,AL MOV BX, FCB MOV DX, Offset MFNAME5 MOV CX,12 CALL MOVER MOV AL,Byte Ptr .FCB MOV Byte Ptr MFNAME6,AL ;save disk in current FCB MOV BX, Offset MFNAME5 MOV DX, FCB MOV CX,12 CABX ;get address of buffer in 'BX' PUSH BX ;restore stack INC BX ;address count byte INC Byte Ptr [BX] ;increase count byte DEC BX ;address maximum MOV AL,Byte Ptr [BX] ;put maximum in 'A' INC BX ;address count CMP AL,Byte Ptr [BX] F JMP INBUFB ;..... ; ; INBUFR: CALL CRLF ;1st new line after a command character POP DX POP CX POP BX POP AX XCHG AL,AH SAHF RET ;..... ; ; CLEARBUF: POP DX ;accounts for call POP BX ;address buffer in 'BX' PUSH BX ;r( LL MOVER PUSH CX PUSH DX PUSH BX MOV CL, SRCHF MOV DX, FCB INT 224 POP BX POP DX POP CX JMPS MFNAME2 ;... ; ; MFNAME1:MOV BX, Offset MFNAME6 MOV DX, FCB MOV CX,12 CALL MOVER PUSH CX PUSH DX PUSH BX MOV CL,SRCHF MOV D ;get index for baud rate MOV DL,AL LAHF ;index into table ADD BX,DX RCR SI,1 SAHF RCL SI,1 MOV AL,Byte Ptr [BX] ;get multiplier POP BX ;get remainder CALL MULHLA ;multiply the 'BX' x 'A' CALL SHFTHL CALL SHFTHL CALL SHFTHNES ; ; ; Check 'CRC' bytes of record just received ; CRCCHK: PUSH BX MOV BX,Word Ptr CRCVAL MOV AL,BH OR AL,BL POP BX JNZ L7A7 RET L7A7: MOV AL,0FFH RET ;..... ; ; ; Generate the CRC tables for fast calculations ; CRCGEN: MOV BX, FCB INT 224 POP BX POP DX POP CX MOV BX,Offset MFNAME5 MOV DX,FCB MOV CX,12 CALL MOVER PUSH CX PUSH DX PUSH BX MOV CL,SRCHN MOV DX, FCB INT 224 POP BX POP DX POP CX ; MFNAME2:INC AL STC JNZ MFNAME3 MOV Byte Ptr L CALL SHFTHL MOV BH,0 CALL DECOUT ;print the seconds portion CALL ILPRT DB ' secs at ',0 CALL PRTBAUD CALL ILPRTQ DB 'To cancel: use CTL-X',CR,LF,0 RET ; BTABLE DW 5,13,20,26,29,48,85,152,280,480,0 ;records/min for.. RECDBL DB 192,7X, OFFSET CRCTBL ;address at start of 'CRC' lookup table MOV CL,0 ; CRCGEN1:XCHG BX,DX ;store table location into 'DE' MOV BX,0 ;clear 'BX' pair MOV AL,CL PUSH CX MOV CH,8 XOR AL,BH MOV BH,AL ; CRCGEN2:SHL BX,1 ;index into the tableMFFLG1,AL RET ;..... ; ; MFNAME3:DEC AL AND AL,3 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,81H MOV BL,AL MOV BH,0 PUSH BX ;save name pointer MOV DX, Offset MFNAME6+1 MOV CX,11 CALL MOVER POP BX MOV DX, 4,48,37,33,20,11,6,3,2,0 ;110-19200 baud ;..... ; ; ; Shows baud rates set for 'time to send' file transfer ; PRTBAUD:MOV BX,(Offset BAUDSPD) MOV DH,0 MOV AL,Byte Ptr MSPEED ;get baud rate code MOV DL,AL ;x1 ADD AL,AL ;x2 ADD AL,AL  JNB CRCGEN3 MOV AL,16 ;using x^ 16 + x^12 + x^5 + 1 algorithm XOR AL,BH MOV BH,AL MOV AL,32+1 XOR AL,BL MOV BL,AL ; CRCGEN3:DEC CH JNZ CRCGEN2 ;make 8 loops, one for each bit ; ; ; Value now in 'BX', table address still stored in FCB+1 MOV CX,11 CALL MOVER XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV Byte Ptr .FCBRNO,AL RET ;..... ; ; MFNAME4: MOVER: MOV AL,Byte Ptr [BX] ;used if an 8080 CPU is active MOV SI,DX MOV [SI],AL INC BX INC DX DEC CX MOV AL,CH OR A ;x4 ADD AL,DL ;x5 ADD AL,DL MOV DL,AL LAHF ;point to correct rate ADD BX,DX RCR SI,1 SAHF RCL SI,1 XCHG BX,DX MOV CL,PRINT INT 224 CALL ILPRT DB ' bps ',CR,LF,0 RET ;..... ; ; BAUDSPD DB '110$',0,0,'300$',0,0,'450$',0'DE'. Exchange, and ; store the 'CRC' value in the two tables after splitting. ; POP CX ;finished borrowing the 'B' reg. XCHG BX,DX ;address back in 'BX', 'CRC' in 'DE' MOV Byte Ptr [BX],DH ;store 1st part of 'CRC' value INC BH ;move up 25L,CL JNZ MFNAME4 RET ;..... ; ; (END OF MULTI-FILE ACCESS ROUTINE) ;======================================================================= ; CALCULATE FILE TRANSFER TIME ; ; ; Shows the time to transfer a file at various baud rates. (110-,0,'600$',0,0,'710$',0,0 DB '1200$',0,'2400$',0,'4800$',0,'9600$',0,'19200$' ;..... ; ; ;----> DVHLDE: Divides 'BX' by value in 'DE', ; Upon exit: 'BC'=quotient,'BL'=remainder ; DVHLDE: PUSH DX ;save divisor MOV AL,DL NOT AL ;negate divis6 bytes MOV Byte Ptr [BX],DL ;store 2nd part of 'CRC' value DEC BH ;move back 256 bytes LAHF ;increment to next location INC BX SAHF INC CL ;done when 'C' reg. turns zero again JNZ CRCGEN1 ;now go do the next location RET ;..... 19200) ; SENDTIME: CALL ILPRT ;print following message: DB 'File open: ',0 MOV BX,Word Ptr RCNT ;get record count. CALL DECOUT ;print decimal number of records ; MOV AL,Byte Ptr HEXSHOW OR AL,AL JZ SENDTIME1 CALL ILPRT DB ' (or MOV DL,AL MOV AL,DH NOT AL MOV DH,AL LAHF ;'DE' is now two's complemented INC DX SAHF MOV CX,0 ;init quotient ; DIVL1: LAHF ;subtract divisor from dividend ADD BX,DX RCR SI,1 SAHF RCL SI,1 LAHF ;bump quotient INC; ; ; Update the CRC value from a character in the 'A' register ; CRCUPD: LAHF ;save all registers just in case XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX MOV BX,Word Ptr CRCVAL ;get current value XCHG BX,DX ;put in ',0 CALL DHXOUT ;now print size in hex. CALL ILPRT DB 'H)',0 ; SENDTIME1: CALL ILPRT DB ' records' DB CR,LF,'Send time: ',0 MOV AL,Byte Ptr MSPEED ;get the speed indicator MOV DH,0 MOV DL,AL ;set up for table access MOV BX,(Offset CX SAHF JB DIVL1 ;loop till sign changes LAHF ;adjust quotient DEC CX SAHF POP DX ;retrieve divisor LAHF ;adjust remainder ADD BX,DX RCR SI,1 SAHF RCL SI,1 RET ;..... ; ; ;----> MULHLA: Multiply the value in 'BX' by 'DE' for now MOV CH,0 XOR AL,DH MOV CL,AL ;now have the character in 'BC' pair MOV BX, Offset CRCTBL ;start of 'CRC' lookup-table ADD BX,CX ;index into the 'CRC' table MOV AL,Byte Ptr [BX] ;get the value from the table XOR AL,DL MOV DH BTABLE) ;point to baud factor table LAHF ;index to proper factor ADD BX,DX SAHF LAHF ;factor in 'DE' ADD BX,DX SAHF MOV DL,Byte Ptr [BX] LAHF INC BX SAHF MOV DH,Byte Ptr [BX] MOV BX,Word Ptr RCNT ;get # of records CALthe value in 'A' ; Return with answer in 'BX' ; MULHLA: XCHG BX,DX ;multiplicand to 'DE' MOV BX,0 ;init product INC AL ;adjust multiplier for zero test ; MULLP: DEC AL JNZ L7A5 RET L7A5: LAHF ADD BX,DX RCR SI,1 SAHF RCL SI,1,AL INC BH ;move 256 bytes for 2nd table location MOV DL,Byte Ptr [BX] ;put value there into 'E' register XCHG BX,DX ;put 'DE' into 'BX' MOV Word Ptr CRCVAL,BX ;updated 'CRC' value with this character POP BX ;restore all registers POPL DVHLDE ;divide BX by value in DE (records/min) PUSH BX MOV BX,CX CALL DECOUT ;print the minutes portion CALL ILPRT DB ' mins, ',0 MOV BX,(Offset RECDBL) ;point to divisors for seconds MOV DX,0 ; calculation MOV AL,Byte Ptr MSPEED  JMPS MULLP ;..... ; ; ; Shift 'BX' register pair one bit to the right ; SHFTHL: RCR BX,1 RET ;..... ; ; ; (END OF FILE TRANSFER TIME ROUTINE) ;======================================================================= ; CRC SUBROUTI)  DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ;==================== END OF CRC SUBROUTINE ============================ ; ; ;=========================START OF MENU ================================ ; ; MENU0: MOV AL,Byte Ptr NFILFLG OR  CP/M' DB CR,LF,LF DB ' The single letter commands may also be used on ' DB 'the',CR,LF DB ' command line when the program is initially ' DB 'executed.',CR,LF,LF,0 ; THREELTR: CALL JMP_NXTSCRN CALL ILPRT DB ' Three line',CR,LF,LF DB ' The following are terminal text ' DB 'buffer commands:',CR,LF,LF,0 ; SKIPLF: CALL ILPRT DB 'DEL - Delete memory buffer and file',CR,LF DB 'WRT - Write memory buffer to disk file',CR,LF,LF,0 CALL NXTSCRN CALL ILPAL,AL JZ MENU ;exit if not saving memory for disk file CALL ILPRT ;else print message DB CR,LF,'** File still open, use DEL, DIR, WRT, E, L ' DB 'or T ** ',CR,LF,BELL,0 JMPS MENU1 ; MENU: XOR AL,AL MOV Byte Ptr ABORTFLG,AL ;null the flae Letter Commands',CR,LF,LF DB 'CPM - Exit from this program to CP/M',CR,LF DB 'DIR - List directory and space free (may specify ' DB 'drive)',CR,LF DB 'ERA - Erase file (may specify drive)',CR,LF DB 'LOG - Change default drive/user no. (specify RT DB ' Local Commands while in Terminal Mode' DB CR,LF,LF,0 MOV AL,Byte Ptr BRKCHR CALL SHFTYPE DB ' - Send a break tone for 300 ms.',CR,LF,0 MOV AL,Byte Ptr PMMIMODEM OR AL,AL JZ SKIPLF1 MOV AL,Byte Ptr CHGBAUD CALL SHFTYPE g ; MENU1: MOV BX, OFFSET RESTSN ;restore record numbers.. MOV DX, OFFSET RECDNOB ;..for new file transfer. MOV CH, (OFFSET RECDNOE)-(OFFSET RECDNOB) CALL MOVE MOV BX,OFFSET RESTROPT ;restore option table MOV DX,OFFSET OPTBL MOV CH, (O' DB 'drive/user)',CR,LF DB ' and reset disks. e.g. LOG A0: or LOG B: ' DB '(user # unchanged)',CR,LF DB 'SPD - Set file output speed in terminal mode' DB CR,LF,0 ; CALL SORPTST JNZ NOTIME CALL ILPRT DB 'TIM - Select Baud rate forDB ' - Change baud rate',CR,LF,0 ; SKIPLF1:MOV AL,EXITCHR CALL SHFTYPE DB ' - Exit to command mode',CR,LF,0 MOV AL,Byte Ptr TRANLOGON OR AL,AL JZ NOTRNLOG MOV AL,Byte Ptr LOGCHR CALL SHFTYPE DB ' - Send log-on message',CR,LF,0 ; NOTRFFSET OPTBE)-(OFFSET OPTBL) CALL MOVE XOR AL,AL MOV Byte Ptr FSTFLG,AL MOV Byte Ptr TIMFLG,AL MOV Byte Ptr FLTRFLG,AL ;reset multi-file trans MOV Byte Ptr MFFLG1,AL ;reset mfaccess routine.. JMP XPRT ;..... ; ; ; * * * * * * * * *  "time-to-send" msg.',CR,LF,0 ; NOTIME: MOV AL,Byte Ptr TOGGLECRC OR AL,AL JZ NOTOCRC CALL ILPRT DB 'TCC - Toggle CRC/Checksum mode on receive',CR,LF,0 ; NOTOCRC:MOV AL,Byte Ptr TOGGLELOC OR AL,AL JZ NOTOGLOC CALL ILPRT DB 'TLC - ToggleNLOG: MOV AL,Byte Ptr NOCONNCT CALL SHFTYPE DB ' - Disconnect from the phone line',CR,LF,0 MOV AL,Byte Ptr LSTTST OR AL,AL JZ NOTLIST MOV AL,Byte Ptr LSTCHR CALL SHFTYPE DB ' - Toggle printer',CR,LF,0 ; NOTLIST:MOV AL,LF CALL STYPE * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; MENU OF COMMANDS ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; MENU2: CALL CLRTST CALL ILPRT DB ' Single Letter Commands',CR,LF,LF DB local command immediate or after ',0 MOV AL,Byte Ptr EXTCHR CALL SHFTYPE DB CR,LF,0 ; NOTOGLOC: MOV AL,Byte Ptr TOGGLELF OR AL,AL JZ NOTOGRUB CALL ILPRT DB 'TLF - Toggle LF after CR in "L" or "T" mode for ' DB 'a disk file',CR,LF,0 ;  MOV AL,Byte Ptr SAVECHR CALL SHFTYPE DB ' - Start copy into buffer',CR,LF,0 MOV AL,Byte Ptr UNSAVECHR CALL SHFTYPE DB ' - Stop copy into buffer',CR,LF,LF DB ' Start & Stop may be toggled as often as ' DB 'desired.',CR,LF DB  ' ? - Display current settings',CR,LF MENU3 DB ' ^ - Function key intercept character, ' DB 'then (0-9)',CR,LF DB ' M - Display the menu',CR,LF DB ' E - Terminal mode with echo',CR,LF DB ' L - Terminal mode with local echo',CR,LF DB ' T - NOTOGRUB: MOV AL,Byte Ptr TOGGLERUB OR AL,AL JZ NOTOGLF CALL ILPRT DB 'TRB - Toggle rubout to backspace conversion',CR,LF,0 ; NOTOGLF:MOV AL,Byte Ptr TOGXOFF OR AL,AL JZ NOTOGXOF CALL ILPRT DB 'TXO - Toggle XOFF testing in terminal mod' A ";" at start of line indicates buffer ' DB 'is copying.',CR,LF DB ' XOFF automatically used to stop input ' DB 'when writing',CR,LF DB ' full buffer to disk, XON sent to ' DB 'resume.',CR,LF,LF,0 MOV A Terminal mode',CR,LF DB ' For copying text to disk use T (E or L) ' DB 'FILENAME.TYP',CR,LF DB ' Start or Stop toggles described on subsequent' DB ' screen.',CR,LF DB ' R - Receive CP/M file using Christensen Protocol' DB CR,Le ' DB 'file output',CR,LF,0 ; NOTOGXOF: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ NONUM MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ NOTOGX2 ; NOTOGX1:CALL ILPRT DB 'NUM - List remote systems',CL,Byte Ptr TRANCHR CALL SHFTYPE DB ' - Transfer ASCII file to remote',CR,LF,LF,0 MOV AL,Byte Ptr LOCNXTCHR OR AL,AL MOV AL,Byte Ptr EXTCHR JNZ REMDFLT CALL SHFTYPE DB ' - Send local control character to remote' DB CR,LF,LF,0 JMPS CKSPF DB ' S - Send CP/M file using Christensen Protocol',CR,LF DB ' COMMAND: R (or S) FILENAME.TYP',CR,LF DB ' R and S can use the following subcommands:' DB CR,LF DB ' B - Bulk transfer using wildcards ' DB '(e.g., *.R,LF,0 ; NOTOGX2:MOV AL,Byte Ptr SETUPTST OR AL,AL JZ NONUM CALL ILPRT DB 'SET - Set modem baud rate',CR,LF,0 ; NONUM: CALL ILPRT DB 'BYE - Disconnect, then return to CP/M' DB CR,LF,0 MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR ACL ; REMDFLT:CALL SHFTYPE DB ' - Next character will be used for local control' DB CR,LF,0 ; CKSPCL: CALL JMP_SPCLMENU ;may have a special menu in the overlay ; ;FALLS ON THROUGH TO 'XPRT' ; ; ; (END OF COMMAND MENU) ;================*)',CR,LF DB ' D - Disconnect when done' DB CR,LF DB ' Q - Quiet mode (no messages to console)' DB CR,LF DB ' V - View or bytes on console' DB CR,LF DB ' X - When done, disconnect, go toL,AL JNZ NONUM0 ;if yes, display 'CAL' MOV AL,Byte Ptr AUTODIAL ;usina a Hayes-type modem? OR AL,AL JZ NOPMMI ;exit if neither ; NONUM0: CALL ILPRT DB 'CAL - Dial number',CR,LF,0 ; NOPMMI: CALL ILPRT DB 'DSC - Disconnect from the phon) ======================================================= ; START OF COMMAND LINE HANDLING ; ; ; Check first to see if a file was opened for copying incoming to disk ; XPRT: CALL CRLF ;turn up a blank line to look nice L7A8: MOV AL,Byte Ptr Nf yes, exit MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ NONUM1 ;if yes, exit CALL INLNCOMP DB 'NUM',0 JNAE L7A24 JMP NUMPRN L7A24: ; NONUM1: MOV AL,Byte Ptr SETUPTST OR AL,AL JZ NXTOPT1 CALL INLNCOMP DB 'SE binary to ASCII digits CALL STYPE MOV AL,' ' CALL STYPE ; FUNCT3: INC BX ;next table location MOV AL,Byte Ptr [BX] OR AL,AL ;see if a binary zero JZ FUNCT5 CMP AL,CR JNZ FUNCT4 CALL ILPRT DB '',0 JMPS FUNCT3 ; FUNCT4: CAFILFLG ;have a file open for text mode copy? OR AL,AL JZ XPRT1 ;if not, exit ; CALL GETSPC ;otherwise show remaining space CALL ILPRT DB ' Bytes of buffer free',CR,LF,LF,0 ; ; ; Show disk drive and user number, then command line ; XT',0 JNAE L7A25 JMP SETUPENT L7A25: ; NXTOPT1:CALL INLNCOMP DB 'WRT',0 JNAE L7A26 JMP WRTFIL L7A26: CALL INLNCOMP DB 'DEL',0 JNAE L7A27 JMP NEWFILE L7A27: CALL INLNCOMP DB 'BYE',0 JNAE L7A28 JMP BYEBYE L7A28: CALL INLNCOMPLL STYPE JMPS FUNCT3 ; FUNCT5: CALL CRLF DEC CH JNZ FUNCT2 CALL CRLF JMP XPRT ;..... ; ; BYEBYE: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JZ L7A30 CALL JMP_GOODBYE ;if yes, disconnect L7A30: MOV AL,Byte Ptr AUTODIPRT1: MOV CL,CURDSK ;current disk function INT 224 ADD AL,'A' ;make ASCII CALL STYPE CALL GETUSER ;get current user number OR AL,AL JZ XPRT2 ;skip if user 0 MOV BH,0 MOV BL,AL CALL DECOUT ;show current user area ; XPRT2: MOV AL DB 'DSC',0 JNAE L7A29 JMP DONETCD L7A29: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ NXTOPT0 ;if yes, exit MOV AL,Byte Ptr AUTODIAl ;using a Hayes-type modem? OR AL,AL JZ NXOPT2 ;exit if neither modem-type ; NXTAL ;using a Hayes-type modem? OR AL,AL JZ L7A31 CALL SMRESET ;if yes, disconnect L7A31: CALL JMP_GOODBYE ;user's custom-area goodbye routine CALL ILPRT DB CR,LF,'<< Exit to CP/M >>',CR,LF,0 JMP EXIT ;return to CP/M ; SMRESET:MOV CH,,'>' CALL STYPE MOV AL,'>' CALL STYPE CALL ILPRT DB 'COMMAND: ',0 XOR AL,AL MOV Byte Ptr XFLG,AL ;null the buffer-length flag ; ; ; Get the command line parameters ; GETCMD: MOV DX,OFFSET CMDBUF ;enter command CALL INBUF MOV ALOPT0:CALL INLNCOMP ;'DE' set from 1st 'INLNCOMP' call DB 'CAL',0 JB NXOPT2 MOV AL,' ' ;fool the system MOV Byte Ptr CMDBUF+3,AL ;..'TBUF' so that it.. JMPS DOOPT ;..looks at option for dial ; NXOPT2: MOV AL,Byte Ptr CMDBUF+2 MOV BX, Of20 CALL TIMER MOV BX, Offset SM_DISC CALL SENDOUT MOV CH,20 CALL TIMER MOV AL,' ' ; ; If showing the +++ and ATH and ATD, etc. move the three semicolons up ; one line. ; DB 90H,90H,90H ;;; CALL STYPE MOV BX,(Offset SM_ATZ) CALL SENDO,Byte Ptr CMDBUF+2 CMP AL,EXITCHR ;exit character JZ XPRT1 ; GETCMD1:CMP AL, Byte Ptr Fncky ;function key intercept character JNZ L7A9 JMP FUNCT ; (supplied from 'INTCPT' table) L7A9: CMP AL,'?' JNZ L7A10 JMP CURPAR L7A10: CMP AL,'fset COMPLIST CALL COMPARE ;compares list pointed to by BX.. JB NOTVLD ;carry set = no match ; DOOPT: CALL SETFCB ;loads command buffer into FCB CALL PROCOPT ;check out the options JMP RESTART ;go to work ;..... ; ; NOTVLD: CALL NTUT ; SMRESET1: MOV CH,2 CALL RECV JNB SMRESET1 RET ;..... ; ; SM_ATZ DB 'ATZ',CR,'$' ;..... ; ; DIR: MOV CL,CURDSK INT 224 MOV Byte Ptr DISKSAV,AL CALL DIRLIST MOV AL,Byte Ptr DISKSAV MOV DL,AL MOV CL,SELDSK INT 224 JMP XP ' JNZ L7A11 JMP L7A8 ;skip the extra line feed L7A11: MOV AL,Byte Ptr CMDBUF+3 CMP AL,':' ;see if request for new drive/user JNZ L7A12 JMP SETDRV L7A12: MOV DX,OFFSET CMDBUF+2 ;point to command CALL INLNCOMP DB 'CPM',0 JNAE L7A1VLDMSG JMP XPRT ;..... ; ; NTVLDMSG: CALL ILPRT DB '++ Invalid command ++',CR,LF,BELL,0 RET ;..... ; ; FUNCT: MOV AL,Byte Ptr INTCPT ;get the function key intercept char. AND AL,07FH ;strip off any parity LAHF ;save the charactRT ;..... ; ; ERASEF: MOV DX, OFFSET CMDBUF ;put cmd line into FCB at 'BX' MOV BX, FCB CALL CMDLINE CALL MOVEFCB ;move FCB+16 to FCB MOV AL,Byte Ptr .FCB+1 CMP AL,' ' JNZ L7A34 JMP NOTVLD ;go if no file specified L7A34: MOV DX, FC3 JMP EXIT L7A13: CALL CRLF ;(1st CR/LF at 'INBUFR') CALL INLNCOMP DB 'LOG',0 JNAE L7A14 JMP LOGNEW L7A14: CALL INLNCOMP DB 'DIR',0 JNAE L7A15 JMP DIR L7A15: CALL INLNCOMP DB 'ERA',0 JNAE L7A_16 JMP ERASEF L7A16: CALL INer for now XCHG AL,AH PUSH AX CALL CLRTST CALL ILPRT DB ' SPECIAL FUNCTION KEY TABLE' DB CR,LF,LF,0 POP AX ;get the character back XCHG AL,AH CMP AL,' ' ;see if a printing character JNB FUNCT1 ;if a printing character, shoB MOV CL,SRCHF INT 224 INC AL ;0 if file not found JNZ ERAFILE ;ok, go erase CALL ILPRT DB '++ File not found ++',CR,LF,BELL,0 JMP XPRT ;..... ; ; ERAFILE:MOV DX, FCB MOV CL,ERASE INT 224 CALL ILPRT DB 'File erased',CR,LF,0 LNCOMP DB 'SPD',0 JNAE L7A17 JMP SETSPD L7A17: CALL INLNCOMP DB 'TIM',0 JNAE L7A18 JMP SETTIM L7A18: CALL INLNCOMP DB 'TCC',0 JNAE L7A19 JMP TOGCRC L7A19: CALL INLNCOMP DB 'TRB',0 JNAE L7A20 JMP TOGRUB L7A20: CALL INLNCOw it LAHF XCHG AL,AH PUSH AX CALL ILPRT DB 'CTL-',0 POP AX XCHG AL,AH ADD AL,40H ;convert binary to ASCII character ; FUNCT1: CALL STYPE ;show on the CRT CALL ILPRT DB ' current function key intercept character',CR,LF,LF,0 ; ; JMP XPRT ;..... ; ; LOGNEW: MOV AL,Byte Ptr NFILFLG ;file open for memory save to disk? OR AL,AL JZ L7A35 JMP NORESET ;if yes, do not reset disk drive now L7A35: MOV AL,Byte Ptr CMDBUF+6 ;any disk drive specified? CMP AL,' ' JNZ LOGMP DB 'TLC',0 JNAE L7A21 JMP TOGLOC L7A21: CALL INLNCOMP DB 'TLF',0 JNAE L7A22 JMP TOGLF L7A22: CALL INLNCOMP DB 'TXO',0 JNAE L7A23 JMP TOGTXOFF L7A23: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ NONUM1 ;i ; Shows the functions of the (0-9) keys ; MOV BX, Offset FNCTBL-1 ;index into the function key table MOV CH,10 ;has ten entries ; FUNCT2: INC BX ;next table location MOV AL,Byte Ptr [BX] ;get the binary function number ADD AL,'0' ;convert* NEW1 ;if not a blank, exit CALL GETDISK ;if not, use current drive ADD AL,'A' ;to compensate for next line ; LOGNEW1:SUB AL,'A' CMP AL,15+1 ;for drives 0-15 JNAE L7A36 JMP NOTVLD ;if more than 15, display error message L7A36: MOV B BYTDLY,AL ; CALL ILPRT DB 'Delay at end of line (0-9): ',0 ; NOKEYS1:CALL STAT JNZ L8A1 JMP NOKEYS1 L8A1: CALL KEYIN CALL STYPE CALL SAVEA SUB AL,'0' CMP AL,10 JNAE L8A2 JMP NOTVLD L8A2: MOV Byte Ptr CRDLY,AL ; SPDMSG: CALLPTST:MOV AL,Byte Ptr SETUPTST ;if setup is 'YES' or PMMIMODEM is.. MOV CH,AL ;..'YES' or autodial modem is 'YES'.. MOV AL,Byte Ptr PMMIMODEM ;..return with zero bit not set. OR AL,CH JZ L8A8 RET L8A8: MOV AL,Byte Ptr AUTODIAL OR AL,CH yte Ptr DISKSAV,AL ;store requested drive CALL GETUSER ;pick up current user number MOV CH,AL ;save it MOV AL,Byte Ptr CMDBUF+7 ;get new user number CALL CHRCHK ;check the char. CALL FINDUSER MOV AL,Byte Ptr CMDBUF+8 ;get 2nd digit ILPRT DB CR,LF,'Char. delay (terminal file mode) is: ',0 MOV AL,Byte Ptr BYTDLY MOV CH,AL MOV AL,CH PUSH BX MOV BL,AL MOV BH,0 CALL DECOUT POP BX CALL ILPRT DB '0 ms. per character',CR,LF DB 'Line delay (terminal file mode) is: ' RET ;..... ; ; TOGCRC: MOV AL,Byte Ptr TOGGLECRC ;allowing CRC/CHECKSUM toggle? OR AL,AL JNZ L8A9 JMP NOTVLD ;if not, exit L8A9: MOV AL,Byte Ptr CRCDFLT ;get present value and switch it NOT AL MOV Byte Ptr CRCDFLT,AL CALL TOGCRC1  CALL CHRCHK ;check the char. CALL L7A37 ; LOGNEW2:CALL SAVEUSER MOV CL,RESET INT 224 MOV AL,Byte Ptr DISKSAV MOV DL,AL MOV CL,SELDSK INT 224 MOV AL,Byte Ptr SAVUSR MOV DL,AL CALL SETUSER JMP XPRT ;..... ; ; CHRCHK: CMP AL,',0 MOV AL,Byte Ptr CRDLY MOV CH,AL PUSH BX MOV BL,AL MOV BH,0 CALL DECOUT POP BX CALL ILPRT DB '00 ms. per character',CR,LF,0 JMP XPRT ;...... ; ; SAVEA: LAHF XCHG AL,AH PUSH AX CALL ILPRT DB CR,LF,0 POP AX XCHG AL,AH  ;show on CRT it has been changed JMP XPRT ;..... ; ; TOGCRC1:CALL ILPRT DB 'Mode: ',0 MOV AL,Byte Ptr CRCDFLT ;see if set for 'CRC' or 'CHECKSUM' OR AL,AL JZ CHEKMSG CALL ILPRT DB 'CRC',CR,LF,0 RET ;..... ; ; CHEKMSG:CALL ILPRT ' JZ CHRCHK1 CMP AL,':' ;in case of A: or A1: or A11: (etc.) JZ CHRCHK1 RET ; CHRCHK1:POP AX ;reset the 'CALL' on the stack JMPS LOGNEW2 ;..... ; ; FINDUSER: MOV CH,0 ;zero the 'B' reg. for 1st time through L7A37: CALL NUMCHK SAHF RET ;..... ; ; SETDRV: MOV AL,Byte Ptr CMDBUF+2 ;get the disk drive SUB AL,'A' ;convert to binary value CMP AL,15+1 ;for drives 0-15 JNAE L8A3 JMP NOTVLD L8A3: MOV DL,AL MOV CL,SELDSK ;select requested drive INT 224 MOV AL, DB 'CHECKSUM',CR,LF,0 RET ;..... ; ; TOGRUB: MOV AL,Byte Ptr TOGGLERUB OR AL,AL JNZ L8A10 JMP NOTVLD L8A10: MOV AL,Byte Ptr CONVRUB NOT AL MOV Byte Ptr CONVRUB,AL CALL TOGRUB1 JMP XPRT ;..... ; ; TOGRUB1:MOV AL,Byte Ptr CONVRU ;if neither, see if a valid number MOV CL,AL ;save MOV AL,CH ;get save first digit ADD AL,AL ;x2 ADD AL,AL ;x4 ADD AL,AL ;x8 ADD AL,CH ;x9 ADD AL,CH ;x10 ADD AL,CL MOV CH,AL ;save RET ;..... ; ; SAVEUSER: MOV AL,CByte Ptr CMDBUF+5 ;get user number, if any CMP AL,' ' ;keep current user area? JNZ L8A4 JMP XPRT L8A4: SUB AL,'0' ;convert to binary value CMP AL,1 ;if a '1', could be units or tens JNZ SETDRV1 ;if not, numbers stop at 15 so exit MOVB OR AL,AL JZ NORUBMSG CALL ILPRT DB 'Rub is backspace',CR,LF,0 RET ;..... ; ; NORUBMSG: CALL ILPRT DB 'Rub is rub',CR,LF,0 RET ;..... ; ; TOGLOC: MOV AL,Byte Ptr TOGGLELOC OR AL,AL JNZ L8A11 JMP NOTVLD L8A11: MOV AL,Byte PH CMP AL,15+1 ;user numbers are 0-15 JNAE L7A39 JMP NOTVLD L7A39: MOV Byte Ptr SAVUSR,AL RET ;..... ; ; NUMGET: MOV DX, Offset CMDBUF CALL INBUF MOV AL,Byte Ptr CMDBUF+2 ;get number CMP AL,' ' JNZ L7A40 RET L7A40: ; NUMCHK: AL,Byte Ptr CMDBUF+6 ;check for a 2nd digit CMP AL,'0' JB SETDRV2 ;if less, not a valid number, ignore SUB AL,'0'-10 ;leave the '10' in as two digits used ; SETDRV1:CMP AL,15+1 ;user areas are 0-15 JNAE L8A5 JMP NOTVLD L8A5: MOV DL,AL tr LOCNXTCHR NOT AL MOV Byte Ptr LOCNXTCHR,AL CALL TOGLOC1 JMP XPRT ;..... ; ; TOGLOC1:CALL ILPRT DB 'Use ',0 MOV AL,Byte Ptr LOCNXTCHR OR AL,AL MOV AL,Byte Ptr EXTCHR JZ LOCMSG CALL SHFTYPE DB ' before local command',CR,LF,0 RE SUB AL,'0' ;remove ascii bias CMP AL,9+1 JNB L7A41 RET ;ok if 9 or less L7A41: POP BX ;remove 1st call from the stack POP BX ;remove 2nd call from the stack JMP NOTVLD ; GETUSER:MOV DL,0FFH ;get current user ; SETUSER:MOV CL,U CALL SETUSER JMP XPRT ;back to work ; SETDRV2:MOV AL,1 JMPS SETDRV1 ;..... ; ; SETTIM: CALL SORPTST JZ L8A6 CALL ILPRT L8A6: CALL ILPRT DB 'Use 0-8 to give baud rate for ''S'' mode ' DB 'time-to-send message,',CR,LF DB 'where 0=1T ;... ; ; LOCMSG: CALL SHFTYPE DB ' to send local command to remote',CR,LF,0 RET ;..... ; ; TOGLF: MOV AL,Byte Ptr TOGGLELF OR AL,AL JNZ L8A12 JMP NOTVLD L8A12: MOV AL,Byte Ptr ADDLF NOT AL MOV Byte Ptr ADDLF,AL CALL TOGLF1 JMSER ;set up bdos call INT 224 RET ;..... ; ; GETDISK:MOV CL,CURDSK ;get current drive INT 224 RET ;..... ; ; NORESET:CALL ILPRT DB '++ Terminal mode file open ++',CR,LF DB '++ Use WRT or DEL before LOG command ++',CR,LF D10, 1=300, 2=450, 3=600, 4=710, 5=1200, ' DB '6=2400, ',CR,LF,'7=4800 8=9600 and 9=19200 Baud.' DB CR,LF,LF,'Enter value: ',0 CALL NUMGET CMP AL,9+1 ;only looking for 0-9 answers JNAE L8A7 JMP NOTVLD L8A7: MOV Byte Ptr MSPEED,AL CALL SETP XPRT ;..... ; ; TOGLF1: CALL ILPRT DB 'LF ',0 MOV AL,Byte Ptr ADDLF ;adding lf after cr? OR AL,AL JNZ LFMSG ;if yes, exit CALL ILPRT DB 'NOT ',0 ; LFMSG: CALL ILPRT DB 'sent after CR in "L" or "T" for a disk file',CR,LB CR,LF,BELL,0 XOR AL,AL JMP XPRT ;..... ; ; SETSPD: CALL ILPRT DB 'Delay between chars. (0-9): ',0 ; NOKEYS: CALL STAT JZ NOKEYS CALL KEYIN CALL STYPE CALL SAVEA SUB AL,'0' CMP AL,10 JNAE L7A42 JMP NOTVLD L7A42: MOV Byte PtrTIM1 JMP XPRT ;..... ; ; SETTIM1:CALL SORPTST JNZ SETTIM2 CALL ILPRT DB 'Rate for the S mode time-to-send message is set to ',0 JMPS SETTIM3 ;... ; ; SETTIM2:CALL ILPRT DB 'Modem speed is ',0 ; SETTIM3:JMP PRTBAUD ;..... ; ; SOR* F,0 RET ;..... ; ; TOGTXOFF: MOV AL,Byte Ptr TOGXOFF OR AL,AL JNZ L8A13 JMP NOTVLD L8A13: CALL ILPRT DB 'Use XOFF testing? (Y/N): ',0 CALL GETANS JB NOCHG3 MOV Byte Ptr XOFFTST,AL ; NOCHG3: CALL XOFFMSG CALL ILPRT DB CR,LF,'Uam just.. MOV Word Ptr HLSAVE,BX ;..to insure they are there JMP XPRT ;..... ; ; WRTFIL: MOV AL,Byte Ptr NFILFLG ;saving memory for a disk file? OR AL,AL JZ NOFILOPN ;not saving a file, don't bother writing CALL WRTFIL1 ;close the file Mrompt ;..... ; ; NEWLINE:MOV AL,CR ;puts CRLF at memory pointed by 'DE' MOV SI,DX ;store it MOV [SI],AL MOV AL,LF ;line feed LAHF ;bump pointer INC DX SAHF MOV SI,DX ;store lf MOV [SI],AL LAHF ;bump pointer INC DX SAse XON waiting after (Y/N): ',0 CALL GETANS JB NOCHG4 MOV Byte Ptr XONWAIT,AL ; NOCHG4: CALL XONMSG MOV AL,Byte Ptr XONWAIT OR AL,AL JNZ L8A14 JMP XPRT L8A14: NOT AL MOV Byte Ptr XOFFTST,AL ;do not allow both CALL ILPRT DB OV Byte Ptr SAVEFLG,AL MOV Byte Ptr WRFLG,AL MOV BX,(Offset FCB3) CALL INITFCB ;blank out 'FCB' to written file MOV BX,(Offset BUFFER) ;can't be erased MOV Word Ptr HLSAVE,BX ;reset to buffer start for next time JMP XPRT ;... ; ; WRTFIL1:HF RET ;..... ; ; SPACES: MOV AL,' ' ;space MOV SI,DX MOV [SI],AL LAHF ;1 INC DX SAHF MOV SI,DX MOV [SI],AL LAHF ;2 INC DX SAHF MOV SI,DX MOV [SI],AL LAHF ;3 INC DX SAHF RET ;..... ; ; ; ; COMPARE:MOV 'Therefore ',0 CALL XOFFMSG JMP XPRT ;..... ; ; GETANS: MOV DX,(Offset CMDBUF) CALL INBUF MOV AL,Byte Ptr CMDBUF+2 ;get answer CMP AL,' ' CMC ;set the carry flag JNZ L8A15 RET L8A15: MOV CH,AL CMP AL,'N' MOV AL,0 JNZ L8A16 MOV AL,Byte Ptr FCB3+1 ;check that file was requested CMP AL,' ' JNZ L8A20 RET L8A20: CALL WRTDSK ;write buffer to disk if not empty WRTFIL2: MOV DX,(Offset FCB3) ;close the file MOV CL,CLOSE INT 224 XOR AL,AL MOV Byte Ptr NFILFLG,AL CH,Byte Ptr [BX] ;compares 'A' reg. with list.. ; COMPLP: INC BX ;..addressed by BX. first element.. CMP AL,Byte Ptr [BX] ;..of list must be number of elements.. JZ VALID ;..being compared. returns with.. DEC CH ;..carry set if 'A' reg. does  RET L8A16: MOV AL,CH CMP AL,'Y' MOV AL,1 JNZ L8A17 RET L8A17: POP AX ;preserve stack JMP NOTVLD ;..... ; ; XOFFMSG:CALL ILPRT DB 'XOFF testing ',0 MOV AL,Byte Ptr XOFFTST OR AL,AL JNZ XOTSTON CALL ILPRT DB 'NOT ',0 ; XO;file written, reset flags RET ;..... ; ; NOFILOPN: CALL ILPRT DB '++ No File Open ++',CR,LF,BELL,0 JMP XPRT ;..... ; ; ; THIS ROUTINE DISPLAYS THE PHONE NUMBERS IN THE LIBRARY ; NUMPRN: PUSH BX CALL CLRTST CALL ILPRT DB ' not.. 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 kTSTON:CALL ILPRT DB 'used',0 ; XONMSG1:CALL ILPRT DB ' in terminal mode file output',CR,LF,0 RET ;..... ; ; XONMSG: CALL ILPRT DB 'XON ',0 MOV AL,Byte Ptr XONWAIT OR AL,AL JNZ XONMSG2 CALL ILPRT DB 'NOT ',0 ; XONMSG2:CALL ILPRT  Library of Phone Numbers of Remote Systems' DB 0 MOV CL,18 ;number of lines to move MOV BX, (OFFSET NUMBLIB) ;address of source memory MOV DX,(Offset BUFFER) ;address of target memory CALL NEWLINE ;start with CRLF MOV SI,DX ;+LF MOV [Seypress CMP AL,'C'-40H ;control-c to abort? JNZ CLRTST POP BX ;clear stack of return address CALL CRLF ;turn up a blank line JMP XPRT ;..... ; ; CLRTST: MOV AL,Byte Ptr SCRNTEST OR AL,AL JZ LOTSALF JMP CLRSCRN ;..... ; ; LOTSALDB 'automatically tested after CR',0 JMPS XONMSG1 ;... ; ; SETUPENT: MOV AL,Byte Ptr SETUPTST OR AL,AL JNZ L8A18 JMP NOTVLD L8A18: MOV DX,(Offset CMDBUF)+1 CALL JMP_SETUPR MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AI],AL LAHF ;and bump it INC DX SAHF ; NUMPRN1:LAHF ;skip PMMI dialing letter INC BX SAHF LAHF ;and equal sign INC BX SAHF MOV CH,LIBLEN-2 ;number of bytes to move CALL MOVE ;move to buffer CALL SPACES ;2 entries + 3 spF:MOV AL,CR CALL STYPE MOV CH,12 MOV AL,LF ; LFLOOP: CALL STYPE DEC CH JNZ LFLOOP RET ;..... ; ; CURPAR: CALL CLRTST CALL ILPRT DB ' Current Settings',CR,LF,LF,0 CALL TOGCRC1 CALL TOGRUB1 MOV AL,Byte Ptr LSTTST L JNZ L8A19 JMP XPRT ;if not, exit, otherwise.. L8A19: MOV CH,'A' ;..send 'AT',CR to autodial modem.. CALL SENDCHR ;..to insure its baud rate.. MOV CH,'T' ;..matches that just selected. CALL SENDCHR MOV CH,CR CALL SENDCHR JMP XPRaces = 63 characters PUSH BX ;save source address PUSH DX ;save destination address LAHF ;skip next two characters INC BX SAHF LAHF INC BX SAHF MOV DX,(17*LIBLEN) ;get offset of 17 times entry length LAHF ;add it to the sourcOR AL,AL JZ NOLIST1 CALL LSTMSG ; NOLIST1:CALL SETTIM1 CALL ILPRT DB 'Terminal mode file buffer is ',0 MOV AL,Byte Ptr NFILFLG ;saving memory for a disk file? OR AL,AL JNZ ACTIVE ;if yes, go say "active" CALL ILPRT DB 'in',0 ;if notT ;..... ; ; NEWFILE:MOV AL,Byte Ptr NFILFLG ;file open for disk save? OR AL,AL JZ NOFILOPN ;if not, show "no file open" message MOV AL,Byte Ptr FCB3+1 ;check that file was requested CMP AL,' ' JZ NOFILOPN ;if no file, do not erase MOV DXe address ADD BX,DX RCR SI,1 SAHF RCL SI,1 POP DX ;restor destination address MOV CH,LIBLEN-2 ;get length of library entry CALL MOVE ;move another entry POP BX ;restore source address CALL NEWLINE ;start next line DEC CL ;one, say "inactive" ; ACTIVE: CALL ILPRT DB 'active',CR,LF,'Unused portion of buffer is ',0 CALL GETSPC CALL ILPRT DB ' bytes',CR,LF,0 CALL TOGLOC1 CALL TOGLF1 CALL XOFFMSG CALL XONMSG CALL SPDMSG CALL CRLF CALL CRLF CALL CRLF JMP ,(Offset FCB3) ;otherwise erase the old file MOV CL,ERASE INT 224 XOR AL,AL MOV Byte Ptr NFILFLG,AL ;no file mentioned, reset flags MOV Byte Ptr SAVEFLG,AL MOV BX,(Offset FCB3) CALL INITFCB MOV BX,(Offset BUFFER) ;reset flags to bottom of r less line to print JNZ NUMPRN1 ;if not finished, do another MOV AL,'$' MOV SI,DX MOV [SI],AL MOV CL,PRINT MOV DX,(Offset BUFFER) ;point to table of numbers to print INT 224 CALL CRLF CALL CRLF POP BX JMP XPRT ;finished, back to p+ XPRT ;..... ; ; GETSPC: MOV BX,(Offset BUFTOP) ;top of memory buffer MOV DX,Word Ptr HLSAVE ;current buffer location SUB BX,DX CALL DECOUT ;print the space remaining RET ;..... ; ; ;********************************************************RS 128 ;storage area for 'CMDBUF' BGNMS RS 2 TIMFLG RS 1 FLTRFLG RS 1 CHRFLG RS 1 TIMVAL RS 2 QUIKTIM RS 2 DISKNO RS 1 DISKSAV RS 1 DSTORE RS 1 FILECT RS 1 FTYCNT RS 1 MAXRAM RS 1 NAMECT RS 1 NBSAVE RS 2 OLDUSER RS 1 SENDFLG RS 1 SAVUSR Z^_;u;t zP0)F= }F=|vv gFPIvv Qv-P vt4TXZ/vt4TXZQ vPz }P(Pv ^;tP(PvvPT(vv*************** ; ; D - A - T - A A - R - E - A ; ;*********************************************************************** ; ; COMPLIST DB 6,'S','R','T','E','L','M' ;..... ; ; ; OPTION TABLE ; OPTBL EQU (Offset $) ANSWFLG DB 'A' BATCHFLG DBRS 1 ; FCB3 RS 33 FCB4 RS 33 FCBBUF RS 15 MFNAME5 RS 12 ;requested name MFNAME6 RS 12 ;current name RS 100 ;stack depth ; ; EVENPAGE EQU ((Offset $)+255)/256*256 ;sets buffers on even page ; ; ORG EVENPAGE ; ; STACK EQU (Offset EVENPD(vvP4(]CP#(P(P(P(DP'vP'P']ËGtw VU vJF%1FF0CP3PPP!FV^ t؃]^Ëܸ1GVUF tFuv~vv~~D 'B' DISCFLG DB 'D' JMPCMD DB 'J' LOCCHFLG DB 'L' ORIGFLG DB 'O' QFLG DB 'Q' RSEEFLG DB 'R' SSEEFLG DB 'S' VSEEFLG DB 'V' XITFLG DB 'X' EPARITY DB '0' ;even parity sub-option (only in S or R mode) OPARITY DB '1' ;odd parity sub-option (only PAGE)-2 ;store original stack pointer CRCTBL RS 512 ;two tables of 128 bytes each BUFFDSK RS 128 ;buffer for disk save BUFFPNT RS 128 ;buffer for printer BUFFER RS 1024*BUFSIZ ;send/receive file buffer BUFTOP RS 0 ;filled in when length is fo+EtyEȻYKKyً3x CC$CCE y3CC1W^~FuF]^^XZ^X3SS y ؃πRP0CPSVW~^Z^XZ^X3R3SSP0CPSVWW^3؎W_E %E%in S or R mode) OPTBE EQU (Offset $) ;..transfer when program initially called. ; ; ; The following must be in the same order as the table above: ; RESTROPT DB 'A','B','D','J','L','O','Q','R','S','V','X','0','1' ; ; ; The next 14 bytes equal the und PBUFF EQU (Offset $) ;printer buffer starts here NAMEBUF EQU (Offset $) ;batch-mode filenames buffer ;..... ; ; ; BDOS EQUATES ; RDCON EQU 1 WRCON EQU 2 BLIST EQU 5 PRINT EQU 9 RDBUF EQU 10 CONST EQU 11 CPMVER EQU 12 RESET EQU 13 SEL] VW_^D %  DEËE E E E uE7E tm ]]]]E ueUUU )]WUFtF uv~JyvDv~;3SSSSSS_ǣD . t. .CCsCCt֋F-0@FFދF3FF܋!number of bytes between RECDNOB and ; RECDNOE. ; RESTSN DB 0,0,0,0,0,0 DW (Offset BUFFER) DB 0,0,0,0,0,NAK ; RECDNOB EQU (Offset $) ;start of table marker RCVRNO DB 0 ;\ RECDNO DB 0,0 ; \ ERRCT DB 0 ; \ ERRCDE DB 0 ; \ EOFLG DB 0 DSK EQU 14 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 SETDMA EQU 26 DSKALL EQU 27 DSKPAR EQU 31 USER EQU 32 FILSIZ EQU 35 REIPL EQU 0 BDOS EQU 5 FCB EQU 5C~]_" " " " WUF uv~FuFFF F} vi[Y3PPPPQS vT5Qv~;rwNNOOv~FFGGvFFYċF-?)FF1F~Cv~]_  ; \ 14 bytes between table markers RECPTR DW (Offset BUFFER) ; / RECINBF DB 0 ; / MAXEXT DB 0 ; / RCNT DB 0,0 ; / DATAFLG DB 0 ;/ BENHERE DB NAK ; RECDNOE EQU (Offset $) ;end of table marker ; ; ; Additional 16-bit initialiH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32 FCBRNO EQU FCB+32 FCB2 EQU 6CH TBUF EQU 80H ;..... ; ; END ܊o w y2y:}ĹW9Wu KK$t w$t$t2 ܉G_ttt4^XZ[YU]MQSRP_D3۹%uPPP8PRS3PD%-?=#=|)D-8yT\D 3E_Xˎ& Azed storage ; CRCVAL DW 0 DIALCT DW 0 HLSAVE DW (Offset BUFFER) HLSAVE1 DW (Offset PBUFF) HLSAVE2 DW (Offset PBUFF) ; ; ; Additional general purpose initialized storage ; ABORTFLG DB 0 ACKFLG DB 0 CRCFLAG DB 0 CRFLAG DB 0 CURRENT DB 52 ;PM.2 UWFVv~ u y ؃ y ރS 3SN;w r;w+@N^Yt tu t؃FV _] v UF fF FfF FfFV ] v ûWg؎Ћ&>MI 300 baud speed value (defaults to 300) DLYFLG DB 0 ECHOFLG DB 0 EXACFLG DB 0 FIRSTME DB 0 FNCKY DB '^' ; Function Key Intercept character FNKFLG DB 0 ;function key activity flag FSTFLG DB 0 LISTFLG DB 0 LOCFLG DB 0 MFFLG1 DB 0 MODCTLB DB    DaPPP*'P*F=unPDPFƋ4V F^;tFƋ4VFP`*-TP\PFO3 $0 t5x t/PV0±$'@'Nuӱ 9nvnX &"^3^.U+;&v^.PF^;r PvX^P6^ƉƋ4F uF]øP PPJ]FFcv]~e07FH NFILFLG DB 0 ONERR DB 0 OPTION DB 0 ORIGSAV DB 0 RINGBKFL DB 0 SAVEFLG DB 0 UARTCTLB DB ORIGMOD ;for originate mode WRFLG DB 0 XFLG DB 0 CMDBUF DB 80H,0 ;command buffer control area ; ; ; General purpose unitialized storage area ; Ƌ4V F^;tFƋ4V^P*nP*vv >]VFVFVFPv F^;uF=uPvY#vt4TXZRPRPvvGXZ^_;u;t xPe)RPRPvvX+ X uvFZ~KF+v%X u]ËF=|]ËF udF=F~v,4X uFvv Pv5X u Fv4,X uoPvY[FFܸFFFCcsdDxXuUoObBfegewod\F uF;FwF u-Pv܊^;t 0PF^;t.Pv4vvЃv,4Xv,4XvVv4,X^;wPvVvvЃF;Pvt^ƉXv4V~PvtXPvtX^# u PvtƊ^;t% PvtXPvt X Pvt X]øPvtt XZY!RFZFFF=|vttPYPvX^RPvtt XZ^_^_vV7^Ɖ@v:X u7vV^ƉF&PvY Fv4,X uoPvYvV^ƉvVX u7vV7^ƉFPvYPv_X u#FwvvY+FvvvvЃF uF u)v4,X uPvVvvЃv4XPv4vvЃ]4F̍v4^Fv4,X ux Pv̊^;t Pv̊^;t PvX6AP;u;rPYPvX^Pvt^PPkFF3RPv4t!XZTPZv4V!P>FF=t F=t=PPYPPYPvX^Pvt^PF F u v4XF u@PvtY PNFF[Lv4XF؉FF uv-~vv F]Ë]F Fv{X u#v~-Pv4^XF=|z0Pv4^X.Pv4^XvvYF=|vvY+Fv̊^;sZPv̊^;v Pv̊Yv́4XwPvXF҉FЉFθF̸FPv4^^ƉFv4,X uv̊ u<Pv̊^;t F́F<>Pv̊^;t F́FFPv4^VF^ƉXF=}YPvX^Pvt X]L PvtX^# ugvtvt X^;|Pvt vt^ƉXvt XRPvtt XZ^_RPvttXZ^_;u;r.vt XRPvtt XZ^_RPvtXZTPZFvt PYPvX^^;|PYPvPv4X^;|0Pv4^Xsv"DFF0Pv4^Xv#vW~v,4X uF u.Pv4^Xv4,X uHvFF0Pv4^Xzvvn~pPvP P Pv̊ uv́4Xv,4Xv́4X+F̸>PvЊ^;tvЁ4XF̸PPv? ^;uPvv% ^;uPPv ^;uP PPEPFԉXFPvP ]X^Pvt^PPvXRPPvtt XZY^_RPv4t!XZTPZv4V"PA u@PvtY v4XIPvtY#]UNV]vvX^FvB F uPvvF]Ë]|PF^PXPF+F ^ t3]Ë]Iv ug%Pv^;t7F-Pv4^^;ƸtHF u v4XvF0PF^;u F*Pv^;tv 4^4XFv4XEFvP u*0Pv4^^+P PvXfFFF=|,vV6^ƉƋ4 u v4XF=tPPKFF uPv4X5^#PvtXPv^;:PFƊ^;tFFF=|5FF=|@vVPvX^P^ƉƉ^ u]voFPvtX5^# u v4V0vt u vtVv PPvX^P6^ƉX]Ë]FF=|0vV6^ƉƋ4 u v,v4XvJ]PF^+PFPvtX^^^ƉF.Pv^;ƸtHF uv4X*Pv^;tv 4^4XFv4XEFvP/ u*0Pv4^^+P PvX^^ƉFlPvP^;ƸtHF u v4XvP8F uFF Fv4ƉƊPvVF^ƉƊP^;t v4XF=t*PF^#PPvX^P^ƉƊD^;tPvtY PvX^P^ƉƊDPvXPPvtX^#^;t3Pv4^;tPvtX PvtX PvtX v# uO PvtX^# u vPv4VPd^;@PvtY @PvtX^# uPPX]Ë]FPPvVPF^+P5 ^;uFF]Ë]FFFv uv4^PdF^M~UFF PvVF޸gPv^;tF=|F=PF^PvVvPvދYvP\PvP\^ƉFܸEPv4^XF=|-Pv4^XF؉F+Pv4^Xv޸Pv1\PFF썆4XPvtX5^# uvv[PvX uF uv4VPMPv4VFP6^;PYPvtXvtgPvtX ufPvtvtVFPvV6^ƉXPvtX5^# u F uF uFPvY F uFF uFPvY awrb _FPRPFFPvnFF=u F=t3PFFPv<FVF=tF=u\FVF uFF Fv4^(~0FF PvVF޸PvދF^^PvVwPvދYvFށP\PvP\^ƉF܍\PF썆\FFF9FF*F FFF FFދF uv4V#PPv4t#t!XZYuRPvtXZTPZPvtX^# uvttXZ uv4t!,\t4XZvtVPv4V!PFPYPF^;|1PvVvt^ƉƊ^;t v4XPYPF^+ƙRPvtPRPvF=u F]ø]Ë]0PPvVPF^+P ^;uFF]Ë]PvY+v4VF^;uP PP|6VFv4 uvVv4^;r v4Fv4VvXFPvXPvtX^,F Fv4^t4vXZTPZFF KF=|!v 4^4XRPvXZTPZv 4^4X3RPvXZTPZvލ\Pvt4^\FvFv 4^4XFvFF uF;FrFFFwv 4XFܸFFTY[ӉTF]ËF u#v4 u v4V2v)]Ë]PvtX^# u6PvtX^# uPv4^;tPvtXvtV P PPPvt XPvtƊ^Pvt X Pvt X, PF^ƁPF^;t+PvtX^PvtYv4VvXFFv4FPvtX^PF^ƁPF^;t(PvtX^PvtYv4VvX]FP0^;ƸvH uH uP9PF^;ƸvH uHPX]Ë]zvFPvtY F= t@PvtX^# uPFPX]Ë]ܸPvtX^# uPvtY#vD]Ëvt vt X^;} PvtX^# u vfPvtX^# uRvtvt X^;t-vtXRPvt TY[?yGz?(C6?30yE>ؗҜ<#I9D2F[%nd( ??$@$@$@CONCONRDRPUNPRN0123456789ABCDEFPvtX^# u 3ҋ]øPvtY#F Pmvt XRPvvvtt XZ^_^_׉VFPvvXZVF?vvvttXZ^_׉VF3ҋ]Evt X u$vtt vvXZ^_;u;r9vt XRPvtt XTPvt Xvt X uPvt Xvvt vt X^;}]Ëvt 4vt^ƉƊ]Ë]vV4XF^;s]Í44X^+ƉFvƋYF]Ë]U؎~NF]vv4Vv5PvXZ^_RPvvXZ^_;u;sp PvtX^# u vPYP^5RPvvXZ^_##RPvt XZTPZPvt Xvvtt vvXZ^_+RPvt XZvt vt X^;vt vt XvvXZ]Ë]{*FP!PF^PvYPv4X]DڍvVvvVc.Pރ]Ë])v4XFv4^ uPF+F^ t3]Ë]يFPA^;~ ZPF^;~ PvYF]Ë]يFPa^;~ zPF^;~PvYF]Ë]iZ80.DQC  Z80.AQ6 Z80.DOC Z80.A86 Z80.CODE8086.ZQ0 CODE8086.Z80 JUMPADDR.ZQ0 JUMPADDR.Z80 ^ƉFXF =|RPvvXZ^_;u;r FvvXZ؃VFRPv XRPvvXZ؃RP3%^YƉƊPv,4^XF ؙRPFu5]XZU ujvvXZVF3RPv X3RPvv0%^YƉƊPv,4v{كFPvtX^# uP PqP؃PvtX^# uwFvVvX^;r^ Pv^;tPvtX^# u Pv4Vv4^Pv4Vv4XFvVvX^;rX Pv^;tPvtX^# u^Xv X3RPFu5XZU uF u-Pv,4^XP!PF^+F^ t3FFPvvF]Ë]P%PF u:PFƊ^;tIvPFF=A}F=P~F@PvXgPvY v Ptvv4^P]v4Xvt vt X^;vt vt X@PvtX^# uPFPX]Ë]׋vtvt X^;}Ovtvt XvlvtXRPvt TY[ӉTPvt XPvt Xvt X uPv P PvtVvVPvtVF uvVPvt V( uF]v ]Ë]v4Fv udv4^P"FF=.t:F=!|]ËF uv,4XFPv4^XFPvX]tX5^# u3Pvt Xv,vt X u Pvt X PvtY FPvt 4vt^ƉX]Ë]bPPF^^#ƉF6VFv4F uvVvtX^;sPF^PvtX^;sMPvX^PF^ƁFv4VvXPvtX+F^+PvtXFPvX vtXFv4VvX FFSF uPF^PF u%FPv WordStar file Scrubber Version %d.%d Bill Bolton, Software Tools r Cannot find file %s w Can't open %s Working * tXFPvXPvYF]Ë]U؎v~N;rNO]ލvVvP~/P]Ë]vFvvPF^+PnPF^;u]øPPPF^+PBP^;u]ø]Ë]v݃FPvtX^# uOutput file flush error %ld characters processed %ld characters were deleted %ld soft hyphens replaced Usage: SCRUB d:file1 d:file2 Where: file1 = source file, (* and ? not allowed) file2 = destination file, (* and ? not allowed) d: = o P PPsFvVvX^;rPvF^;|FPv4^Xv4XPvtX^# uF=t+PvtXPvtY v,4XvF= tZPvF^;|PF= t PFX2FPvtXptional drive identifier i.e. SCRUB A:FOOBAR.WST B:FUBAR.DOC BAD FILE$%03dcon: TOO MANY ARGS$warw REDIRECTION ERROR$cFREE$ READ$WRITE$6% NO CORE$ $$@Y@@חA7yACnF?O8M 0HwZ۾sOu, vXv] v u&vP=,DD u]Ív3]Ë] P%DDFv4v4X3FPP5DD^;t]øFF;|h!VFPX4^;tWF=tPPXX$$$Ix3FFFVvVvV^;t%PP513P-DDvVF^;t3PP 13Pq-DD636:6FPX4VvP8XXFPX4VDD u*FPX4VPXXFPX4V`P`P@/DDt"6:VFPX4P#X^;t<FPX4P"X"6"A TITLE 'UPPERCASE FUNCTION' PUBLIC CAPS CSEG ;CAPITALIZE AL CAPS: CMP AL,'a' JL RETURN CMP AL,'z' JG RETURN AND AL,01011111B RETURN: RET END 33FFF=v, uv44F:Vv^;t F udvP2DD uA3Vv^;t)vP>DDP6XP=P9F vQP9-Vv^;tv4 uvPtz~ uPPo#!vPPY# ut! uPP-# P ^;t3!P P ^^Pv^P6wP"P4DDP3DDPPXX^;t]Ë=}]Í"PPX4VR4z ugPP/P<,DDL~~ uz uPP/P,DDrn]2F uF=v4 u FFFFmF=|SPPP(/PP/PP /2PP.WPP.FPPg"v3FF;F|FF;|FPFPX4VFP8X4V u^,4VF^;tEFFF;|0FPX4VFPXXvpvXv;vPvX3PT+DD3FF;F|#FPvX4V*DDFv3PF^;ƸuHP +DD]T33PPv -^;tvPP].]þvV6DD^;u!vPP0.6*DD]6DD6S,DDPX3V]Ë] 3FFF= |E Vvv^;t-vvPvPvXXv Vv ^;uvPvX. FF= |E Vvv^;t-vvPvPvXXvvv3F]Ë]Ɗ^;u3PP:PP:6^DD=| =}!vPP~-6.*DD]Í663;|K6DDPP6XX6DDPP6XXPvvƊF u,*VF^;t?VF^;t]3]Ë]:Vv^;uG:Vv^;t.FPvA^;tPvY3]D:Vv^;u.FPvA^;tPvY3]ÍvƊPP,3PPPd+^;tPPP,V^;uuY= t~ u!6P,6,+= tz u6R,x6(DD6(DD6(DD;u!vPP+F u?VF^;t7vƊF u .VF^;u3]*VF^;tavF uv.VF^;tvF uv.VF^;t'vƊPF^;t3]v u P(DD]3]Ë]3]c]=6,]jVgF^;u%F=t0u]33V1^;t ]P6Y+]Ë]63FV6^;KV6O)DD^;t]3]Ë]:Vv^;t PPXFF= tvP0DDPvX3FFvv uF=|vPvXPvvX.Vvv^;tPvY*Vvv^;t&F;F|vPvX? v]3#PFP6XX4XF1P6YP^#PFP6XX4XFF=}aF؉FF=tPFPXFF]Ë]]v(DDFPv(DDYPF^ Ƌ]Ë]'v u2vP,DD uvP7DDP- ^vv3]ËGtw VU v2F%1FF0CP3PPP!FV^ t؃]^Ëܸ1GVUF tFuv~vv~~D+EtyEȻYKKyً3x CC$CCE y3CC1v_ PvqX uPvHX u3PvVPvYF uvu~zvcviF]Ë]gF FH=v7X u"v&R~+vƸ-F=|tvƸ0vƸ.vvЃv,v,vVv,^;wPvVvvЃF;FwvvY+3FvvvvЃF uF u(v, uPvVvvЃvPv4vvЃc]4F̍v4^W^~FuF]^^XZ^X33SS^XZ^X3SS y ؃πRP0CPSVWW^3؎W_E %E%] VW_^D %  DEËE E E E uE7E tm ]]]]E ueUUU )]WUvvYF=|vvY+3F3Vv^;|vƸ0rvFF0PvXP`vvTh~Vv, uF uvƸ.v, uIv=FF0PvXXFv4,X ux Pv̊^;t Pv̊^;t PvX6APv̊^;sZPv̊^;v Pv̊Yv́4XwPvX+F҉FЉFθF̸FPv4^^ƉFv4,X uv̊ u<Pv̊^;t FFtF uv~JyvDv~;3SSSSSS_Nj, . t. .CCsCCt֋F-0@FFދF3FF܋!~]_" " " " WUF uv~FuFFF F} viv*vO~v3VF+F ^ t3]Ë]v u%Pv^;t_F-Pv4^;ƸtHF u vvF0PF^;u F*Pv^;tv 4XFvF3FvP)DD uF<>Pv̊^;t F́FFPv4^VF^ƉXF=}0P P PGv̊ uv́4Xv,4Xv́4X+@F̸>PvЊ^;tvЁ4XBF̸PDPv ^;uPvv ^;uPF[Y3PPPPQS vT5Qv~;rwNNOOv~FFGGvFFYċF-?)FF1F~Cv~]_ ܊o w y2y:}ĹW9Wu KK$t w$t$t2 ܉G_ttt4^XZ[YU]MQ-0PvƊX+V PvX^^ƉF.Pv^;ƸtHF uv*Pv^;tv 4XFvF3FvPDD u-0PvƊX+V PvX^^ƉF3FlPvP"DD^;ƸtHF u vPvw ^;uHP P[P\PFԉXFPvCۃP ]3F3FF=|)FP6X4 u vF=tmPPFF uMPv5^#PvtXVvDD^;:Vv^;SRP_D3۹%uPPP8PRS3PD%-?=#=|)D-8yT\D 3E_Xˎ& A.2 UWFVv~ u y ؃ y ރS 3SN;w r;w+@N^YvPaF uFF Fv~FF 3PvV!F޸gPv^;tF=|F=PF^PvVPvދYvP\Pv1P\^ƉF܍v܋ƸEF=|v܋Ƹ-F؉Fv܋t'3FF=|3FF=|/PvX^P6`XvPvvPDD^;t vF=t(PvX#VPvX^P6`XD^;tPvtY PvX^P6`XDPvXPPvtX^#^;t/Pv4^;tvtt tu t؃FV _] v UF fF FfF FfFV ] v ûWg؎Ћ&>rtO3I  UF t5x t/PV±$'@'Nuӱ 9nvnX&^3^Ƹ+v޸&Pv \Pm!DDF썆\FF uFF Fv~FF 3PvVF޸PvދF^^PvVPvދYvFށP\Pv2P\^ƉF܍\P DDF썆\FFF9FF*F F vt vt vPvtX5^# ufvDDPvX uF uv4VPVv4VFP^;lvt vtDDPvtX uEPvtvtVFPFP6XXPvtX5^.U+;&v^.PF^;rPvX^P6X4F uF]øP PPFDD]3FF0_vY~aX uvBn~G3F8(v"X u3]ËF=|3]ËF udF=FPFF FFދF u)F Fvt4vXZTFF EF=|v 4XRPvXZTv 4X3RPvXZTvލ\Pvt4F u2\F3RPvt4XZ^_;u;r v܁vDDFF u# u F uv4V#PV3RPv4t#t!XZY[RPvtXZTPvtX^# uvttXZ uv4t!,\t4XZvtVPv4V!P3FF=|(Pvtv^;t vFRPvtTY[Ӊ0~v, u@Fvv" Pv4X u Fv, ukPvYFP6XBvPZ܃]Ë]FFvRPvtt XZY[K^_RPv4t!XZTv4V"P@ u@PvtY vYPvtY#]UNV]vvvX^Fv F uPvvF]Ë]7PF^PDD u]v+DDFPvtX5^׉VF3ҋ][aNvt X u$vtt vvXZ^_;u;r9vt XRPvtt XZ^_RPvvXZ^_;u;sR PvtX^# uvYDDRPvvXZ^_##RPvt XZTvt 3vVDDvtt vvXZ^_4^ uv,4Xv4^Pv4^X uF]Ë]FFv4^Pv4^X uF]Ë]ov4XFv4^ uPF+F^ t3]Ë]&֊FPA^;~ ZPF^;~ PvY# u v4V7DDvt u vtVDDvDD3PPvX^P6XX3]Ë]3FF=|,FP6X4 uv8DDvv DD]PPF^+P ]Ë]9PF^+PCDDFPvtX^# u PvtX^# +RPvt XZvt vt X^;vt vt XvvXZ]Ë]*FP!PF^ƉFXF =|RPvvXZ^_;u;r FvvXZ؃VFRPv XRPvvXZ؃RPgݍ~^YƉƊPv,4^XF ؙRPFuF]Ë]ՊFPa^;~ zPF^;~PvYF]Ë]vDDFPvtX^# ujP PP(DDPvtX^# uv3FvVvX^;r^ Vv^;tPvtX^# u Pv4VvƊPv4VxuvDDPv4tY Vv4VP@^;@PvtY Pv4tY#@PvtX^# uP3PX]Ë]bPF^+PlDDFPvtX^# uN PvtX^# uv,DDVv4VP^;5XZU ujvvXZVF3RPv X3RPvvd܍~^YƉƊPv,4^Xv X3RPFu5(XZU uF u-Pv,4^XP!PF^+F^ t3FFPvvF]Ë]#P%PF u:Pvv3FvVvX^;rX Vv^;tPvtX^# u v PtvvƊP\vvt vt X^;vt vt X@PvtX^# uPFPX]Ë]*ԋvtvt X^;}Kvtvt XvDDvt@PvtY @PvtX^# uP3PX]Ë]FPPvVPF^+PZ ^;uFF]Ë]}FFFv uv4^PdFF uFPvY F uFF u^;tHvPDDFF=A}F=P~F@PvXgPvY P PvtVvVPvtVD uvVPvt V& uF]vDD3]Ë]8v4Fv ubvƊPDDFF=.XRPvt TY[ӉTvt 3Pvt Xvt X uPvtX5^# u-vt 3vDDvt X u vt  PvtY vt PvtXF]FPvY Yawrb _FPRPFFPvFF=u F=t3PFFPvFVF=tF=uPRPv5F=u F]ø]Ë] vVvFPt8F=!|]ËF uv,vƋFFPvX3]Ë]PPF^^#ƉF6Fv4F uvVvtX^;sPF^PvtX^;sMPvX^PF^ƁFv4VvXPvtX+F^+PvtXFPvX @(#)usq.c 1.7u (UCF) 82/12/15Wildexp ERRORNo files Ou?P>]Ë]PPvVPF^+P^;uFF]Ë]PvY+v4VF^;u^P PP,6Fv4 uvVv4^;r v4Fv4VvXFPvXPvtX^PF^ƁPF^;t+PvtvtXFv4VvX FFSF uPF^PF u%FPvtXFPvXPvYF]Ë]U؎v~N;rNO]ZڍvVvP?P߃]Ë]?vQDDFPvtX^# udP PPeDD3FvV. tput drive = %s ERROR - Ignoring %s Can't define -r and -n at the same time. Can't define -r and -n at the same time.File unsqueezer version %s 1.83c 14 Oct 83Originally by Richard Greenlaw Usage: usq [d:] [-n | -r] [d:]afn.aft ... -n Nlmode: re\$M7ŗ;>wzZSKk2]q(XPtc\4?,ou h}V Po&@Mmove carriage returns -r CrNlmode: convert newline to cr,lf rbusq: can't open %s usq: %s is not a SQueezed file usq: %s has invalid decode tree usq: %s -> %s wbusq: can't create %s usq: bad checksum in %s *.*BAD FILE$%03dcon: TOO MANY ARGS${q((⫠8zp EQ@Թ]ֹVk@^Js@R#Ú~F`W e>5 ˛+5:T?}_1w;-s@R#ÚC'\4?s-c1@C:¦^ukI5sbp\4:*BP[Sxgwarw REDIRECTION ERROR$cFREE$READ$WRITE$4 NO CORE$ $$@Y@@חA7yACnF?O8M30HwZ?sOu?{Gz?-C6?:0yE>ؗҜ<2#I9DFHGEȭ@h~S WĨ&%0﹯j-t@:?3 ^LjĹ+:5H:*s_y7FiTļ||S9&7!3o3$݌"~,=j x7Yu:}?\5zjZ/x/0M7} ~{ssgf[&&Z|{Ńf&C &Zد@\BZCV %X瞫zMc\rs@,ljr%ڪ4PZGkI5 Թ~F`W ~6>\k-?PH&k约asW`:fe:1!7W5v5-oy8ݳQkDgyn;egV{Q7t{LR{Q7ǰifRXNuUo^,CWf޿?=VbFH3Е^lc\Oozyb #߻Jq892Ӂ+iu`臾i7;#>ЃGifAo#Gi%: !6js-tli>tOMf>B-qLvc`kϻx9B1<8WX<+Ńfkp9Jk7}1'`>Jf5a,j㑸)Մq~t~TgnA4»,"|?]45s([n5K9*$VPӈ~{nh(M?,iD\9?I5 _]`(*ǹÚ~!h,!-)?Itٯ5 ^ׄ?&UGCi@rߣ? T׈v gV׈qn;}gV׈vvFo=e=Ftm(5Ħ %A)m'jlљk vbV׈YN?.6~{`uvµFoq}n;bV׈t?(mkP) j=Yؔ`ګm UG}6OMt@QQMMn;Yibޡgof MOXGjs5K#OQib ꘪ"6xv}DzSZF_\f i4ӵc;}wEB9ЕUi5^f{s^_uAozz[ŵ4sSJ^huzh_߿.!f+SZXv?ƊCZwh ^|4{hiK:0Y>՝xm^'A4szֿ~P{qn&ah(mR ޫs5JҢW4FaMX%h(-j;1ʞXGT>9ÚC'PZh]1?aWs5Np4e+r+4?5Ҩyo#S֤h_h(N*W^upO+ Wił{snGCiBq5ڎdq5aCss٣h(M˝&3cL/Ee4gaS+ V %#䈏0$݌"Z8~}6ޑmZ s=ߚvIIٲ#zG5܆ljl#",yh=4j5fNϣ aC4szgP!]Pϣۋcikzһ(s{E !Q<`ABccKTZ#o$ۋs^|t`MOVǠFH3o'.s^x1MEێzv%Ւ]OB }|\CM6xIԻsigOqsۻ]Gqc:hSRY(~J aIfP,ǹ2%;Ji~)PV ?H# %8? vo+֟ %8\عTkTGa+j-=B8<גjm O@W UӇk;3@q%ڽLS+ooT$x=QM!ֹ:?w>n<\MNn+y^E5td;{SOGRAM ONLY WORKS WITH STRICT CP/M STANDARDS. ; THAT IS, ONLY CALLS THRU ADDRESS 0 AND 5 ARE VALID FOR ; BIOS CALLS. DO NOT ATTEMPT TO RUN THIS EMULATOR WITH ; PROGRAMS THAT DO DIRECT I/O OR PLAY GAMES INSIDE CP/M. ; ; Z80 SETS UP A TPA OF 48K, BUT MAY ;BDOS INTERRUPT VECTOR BDOS_LIST EQU 5 ;LIST OUTPUT BDOS_DIRECT EQU 6 ;DIRECT CONSOLE I/O BDOS_PRINT EQU 9 ;PRINT STRING BDOS_INPUT EQU 10 ;READ CONSOLE BUFFER BDOS_OPENF EQU 15 ;OPEN FILE BDOS_CLOSEF EQU 16 ;CLOSE FILE BDOS_READ_NEXT EQU 20 BE MODIFIED FOR ANY SIZE UP TO 64K ; ; TO ASSEMBLE, YOU WILL NEED: ; Z80.A86 MAIN SOURCE ; CODE8086.Z80 8086 INSTRUCTIONS FOR 8080 OP CODES ; JUMPADDR.Z80 JUMP TABLE DEFINITION ; ; ASM86 AND GENCMD WILL GENERATE A COMPACT MODEL PROGRAM ; (N ;READ SEQUENTIAL BDOS_GET_DISK EQU 25 ;RETURN CURRENT DISK NUMBER BDOS_DMA_OFFSET EQU 26 ;SET DMA OFFSET BDOS_DMA_BASE EQU 51 ;SET DMA BASE BDOS_TERMINATE EQU 143 ;TERMINATE PROCESS BDOS_PARSE EQU 152 ;PARSE FILE NAME ; CR EQU 0DH ;CARRAIGEOT SO COMPACT WHEN YOU SEE HOW MUCH CORE IT EATS) ; THE CODE SECTION IS PROGRAM CODE ; THE DATA SECTION IS PROGRAM DATA ; THE EXTRA SECTION IS THE Z80 TPA ; ; TO INVOKE: ; Z80 filename.typ ; NOTE: .COM IS NOT ASSUMED AND MUST BE INCLUDED ; Z80  RETURN LF EQU 0AH ;LINE FEED BEL EQU 07H ;RING BELL ; ZJMP EQU 0C3H ;Z80 JUMP OP CODE ZCALL EQU 0CDH ;Z80 CALL OP CODE ZLDCNN EQU 0EH ;Z80 LD C,nn OP CODE ZLDENN EQU 01EH ;Z80 LD E,nn OP CODE ZLDEC EQU 059H ;Z80 LD E,C OP CODE CSWILL PROMPT FOR A COMMAND TAIL ; ; FUTURE VERSIONS WILL SUPPORT DYNAMIC MEMORY ALLOCATION FOR VARIABLE ; TPA SIZES. THE CBIOS JUMP TABLE LOGIC IS INCLUDED, BUT DOES NOT WORK. ; NEXT VERSION WILL FUNCTION PROPERLY. MAYBE EVEN A CCP LIKE INTERFACE! ; ;EG CALL INITIALIZE ;SET UP CP/M-80 AREAS, ETC CALL LOAD_Z80 ;LOAD Z80 PROGRAM INTO ESEG JC EXIT CALL RUN_Z80 ;EMULATION EXIT: MOV DX,OFFSET MSG_TERMINATE CALL PRINT MOV CL,BDOS_TERMINATE INT BDOS ;TERMINATE PROCESS ; INITIALIZE:  DO NOT USE THIS PROGRAM IN SENSITIVE APPLICATIONS, ; AS IT HAS MORE BUGS THAN THE JERSEY SWAMPS ; MOV CL,BDOS_GET_DISK INT BDOS MOV Z80_DISK,AL ;Z80 CURRENT DISK MOV DX,OFFSET QRY_TAIL CALL PRINT1 MOV DX,OFFSET Z80_BUF PUSH DS PUSH ES POP DS MOV CL,BDOS_INPUT INT BDOS MOV DX,OFFSET Z80_PFCB ;PARSE CONTROL BLOCK MOV CL,BDOS_PARSE INT BDOS POP DS MOV Z80_BF,0 RET ; LOAD_Z80: MOV CL,BDOS_OPENF MOV DX,OFFSET FCB INT BDOS ;OPEN Z80 PROGRAM FILE INC AL ;0FFH=ERROR JZ LOAD_ERROR MOV CL,BDOS_DMA_BASE MOV DX,ES ;DMA BASE AT ESEG ORIGIN INT BDOS ;SET IT/  MOV DX,OFFSET Z80_TPA ;BEGIN LOADING THE FILE AT 0100H LOAD_LOOP: PUSH DX MOV CL,BDOS_DMA_OFFSET INT BDOS ;DMA NOW POINTS TO NEXT 128 BYTE BLOCK MOV CL,BDOS_READ_NEXT MOV DX,OFFSET FCB INT BDOS ;READ NEXT RECORD OR AL,AL ;0 INDICATEP/M-86$' MSG_RANGE_ERROR DB 'BRANCH OUTSIDE ADDRESS SPACE$' MSG_Z80_OP DB 'Z80 OP CODE DETECTED, ONLY 8080 ALLOWED$' MSG_Z80 DB CR,LF,'z80-->$' MSG_CR_LF DB CR,LF,'$' QRY_TAIL DB CR,LF,'ENTER COMMAND TAIL: $' ESEG Z80_BOOT DB 0C3H ;JP BOOT DS READ OK JNZ LOAD_EXIT ;END OF FILE POP DX ADD DX,128 ;POINT TO NEXT BLOCK JMP LOAD_LOOP LOAD_EXIT: POP DX ;RESTORE STACK MOV CL,BDOS_CLOSEF MOV DX,OFFSET FCB INT BDOS ;CLOSE IT UP MOV DX,OFFSET Z80_DMA ;SET DEFAULT DMA MOV CL,W 0BF13H ;0FFFFH RETURNS TO 8086 Z80_IOBYTE DB 0 ;IOBYTE Z80_DISK DB 0 ;CURRENT DISK Z80_BDOS DB 0C3H ;JMP BDOS DW 0BF00H ;SET FOR 48K TPA ORG 05CH ;Z80 FCB Z80_FCB: DB 0,' ',' ',0,0,0,0,0 ORG 07FH Z80_BUF: Z80_BF DB 20 ;LEBDOS_DMA_OFFSET INT BDOS CLC ;RESET ERROR RET LOAD_ERROR: MOV DX,OFFSET MSG_NO_FILE CALL PRINT STC ;SET ERROR RET RUN_Z80: MOV SI,0100H ;INITIALIZE Z80 IP TO BASE OF TPA PUSHF RUN_LOOP: CMP SI,0C000H ;TOP OF Z80 MEMORY JNNGTH CODE FOR READ Z80_DMA: DB 0 Z80_TAIL: ORG 0100H ;BEGINNING OF Z80 TPA Z80_TPA: ORG 0BF10H ;BIOS JUMP TABLE DB ZJMP DW 0FFFFH ;JP COLDBOOT DB ZJMP DW 0FFFFH ;JP WARMBOOT DB ZJMP DW OFFSET ZBIOS1 ;JP CONST DB ZJMP DW B Z80_RANGE_ERROR ;JUMP OUT OF RANGE CMP SI,0BF00H ;BDOS CALL VECTOR JE Z80_BDOS_CALL Z80_OK: MOV DI,ES:[SI] ;DI[L] CONTAINS Z80 INSTRUCTION AND DI,00FFH ;REMOVE HIGH ORDER BYTE SAL DI,1 ;MULTIPLY BY 2 FOR JUMP OFFSET INC SI ;BUMP Z80 OFFSET ZBIOS2 ;JP CONIN DB ZJMP DW OFFSET ZBIOS3 ;JP CONOUT DB ZJMP DW OFFSET ZBIOS4 ;JP LIST DB ZJMP DW 0FFFEH ;JP PUNCH (NG) DB ZJMP DW 0FFFEH ;JP READER (NG) DB ZJMP DW 0FFFEH ;JP HOME (NG) DB ZJMP DW 0FFFEH ;JP SELDSK (NGINSTRUCTION ADDRESS MOV BX,ES:[SI] ;WORD AFTER OP CODE MOV AX,JTABLE[DI] ;AX IS ADDRESS OF OP ROUTINE POPF CALL AX ;EXECUTE INSTRUCTION PUSHF JMP RUN_LOOP ;NEXT PLEASE Z80_BDOS_CALL: MOV CH,0 MOV CL,Z_C MOV DX,Z_DE PUSH SI PUSH ) DB ZJMP DW 0FFFEH ;JP SETTRK (NG) DB ZJMP DW 0FFFEH ;JP SETSEC (NG) DB ZJMP DW 0FFFEH ;JP SETDMA (NG) DB ZJMP DW 0FFFEH ;JP READ (NG) DB ZJMP DW 0FFFEH ;JP WRITE (NG) DB ZJMP DW 0FFFEH ;JP LISTST (NG) DB ZJMP DW 0FFFEH DS PUSH ES POP DS INT BDOS POP DS MOV Z_HL,BX MOV Z_A,AL MOV Z_DE,DX POP SI CALL Z80_RET JMP RUN_LOOP Z80_RANGE_ERROR: CMP SI,0FFFFH JE Z80_END ;BOOT MOV DX,OFFSET MSG_RANGE_ERROR CALL PRINT Z80_END: POPF RET ; JTABLE:;JP SECTTRANS (NG) ZBIOS1: ;GET CONSOLE STATUS DB ZLDCNN,BDOS_DIRECT ;LD C,BDOS_DIRECT (RAW I/O) DB ZLDENN,0FEH ;LD E,BDOS_GET_STATUS DB ZJMP DW 0BF00H ;JP BDOS ZBIOS2: ;GET ONE CHARACTER DB ZLDCNN,BDOS_DIRECT ;LD C,BDOS_DIRECT (RAW  INCLUDE JUMPADDR.Z80 ;JUMP ADDRESS TABLE INCLUDE CODE8086.Z80 ;8086 INSTRUCTIONS FOR Z80 OP CODES PRINT: PUSH DX MOV DX,OFFSET MSG_Z80 CALL PRINT1 POP DX CALL PRINT1 MOV DX,OFFSET MSG_CR_LF PRINT1: MOV CL,BDOS_PRINT INT BDOS RET I/O) DB ZLDENN,0FDH ;LD E,BDOS_INPUT_CHAR DB ZJMP DW 0BF00H ;JP BDOS ZBIOS3: ;SEND ONE CHARACTER DB ZLDCNN,BDOS_DIRECT ;RAW I/O DB ZLDEC ;LD E,C DB ZJMP DW 0BF00H ;JP BDOS ZBIOS4: ;ONE CHAR TO LIST DB ZLDCNN,BDOS_LIST ;LD CvCCODE8086.Z80:  o!"#$&%')(*,+.-/0123465789{z DSEG ORG 05CH FCB: ORG 0100H ;PAST UDA Z_REGISTERS: ;PRIMARY REGISTER SET Z_C RB 1 ;REGISTER C Z_B RB 1 ;REGISTER B Z_E RB 1 ;REGISTER E Z_D RB 1 ;REGISTER D Z_L RB 1 ;REGISTER L Z_H RB 1 ;REGISTER H Z_F RB 1 ;REGISTER F.,OUTPUT DB ZLDEC ;LD E,C DB ZJMP DW 0BF00H ;JP BDOS ; Z80PFCB: DW OFFSET Z80_TAIL DW OFFSET Z80_FCB ORG 0BFFFH DB 0 ;MAKE SURE MP/M-86 DOES END >]}ӫ/TEK;-]wߩwj.HeL|&"U +9V)0>vꝏGy⾨)v,|<%-cw&Gt}QS,;xʿc`/kFn ގG݉_"Bw,|Bcl|⾨ߩʖcsBʷ..Z80 CONTROL FLAGS Z_A RB 1 ;REGISTER A ORG 0100H Z_BC RW 1 ;REGISTER BC Z_DE RW 1 ;REGISTER DE Z_HL RW 1 ;REGISTER HL Z_AF RW 1 ;REGISTER AF Z_SP RW 1 ;Z80 STACK POINTER MSG_NO_FILE DB 'NO Z80 FILE$' MSG_TERMINATE DB 'EXITING TO M/ cl|G⾨c)@ݱTh>Nw{1z[9uhq_pN%Vs Bw 85X*x4}QSAY;xʿc5Hm/ ގG%q_GUN;v>⾨EW"߱ThE}WGS;v>+q_TX3q/[v,|<E-/4Ke;J;S~:ex-cS8 ގG;t!괛»c{KAx;x^ӌt-vr ۱Th}QS;x^Kvr ۱Th8q_Ts P۱ThN}QSi;x^K۱Th J1Z g/ ގG;}QSis ;x9mv,|<ENM1Z Ž9^NAKe;vΎt X*xSIuV ex-qVNKe;v}Qg寠 ;x^KAqVNKe;v:}Qg寠s vSoRǣ/»c{KAx;x^ӌt-vSoRǣb}Qg寠9^Rge۱T(T9^R(w q X*xhT/k)u4x;v>:⾨:1<Xg;ENuw,RߙcsVw,|)Ke;v!w&N+ߎGi;E-XX*x6Nw=GN|b|-iFYs w)@clђ/j1Z g(4x;v>-E;xY3ҵwkp߱T(]w⾨EW۱H} Ke;E-Rv,R);v>@_ ;>clQ.}QS -7w";x9oRǣt>;x^Kv|vr X*x.NwUjг[9u(]'⾨JxMx;x-q kp߱T(EN%v3c";L1poێ9^NAx ;v>+EN1Z o/Ke;vQ⾨ߩ^);xc5Hm/Ke;vENex-1)oRǣ}QSލVRގ9^R(wfkyX*x#-q_T7ws\[ 1Z /kFn ގG;ENuSx71彥 s pvfkyX*xcw⾨ߩn Fss ;F۱ThIC5J1Z ŽQ:hv,|+w ۱T('Z~v,R)Ke;⾨w oRǣtJ;k;L1)VKe;ňSńKe;voeEF=;S<Xg;v%*ZnO";L1)dQ+;v>NG;ܞ;LܱH}g9^RsZ޻5x;v>ޝ/jUXSȢKe;v!Z~uS\[ 1Z c5#]{oRǣi~)M1彥 s eHޭ۱Th}QSލvryo)o/k)sZ޻5x;v>؅/j۱؎G;v$n41彥 s ;xY3ҵwkv,|<1N;r/k);x9hv,|<ڱq_T9^R;x9hv,|<~vvKe;/UŽ9^Rvy۱ThyQv2SoRǣEnRގ9^4#]{9hv,|DclOGmTQ8Ʉ؎E;w,Rߙ؎oOc3Ke;x7vryo)o"JzcZELV]{Ke;v@_ލs\[ oHU*bZ޻X*x{⾨ߩn FݱH}g9^ʷc{KAx;xY3ҵwkv,|<ڽ#q_ُ8cRǣ}[YF=;S<Xg;vD5S eю9^{K!v 85X*x;ENfnOƎE;w,Rߙc5Hm/ ގG21)@clю%q_Tt/k)9^NKe;v}QSAv2cSoRǣq_Tގ9^Rx;x9hv,|4}QxR8Ʉ؎E;w,Rߙ؎oO[9{;R٧!v>r2*9^{K;S<LرTB5SAݱH}g|;v>;xoyχX*xljʪ[*Y*)RَTRǣq_RَoylRǣr{;r2!}QUw Ycl/jXSKe;v?}Qw clJ;w&oRǣc}QRǣ4y⾨ߩVex-r/P6x;v>%l/k)sBX*x/ws pvr eclQ}QSMw2oRǣ44}QSM1Z Ž9^Nlv,c8)@clxw⾨ ex-1۱Th/j8&ex-apSoRǣ}Q9cގ ގG]s*h7wc/v2Z޻q X*x4ޑ/j8;x^Kv 8hv,|<E Ws Pw X*x4މ/j8w21۱Th+hg/k)cw&8([*Y*c3T/ΫycbtǷclѯ}Qw&w ʷcl#Zf;S<>clѓ'Z*ow|#x>He;RKe;Z|=4}Qx~8Ʉ؎E;w,Rߙ؎oC[9{;R١!v>=r2:cR89!ɄKe;.}Qg9ecg9SQC;oo/k)sov,|ENex-1)oRǣ}QSVex-r/pKe;v%괿c9^N4x;v>@G;ig/k)siv,|<ڡ;q_T9^Rsiv,|<ځ/wӄs NclYN۱Th}Qg9e;x^KAwNKe;v!:)+a/k);rJ ގG;u :)cގ)@clN]rnRގ9^4#]{g9SoRǣ:Eex-qS:hv,|<)NuV Zcge۱ThN}Qg寠s wSoRǣ/c0 VKe;}QˌUs\[6/GN|ގGO/j;- He'N,|=%q_"UA{c";x-ck۱H^;s4x;v>=/UwdBl";LqQlǷԷTvoyχHRRA RCR Z_A,1 RET CODE20: ;JR NZ,dd JMP Z80_NFG CODE21: ;LD HL,nnnn INC SI INC SI MOV Z_HL,BX RET CODE22: ;LD (nnnn),HL INC SI INC SI MOV AX,Z_HL MOV ES:[BX],AX RET CODE23: ;INC HL INC Z_HL RET CODE24: eKe;Cw^s;S<Xg;%:+-7w";)@+ߎGO/j6c{ƅ)۱Tʪw|2GN|v2Ke;*-q_Fv=x>DclQ#6"l=G9۱H}gE;wamʔn/gb+;RKe;jw⾨^̢Mx;x-RȢ߿Й ;INC H INC Z_H RET CODE25: ;DEC H DEC Z_H RET CODE26: ;LD H,nn INC SI MOV Z_H,BL RET CODE27: ;DAA MOV AL,Z_A DAA MOV Z_A,AL RET CODE28: ;JR Z,dd JMP Z80_NFG CODE29: ;ADD HL,HL MOV AX,Z_HL ADD Z_HL,A4#]{sw,|<4}QxwdBl";LqQlǷZ*S)ۑʔX*xT;EdB%s v=x>D9clQB5PݱH}g⎁:NZv,|<;x<]^-Ke;j/jtǷZ*oylG*8Tv"6n Ǝ9^Ėv,|<@mTEZwX RET CODE2A: ;LD HL,(nnnn) INC SI INC SI MOV AX,ES:[BX] MOV Z_HL,AX RET CODE2B: ;DEC HL DEC Z_HL RET CODE2C: ;INC L INC Z_L RET CODE2D: ;DEC L DEC Z_L RET CODE2E: ;LD L,nn INC SI MOV Z_L,BL RET CODE2dBl";LqQlǷZ*S1˙T@,|<%q_z6e:3[ Gwr kp߱T~⾨?WEr{;r2!cw&8(--L?Tj=-@:xW⾨(w&)@+ߎG5FXE1ŽoyχX*x4'Z*fb)Rَ; *** CODE8086.Z80 *** VERSION 1.0 08/12/83 ; ; 8086 INSTRUCTIONS TO EMULATE Z80 OP CODES ; CODE00: ;NOP RET CODE01: ;LD BC,nnnn INC SI INC SI MOV Z_BC,BX RET CODE02: ;LD (BC),A MOV BX,Z_BC MOV AL,Z_A MOV ES:[BX],AL RETF: ;CPL XOR Z_A,0FFH RET CODE30: ;JR NC,dd JMP Z80_NFG CODE31: ;LD SP,nnnn INC SI INC SI MOV Z_SP,BX RET CODE32: ;LD (nnnn),A INC SI INC SI MOV AL,Z_A MOV ES:[BX],AL RET CODE33: ;INC SP INC Z_SP RET CTKe;h0 9!h/ ގ3b;v>E}UQ8Ʉ؎E;w,Rߙ؎o3Ke1sHe1:blXw⾨Ke;h^ܞLX3q";06T-,FC,|<@u v@ex-dŽGc]FYX3q(X*x4֑/j{~ CODE03: ;INC BC INC Z_BC RET CODE04: ;INC B INC Z_B RET CODE05: ;DEC B DEC Z_B RET CODE06: ;LD B,nn INC SI MOV Z_B,BL RET CODE07: ;RLCA ROL Z_A,1 RET CODE08: ;EX AF,AF' JMP Z80_NFG CODE09: ;ADDODE34: ;INC (HL) MOV BX,Z_HL INC ES: BYTE PTR [BX] RET CODE35: ;DEC (HL) MOV BX,Z_HL DEC ES: BYTE PTR [BX] RET CODE36: ;LD (HL),nn INC SI MOV AL,BL MOV BX,Z_HL MOV ES:[BX],AL RET CODE37: ;SCF STC RET CODE38: /v|#x>|xoRǣ8q_RYw|Keb)RَTKe;:ENEMx;x-}Rǣ1 6x8Ʉ؎E;w,Rߙ؎oRY vr&#ŀX*x4VE3&X*x4^[nOQN&v,RߙcGv|KebǷj=-@:x4}Q HL,BC MOV AX,Z_BC ADD Z_HL,AX RET CODE0A: ;LD A,(BC) MOV BX,Z_BC MOV AL,ES:[BX] MOV Z_A,AL RET CODE0B: ;DEC BC DEC Z_BC RET CODE0C: ;INC C INC Z_C RET CODE0D: ;DEC C DEC Z_C RET CODE0E: ;LD C,nn INC SI  ;JR C,dd JMP Z80_NFG CODE39: ;ADD HL,SP MOV AX,Z_SP ADD Z_HL,AX RET CODE3A: ;LD A,(nnnn) INC SI INC SI MOV AL,ES:[BX] MOV Z_A,AL RET CODE3B: ;DEC SP DEC Z_SP RET CODE3C: ;INC A INC Z_A RET CODE3D: ;DEݱH}g?X*x4#Zf1Dž)۱Tdq .;>Bw Yc{K!vfky#Ke;)FdQN&RȢs Z޻XSȢw Y#Ke;)#;x-w=x>D9c3Ke;)Rac3}RN댸_xB[Qhugzv MOV Z_C,BL RET CODE0F: ;RRCA RCR Z_A,1 RET CODE10: ;DJNZ JMP Z80_NFG CODE11: ;LD DE,nnnn INC SI INC SI MOV Z_DE,BX RET CODE12: ;LD (DE),A MOV BX,Z_DE MOV AL,Z_A MOV ES:[BX],AL RET CODE13: ;INC DE INC C A DEC Z_A RET CODE3E: ;LD A,nn INC SI MOV Z_A,BL RET CODE3F: ;CCF CMC RET CODE40: ;LD B,B MOV AL,Z_B MOV Z_B,AL RET CODE41: ;LD B,C MOV AL,Z_C MOV Z_B,AL RET CODE42: ;LD B,D MOV AL,Z_D MOV Z_B,AL R72e: ){Hs- vTrRwVTdg"R;vE:3[ Gwr kp߱T~⾨?WEr{;r2!cw&8(--Z_DE RET CODE14: ;INC D INC Z_D RET CODE15: ;DEC D DEC Z_D RET CODE16: ;LD D,nn INC SI MOV Z_D,BL RET CODE17: ;RLA RCL Z_A,1 RET CODE18: ;JR dd JMP Z80_NFG CODE19: ;ADD HL,DE MOV AX,Z_DE ADD Z_HL,AET CODE43: ;LD B,E MOV AL,Z_E MOV Z_B,AL RET CODE44: ;LD B,H MOV AL,Z_H MOV Z_B,AL RET CODE45: ;LD B,L MOV AL,Z_L MOV Z_B,AL RET CODE46: ;LD B,(HL) MOV BX,Z_HL MOV AL,ES:[BX] MOV Z_B,AL RET CODE47: ;LD B,AX RET CODE1A: ;LD A,(DE) MOV BX,Z_DE MOV AL,ES:[BX] MOV Z_A,AL RET CODE1B: ;DEC DE DEC Z_DE RET CODE1C: ;INC E INC Z_E RET CODE1D: ;DEC E DEC Z_E RET CODE1E: ;LD E,nn INC SI MOV Z_E,BL RET CODE1F: ;0  MOV AL,Z_A MOV Z_B,AL RET CODE48: ;LD C,B MOV AL,Z_B MOV Z_C,AL RET CODE49: ;LD C,C MOV AL,Z_C MOV Z_C,AL RET CODE4A: ;LD C,D MOV AL,Z_D MOV Z_C,AL RET CODE4B: ;LD C,E MOV AL,Z_E MOV Z_C,AL RET CODE4C: ,Z_B MOV ES:[BX],AL RET CODE71: ;LD (HL),C MOV BX,Z_HL MOV AL,Z_C MOV ES:[BX],AL RET CODE72: ;LD (HL),D MOV BX,Z_HL MOV AL,Z_D MOV ES:[BX],AL RET CODE73: ;LD (HL),E MOV BX,Z_HL MOV AL,Z_E MOV ES:[BX],AL RET CODE7;SBC A,B MOV AL,Z_B SBB Z_A,AL RET CODE99: ;SBC A,C MOV AL,Z_C SBB Z_A,AL RET CODE9A: ;SBC A,D MOV AL,Z_D SBB Z_A,AL RET CODE9B: ;SBC A,E MOV AL,Z_E SBB Z_A,AL RET CODE9C: ;SBC A,H MOV AL,Z_H SBB Z_A,AL RET ;LD C,H MOV AL,Z_H MOV Z_C,AL RET CODE4D: ;LD C,L MOV AL,Z_L MOV Z_C,AL RET CODE4E: ;LD C,(HL) MOV BX,Z_HL MOV AL,ES:[BX] MOV Z_C,AL RET CODE4F: ;LD C,A MOV AL,Z_A MOV Z_C,AL RET CODE50: ;LD D,B MOV AL,Z_B 4: ;LD (HL),H MOV BX,Z_HL MOV AL,Z_H MOV ES:[BX],AL RET CODE75: ;LD (HL),L MOV BX,Z_HL MOV AL,Z_L MOV ES:[BX],AL RET CODE76: ;HALT HLT RET CODE77: ;LD (HL),A MOV BX,Z_HL MOV AL,Z_A MOV ES:[BX],AL RET CODE78:  CODE9D: ;SBC A,L MOV AL,Z_L SBB Z_A,AL RET CODE9E: ;SBC A,(HL) MOV BX,Z_HL MOV AL,ES:[BX] SBB Z_A,AL RET CODE9F: ;SBC A,A MOV AL,Z_A SBB Z_A,AL RET CODEA0: ;AND B MOV AL,Z_B AND Z_A,AL RET CODEA1: ;AND C  MOV Z_D,AL RET CODE51: ;LD D,C MOV AL,Z_C MOV Z_D,AL RET CODE52: ;LD D,D MOV AL,Z_D MOV Z_D,AL RET CODE53: ;LD D,E MOV AL,Z_E MOV Z_D,AL RET CODE54: ;LD D,H MOV AL,Z_H MOV Z_D,AL RET CODE55: ;LD D,L MO ;LD A,B MOV AL,Z_B MOV Z_A,AL RET CODE79: ;LD A,C MOV AL,Z_C MOV Z_A,AL RET CODE7A: ;LD A,D MOV AL,Z_D MOV Z_A,AL RET CODE7B: ;LD A,E MOV AL,Z_E MOV Z_A,AL RET CODE7C: ;LD A,H MOV AL,Z_H MOV Z_A,AL RET  MOV AL,Z_C AND Z_A,AL RET CODEA2: ;AND D MOV AL,Z_D AND Z_A,AL RET CODEA3: ;AND E MOV AL,Z_E AND Z_A,AL RET CODEA4: ;AND H MOV AL,Z_H AND Z_A,AL RET CODEA5: ;AND L MOV AL,Z_L AND Z_A,AL RET CODEA6: ;ANV AL,Z_L MOV Z_D,AL RET CODE56: ;LD D,(HL) MOV BX,Z_HL MOV AL,ES:[BX] MOV Z_D,AL RET CODE57: ;LD D,A MOV AL,Z_A MOV Z_D,AL RET CODE58: ;LD E,B MOV AL,Z_B MOV Z_E,AL RET CODE59: ;LD E,C MOV AL,Z_C MOV Z_E,AL  CODE7D: ;LD A,L MOV AL,Z_L MOV Z_A,AL RET CODE7E: ;LD A,(HL) MOV BX,Z_HL MOV AL,ES:[BX] MOV Z_A,AL RET CODE7F: ;LD A,A MOV AL,Z_A MOV Z_A,AL RET CODE80: ;ADD A,B MOV AL,Z_B ADD Z_A,AL RET CODE81: ;ADD A,C D (HL) MOV BX,Z_HL MOV AL,ES:[BX] AND Z_A,AL RET CODEA7: ;AND A MOV AL,Z_A AND Z_A,AL RET CODEA8: ;XOR B MOV AL,Z_B XOR Z_A,AL RET CODEA9: ;XOR C MOV AL,Z_C XOR Z_A,AL RET CODEAA: ;XOR D MOV AL,Z_D XOR Z_A, RET CODE5A: ;LD E,D MOV AL,Z_D MOV Z_E,AL RET CODE5B: ;LD E,E MOV AL,Z_E MOV Z_E,AL RET CODE5C: ;LD E,H MOV AL,Z_H MOV Z_E,AL RET CODE5D: ;LD E,L MOV AL,Z_L MOV Z_E,AL RET CODE5E: ;LD E,(HL) MOV BX,Z_HL  MOV AL,Z_C ADD Z_A,AL RET CODE82: ;ADD A,D MOV AL,Z_D ADD Z_A,AL RET CODE83: ;ADD A,E MOV AL,Z_E ADD Z_A,AL RET CODE84: ;ADD A,H MOV AL,Z_H ADD Z_A,AL RET CODE85: ;ADD A,L MOV AL,Z_L ADD Z_A,AL RET CODE86:AL RET CODEAB: ;XOR E MOV AL,Z_E XOR Z_A,AL RET CODEAC: ;XOR H MOV AL,Z_H XOR Z_A,AL RET CODEAD: ;XOR L MOV AL,Z_L XOR Z_A,AL RET CODEAE: ;XOR (HL) MOV BX,Z_HL MOV AL,ES:[BX] XOR Z_A,AL RET CODEAF: ;XOR  MOV AL,ES:[BX] MOV Z_E,AL RET CODE5F: ;LD E,A MOV AL,Z_A MOV Z_E,AL RET CODE60: ;LD H,B MOV AL,Z_B MOV Z_H,AL RET CODE61: ;LD H,C MOV AL,Z_C MOV Z_H,AL RET CODE62: ;LD H,D MOV AL,Z_D MOV Z_H,AL RET CODE63:  ;ADD A,(HL) MOV BX,Z_HL MOV AL,ES:[BX] ADD Z_A,AL RET CODE87: ;ADD A,A MOV AL,Z_A ADD Z_A,AL RET CODE88: ;ADC A,B MOV AL,Z_B ADC Z_A,AL RET CODE89: ;ADC A,C MOV AL,Z_C ADC Z_A,AL RET CODE8A: ;ADC A,D MOVA MOV AL,Z_A XOR Z_A,AL RET CODEB0: ;OR B MOV AL,Z_B OR Z_A,AL RET CODEB1: ;OR C MOV AL,Z_C OR Z_A,AL RET CODEB2: ;OR D MOV AL,Z_D OR Z_A,AL RET CODEB3: ;OR E MOV AL,Z_E OR Z_A,AL RET CODEB4: ;OR H M ;LD H,E MOV AL,Z_E MOV Z_H,AL RET CODE64: ;LD H,H MOV AL,Z_H MOV Z_H,AL RET CODE65: ;LD H,L MOV AL,Z_L MOV Z_H,AL RET CODE66: ;LD H,(HL) MOV BX,Z_HL MOV AL,ES:[BX] MOV Z_H,AL RET CODE67: ;LD H,A MOV AL,Z_ AL,Z_D ADC Z_A,AL RET CODE8B: ;ADC A,E MOV AL,Z_E ADC Z_A,AL RET CODE8C: ;ADC A,H MOV AL,Z_H ADC Z_A,AL RET CODE8D: ;ADC A,L MOV AL,Z_L ADC Z_A,AL RET CODE8E: ;ADC A,(HL) MOV BX,Z_HL MOV AL,ES:[BX] ADC Z_A,AOV AL,Z_H OR Z_A,AL RET CODEB5: ;OR L MOV AL,Z_L OR Z_A,AL RET CODEB6: ;OR (HL) MOV BX,Z_HL MOV AL,ES:[BX] OR Z_A,AL RET CODEB7: ;OR A MOV AL,Z_A OR Z_A,AL RET CODEB8: ;CP B MOV AL,Z_B CMP Z_A,AL RET CODEBA MOV Z_H,AL RET CODE68: ;LD L,B MOV AL,Z_B MOV Z_L,AL RET CODE69: ;LD L,C MOV AL,Z_C MOV Z_L,AL RET CODE6A: ;LD L,D MOV AL,Z_D MOV Z_L,AL RET CODE6B: ;LD L,E MOV AL,Z_E MOV Z_L,AL RET CODE6C: ;LD L,H L RET CODE8F: ;ADC A,A MOV AL,Z_A ADC Z_A,AL RET CODE90: ;SUB B MOV AL,Z_B SUB Z_A,AL RET CODE91: ;SUB C MOV AL,Z_C SUB Z_A,AL RET CODE92: ;SUB D MOV AL,Z_D SUB Z_A,AL RET CODE93: ;SUB E MOV AL,Z_E SUB9: ;CP C MOV AL,Z_C CMP Z_A,AL RET CODEBA: ;CP D MOV AL,Z_D CMP Z_A,AL RET CODEBB: ;CP E MOV AL,Z_E CMP Z_A,AL RET CODEBC: ;CP H MOV AL,Z_H CMP Z_A,AL RET CODEBD: ;CP L MOV AL,Z_L CMP Z_A,AL RET CODEBEMOV AL,Z_H MOV Z_L,AL RET CODE6D: ;LD L,L MOV AL,Z_L MOV Z_L,AL RET CODE6E: ;LD L,(HL) MOV BX,Z_HL MOV AL,ES:[BX] MOV Z_L,AL RET CODE6F: ;LD L,A MOV AL,Z_A MOV Z_L,AL RET CODE70: ;LD (HL),B MOV BX,Z_HL MOV AL Z_A,AL RET CODE94: ;SUB H MOV AL,Z_H SUB Z_A,AL RET CODE95: ;SUB L MOV AL,Z_L SUB Z_A,AL RET CODE96: ;SUB (HL) MOV BX,Z_HL MOV AL,ES:[BX] SUB Z_A,AL RET CODE97: ;SUB A MOV AL,Z_A SUB Z_A,AL RET CODE98: 1 : ;CP (HL) MOV BX,Z_HL MOV AL,ES:[BX] CMP Z_A,AL RET CODEBF: ;CP A MOV AL,Z_A CMP Z_A,AL RET CODEC0: ;RET NZ JZ RETC0 JMP Z80_RET RETC0: RET CODEC1: ;POP BC CALL Z80_POP MOV Z_BC,AX RET CODEC2: ;JP NZ nnnn DEE2: ;JP PO,nnnn PUSHF INC SI INC SI POPF JPE RETE2 MOV SI,BX RETE2: RET CODEE3: ;EX (SP),HL MOV AX,Z_HL MOV BX,Z_SP XCHG AX,ES:[BX] MOV Z_HL,AX RET CODEE4: ;CALL PO,nnnn PUSHF INC SI INC SI POPF JPE RETE4 FFFH ;TERMINATE ON NEXT INSTRUCTION RET  PUSHF INC SI INC SI POPF JZ RETC2 MOV SI,BX RETC2: RET CODEC3: ;JP nnnn MOV SI,BX RET CODEC4: ;CALL NZ,nnnn PUSHF INC SI INC SI POPF JZ RETC4 JMP Z80_CALL RETC4: RET CODEC5: ;PUSH BC MOV AX,Z_BC CALL Z80_PUSHJMP Z80_CALL RETE4: RET CODEE5: ;PUSH HL MOV AX,Z_HL CALL Z80_PUSH RET CODEE6: ;AND nn INC SI AND Z_A,BL RET CODEE7: ;RST 20 MOV BX,020H JMP Z80_CALL RET CODEE8: ;RET PE JPO RETE8 JMP Z80_RET RETE8: RET CODEE9:  RET CODEC6: ;ADD A,nn INC SI ADD Z_A,BL RET CODEC7: ;RST 0 MOV BX,0 JMP Z80_CALL RET CODEC8: ;RET Z JNZ RETC8 JMP Z80_RET RETC8: RET CODEC9: ;RET JMP Z80_RET RET CODECA: ;JP Z,nnnn PUSHF INC SI INC SI  ;JP (HL) MOV SI,Z_HL RET CODEEA: ;JP PE nnnn PUSHF INC SI INC SI POPF JPO RETEA MOV SI,BX RETEA: RET CODEEB: ;EX DE,HL MOV AX,Z_HL XCHG AX,Z_DE MOV Z_HL,AX RET CODEEC: ;CALL PE,nnnn PUSHF INC SI INC SI PO POPF JNZ RETCA MOV SI,BX RETCA: RET CODECB: ;MULTIPLE JMP Z80_NFG CODECC: ;CALL Z,nnnn PUSHF INC SI INC SI POPF JNZ RETCC JMP Z80_CALL RETCC: RET CODECD: ;CALL nnnn INC SI INC SI JMP Z80_CALL RET CODECE: PF JPO RETEC JMP Z80_CALL RETEC: RET CODEED: ;MULTIPLE JMP Z80_NFG CODEEE: ;XOR nn INC SI XOR Z_A,BL RET CODEEF: ;RST 28 MOV BX,028H JMP Z80_CALL RET CODEF0: ;RET P JS RETF0 JMP Z80_RET RETF0: RET CODEF1: ;ADC A,nn INC SI ADC Z_A,BL RET CODECF: ;RST 8 MOV BX,8 JMP Z80_CALL RET CODED0: ;RET NC JC RETD0 JMP Z80_RET RETD0: RET CODED1: ;POP DE CALL Z80_POP MOV Z_DE,AX RET CODED2: ;JP NC,nnnn PUSHF INC SI INC SI ;POP AF CALL Z80_POP MOV Z_A,AL SAHF RET CODEF2: ;JP P,nnnn PUSHF INC SI INC SI POPF JS RETF2 MOV SI,BX RETF2: RET CODEF3: ;DI CLI RET CODEF4: ;CALL P,nnnn PUSHF INC SI INC SI POPF JS RETF4 JMP Z80_CALL  POPF JC RETD2 MOV SI,BX RETD2: RET CODED3: ;OUT (nn),A INC SI MOV DH,0 MOV DL,BL MOV AL,Z_A OUT DX,AL RET CODED4: ;CALL NC,nnnn PUSHF INC SI INC SI POPF JC RETD4 JMP Z80_CALL RETD4: RET CODED5: ;PUSH DE MOV ARETF4: RET CODEF5: ;PUSH AF LAHF MOV AL,Z_A CALL Z80_PUSH RET CODEF6: ;OR nn INC SI OR Z_A,BL RET CODEF7: ;RST 30 MOV BX,030H JMP Z80_CALL RET CODEF8: ;RET M JNS RETF8 JMP Z80_RET RETF8: RET CODEF9: ;LD SP,X,Z_DE CALL Z80_PUSH RET CODED6: ;SUB nn INC SI SUB Z_A,BL RET CODED7: ;RST 10 MOV BX,010H JMP Z80_CALL RET CODED8: ;RET C JNC RETD8 JMP Z80_RET RETD8: RET CODED9: ;EXX JMP Z80_NFG CODEDA: ;JP C,nnnn PUSHL MOV AX,Z_HL MOV Z_SP,AX RET CODEFA: ;JP M,nnnn PUSHF INC SI INC SI POPF JNS RETFA MOV SI,BX RETFA: RET CODEFB: ;EI STI RET CODEFC: ;CALL M,nnnn PUSHF INC SI INC SI POPF JNS RETFC JMP Z80_CALL RETFC: RETvZJUMPADDR.Z80*  !#$"%&o)('lVQ [ݚo$-NzmZ-!^4䷀i `+ka[HZ얘t-SHF INC SI INC SI POPF JNC RETDA MOV SI,BX RETDA: RET CODEDB: ;IN A,(nn) INC SI MOV DH,0 MOV DL,BL IN AL,DX MOV Z_A,AL RET CODEDC: ;CALL C,nnnn PUSHF INC SI INC SI POPF JNC RETDC JMP Z80_CALL RETDC: RET CODEDD: CODEFD: ;MULTIPLE JMP Z80_NFG CODEFE: ;CP nn INC SI CMP Z_A,BL RET CODEFF: ;RST 38 MOV BX,038H JMP Z80_CALL RET Z80_PUSH: PUSH BX DEC Z_SP DEC Z_SP MOV BX,Z_SP MOV ES:[BX],AX POP BX RET Z80_POP: PUSH BX Mִ%w-Guq GuqGuqGuq GuqGuq pKIߏf;MM>M&M6w-}'}?w)-}'}?yM-}'}?y<-}'}?y-}'}?y\-}'}?y,-}'}?ym[N~T.1 ;MULTIPLE JMP Z80_NFG CODEDE: ;SBC A,nn INC SI SBB Z_A,BL RET CODEDF: ;RST 18 MOV BX,018H JMP Z80_CALL RET CODEE0: ;RET PO JPE RETE0 JMP Z80_RET RETE0: RET CODEE1: ;POP HL CALL Z80_POP MOV Z_HL,AX RET COOV BX,Z_SP MOV AX,ES:[BX] INC Z_SP INC Z_SP POP BX RET Z80_CALL: MOV AX,SI CALL Z80_PUSH MOV SI,BX RET Z80_RET: CALL Z80_POP MOV SI,AX RET Z80_NFG: ;Z80 ONLY OP CODE DETECTED MOV DX,OFFSET MSG_Z80_OP CALL PRINT MOV SI,0F1 ..1.5..żn;Q]3<n;Q]in;Q]n;Q]n;Q]n;Q]an;Q]iwGu1Gu1Gu1 Gu1Gu1 Gu1.pKIߏb.pKIߏbnpKIߏb.pKIODE2E DW OFFSET CODE2F DW OFFSET CODE30 DW OFFSET CODE31 DW OFFSET CODE32 DW OFFSET CODE33 DW OFFSET CODE34 DW OFFSET CODE35 DW OFFSET CODE36 DW OFFSET CODE37 DW OFFSET CODE38 DW OFFSET CODE39 DW OFFSET CODE3A DW OFFSߏb.pKIߏb.pKIߏb. pKIߏbnv-}'}? -}'}?|-}'}?L-}'}? -}'}?l-}'}?Gu17[N~Ts Gu1W[N~T[N~Tx[N~T8[N~T[N~TX[N~T.fn;Q]bn;Q]n;Q]bn;Q]jn;Q]bnET CODE3B DW OFFSET CODE3C DW OFFSET CODE3D DW OFFSET CODE3E DW OFFSET CODE3F DW OFFSET CODE40 DW OFFSET CODE41 DW OFFSET CODE42 DW OFFSET CODE43 DW OFFSET CODE44 DW OFFSET CODE45 DW OFFSET CODE46 DW OFFSET CODE47 DW ;Q]*-}'}?Ywe-}'}?Yw GuqpKIߏ6m\-}'}?X[N~Tn;Q]GuqpKIߏ6>mL-}'}?[N~T.n+-}'}?Guq.nM-}'}?y[N~Ts.nn;Q]wOFFSET CODE48 DW OFFSET CODE49 DW OFFSET CODE4A DW OFFSET CODE4B DW OFFSET CODE4C DW OFFSET CODE4D DW OFFSET CODE4E DW OFFSET CODE4F DW OFFSET CODE50 DW OFFSET CODE51 DW OFFSET CODE52 DW OFFSET CODE53 DW OFFSET CODE54  pKIߏv-}'}?[N~T.ngn;Q]w Guq{n;Q]-}'}? Guq.f4.f.fp.fp.f.fn;Q]hwwwwwwQ[N~T3Gu1À[N~ DW OFFSET CODE55 DW OFFSET CODE56 DW OFFSET CODE57 DW OFFSET CODE58 DW OFFSET CODE59 DW OFFSET CODE5A DW OFFSET CODE5B DW OFFSET CODE5C DW OFFSET CODE5D DW OFFSET CODE5E DW OFFSET CODE5F DW OFFSET CODE60 DW OFFSET CODE6T3Gu1 Gu1Gu1Gu1 Gu1Gu1 pKIߏb~;||>|&|6w-}'}?w/-}'}?M-}'}?<-}'}?-}'}?\-}'}?,-}'}?m[N~T3.f2.f1 DW OFFSET CODE62 DW OFFSET CODE63 DW OFFSET CODE64 DW OFFSET CODE65 DW OFFSET CODE66 DW OFFSET CODE67 DW OFFSET CODE68 DW OFFSET CODE69 DW OFFSET CODE6A DW OFFSET CODE6B DW OFFSET CODE6C DW OFFSET CODE6D DW OFFSET C.f2.f6.f.fn;Q]4Ln;Q]hn;Q]n;Q]n;Q]n;Q]`n;Q]hwGuqGuqGuq GuqGuq Guq.npKIߏ.npKIߏbvpKIߏb6pKIߏb6pK; *** JUMPADDR.Z80 *** VERSION 1.0 08/12/83 ; ; JUMP ADDRESS TABLE FOR Z80 EMULATOR ; DW OFFSET CODE00 DW OFFSET CODE01 DW OFFSET CODE02 DW OFFSET CODE03 DW OFFSET CODE04 DW OFFSET CODE05 DW OFFSET CODE06 DW OFFSET CODE07 DW ODE6E DW OFFSET CODE6F DW OFFSET CODE70 DW OFFSET CODE71 DW OFFSET CODE72 DW OFFSET CODE73 DW OFFSET CODE74 DW OFFSET CODE75 DW OFFSET CODE76 DW OFFSET CODE77 DW OFFSET CODE78 DW OFFSET CODE79 DW OFFSET CODE7A DW OFFSIߏb6pKIߏb6 pKIߏbvv-}'}? -}'}?|-}'}?L-}'}? -}'}?l-}'}?Gu1;[N~T Gu1[[N~TWpKIߏn;Q]\-}'}? Guq.6-}'}?pKIߏbn;Q]\|-}'}? Guq5..6U[N~OFFSET CODE08 DW OFFSET CODE09 DW OFFSET CODE0A DW OFFSET CODE0B DW OFFSET CODE0C DW OFFSET CODE0D DW OFFSET CODE0E DW OFFSET CODE0F DW OFFSET CODE10 DW OFFSET CODE11 DW OFFSET CODE12 DW OFFSET CODE13 DW OFFSET CODE14 ET CODE7B DW OFFSET CODE7C DW OFFSET CODE7D DW OFFSET CODE7E DW OFFSET CODE7F DW OFFSET CODE80 DW OFFSET CODE81 DW OFFSET CODE82 DW OFFSET CODE83 DW OFFSET CODE84 DW OFFSET CODE85 DW OFFSET CODE86 DW OFFSET CODE87 DW TW..n;Q]\w8M-}'}?w8-}'}?w8,-}'}?Guq.pKIߏ.pKIߏ4.pKIߏ 1nn;Q]ln;Q]l.fn;Q]6-}'}?Gu[N~T DW OFFSET CODE15 DW OFFSET CODE16 DW OFFSET CODE17 DW OFFSET CODE18 DW OFFSET CODE19 DW OFFSET CODE1A DW OFFSET CODE1B DW OFFSET CODE1C DW OFFSET CODE1D DW OFFSET CODE1E DW OFFSET CODE1F DW OFFSET CODE20 DW OFFSET CODE2OFFSET CODE88 DW OFFSET CODE89 DW OFFSET CODE8A DW OFFSET CODE8B DW OFFSET CODE8C DW OFFSET CODE8D DW OFFSET CODE8E DW OFFSET CODE8F DW OFFSET CODE90 DW OFFSET CODE91 DW OFFSET CODE92 DW OFFSET CODE93 DW OFFSET CODE94 Gu[N~TGuـ[N~T.v.nm..VpKIߏb.pKIߏbq. pKIߏbn;Q]v-}'}?wX|-}'}?wX -}'}?wXGuGu Gu `ZT3.f2.f1 DW OFFSET CODE22 DW OFFSET CODE23 DW OFFSET CODE24 DW OFFSET CODE25 DW OFFSET CODE26 DW OFFSET CODE27 DW OFFSET CODE28 DW OFFSET CODE29 DW OFFSET CODE2A DW OFFSET CODE2B DW OFFSET CODE2C DW OFFSET CODE2D DW OFFSET C2  DW OFFSET CODE95 DW OFFSET CODE96 DW OFFSET CODE97 DW OFFSET CODE98 DW OFFSET CODE99 DW OFFSET CODE9A DW OFFSET CODE9B DW OFFSET CODE9C DW OFFSET CODE9D DW OFFSET CODE9E DW OFFSET CODE9F DW OFFSET CODEA0 DW OFFSET CODEA X= Y= Z=  200$<$<p Set Up for: NEC1 DW OFFSET CODEA2 DW OFFSET CODEA3 DW OFFSET CODEA4 DW OFFSET CODEA5 DW OFFSET CODEA6 DW OFFSET CODEA7 DW OFFSET CODEA8 DW OFFSET CODEA9 DW OFFSET CODEAA DW OFFSET CODEAB DW OFFSET CODEAC DW OFFSET CODEAD DW OFFSET C Advanced Personal Computer on standard serial port ðv/.F ڋ++2!22@2 N2'2ÐS` UART/Modem Control Current settings -  Enter choices below - for no ODEAE DW OFFSET CODEAF DW OFFSET CODEB0 DW OFFSET CODEB1 DW OFFSET CODEB2 DW OFFSET CODEB3 DW OFFSET CODEB4 DW OFFSET CODEB5 DW OFFSET CODEB6 DW OFFSET CODEB7 DW OFFSET CODEB8 DW OFFSET CODEB9 DW OFFSET CODEBA DW OFFSchange Y RBaud Rate (110, 300, 600, 1200, 2400, 4800, 9600, 19200): 6[ c!110s`X!300sUM!600sJB!1200s>6!2400s2*!4800s&!9600s!19200s ! sN..Y  Word Length (7, 8): [ 7s 8 s s ET CODEBB DW OFFSET CODEBC DW OFFSET CODEBD DW OFFSET CODEBE DW OFFSET CODEBF DW OFFSET CODEC0 DW OFFSET CODEC1 DW OFFSET CODEC2 DW OFFSET CODEC3 DW OFFSET CODEC4 DW OFFSET CODEC5 DW OFFSET CODEC6 DW OFFSET CODEC7 DW  .V Y R Stop Bits (1, 2): \[ 1@s 2s w s c.W Y  Parity (None, Even, Odd): [ = NONEs$1 EVEN0s% ODDs  s .X . V . X . W . New settings - [dzWord length is .V <u OFFSET CODEC8 DW OFFSET CODEC9 DW OFFSET CODECA DW OFFSET CODECB DW OFFSET CODECC DW OFFSET CODECD DW OFFSET CODECE DW OFFSET CODECF DW OFFSET CODED0 DW OFFSET CODED1 DW OFFSET CODED2 DW OFFSET CODED3 DW OFFSET CODED4   % MODEM 9.01.04 - 24/Sep/83 CP/M-86 version by Michael Mellinger and Bill Bolton _seven SeightJ, number of stop bits is .W <@u %onetwo, parity is .X <u none .X <u odd even .$ .V .$.W $0.X ++ Incorrect entry ++ t@  @ %2. t'lCarrier 4 DW OFFSET CODED5 DW OFFSET CODED6 DW OFFSET CODED7 DW OFFSET CODED8 DW OFFSET CODED9 DW OFFSET CODEDA DW OFFSET CODEDB DW OFFSET CODEDC DW OFFSET CODEDD DW OFFSET CODEDE DW OFFSET CODEDF DW OFFSET CODEE0 DW OFFSET CODEESTRING #0 at 240HSTRING #1 at 260HSTRING #2 at 280HSTRING #3 at 2A0HSTRING #4 at 2C0HSTRING #5 at 2E0HSTRING #6 at 300HSTRING #7 at 320H$uZnot Rpresent Ì.0I.2I[؎м0ISyog.0D.oC.Cc.pC< tUm u .C.oC.oC.<t RSZODEEE DW OFFSET CODEEF DW OFFSET CODEF0 DW OFFSET CODEF1 DW OFFSET CODEF2 DW OFFSET CODEF3 DW OFFSET CODEF4 DW OFFSET CODEF5 DW OFFSET CODEF6 DW OFFSET CODEF7 DW OFFSET CODEF8 DW OFFSET CODEF9 DW OFFSET CODEFA DW OFFSSA 1-301-344-9156H=Dave Hardy 1-313-846-6127I=Wayne Hammerly 1-301-953-3753J=RBBS Pasadena 1-213-356-1034K=David Kozinn 1-216-334-4604L=Program Store 1-202-337-4694M=Kelly Smith 1-805-527-9321N=SuperBrain Sys 1-617-862-0781O=R.L.PloufuZõuދ.oCt9 ** There may be text in the memory buffer ** ** It will be lost unless NOL or WRT commands are used ** .ȻQ KuuuCC GxCqC<.C.C ~ Single Letter ET CODEFB DW OFFSET CODEFC DW OFFSET CODEFD DW OFFSET CODEFE DW OFFSET CODEFF ; fe 1-703-524-2549P=K.Petersen 1-313-759-6569RQ=Bruce Ratoff 1-201-272-1874R=Mark Pulver 1-312-789-0499S= T= U= V= W= 2 Commands H - Display this information ? - Display current settings T - Terminal mode E - Terminal mode with echo L - Terminal mode with local echo For capturing text use T(or E or L) FILENAME.TYP and Start & Stop toggles descrip input when writing full buffer to disk, XON sent to resume. .$ - Transfer ASCII file to remote .  .&u3 - Send local control character to remote 7 - Next character will be used for local control u Drive A\Use XOFF testing? (Y/N): @r.m. u..CUse XON waiting after (Y/N): r.g. u`..oJUse echo waiting before transmitting next character (Y/N): r.!. u..bed on subsequent screen. R - Receive CP/M file using Christensen Protocol S - Send CP/M file using Christensen Protocol Command is: R(or S) FILENAME.TYP R and S can use the following subcommands: B - Bulk transfer using wild<tPX, User XZ.oCu 7 bytes of buffer free COMMAND (H for Help): C!CKCPMr?LOGre3DIRrB'ERArpDSCr?rc SPDrFOPr? TIMrTCCr\TBRrTLCrTLFrSWaiting for character echo . u,NOT $used in terminal mode file output úC.C< t. u}_.oC uh.D< t`Dv .oC.CD .C.>oCt3.D< t+.C  3 .oC.CD{ .CE++ No File Open ++ )/C:tuHIT any KEY to CONTINUEt.tm is initially executed. ? Three Letter Commands CPM - Exit from this program to CP/M DIR - List directory and space free (may specify drive) ERA - Erase file (may specify drive) LOG - Change default drive/user (specify drive/use./D<r.C< t7.C< tȊ<rqQbY:tZ Insert disk for drive ./DA Hit return when ready& < u ./DG ++ Terminal mode file open ++ ++ Use WRT or DEL before LOG command ++  ~ wuJ Current Settings .. tm :HTerminal mode file buffer is .oCtinactive Unused portion of buffer is 2 bytes .t~ .R .CÊ؊NJr) and reset disks. e.g. LOG A0, LOG B (user unchanged) FOP - Display commands for setting terminal mode file output parameters .t8DSC - Disconnect the modem from the telephone line .u+TIM - Set S mode time-to-send messa 2C\ >] u\u5 ++ File not found ++ \ File erased . u>u ** Disconnected ** ] Enter character output delay [0(none) - 9(longest delay)]: Ks.[ Enter additional delay after [0V Commands for Setting Terminal Mode File Output Parameters SPD - Set speed of file output TEF - Toggle transmission of end-of-file character .  tLTSL - Toggle stripping linefeeds TWE - Toggle wait for character echo .tF`ge . t/QTCC - Toggle Checksum/CRC mode on receive .t.TBR - Toggle backspace to rub conversion . t]TLC - Toggle 1) local command immediate 2) local command after .&} .  t6TLF - Toggle send linefeed aft-9]: s.iCd .C< t ,0< rXz, Terminal mode file output delay is 0..X seconds per character Additional delay after is 0.. seconds < s0 Sط, [. t Use 0-7 to give baud rate for STXF - Toggle XOFF testing TXN - Toggle XON waiting after . End-of-file character .uNOT sent in terminal mode file output SL Library of Phone Numbers of Remote Systems 4I"ڈBCC CCer carriage return INUM - List remote systems . t#"SET - Set communication ports  The following are terminal text buffer commands: DEL - Delete memory buffer and file NOL - Return to terminal mode - no loss of data in buffer  mode time-to-send message, where 0=110, 1=300, 2=600, 3=1200, 4=2400 5=4800, 6=9600 and 7 = 19200 baud Enter value: <r'.[. u: Rate for the S mode time-to-send message is set to  Modem speed is û.ڊCt" ڈ CBð ڈCCCð$ڈڱ 4I74[< t< t< t< r<rP( X)QRSб[ZYP  XVQRS.&2&[ZY^QRS2,&[ZY QRS2?&[ZYQRS.Y&X&2[ZYQRSm&2[ZY  .  u. BLinefeed .  tNOT sent after in terminal mode file output . u3 / <t<t g b]v#UEXZRB#?/ uOB)u>2,ZY[XĞZ[SR/CC Cu] u<QPr*6.C|.C urdr ..C;.wC u.3DrsB.wCX ]< ud,r.wC t!File open, ready to receive .C uC.P4^uX[Awaiting initial NAK b<u;D t < tÊ< ..qC t <t(\2 ++ Checksum error ++ C u)Y ** Entering terminal mode ** -File open: .C ( Hex) Records Send time: .лn=ڊC7.CSj mins, =.ڊ[jwtqn: secs at To cancel use ctrl-X  0` .C0pK = .C<u7* null string *".C<t< t4u S [C9:t.C .C Enter number to transmit string [.Cs$1.C tPrinter is on Printer is off PwuXي.C u;[ò}<uu.C.8D]4.4D\D`1 r%f$u.4D\ڵ ׇ.4D8D:Duû4.4D.8D TO QUIT: CúCD+úDúDõRzZ<u . uÊ<u t<uCuP. tu.  tXP< tXP.1D. tX< t.&\H)[.C.Cð.Cu2.CÊ2õ 9s<uÊ. t<u.qC t< ++ <t HNAK received not ACK - .C.C< s.qC tu Can't send sector -- Aborting $.qC t3 le names allowed ++ D No file specified ˺\tError - Can't make file Directory is likely full $#\}.C}2h\uBCan't open file$.qC upú\tCan't close file$.Cx.C.C.C<available Overlays ; for your hardware.) ; ; ; ; After Editing your Overlay Source File to conform to your ; Hardware environment, proceed as follows: ; ; ; ASM86 M8GP (Assemble the Overlay File ) ; PIP MDM.H86=MDM840.H86,M8GP.H86 (Appuñ4IQR\ZY tt+++ File read error ++$ڇ 8086 translator) ; is virtualy useles4I4Is with large files. ; Various routines had to be changed to work properly with CPM86 and MPM86 ; When making mods to MDM8xx keep in mind that they should work on CPM86 as ; well as MPM86, so dont use BIOS calls and stuff as such... ; ; Alex Soya ; Sysop Melbourne RCPM ; ; P.O. Box 121 ; Melbourne Beach ; Fl. 32951 ; ; ; MDM8xx COPYRIGHTED 1984 BY ALEX K. SOYA ; MDM7xx COPYRIGHTED 1984 BY IRVIN M. HOFF ; ; THIS TELEPHONE MODEM PROGRAM USES THE CHRISTENSEN PROTOCOL. IT HAS ; BOTH 'CRC' AND CHECKSUM CAPABILITY FOR ERROR-DETECTION. IT SUPPORTS ; DIALING AND AUTO-REDIALING FOR THE ANCHOR AUTOMATION SIGNALMAN MARK ; XII, US ROBOTICS MODEMS, THE HAYES SMARTMODEM 300 AND 1200 AND PMMI ; S-100 MODEMS. IT SUPPORTS UP TO TWO AL pagesize 51 VERSION EQU 840 ;MDM840a(10/27/84) -- CP/M MODEM PROGRAM * ; ; MDM841.A86 ; ; ; 840A 10/27/84 - Fixed Timing Loops Alex Soya ; 840 10/23/84 - Added stuff from MDM740 Dennis Vallianos ; 830 - Translation TERNATE DIALING SYSTEMS SUCH ; AS 'MCI', 'SPRINT', ETC. IT IS COPYRIGHTED TO DETER COMMERCIALISM. ; ; OTHER EXTERNAL MODEMS MAY BE READILY USED, ALTHOUGH MANUAL DIALING ; MAY BE NECESARY. OVERLAYS HAVE BEEN MADE ALLOWING RAPID ADAPTATION ; TO VARIOfrom MDM730 Alex Soya ;------------------------------------------------------------------------ ; Translation of MDM740.ASM for CPM86 and MPM86. ; ; This translation follows the same principle of using overlays ; to adapt MDM8xx to different haUS COMPUTERS. THE PROGRAM CONFORMS READILY TO NUMEROUS I/O ; DEVICES INCLUDING THE 2661, 8250, 8251, Z80-SIO, ETC. ; ; ;*********************************************************************** ; ; GENERAL INTEREST: When transferring files modem-tordware environments as was so ; successfully done with MDM7xx. ; ; The procedure to adapt MDM8xx to specific hardware has changed ; somewhat due to the facts that DDT86 can not be used to overlay ; H86 (HEX) files and no SAVE command beeing available -modem, the batch ; mode is extremely useful. It allows automatic transmission of nu- ; merous files while the operator at the receiving end does virtually ; nothing. It can be used for single files or with wildcards. With ; normal single prin CPM86. ; ; The Procedure is now as follows: ; ; Required Files: MDM8xx.H86 (xx is Version Number) ; The Main Program in Hex Form. ; ; M8GP.A86 (The General None Specific ; Overlay. ; or ; One of the 4 ogram transfer, the receiving end switches from CRC ; to checksum in one minute and times out completely in 120 seconds. ; (In batch mode it times out in 3 minutes for receive.) This offers ; ample opportunity to transfer programs between individto set even parity NOPARMSK EQU 10H ;mask to reset to no parity ODPARMSK EQU 0CFH ;mask to set odd parity ; ANSWMOD EQU 1EH ;answer mode ORIGMOD EQU 1DH ;originate mode WAITCTS EQU 150 ;number of seconds (x5) to wait for the ;compu 4=710 ;5=1200 6=2400 7=4800 8=9600 9=19200 BYTDLY DB 5 ;0=0 delay 1=10 ms 5=50 ms - 9=90 ms ;defaut time to send character in ter- ;minal mode file transfer for slow BBS CRDLY DB 5 ;0=0 delay 1=100 ms 5=500 ms - 9=900 ms ;duals. ; ; ; M8LIB.CMD can be used to very easily and very quickly change ; any of the telephone overlay numbers. ; ; M8FNK.CMD can be used to quickly and easily change any of the ; 10 function key assignments (or the function key inteter to answer after PMMI auto-dial ;100=20 sec, 150=30 sec, 255=51 sec. ;any number 0-255 acceptable ; ; (END OF SPECIAL PMMI EQUATES) ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; YES EQU 0FFH NO EQU 0 efault time for extra wait after CRLF ;in terminal mode file transfer NOOFCOL DB 5 ;number of directory columns SETUPTST DB NO ;yes=non-PMMI setup routine SCRNTEST DB NO ;yes=if home cursor and clear screen ;routine at CLRSCRN RETRY DBrcept ; character itself, which is currently the '^' character. ; ; ; This program may be used freely for any non-commercial purpose, ; provided that the user does not remove or alter this notice or ; the copyright statement. It is not covered  ; ; BUFSIZ EQU 16 ;buffer size in Kbytes for ASCII capture to disk ;(16k is one file extent) XFRSIZ EQU 4 ;file transfer buffer in Kbytes. Do not make ;any larger than BUFSIZ. 16k works fine on all ;but very slowest systems ;  YES ;yes=reset the error limit to try again ;no=abort after 10 consecutive errors ;(ARPANET users should select yes) BAKUPBYTE DB NO ;yes=make .BAK file CRCDFLT DB YES ;yes=default to CRC checking ;no=default to Checksum checking by a warranty either ; express or implied. No changes or alterations are authorized. ; If desirious of modifying the program for national release, it ; may be used for such purposes only if the name is changed and ; credit given where appropriate. ; BDNMCH EQU 75H ;bad name match ERRLIM EQU 10 ;maximum allowable consecutive errors ERRCRC EQU 6 ;CRC tries, then switches to CHECKSUM LIBLEN EQU 34 ;length of each phone library entry SHOWHEX EQU NO ;yes, show both decimal and hex record counTOGGLECRC DB YES ;yes=allow toggling of Checksum to CRC CONVRUB DB YES ;yes=convert rub to backspace TOGGLERUB DB YES ;yes=allow toggling of rub to backspace ADDLF DB NO ;no=no LF after CR to send file in ;terminal mode (added by remote echo ; Many people have contributed in the past to make MODEM7 what it ; was when I renamed the program to MDM700 and began this series. ; Their achievements range from modest changes to significant ma- ; jor additions: ; ; Ward Christensen, Jim Millts ;no, show just standard decimal record count RUB EQU 7FH ;rub CRC EQU 'C' ;requests 'CRC' instead of 'CKSUM' ESC EQU '['-40H ;^[ = escape SOH EQU 'A'-40H ;^A = start of header EOT EQU 'D'-40H ;^D = end of text EXITCHR EQU 'E'-40H ) TOGGLELF DB YES ;yes=allow toggling of LF after CR TRANLOGON DB NO ;yes=allow transmission of logon ;write logon sequence at location LOGON RESERVED DB NO ;Reserved for Future releases LOCNXTCHR DB NO ;yes=local cmd if EXTCHR precedes s, Mark Zeigler, Keith Petersen, ; Paul Kelly, Bruce Ratoff, Ron Fowler, Rich Berg, Bob Clyne, ; Bill Earnest, Ben Bronson, Paul Hansknecht, John Mahr, Bob ; Plouffe, Sigi Kluger, Frank Gaude' and others. ; ; I do not mean to slight any ;^E = exit character ACK EQU 'F'-40H ;^F = acknowledge OKNMCH EQU 'F'-40H ;^F = ok 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 = carriage return XON  ;no=not local cmd if EXTCHR precedes TOGGLELOC DB YES ;yes=allow toggling of LOCNXTCHR LSTTST DB YES ;yes=allow toggling of printer on/off ;in terminal mode. Set to no if using ;the printer port for the modem XOFFTST DB NO ;yes=allow tone, and hope I have included those ; who made the most significant advancements to the program. ; - Irv Hoff W6FFC ; ;*********************************************************************** ; ; PORT EQU 0C0H ;your base port (data or status) EQU 'Q'-40H ;^Q = XON character XOFF EQU 'S'-40H ;^S = XOFF character NAK EQU 'U'-40H ;^U = not acknowledge CANCEL EQU 'X'-40H ;^X = cancel send or receive EOFCHAR EQU 'Z'-40H ;^Z = end of file ; ; ORG 0100H ; ; JMP START ;skip the esting of XOFF from remote ;while sending a file in terminal mode XONWAIT DB NO ;yes=wait for XON after sending CR while ;transmitting a file in terminal mode TOGXOFF DB YES ;yes=allow toggling of XOFF testing IGNORCTL DB YES ;yes=do n; MODCTL1 EQU PORT ;modem control port MODDATP EQU PORT+1 ;modem data port MODRCVB EQU 02H ;modem receive bit (DAV) MODRCVR EQU 02H ;modem receive ready MODSNDB EQU 01H ;modem send bit MODSNDR EQU 01H ;modem send ready bit ; ; ;+++++++data area below ; ; ; ; THESE ROUTINES AND EQUATES ARE AT THE BEGINNING OF THE PROGRAM SO ; THEY CAN BE PATCHED BY A MONITOR OR OVERLAY FILE WITHOUT RE-ASSEMBLING ; THE PROGRAM. ; PMMIMODEM DB YES ;yes=PMMI modem AUTODIAL DB NO ;yes=Hayes-type aot send control characters ;above CTL-M to CRT in terminal mode ;no=send any incoming CTL-char to CRT EXTRA1 DB 0 ;for future expansion EXTRA2 DB 0 ;for future expansion BRKCHR DB '@'-40H ;^@ = Send a 300 ms. break tone NOCONNCT DB 'N++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SPECIAL EQUATES FOR PMMI ; MODCTL2 EQU PORT+3 ;modem status port ; BAUDRP EQU PORT+2 ;modem baud rate port BRKMSK EQU 0FBH ;mask to set break EVPARMSK EQU 20H ;mask utodial modem TOUCHPULSE DB 'T' ;T=touch, P=pulse (autodial-only) ; CLOCK DB 40 ;clock speed in MHz x 10, 25.5 MHz max. ;2 MHz=20, 3.68 MH=37, 4 MHz=40, etc. MSPEED DB 1 ;sets display time for sending a file ;0=110 1=300 2=450 3=600 4 '-40H ;^N = Disconnect from phone line LOGCHR DB 'L'-40H ;^L = Send logon LSTCHR DB 'P'-40H ;^P = Toggle printer UNSAVECHR DB 'R'-40H ;^R = Close input text buffer TRANCHR DB 'T'-40H ;^T = Transmit file to remote SAVECHR DB 'Y'-40H ;^Y = Opehange to match ; your terminal. (Heath uses ESC 4AH for clear to end of screen, ESC 45H ; to clear screen. Lear Siegler and others use ESC 79H for clear to end ; of screen and ESC 3AH to clear screen.) Room allowed for four bytes. ; (Last zero neede============================= ; ; SETS THE BAUD RATE ; ;======================================================================= ; ; SETBAUD:MOV AL,Byte Ptr ANSWFLG ;if 'O' or 'A' not requested and OR AL,AL ; baudrate not specified, returnn input text buffer EXTCHR DB '^'-40H ;^^ = Send next character ; ; ; Equates used only by PMMI routines grouped together here. ; PULSERATE DB 250 ;125=20pps dialing, 250=10pps CHGBAUD DB 'B'-40H ;^B = Used with PMMIMODEM in terminal ;modd for stopping the string display. Any extra 0's just ; act as NOP's.) ; CLREOS: CALL ILPRT DB ESC,79H,0,0,0 RET ;..... ; ; CLRSCRN: CALL ILPRT DB ESC,3AH,0,0,0 RET ;..... ; ; ;======================= SIGN-ON MESSAGE ==============s JZ FIXBAUD ; with current mode and rate MOV AL,Byte Ptr ORIGFLG ;if option requested, a blank returns OR AL,AL ; with current mode and rate JZ FIXBAUD RET ;no change if neither 'O' or 'A' shown ; FIXBAUD:CALL GETBAUD ;calculate to change baud rate on fly PMMIPORT DB MODCTL1 ; Pmmi Port location ; ; Handles in/out ports for data and status ; IN_MODCTL1: IN AL,MODCTL1 ! RET DB 0,0,0,0,0,0,0 ;spares if needed for non-PMMI OUT_MODDATP: OUT MODDATP,AL ! RET ;out modem ================ ; ; Send version number and date ; SYSVER: MOV AL,Byte Ptr PMMIMODEM ;using the PMMI S-100 modem? OR AL,AL JZ SYSVER1 ;go if not CALL ILPRT DB 'Version for PMMI S-100 modem starting at port: ',0 MOV AL,Byte Ptr PMMIPORT e PMMI baud rate divisor CALL SETMSPD ;set the file time transfer value CALL OUT_BAUDRP ;set the PMMI board to that baudrate CMP AL,52 MOV AL,5FH ;DTR (filter for over 300 baud) JB GT300 ;yes, greater than MOV AL,7FH ;DTR (filter for 3data port DB 0,0,0,0,0,0,0 ;spares if needed for non=PMMI IN_MODDATP: IN AL,MODDATP ! RET ;in modem data port DB 0,0,0,0,0,0,0 ;spares if needed for non-PMMI ANI_MODRCVB: AND AL,MODRCVB ! RET ;bit to test for receive ready CPI_MODRCVR: CMP ACALL HEXO ; put in PMMI control port number CALL ILPRT DB 'H',CR,LF,0 RET ;..... ; ; SYSVER1:CALL ILPRT ;if not using the PMMI S-100 board DB 'Version for Non-PMMI modem',CR,LF,0 RET ;..... ; ; ;==================== LOGON MESSAGE (IF 00 and less baud) ; GT300: CALL OUT_MODCTL2 MOV Byte Ptr MODCTLB,AL ;save modem control byte ; OFFHOOK:MOV BX,7500 ;throw in some delay ; OFFDLY: DEC BL JNZ OFFDLY DEC BH JNZ OFFDLY MOV AL,Byte Ptr UARTCTLB ;UART control byte for 'A'L,MODRCVR ! RET ;value of receive bit when ready ANI_MODSNDB: AND AL,MODSNDB ! RET ;bit to test for send ready CPI_MODSNDR: CMP AL,MODSNDR ! RET ;value of send bit when ready ; ; ;====================== SPECIAL PMMI PORTS ==========================ANY) =========================== ; ; Insert your logon message here. End with a 0 (for"CALL ILPRT"). ; PMMIusers have 59 bytes available, non-PMMI users have approximately ; 2K bytes available as they can overwrite all the following PMMI rou- ; tines or 'O' CALL OUT_MODCTL1 ;now set to answer or originate MOV AL,CL MOV Byte Ptr MSPEED,AL ;set the file transfer time value XOR AL,AL ;clear the flags RET ;..... ; ; ;======================================================================= === ; IN_BAUDRP: IN AL,BAUDRP ! RET ;in baudrate port OUT_BAUDRP: OUT BAUDRP,AL ! RET ;out baudrate port OUT_MODCTL1: OUT MODCTL1,AL! RET ;out modem control port #1 OUT_MODCTL2: OUT MODCTL2,AL! RET ;out modem control port #2 ; ;================= if they wish. This method allows the external overlays to have ; plenty of room. It keeps the phone number library at a fixed location. ; LOGON RB 59 ;up to 59 characters allowed DB 0 ;to terminate the logon message ;..... ; ; ;============ ; CALCULATES THE BAUD RATE DIVISOR ; ; Returns with current baud rate intact if a blank or null in the speed ; field (extent area). ; GETBAUD:MOV AL,Byte Ptr FCB+9 ;get 1st digit of requested baudrate CMP AL,' ' ;if a space, return with cu= END OF SPECIAL PMMI PORTS ========================== ; ; LOGONPTR DW (Offset LOGON) JMP_DIAL: JMP DIAL JMP_DISCONNT: JMP DISCONNT JMP_GOODBYE: JMP GOODBYE JMP_INITMOD: JMP INITMOD JMP_NEWBAUD: JMP NEWBAUD JMP_NOPARITY: JMP NOPARITY JMP_PARITY: === NON-PMMI INITIALIZATION (IF ANY) ====================== ; ; Insert your initialization routine here if needed. Can replace the ; following special PMMI area to set speed and auto-dial. Over 950 ; bytes are available for this purpose. (End your rrrent speed MOV AL,Byte Ptr CURRENT JNZ LA14 RET LA14: MOV AL,Byte Ptr FCB+9 OR AL,AL ;if a null, return with current speed MOV AL,Byte Ptr CURRENT JNZ LA15 RET LA15: ; MOV DX, FCB+9 ;get the requested speed MOV BX,0 ; DECLPJMP PARITY JMP_SETUPR: JMP SETUPR JMP_SPCLMENU: JMP SPCLMENU JMP_SYSVER: JMPS SYSVER JMP_BREAK: JMP SENDBRK ; ; ; NEXT EIGHT LINES SHOULD NOT BE CHANGED BY USER OVERLAY AS THESE GO TO ; SPECIFIC LOCATIONS IN THE MAIN PROGRAM, NOT IN THE OVERLAY. ;outine with a RET.) ; ; INITMOD: RET ; ;========== NON-PMMI SETUP (SPEED CHANGE, ETC.) IF ANY ============== ; ; Insert your speed change and/or auto-dialing routines here. ; Over 950 bytes are available (INCLUDING INITMOD, above). ; End your rout: MOV SI,DX ;get the ASCII digit MOV AL,[SI] INC DX CMP AL,' ' JZ DECLP CMP AL,'0' ;numerals are 0-9 JB BADRATE CMP AL,'9'+1 JNB BADRATE SUB AL,'0' MOV CH,BH MOV CL,BL SHL BX,1 SHL BX,1 ADD BX,CX SHL BX,1 ADD AL,BL MOV JMP_ILPRT: JMP ILPRT JMP_INBUF: JMP INBUF JMP_INLNCOMP: JMP INLNCOMP JMP_INMODEM: JMP INMODEM JMP_NXTSCRN: JMP NXTSCRN JMP_TIMER: JMP TIMER JMP_CTYPE: JMP CTYPE JMP_KEYIN: JMP KEYIN ; ; ; Clear sequences are for Televideo, Lear Siegler, etc. Cine with a RET. ; SETUPR: RET ; ; ; Not needed if using the PMMI board, as it has its own break routine ; SENDBRK: RET ; ; ;**************** START OF SPECIAL PMMI ROUTINES ********************** ; ; ;==========================================5  BL,AL JNZ DIGNC INC BH ; DIGNC: MOV AL,DL CMP AL,FCB+12 JNZ DECLP MOV AL,BH NOT AL MOV DH,AL MOV AL,BL NOT AL MOV DL,AL INC DX MOV BX,15625 ;250000/16 MOV CX,-1 ; DIVLP: INC CX ADD BX,DX JB DIVLP MOV AL,CH OR AL,AL est byte OR AL,AL ;set flags JZ LA25 RET ;if even parity not specified return LA25: MOV AL,Byte Ptr UARTCTLB ;get uart/modem control byte AND AL,ODPARMSK ;set for parity OR AL,EVPARMSK ;now set for even parity ; PARITY1:MOV Byte Ptrnu ; command line, so move the characters down 4 to compensate. Needed for ; auto-redialing of menu command line entries. ; MOV CL,AL ;put into the 'C' reg. MOV CH,0 ;will move original number down 4 SUB AL,4 ;eliminate the 'CAL' portion  MOV AL,CL MOV Byte Ptr CURRENT,AL ;can use this the next time by default JNZ BADRATE RET ; BADRATE:CALL ERXIT DB '++ INVALID BAUDRATE ++$' ;..... ; ; ;======================================================================= ; SETS 'M UARTCTLB,AL JMP OUT_MODCTL1 ;send to PMMI - ; ;when OUT$MODCTL1 does return, it ;..... ;will go back to calling routine ; ; NOPARITY: MOV AL,Byte Ptr PMMIMODEM OR AL,AL JNZ LA26 RET LA26: MOV AL,Byte Ptr UARTCTLB ;get UART/modemMOV Byte Ptr [BX],AL ;store new count at cmdbuf+1 INC BX ;CMDBUF+2 (first character of string) XCHG BX,DX ;'DE' now has CMDBUF+2 MOV BX, Offset CMDBUF+6 ;point to number (or letter) to dial CALL MOVER ;move the group down 4 places JMP DIAL4SPEED' TO BAUD RATE ; ; SETMSPD:MOV CL,0 ;changes PMMI mspeed for 110-710 baud CMP AL,100 ;<300 baud JNAE LA17 RET LA17: INC CL ;c=1 for 300 baud CMP AL,40 ;<450 baud JNAE LA18 RET LA18: INC CL ;c=2 for 450 baud CMP AL,30  control byte OR AL,NOPARMSK ;reset parity bit on PMMI JMP OUT_MODCTL1 ;..... ; ; ;==================== END OF PARITY ROUTINES =========================== ; ; ;======================================================================= ; ; HA ;check if library number, then dial ;... ; ; ; Comes here if no phone number was manually entered after 'CAL' and if ; no phone library code was entered. Displays the phone number library ; then asks for an entry. ; DIAL2: MOV CL,18 ;number o ;<600 baud JNAE LA19 RET LA19: INC CL ;c=3 for 600 baud CMP AL,24 ;<710 baud JNAE LA20 RET LA20: INC CL ;c=4 for 710 baud RET ;..... ; ; ; Change baudrate on-the-fly with CTL-B (while in terminal mode) ; NEWBAUD:MOV AL,Byte YES/PMMI DIALING ROUTINES ; ;======================================================================= ; ; RB 640 ;FOR EXPANSION ; ; Modem control command words ; BRKMASK EQU 0 ;tele line on hook (break while dialing) CLEAR EQU 3FH ;idle mof lines to move MOV BX, Offset NUMBLIB ;start of phone number library MOV DX, Offset BUFFER ;buffer add. to store them temporarily CALL NEWLINE ;start with CR/LF MOV SI,DX ;+LF MOV [SI],AL INC DX ;and bump it ; DIAL3: MOV CH,LIBLEN ;nuPtr PMMIMODEM OR AL,AL JNZ LA21 RET LA21: CALL ILPRT DB CR,LF,'Enter new Baudrate: ',0 MOV BX, FCB+9 MOV Byte ptr [BX],' ' ;keep current baud if none included ; NEWBAUD1: CALL KEYIN ;get the baud rate CMP AL,CR ;carriage ret finishde DTMSK EQU 1 ;dial tone mask MAKEM EQU 1 ;tele line make (off hook) RBLMT EQU 35 ;7 seconds to wait til no-ring-heard msg RBWAIT EQU 50 ;5 second delay before redialing PMMI SMRWAIT EQU 15 ;1.5 sec delay before redialing HAYES TMPUL EQU 8mber of bytes to move CALL MOVE ;move to buffer CALL SPACES ;2 entries + 3 spaces = 71 characters PUSH BX ;save source address PUSH DX ;save destination address MOV DX,(17*LIBLEN) ;get offset of 17 times entry length ADD BX,DX ;add ies baud rate entry JNZ LA22 CALL CRLF ;if a 'CR', baud rate has been entered LA22: JNZ LA23 JMP FIXBAUD ;go change the baud rate LA23: ;..... ; ; NEWBAUD2: CMP AL,'0' ;numerals are 0-9 JB NEWBAUD1 CMP AL,'9'+1 JNB NEWBAUD1 ;if 0H ;timer pulses mask bit TRATE EQU 250 ;value for 0.1 second ;..... ; ; ; Dialing routine ; DIAL: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ DIAL1 MOV AL,Byte Ptr AUTODIAL OR AL,AL JNZ LA29 RET ;return if neithert to source address POP DX ;restore destination address MOV CH,LIBLEN ;get length of library entry CALL MOVE ;move another entry POP BX ;restore source address CALL NEWLINE DEC CL ;one less line to print JNZ DIAL3 ;if not zero, prinot a numeral, ignore, ask again MOV Byte Ptr [BX],AL ;store answer starting at FCB+9 CALL STYPE ;show the numeral on the CRT INC BX ;next storage location in FCB JMPS NEWBAUD1 ;get the next numeral ;..... ; ; ;======================= PAR modem LA29: CALL SMNOISEY ;make sure autodial modem speaker is on ; DIAL1: XOR AL,AL MOV BYTE PTR AUTODIR,AL ;zero the direct to terminal mode flag MOV BYTE PTR AUTOFL,AL ;zero the auto-linking flag MOV Byte Ptr CRFLAG,AL ;zero the continunt another MOV AL,'$' ;BDOS print routine terminate character MOV SI,DX ;store in buffer MOV [SI],AL CALL CLRTST MOV CL,PRINT MOV DX, Offset BUFFER ;print the library on the CRT INT 224 CALL JMP_ILPRT ;ask which one is wanted DB CR,LITY ROUTINES =============================== ; ;--->PARITY: Routine to setup PMMI for odd/even parity. ; PARITY: MOV AL,Byte Ptr PMMIMODEM ;is modem a PMMI? OR AL,AL ;set flags JNZ LA24 RET ;no, return LA24: MOV AL,Byte Ptr OPARITY ;geous dial flag MOV BX,0 MOV Word Ptr DIALCT,BX ;zero the dial count MOV BX, Offset CMDBUF+1 ;point to the number of characters in.. MOV AL, Byte Ptr [BX] ;..the buffer, then get the number CMP AL,3+1 ;anything typed after 'CAL'? JB DIAL2 ;ifF,'Enter library code or phone number,',CR,LF DB 'Hit RET to abort this function now or',CR,LF DB 'CTL-X quits while dialing or ringing: ',0 MOV DX, Offset CMDBUF CALL INBUF ;get the answer from the keyboard ; ; ; You now have either a libraryt odd parity request byte OR AL,AL ;set flags JNZ EVENPAR ;if not odd see if it is even MOV AL,Byte Ptr UARTCTLB ;get uart/modem control byte AND AL,ODPARMSK JMPS PARITY1 ;... ; ; EVENPAR:MOV AL,Byte Ptr EPARITY ;get even parity requ not, go through library routine ; ; ; If there were only 3 characters, then "CAL" was typed -- the user ; obviously expecting to get a phone number (or letter) from the library ; file. If 4 or more, a number (or letter) was typed in from the me5  code or a manually entered phone num- ; ber. These either came from the menu command line or from the library ; command line. Next we see if a code, if so, get the corresponding ; line with phone number from the library. If a number greater than ; o ;error if not a number or a letter ; ; ; Now have a match between the requested code and one in the library. ; E-reg. holds the library line number (1-36) that matches the requested ; code (A-Z or 0-9). ; DIAL9: MOV BX,(Offset NUMBLIB) ;phone numb ; ; ; Loop to dial the phone number pointed to by 'BX', character count in ; the 'DL' register. ; DIAL15: MOV AL,Byte Ptr [BX] ;get first number from the buffer OR AL,AL ;set flags JNZ L2A6 JMP DIALBAD ;bad number if a null L2A6: ; ; ;ne digit, we ignore the library look-up. (Ringback numbers must end ; with letter 'R'.) ; DIAL4: MOV BX,Offset CMDBUF+1 ;number of characters in buffer MOV AL,Byte ptr [BX] OR AL,AL ;null means CR was typed JNZ LA30 JMP DIALEXIT2 ;abort dialer library MOV CX,LIBLEN ;length of library entry MOV AL,DL ;number of times to library length to BX OR AL,AL ;set flags JZ DIAL11 ; DIAL10: MOV AL,Byte Ptr [BX] ;get first char of selected lib entry OR AL,AL ;set flags JNZ LA2 JMP D Dial a digit, check keyboard for abort ; CALL DIALA ;dial a digit, show on CRT CALL STAT ;keypress? JZ DIAL17 ;if not, exit CALL KEYIN ;yes, go get it CMP AL,CANCEL ;CTL-X? JNZ DIAL17 ;if not, exit MOV AL,Byte Ptr AUTODIAL ;usiing, return to menu LA30: MOV Byte Ptr NUMBER,AL MOV BX,OFFSET CMDBUF+3 MOV AL,BYTE PTR [BX] ;see if at least two chars. entered CMP AL,'/' ;slash for linking, direct to terminal. JNZ LA30A CALL AUTO ;..mode on answer LA30A: CMP AL,',' IALBAD ;send bad library msg and abort LA2: ADD BX,CX ;increment 'BX' by library length DEC DL ;countdown JNZ DIAL10 ;not there yet, loop ; ; ; Now have the line in the phone number library matching the requested ; letter so store that lng a Hayes-type modem? OR AL,AL JNZ L2A7 JMP DIALEXIT ;if not, exit now, otherwise clear line L2A7: ; ; ; If using an autodial modem, backspace 30 times to make sure the entire ; number plus "DT" part of "ATDT" is erased. ; MOV CL,30 ; DIA;comma used for linking JNZ DIAL5 CALL AUTO1 ;if so, set it up for auto-linking ; ; ; Check to see how many characters were typed. If more than one, then ; was a hand-entered phone number, so exit. ; DIAL5: CALL DIALBGN ;disconnect, reconnectine starting at 'CMDBUF+1' ; DIAL11: MOV CH,LIBLEN ;number of characters to get from table MOV DX, Offset CMDBUF+1 ;point to buffer XCHG BX,DX ;'BX' points to CMDBUF+1 MOV Byte Ptr [BX],CH ;length of each table entry XCHG BX,DX ;restore the L16: MOV CH,BKSP CALL SENDCHR ;send to the modem to cancel call DEC CL JNZ DIAL16 ;if not zero, do another MOV CH,CR CALL SENDCHR MOV AL,' ' CALL STYPE ;show on CRT JMP DIALEXIT ;now go abort ; DIAL17: INC BX ;bump pointer DEC, wait for tone MOV AL,BYTE PTR AUTOFL ;auto-link flag set? OR AL,AL JZ LA30B JMP AUTO2 ;if yes, exit LA30B: MOV AL,BYTE PTR NUMBER ;number of chars. in buffer MOV BX,OFFSET CMDBUF+1 MOV BYTE PTR [BX],AL ;reset the character count, if needregisters INC DX ;point to first char position in buffer CALL MOVE ;move the table entry to the buffer ; ; ; Now have the full line including phone number in 'CMDBUF' area. Scan ; past the descriptive portion of library entry - terminate scan  DL ;one less character to go JNZ DIAL15 ;if not done, send the next digit ; ; ; Show the number of dial attempts ; CALL JMP_ILPRT DB ' - try #',0 MOV BX,Word Ptr DIALCT ;increment the dial count INC BX MOV Word Ptr DIALCT,BX CALLed CMP AL,1 ;more than 1 character JNA LA32 JMP DIAL14 ;if more than one, hand-entered number LA32: MOV BX, Offset CMDBUF+2 ;first character in phone number line ; ; ; If just one character entered, see if a (A-Z) letter ; DIAL6: MOV AL,Bat the ; first '.' This allows commas and numbers to be part of the text, such ; as: ; 'A=DataTech, Node 7..1-408-238-9621' ; DIAL12: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JZ DIAL12A CALL SMINIT ;if yes, initiali DECOUT ;show number of attempts so far MOV AL,' ' ;extra space to position cursor CALL STYPE MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JZ DIAL19 ;if not, exit MOV CH,CR ;tells the modem the number is done CALL SEyte ptr [BX] MOV CH,'A' ;first letter of alphabet MOV DL,0 ;counts number of letters to match MOV CL,26 ;number of letters in alphabet ; DIAL7: CMP AL,CH ;letter from table? JNZ LA33 JMP DIAL9 ;if yes, get phone number, else LA33: ze ; DIAL12A: MOV BX, Offset CMDBUF+1 MOV DL,Byte Ptr [BX] ;number of chars in buffer INC BX ;point to 1st character in buffer ; DIAL13: MOV AL,Byte ptr [BX] ;get next character CALL STYPE ;show it INC BX ;bump pointer DEC DL ;decreNDCHR ;just have one character to send ; DIAL18: CALL JMP_INMODEM ;catch any output from the modem JNB DIAL18 JMP SMRESULT ;number sent to modem, now get results ; ; ; Dialing is all done, this section is PMMI-only ; DIAL19: MOV AL,07FH ;tINC CH ;make next letter (A-Z) INC DL ;count up DEC CL ;count down JNZ DIAL7 ;try next one in (A-Z) table ; ; ; If not (A-Z) then should be (0-9) ; MOV CH,'0' ;first digit to check MOV DL,26 ;point past alpha codes MOV CL,10 ;ment count JNZ L2A4 JMP DIALEXIT ;exit if no '.' (bad lib entry) L2A4: CMP AL,'.' ;dot? JZ DIAL15 ;yes, go dial the phone JMPS DIAL13 ;no, loop for next character ;..... ; ; ; There is a user entered phone number in 'CMDBUF' area ; urn on PMMI 'DTR' CALL OUT_MODCTL2 ;timer rate? MOV CH,1 ;0.1 second per interval CALL JMP_TIMER ;wait for modem to turn on 'DTR' MOV AL,5DH ;2 stop bits, no parity, 8 data bits CALL OUT_MODCTL1 MOV DH,4 ;clear to send mask MOV CL,WAInumber of digits in table ; DIAL8: CMP AL,CH ;number from table? JZ DIAL9 ;if yes, go dial, else INC DL ;make next table line number INC CH ;make next digit to compare DEC CL ;count down - loop counter JNZ DIAL8 ;loop JMP DIALBAD DIAL14: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JZ L2A5 CALL SMINIT ;if yes, initialize L2A5: MOV BX, Offset CMDBUF+1 MOV DL,Byte Ptr [BX] ;get number of chars in buffer INC BX ;point to 1st character to dial ;.....6 TCTS ;wait time for CTS CALL WAIT ;..(30 seconds, can set 'WAITCTS' for ;..up to 51 seconds for European use) ; ; If PMMI connection made, go get options for starting communications ; JNAE L2A8 JMP CONMADE ;connection made ; ; ; ConnALL JMP_TIMER DEC DL ;one less loop to make JNZ CONMADE3 ;see if a keyboard character yet MOV AL,BELL ;sound a bell CALL STYPE JMPS CONMADE2 ;..... ; ; ; Automatic dialing routine, prints the number being dialed. If we find ; 'R', it eIT1: MOV SP,OFFSET STACK ;make sure the stack is normal again CALL JMP_GOODBYE ;user routine to disable DTR, if any CALL DISCONNT ;hang up the phone and reset the modem ; DIALEXIT2: MOV BYTE PTR CRFLAG,0 ;reset the continuous redial flag JMPection not made, see if a redial is desired ; L2A8: ; CALL DISCONNT ;hang-up so we can redial if desired ; DIALAGN:MOV SP,OFFSET STACK ;reset the stack to normal, just in case MOV AL,Byte Ptr CRFLAG ;continuous redial flag OR AL,AL JZ L2A9ither has to be the final character for ringback or toss it. ; DIALA: CALL STYPE ;print whatever character, dashes, etc. CMP AL,'R' ;could it be a ringback character? JNZ DIALA1 ;if not, probably a number so exit MOV AL,DL ;get the charact MENU ;..... ; ; ; Disconnect from the line, reconnect and wait for the dialtone. ; DIALBGN:MOV AL,Byte Ptr AUTODIAL ;Hayes-type modem? OR AL,AL JZ DIALBG1 RET ;if yes, finished ; DIALBG1:MOV AL,MAKEM ;go off-hook CALL OUT_MODCTL1 M JMP DIALAGN2 ;if already set, go dial again L2A9: L2A10: CALL JMP_ILPRT ;see if we should keep trying DB CR,LF,CR,LF,' Redial? (C/Y/N/Q): ',BELL,0 CALL KBDCHR PUSH AX CALL CRLF ;turn up a line POP AX CMP AL,'Y' ;redial? JZ DIer count. Is this "r".. CMP AL,1 ;..the last character in the string? JNZ L2A13 JMP RINGBK ;yes, must be ringback char, do ringback L2A13: RET ;if not, ignore the 'r' ; DIALA1: MOV CH,AL ;store the character for now CALL DIALAD ;chOV DH,DTMSK ;dial tone mask MOV CL,50 ;waits up to 10 sec. for dial tone CALL WAIT ;wait for dial tone ; ; ; Wait subroutine will return with carry set if unable to get dialtone. ; If carry is not set, the dialtone was received. ; JNAE L2A1ALAGN2 ;yes, redial CMP AL,'C' ;continuous redial? JZ DIALAGN1 ;if yes, set continuous redial flag CMP AL,'Q' ;kill the Hayes-type modem speaker? JZ L2A11 JMP DIALEXIT1 ;none of these, quit L2A11: CALL SMQUIET ;strangle speaker ; DIeck for alternate dialing like 'MCI' MOV AL,CH ;get the original character back DIALA2: CMP AL,'*' ;* is a valid dial digit JZ DIALA3 CMP AL,'#' ;# is a valid dial digit JZ DIALA3 CMP AL,',' ;comma indicates a short delay-time JZ DIALA8 RET ;if dial tone within 10 seconds L2A18: CALL JMP_ILPRT ;otherwise print error message DB CR,LF,CR,LF,'++ NO DIAL TONE ++',BELL,0 POP BX ;restore the stack to normal JMP DIALEXIT ;forget it. ;..... ; ; ; Do any alternate dialing sALAGN1: MOV AL,1 MOV Byte Ptr CRFLAG,AL ;continuous redial flag ; DIALAGN2: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ DIALAGN3 ;if yes, exit MOV CH,RBWAIT ;wait for PMMI reset (or busy) CALL JMP_TIMER ;or bus3 CMP AL,'0' ;digits are (0-9) JNB L2A14 RET ;exit less than ASCII '0' L2A14: CMP AL,'9'+1 JNAE L2A15 RET ;exit if more than ASCII '9' L2A15: SUB AL,'0' ;strip ASCII - could also do 'ANI 0FH' JNZ DIALA3 MOV AL,10 ;convert zeuch as 'MCI' or 'SPRINT' ; DIALAD: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ L2A19 RET ;if not, exit L2A19: MOV AL,Byte Ptr TOUCHPULSE ;using touch tone dialing? CMP AL,'T' JZ L2A20 RET ;if not, ignore L2A20y tone may be sensed as dialtone JMPS DIALAGN4 ; DIALAGN3: MOV CH,SMRWAIT CALL JMP_TIMER ; DIALAGN4: CALL CRLF ;start a new line JMP DIAL5 ;redial entry point ;..... ; ; ; Connection has been made ; CONMADE: MOV AL,BYTE PTR PMro to 10 pulses ; ; ; Sends the digit to the modem. Waits 100 ms. after each digit to in- ; sure it gets to the modem ok. ; DIALA3: MOV CL,AL MOV AL,Byte Ptr PMMIMODEM ;using a PMMI? OR AL,AL JNZ DIALA4 ;if yes, exit CALL SENDCHR ;charac: MOV AL,CH ;get the character back CMP AL,'<' ;alternate dialing system #1 (MCI?) JNZ DIALAD1 ;if not, exit PUSH BX ;save the current values MOV BX,(Offset ALTDIAL1) ;alternate dialing area JMPS DIALAD2 ; DIALAD1:CMP AL,'>' ;alternMIMODEM OR AL,AL JZ CONMADE1 MOV AL,Byte Ptr CURRENT ;get current baud rate CALL OUT_BAUDRP ;set baudrate ; CONMADE1: MOV CH,2 CALL JMP_TIMER CALL JMP_ILPRT DB BELL,CR,LF,CR,LF,' CONNECTED',0 MOV AL,BYTE PTR AUTODIR ;going direter is already in the 'B' reg. MOV CH,1 ;slight delay to let modem settle down JMP JMP_TIMER ; DIALA4: MOV AL,Byte Ptr PULSERATE CALL OUT_BAUDRP ; DIALA5: CALL IN_BAUDRP AND AL,TMPUL JNZ DIALA5 ; DIALA6: CALL IN_BAUDRP AND AL,TMPUL ate dialing system #2 (Sprint?) JZ L2A21 RET ;if neither, exit L2A21: PUSH BX ;save the current values MOV BX,(Offset ALTDIAL2) ; DIALAD2:MOV AL,Byte Ptr [BX] CMP AL,'$' ;ready to terminate? JZ DIALAD3 ;if yes, exit ; ; ; Move thct to terminal mode? OR AL,AL JZ CONMADE1A JMP RETURN ; CONMADE1A: MOV AL,BYTE PTR CRFLAG ;in continuous redial or first time try? OR AL,AL JNZ CONMADE1B JMP RETURN ;go to terminal mode if first time ; CONMADE1B: CALL JMP_ILPRT DB 'JZ DIALA6 ; DIALA7: MOV AL,MAKEM CALL OUT_MODCTL1 ; DIALA8: CALL IN_BAUDRP AND AL,TMPUL JNZ DIALA8 MOV AL,BRKMASK CALL OUT_MODCTL1 ; DIALA9: CALL IN_BAUDRP AND AL,TMPUL JZ DIALA9 DEC CL JNZ DIALA7 MOV AL,MAKEM CALL OUT_MODCTL1 e semicolons up one line if you do not want to see the SPRINT ; number dialed. ; CALL STYPE ;display the character MOV CH,AL ;need the char. in 'CH' to send to modem CALL DIALA2 ;send proper characters to the modem INC BX ;next location  - any key for terminal mode ',0 ; CONMADE2: MOV DL,10 CONMADE3: CALL STAT ;keypress? JZ CONMADE4 ;exit if no keys pressed CALL KEYIN XOR AL,AL JMP RETURN ;key pressed, go to terminal mode ; CONMADE4: MOV CH,1 ;wait 0.1 second C MOV CH,2 JMP JMP_TIMER ;..... ; ; Print bad library number message and abort if a null is encountered. ; DIALBAD: CALL JMP_ILPRT DB CR,LF,CR,LF,'++ Bad library number called ++',CR,LF,0 ; DIALEXIT: CALL CRLF ;turn up a new line ; DIALEX6  CALL STAT ;keypress? JZ DIALAD2 ;if not, do the next character CALL KEYIN ;yes, go get it CMP AL,CANCEL ;ctl-x? JNZ DIALAD2 ;if not, handle the next character POP BX ;if yes, reset the stack JMP DIALEXIT ;if yes, exit ; DIALAD3:Mm SM_SPKOFF DB 'ATM0',CR,'$' ;turns the speaker off SM_SPKON DB 'ATM1',CR,'$' ;turns the speaker on SPKRFLG DB 0 ;0 = speaker has not been silenced ;..... ; ; ; Set the autodial modem for pulse dialing ; SMINIT: MOV AL,Byte Ptr TOUCHPULSE ;touchetry CMP AL,'4' ;'ERROR', single digit result code JNZ L2A32 JMP FAILED ;error, go display L2A32: CMP AL,'E' ;'ERROR', verbose result code JNZ L2A33 JMP FAILED ;error, go display L2A33: CMP AL,'5' ;'CONNECT 1200' single digit resuOV AL,' ' MOV CH,AL ;clears 'CH' from last digit sent CALL STYPE ;separate from the main number POP BX ;restore the stack RET ;..... ; ; ; Disconnect the autodial modem from the phone line. Sends 'I, CR' to ; the Racal-Vadic to retur or pulse dialing for autodial? MOV Byte Ptr SM_DIAL+3,AL ;store MOV BX,(Offset SM_DIAL) CALL SENDOUT ; SMINIT1:CALL JMP_INMODEM ;wait for modem to finish, if needed JNB SMINIT1 RET ;..... ; ; ; Send the string pointed to by 'BX' to both tlt code JNZ SMDM1 JMP ON_1200 ;connected, reset redial flags ; SMDM1: CMP AL,LF ; is end-of-line for verbose mode JZ SMRESULT ;yes, go get the next response CMP AL,CR ; may precede digit in digit mode JZ SMRESULT ;yes, go get thn to idle mode. ; GOODBYE: DISCONNT: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type autodial modem? OR AL,AL JNZ DISCONN1 ;if yes, skip PMMI section XOR AL,AL CALL OUT_MODCTL1 ;hang up CALL OUT_MODCTL2 ;clear DAV, ESD, etc. PUSH CX MOhe CRT and the modem. ; SENDOUT:CALL SENDNOW ;wait until modem is ready MOV AL,Byte Ptr [BX] ;get the character CMP AL,'$' JNZ L2A29 RET ;if yes, finished L2A29: MOV AL,Byte Ptr [BX] CALL OUT_MODDATP ;send to modem ; ; ; If you wante next response ; CALL STAT ;else, see if want to abort ringing JZ SMDM1A ;if not, get next character CALL KEYIN ;else, get character from keyboard CMP AL,CANCEL ;CTL-X to terminate dialing? JNZ SMDM1A ;if not, keep going MOV CH,CR V CH,10 ;1 second for PMMI to disconnect CALL JMP_TIMER POP CX RET ;... ; ; ; Disconnect the autodial modem from the phone line ; DISCONN1: MOV CH,12 ;wait 1.2 seconds pause CALL JMP_TIMER MOV BX,(Offset SM_DISC) ;get into command m to print the +++ ATD, etc. from Hayes-type units, move the ; three semicolons down one line. ; ;;; CALL STYPE ;show on CRT DB 90H,90H,90H INC BX JMPS SENDOUT ;..... ; ; ; Checks for answer from Hayes-type autodial modem ; SMRESULT: CACALL SENDCHR ;tells the modem to hang up right away JMP DIALEXIT ;abort dialing routine ; SMDM1A: CALL JMP_INMODEM ;get next character JMPS SMDM1 ;loop until end of response encountered ; ; ; The Anchor modem gives a busy result code, althouode CALL SENDOUT MOV CH,12 ;another 1.2 seconds pause CALL JMP_TIMER MOV AL,' ' ;space character ; ; If printing +++ and ATH, ATD, etc. move the three semicolons up one ; line to include a space on the crt to look better. ; DB 90H,90H,90HLL RCVREADY ;see if any incoming character yet JZ SMRESUL1 ;if yes, exit and look at it CALL STAT ;else see if want to abort ringing JZ SMRESULT ;if neither, wait for one of them CALL KEYIN ;get character from keyboard CMP AL,CANCEL ;CTL-gh still waits the ; normal time-out period to do it. ; BUSY: CALL JMP_ILPRT DB 'busy! ',0 JMP DIALAGN ;..... ; ; ; Failed call is usually caused by continuous ringing with no answer. ; The modem times out (can be set to either 30 seconds or 60 ;;; CALL STYPE ;show on local crt only MOV BX,(Offset SM_DISC1) ;now disconnect the modem CALL SENDOUT ; DISCONN2: CALL JMP_INMODEM ;wait 0.1 seconds after last char. JNB DISCONN2 RET ;... ; ; ; Hayes Stuff ; SMQUIET: MOV AL,Byte PX to terminate dialing? JNZ SMRESULT ;if not, keep going MOV CH,CR CALL SENDCHR ;tells the modem to hang up right away JMP DIALEXIT ;abort dialing routine ; SMRESUL1: CALL IN_MODDATP ;get the character, then AND AL,7FH ;remove an seconds. ; FAILED: CALL JMP_ILPRT DB 'abort ',0 JMP DIALAGN ;..... ; ; NO_CARRIER: CALL JMP_ILPRT DB 'no carrier ',0 JMP DIALAGN ;..... ; ; ON_LINE: CALL JMP_ILPRT DB 'on line',0 JMP CONMADE ;..... ; ; ON_1200: CALL JMP_ILPtr SPKRFLG ;speaker flag set to quiet? OR AL,AL JZ L2A23 RET ;if yes, forget it L2A23: MOV AL,YES MOV BYTE PTR SPKRFLG,AL ;flip the flag to quiet, now MOV BX,(Offset SM_SPKOFF) CALL SENDOUT MOV CH,6 JMP JMP_TIMER ;time for an 'ok' fry parity MOV CH,AL ;store for 'GIVLF' area if needed CMP AL,'B' ;'BUSY' (for Anchor modems, etc.) JZ BUSY ;if busy, flush string and retry CMP AL,'0' ;'OK' single digit result code JZ SMRESUL1 ;ok, loop for next response CMP AL,'O' ;RT DB 'on at 1200',0 JMP CONMADE ;..... ; ; END OF SPECIAL HAYES-LIKE HANDLING ;------------------------------------------------------------------------ ; ; Handles the special ringback numbers. Dials, lets it ring only once, ; hangs up and thom modem and return ;..... ; ; SMNOISEY: MOV AL,Byte Ptr SPKRFLG ;speaker already turned on? OR AL,AL JNZ L2A24 RET ;if yes, forget it L2A24: MOV AL,NO ;set for noisey, now MOV BYTE PTR SPKRFLG,AL MOV BX,(Offset SM_SPKON) CALL SEN'ok' verbose digit result code JZ SMRESUL1 ;ok loop for next response CMP AL,'1' ;'CONNECT', single digit result code JNZ L2A30 JMP ON_LINE ;connected, reset redial flags L2A30: CMP AL,'C' ;'CONNECT', verbose result code JNZ L2A31 JMPen redials. ; RINGBK: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ RINGBK2 ;if yes, ringback not possible MOV AL,Byte Ptr CMDBUF+1 ;get the number of chars. in the buffer DEC AL ;subtract 1 to avoid the ringback char DOUT MOV CH,6 JMP JMP_TIMER ;..... ; ; ; Hayes-like autodial modem control codes ; SM_DIAL DB 'ATDT $' ;set for touch (or pulse) dialing SM_DISC DB '+++$' ;puts the modem in local command mode SM_DISC1 DB 'ATH0',CR,'$' ;disconnects the mode ON_LINE ;connected, reset redial flags L2A31: CMP AL,'3' ;'NO CARRIER', single digit result code JZ NO_CARRIER ;no carrier, flush string and retry CMP AL,'N' ;'NO CARRIER', verbose result code JZ NO_CARRIER ;no carrier, flush string and r7  MOV Byte Ptr CMDBUF+1,AL ;store the new value MOV DH,DTMSK ;load tone detect mask MOV CL,RBLMT ;waits up to 7 seconds for a ring CALL WAIT JB RINGBK0 ;if no ring detected, pretend we got one JMP RINGBK1 ;hangup, redial, & listen for carrerminal mode on answer AUTOFL DB 0 ;auto-linking flag NUMBER DB 0 ;number of characters in CMDBUF ;..... ; ; ; Time-out routine. Must be called with mask in 'D' reg. for input at ; relative port 2 and number of seconds (times 10) in 'C' reg. 0.1 seconds for each unit in 'B' reg. ; TIMER: PUSH BX ; TIMER1: PUSH CX ; TIMER2: CALL JMP_INMODEM ;100 ms. delay per loop JNB TIMER2 POP CX DEC CH JNZ TIMER1 POP BX RET ;..... ; ; ; ;************** END OF SPECIAL HAYES/PMMI ROUTINier ; RINGBK0: MOV CH,25 ;got a ring, wait 2.5 sec CALL TIMER CALL IN_BAUDRP ;is tone still present? AND AL,DH JNZ RINGBK1 JMP DIALAGN ;yes, must be busy, do a normal redial ;..... ; ; ; Hang up, redial and listen for dial tone ; R ; WAIT: MOV CH,2 CALL TIMER ;wait for timer to go high then low CALL IN_BAUDRP ;PMMIADDR+2 (modem status port) AND AL,DH ;(CTS or dialtone mask) JNZ L2A39 RET ;active low, so return on 0 L2A39: PUSH CX ;save.. PUSH DX ;..activeES ********************* ; ; ;======================================================================= ; ORG ((offset $+255+50)/256*256)-50 ;even page for 'NUMLIB' ; ; ; CRITE: CALL JMP_ILPRT DB 'for Menu)',CR,LF,'Copyright (c) ' DB '1984 - IrINGBK1:CALL HANGUP ;hang up the phone CALL JMP_ILPRT DB 'ringback set, first ring ',0 MOV CH,RBWAIT ;wait 5 seconds before redialing.. CALL JMP_TIMER ;..for line to clear, etc. CALL DIALBGN ;disconnect, reconnect, wait for tone JNB L2A38  registers CALL STAT ;keypress? JZ WAIT1 ;if not, exit CALL KEYIN ;yes, get char CMP AL,CANCEL ;CTL-X to intentionally abort? JZ WAIT2 ;yes, disconnect, jmp to menu ; WAIT1: POP DX ;restore.. POP CX ;..registers DEC CL ;countvin M. Hoff',CR,LF DB 'Translation to CPM-86 - Alex K. Soya',CR,LF,0 RET ;..... ; ; END OF SPECIAL PATCH AREA ;======================================================================= ; ; Long distance alternate dialing such as MCI, SPRINT, etc. JMP DIALEXIT ;go redial number L2A38: MOV AL,BYTE PTR NUMBER ;number of characters in buffer CMP AL,1+1 ;more than one character? JNB L2A38A JMP DIAL12 ;go redial for the table ringback number ; L2A38A: JMP DIAL14 ;if more than one, han-down JNZ WAIT STC ;set carry to indicate mask not set RET ;..... ; ; WAIT2: POP DX ;reset.. POP CX ;..stack JMP DONETCD ;disconnect ;..... ; ; (END OF HAYES/PMMI DIALING ROUTINE) ;========================================= Must end ; with a '$', use as many commas (2 seconds delay, each) as needed to ; let the alternate dialing code return with a new dial tone. Fill in ; any character (periods are fine) after the $ to keep number of columns ; to 24, i.e., '1234567,,,,d-entered number ;..... ; ; RINGBK2:CALL JMP_ILPRT DB CR,LF,'++ No ringback for autodial modem ++',0 POP BX ;reset the stack JMP DIALEXIT ;..... ; ; HANGUP: MOV AL,CLEAR CALL OUT_MODCTL2 XOR AL,AL JMP OUT_MODCTL1 ;turn off DTR, origi============================== ; SPECIAL PMMI MENU ; SPCLMENU: MOV AL,Byte Ptr PMMIMODEM OR AL,AL JNZ L2A40 RET L2A40: CALL JMP_NXTSCRN CALL ILPRT DB ' Additional Subcommands for PMMI Modems' DB CR,LF,LF DB ' Modem control:'12345,,$.....' -- the first group is the ; MCI or SPRINT access number, the second group is the user number. A ; small delay is usually required after the billing number also. ; ALTDIAL1 DB 'xxxxxxx,,,,,,xxxxxxxx,,$' ;accessed by a < character ; nate/answer tones ;..... ; ; ; This is the auto-linking area. Up to 32 numbers may be linked, each ; should have a comma for a separator, such as: ; ; B>>COMMAND: CAL A,F,3,A,G,A,H ; AUTO: MOV BYTE PTR AUTODIR,AL ;direct to terminal mode on answe,CR,LF DB ' A - Answer tone for send or receive',CR,LF DB ' O - Originate tone for send or receive',CR,LF,LF DB ' Parity option:',CR,LF DB ' 1 - Set and check for odd parity',CR,LF DB ' 0 - Set and check for even parity',CR,LF DB ' ALTDIAL2 DB 'xxxxxxx,,,,,,xxxxxxxx,,$' ;accessed by a > character ; ;======================================================================= ; HEXSHOW DB SHOWHEX ;can easily change SHOWHEX via DDT ; SAVSIZ DB XFRSIZ*8 ;can easily change buffer sir ; AUTO1: MOV BYTE PTR AUTOFL,0FFH ;set the auto-linking flag MOV BYTE PTR CRFLAG,0FFH ;set the continuous redial flag MOV CH,64 ;maximum number of characters to move MOV BX,OFFSET CMDBUF+1 ;start with number in the string MOV DX,OFFSET CMDBUF Both ends must be capable of these options' DB CR,LF DB ' which are available only in R and S modes.' DB CR,LF DB ' The parity checking will be part of the' DB CR,LF DB ' file transfer protocol.',CR,LF,Lze for file ;transfers with DDT for "NUMBLIB-1" ad- ;dress. Normally 4k (32 records or 4k). ; ;======================================================================= ; ; Phone number library table for auto-dialing. Each number must be as +65 ;move to aft part of buffer JMP MOVE ;..... ; ; ; Linking routine ; AUTO2: MOV AL,BYTE PTR AUTOFL ;increment the flag for each new try INC AL INC AL MOV BYTE PTR AUTOFL,AL MOV CL,AL ;hold momentarily MOV CH,0 MOV AL,BYTE PTR CMDBF DB ' Speed Options:',CR,LF DB ' After entering your primary and secondary ' DB 'options,',CR,LF DB ' you can set the modem speed by placing a ' DB ' "." after',CR,LF DB ' the options followed by the speed e.g., ' DB '3 ; long as"LIBLEN" (EQU at start of program). Some areas require extra ; characters such as: 1-313-846-7127. Room is left for those. Use ; a (<) for alternate dialing system #1, and a (>) for alternate dialing ; System #2. Either would preceed the aUF+65 ;see how many characters typed CMP AL,CL JNB AUTO3 MOV AL,1 ;reset the flag to start over MOV CL,AL MOV BYTE PTR AUTOFL,AL ; AUTO3: MOV BX,OFFSET CMDBUF+65 ADD BX,CX JMP DIAL6 ;go to work ;..... ; ; AUTODIR DB 0 ;direct to t00, 600.',CR,LF,LF DB ' EXAMPLE: SBO.600 will set the modem for ' DB '600 baud',CR,LF,0 RET ;all done ;..... ; (END OF PMMI MENU) ;======================================================================= ; ; ; Timer routine. Waits 7 ctual number, for example: ; ; DB 'A=Alan Alda..........<123-456-7890' ;'A' ; ; - - - - - - - - - - - - ; ; NOTE: At least one dot (.) MUST precede the actual phone number ; ; '----5---10---15---20---25---30--34' total number of bytes in the function key library (including flags) ; is 256. ; INTCPT DB '^' ;intercept character (prefix) ; FNCTBL DB 0,'DIR ',CR,0 DB 1,'DIR *.* $U0AD ',CR,0 DB 2,'XMODEM S ',0 DB 3,'XMODEM R ',0 DB 4,'BYE ',CR,0 DB 5,'Rte Ptr PMMIMODEM OR AL,AL JZ RESTART2 CALL SETBAUD ;just the PMMI has to check each time ; RESTART2: CALL MOVEFCB MOV AL,Byte Ptr OPTION ;get main option CMP AL,'D' ;disconnect? JNZ L3A4 JMP DONETCD ;yes, disconnect then back to NUMBLIB DB 'A=Bob Robesky.......1-209-227-2083' ;'A' DB 'B=Byron McKay.......1-415-965-4097' ;'B' DB 'C=Bruce Jorgens.....1-509-255-6324' ;'C' DB 'D=Phil Cary.........1-505-522-8856' ;'D' DB 'E=Bill Earnest......1-215-398-3937' ;'E' DB 'F=Chuck BBS ',CR,0 DB 6,'(vacant)',0 DB 7,'(vacant)',0 DB 8,'(vacant)',0 DB 9,'Nice chatting, see you again soon... ',CR,0 RS 256-((Offset $)-(Offset FNCTBL)) ; ; ; ;*********************************************************************** ; ; ; P - the menu L3A4: CMP AL,'M' ;menu asked for? JNZ L3A5 JMP MENU2 ;go display the menu L3A5: CMP AL,'R' ;want to receive a file? JNZ L3A6 JMP RCVFIL ;exit if yes L3A6: CMP AL,'S' ;want to send a file? JNZ L3A7 JMP SENDFIL ;exiForsberg....1-503-621-3193' ;'F' DB 'G=Ron Fowler........1-414-563-9932' ;'G' DB 'H=Charlie Hoffman...1-813-831-7276' ;'H' DB 'I=Jack Kinn.........1-817-547-8890' ;'I' DB 'J=Walt Jung.........1-301-661-2175' ;'J' DB 'K=Sigi Kluger.......1-915-598 R - O - G - R - A - M S - T - A - R - T - S H - E - R - E ; ; ;*********************************************************************** ; ; START: MOV AX,CS ; stack resides in the Code Segment MOV SS,AX MOV SP, Offset STACK ;start local stackt if yes L3A7: CMP AL,'T' ;want terminal mode? JNZ RESTART3 ;if not, exit XOR AL,AL MOV Byte Ptr ECHOFLG,AL ;reset echo flag MOV Byte Ptr LOCFLG,AL ;reset local flag JMP DSKSAVE ;exit if yes ; RESTART3: CMP AL,'E' ;want echo -1668' ;'K' DB 'L=Keith Petersen....1-313-759-6569' ;'L' DB 'M=Wayne Masters.....1-408-378-7474' ;'M' DB 'N=Dick Mead.........1-213-799-1632' ;'N' DB 'O=Al Mehr...........1-408-238-9621' ;'O' DB 'P=Pasadena RBBS.....1-213-577-9947' ;'P' DB 'Q=M ; ; ; The 'FIXCNT' calculations are done here and the values stored so the ; overhead of doing the calculation is not incurred in the RECV routine ; where it is desired to pick up a character from the modem data port as ; quickly as possible. ; Mmode? JNZ NOECHO ;if not, exit MOV Byte Ptr ECHOFLG,AL ;set the echo flag XOR AL,AL MOV Byte Ptr LOCFLG,AL ;reset local flag JMP DSKSAVE ; NOECHO: CMP AL,'L' ;want local echo mode? JNZ NOLOCAL ;if not, exit MOV Byte Ptr LOCFLG,ark Pulver.......1-312-789-0499' ;'Q' DB 'R=Bruce Ratoff......1-201-272-1874' ;'R' DB 'S=Ken Stritzel......1-201-584-9227' ;'S' DB 'T=TCBBS, Dearborn...1-313-846-6127' ;'T' DB 'U=AnaHUG RCPM.......1-714-774-7860' ;'U' DB 'V=Dave Austin.......1-70OV BX,590 ;adjust to get 1 second time intervals CALL FIXCNT MOV Word Ptr TIMVAL,BX MOV BX,36 ;should be 1/16 of above value CALL FIXCNT MOV Word Ptr QUIKTIM,BX ; ; ; Now display the program name and version number and we are under way ; AL ;set the local flag XOR AL,AL MOV Byte Ptr ECHOFLG,AL ;reset echo flag JMP DSKSAVE ; NOLOCAL:CALL NTVLDMSG ;say not a valid option JMP MENU ;then go back to the command mode ;.... ; ; INITADR:CALL GETUSER ;get current user num7-257-6502' ;'V' DB 'W=Paul Bagdonovitch.1-201-747-7301' ;'W' DB 'X=Kirk De Haan......1-408-296-5078' ;'X' DB 'Y=Byron Kantor......1-619-273-4354' ;'Y' DB 'Z=Chuck Metz........1-408-354-5934' ;'Z' DB '0=Bill Parrott......1-913-682-3328' ;'0' DB CALL ILPRT DB CR,LF,'MDM',VERSION/100+'0',VERSION MOD 100/10+'0' DB VERSION MOD 10+'0',' modem pgm (type M ',0 CALL CRITE CALL JMP_SYSVER ;give configuration message CALL CRCGEN ;generate tables for fast 'CRC' check CALL INITADR ;initialber MOV Byte Ptr OLDUSER,AL ;save to restore upon exit CALL GETMAX ;find maximum ram for printer use JMP JMP_INITMOD ;initialize non-PMMI systems if needed ;..... ; ; ; Get the function key intercept character and put in appropriate places  '1=Larry Snyder......1-305-671-2330' ;'1' DB '2=Alex Soya.........1-305-259-7955' ;'2' DB '3=Tony Stanley......1-912-929-8728' ;'3' DB '4=Ed Svoboda........1-408-732-9190' ;'4' DB '5=Tampa Bay Bandit..1-813-937-3608' ;'5' DB '6=Thousand Oaks....ize addresses CALL INTERCEPT ;establish the function key intercept CALL PROCOPT ;process any options MOV AL,Byte Ptr OPTION ;any options on the command line? CMP AL,' '+1 JNB RESTART JMP MENU ;if not, show the menu ; ; ; Comes here  ; INTERCEPT: MOV AL,Byte Ptr INTCPT ;get the function key intercept char. AND AL,07FH ;strip off any parity MOV Byte Ptr FNCKY,AL ;store CMP AL,' ' ;printing character? JNB INTER2 ;if yes, exit ADD AL,40H ;change to printing charac.1-805-492-5472' ;'6' DB '7=Bill Wood.........1-619-256-3914' ;'7' DB '8=Spare.............1-xxx-xxx-xxxx' ;'8' DB '9=Spare.............1-xxx-xxx-xxxx' ;'9' DB 0 ;end ; '----5---10---15---20---25---30--34' ; ;-------------------------------from menu once the options have been set ; RESTART:MOV SP, Offset STACK ;make sure we have a clean stack CALL CKCHAR ;catch any garbage characters left over MOV AL,Byte Ptr PMMIMODEM OR AL,AL JNZ RESTART1 ;if yes, accept 'C' or 'D' MOV AL,Byter JMP FIXFNK ;fix-patch area of extra bytes ; INTER1: MOV AL,'^' MOV BYTE PTR MENU3,AL ;store the "control-" character RET ; INTER2: MOV Byte Ptr MENU3+1,AL RET ;..... ; ; ; Process any options - put 0 in appropriate place in option tab---------------------------------------- ; ; This is the storage area for the ten function keys. The M7FNK.COM ; program dynamically allocates the storage for the keys. Thus, no ; function key is limited to so-and-so many characters. Rather, the ; te Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JZ RESTART2 ;exit if neither modem-type ; RESTART1: MOV AL,Byte Ptr OPTION ;get the option CMP AL,'C' ;call (dial) function? JNZ L3A2 JMP JMP_DIAL ;yes, go to it L3A2: MOV AL,By8 le if ; option is selected ; PROCOPT:MOV DX,Offset FCB+1 MOV SI,DX MOV AL,[SI] MOV Byte Ptr OPTION,AL CMP AL,' ' ;exit if no options JNZ OPTLP RET ; OPTLP: INC DX MOV SI,DX MOV AL,[SI] CMP AL,' ' JZ ENDOPT MOV BX, Offset OPTBL 'CALL SETFCB JMP MENU ;abort to command line ;..... ; ; BDOPT: CALL ILPRT DB CR,LF,'++ Bad option ++',CR,LF,LF,0 ;..... ; ; ; Check for any garbage characters on line - catch and ignore ; CKCHAR: CALL RCVREADY ;any characters ready to receCONVRUB ;convert rub to backspace? OR AL,AL JZ NOTRUB ;exit if no conversion MOV CH,BKSP ;call it a backspace JMP NOTOG ;go send a backspace ; NOTRUB: MOV AL,Byte Ptr FNKFLG ;get function key active flag OR AL,AL JZ NOF ;if not MOV CH, (Offset OPTBE)-(Offset OPTBL) ; OPTCK: CMP AL,Byte Ptr [BX] JNZ OPTNO CMP AL,'O' ;want originate tones? MOV CH,AL ;store momentarily MOV AL,ORIGMOD JZ OPTCK1 MOV AL,CH ;get the option back CMP AL,'A' ;want answer tones? ive? JZ L3A17 RET ;if not, return L3A17: CALL IN_MODDATP ;otherwise get the character and ignore JMPS CKCHAR ;check for any additional characters ;..... ; ; ; Revised terminal routine allowing memory save. First checks for bad ; option set yet, exit MOV AL,CH ;get character CMP AL,'0' JB NOFNK1 ;ignore invalid key codes CMP AL,'9'+1 JNB NOFNK1 AND AL,0FH ;make 0..9 JMP SENDFK ; NOF: MOV AL,Byte Ptr INTCPT ;check intercept character CMP AL,CH JNZ NOFNK1 ;skip JNZ OPTCK2 ;if not, exit MOV AL,ANSWMOD ; OPTCK1: MOV Byte Ptr UARTCTLB,AL ; OPTCK2: MOV Byte Ptr [BX],0 JMPS OPTLP ; OPTNO: INC BX DEC CH JNZ OPTCK CALL NTVLDMSG POP BX ;preserve stack JMP MENU ; ENDOPT: MOV AL,Byte Ptr VSEEFLG s, to prevent wiping out the disk with accidental memory save. ; DSKSAVE:MOV AL,Byte Ptr BATCHFLG ;batch flag set? OR AL,AL JNZ DSKSAVE1 ;if not set, everything is normal MOV AL,'B' ;if set, shouldn't be, so reset it MOV Byte Ptr BATCHFLG,ALif no function key MOV Byte Ptr FNKFLG,AL ;set the function flag JMP TERML ;do not send the intercept character ; NOFNK1: XOR AL,AL ;reset the flag MOV Byte Ptr FNKFLG,AL MOV AL,Byte Ptr EXACFLG OR AL,AL ;exact? MOV AL,0 ;(cannot  OR AL,AL JNZ CKOPTN MOV Byte Ptr QFLG,AL ;quiet mode for watching data items ; CKOPTN: MOV AL,Byte Ptr OPTION ;check on the primary option CMP AL,'D' ;going to disconnect? JNZ L3A9 RET L3A9: CMP AL,'E' ;return if echo option  JMP NOTVLD ;if set, error for 'E', 'L' or 'T' ; DSKSAVE1: MOV Byte Ptr XFLG,AL ;will use the ASCII capture buffer size MOV AL,Byte Ptr NFILFLG ;already saving for a file? OR AL,AL JZ DSKSAVE2 ;exit if not, and open a file CALL BUuse 'XRA A' here) MOV Byte Ptr EXACFLG,AL ;clear for next time JZ NTEXAFLG ;go if EXACFLG not set 'YES' MOV AL,Byte Ptr LOCNXTCHR OR AL,AL ;should we send on exacflg? JNZ L3A20 JMP NOTOG ;jump if LOCONEXTCHR 'NO' L3A20: MOV AL,Byte P JNZ L3A10 RET L3A10: CMP AL,'M' ;return if help option JNZ L3A11 RET L3A11: CMP AL,'L' ;return if local echo option JNZ L3A12 RET L3A12: CMP AL,'T' ;return if terminal mode JNZ L3A13 RET L3A13: MOV CH,AL ;save the primaryFMSG ;tell if buffer if on or off JMPS TERM ; DSKSAVE2: MOV AL,Byte Ptr .FCB+1 ;first character of filename (if any) CMP AL,' ' ;file specified? JNZ GOODNM ;yes, good name XOR AL,AL MOV Byte Ptr NFILFLG,AL ;show no file being saved tr EXTCHR ;we want to send EXTCHR in any case CMP AL,CH JNZ L3A21 JMP NOTOG ;send if EXTCHR L3A21: JMPS LOCCHK ;otherwise do local stuff ;... ; ; NTEXAFLG: MOV AL,Byte Ptr EXTCHR ;treat next character in special way? CMP AL,CH  option for a moment MOV AL,Byte Ptr PMMIMODEM ;PMMI modem? OR AL,AL JNZ CKOPTN0 ;if yes, accept 'C' MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JZ CKOPTN1 ;exit if neither ; CKOPTN0:MOV AL,CH ;get the character back MOV Byte Ptr SAVEFLG,AL ;reset the flag to zero JMPS TERM ;... ; ; GOODNM: CALL ERASFIL MOV BX, Offset FCB3 CALL INITFCB MOV BX, Offset FCB ;move the disk name into FCB3 area MOV DX, Offset FCB3 MOV CH,12 CALL MOVE MOV DX, Offset F ;check against this control character JNZ NTEXA1 ;yes, set exacflg for next character MOV AL,1 MOV Byte Ptr EXACFLG,AL ;set the flag JMP TERM ;do not send, get next character ; NTEXA1: MOV AL,Byte Ptr LOCNXTCHR OR AL,AL ;should we se CMP AL,'C' ;going to call a number now? JNZ L3A14 RET L3A14: ; CKOPTN1:MOV AL,Byte Ptr NFILFLG ;saving memory for disk file? OR AL,AL JZ CKOPTN2 ;if not, continue POP BX ;reset the stack from 'CALL PROCOPT' JMP MENU0 ;go show CB3 ;now make a file from that name MOV CL,MAKE INT 224 MOV DX, Offset FCB3 ;now open the file from FCB3 MOV CL,OPEN INT 224 MOV BX, offset BUFFER ;reset pointers to start of buffer MOV Word Ptr HLSAVE,BX MOV AL,1 MOV Byte Ptr NFILFLG,And if not EXACFLG? JZ LOCCHK JMP NOTOG ;jump if loconextchr 'YES' ; LOCCHK: CALL EXITTST1 ;want to exit to menu? MOV AL,Byte Ptr NOCONNCT ;want to disconnect from line? CMP AL,CH JNZ L3A23 JMP DONETCD ;if yes go disconnect L3A23: MOthe 'FILE OPEN' message ; CKOPTN2:MOV AL,CH ;get the option back CMP AL,'S' JZ CKFILE CMP AL,'R' JNZ BDOPT ;none of these, bad option MOV AL,Byte Ptr BATCHFLG ;see if the batch mode flag is set OR AL,AL JNZ CKFILE RET ;if yes, eL ;show now saving to memory for disk file CALL BUFMSG2 ;show buffer is available ; TERM: MOV AL,Byte Ptr LSTTST ;allowing the printer to be used? OR AL,AL JZ L3A18 CALL GOLIST ;if yes, see if anything to print L3A18: CALL STAT ;kV AL,Byte Ptr TRANCHR ;output text file to remote? CMP AL,CH JNZ L3A24 JMP TRANSFER L3A24: MOV AL,Byte Ptr TRANLOGON OR AL,AL JZ SKPLOGON MOV AL,Byte Ptr LOGCHR ;send logon? CMP AL,CH JNZ L3A25 JMP SENDLOG L3A25: ; SKPLOGON: xit ; CKFILE: MOV AL,Byte Ptr FCB+17 ;'S' and 'R' need a file name CMP AL,' ' JZ REENT RET ;exit if a file name is present ; REENT: CALL ILPRT DB '++ Enter primary option plus file name ++' DB CR,LF,BELL,0 POP BX ;reset stack from eyboard have a character? JNZ L3A19 JMP TERML ;if not, see if any incoming L3A19: CALL KEYIN ;get character from keyboard MOV CH,AL ;save for now to protect 'A' reg. CMP AL,RUB ;test for rub JNZ NOTRUB ;exit if not MOV AL,Byte Ptr 8  MOV AL,Byte Ptr LSTTST ;going to use the external printer? OR AL,AL JZ NOLST ;if not, skip this area MOV AL,Byte Ptr LSTCHR ;get the printer control-character CMP AL,CH ;did we just ask for printer control? JNZ NOLST ;if not, exitCHG AL,AH SAHF JNB SENDC2 ;carry set means no more files MOV AL,'B' ;stop batch MOV Byte Ptr BATCHFLG,AL ;mode option MOV AL,EOT ;final transfer end CALL SEND JMP DONE ; SENDC1: MOV AL,Byte Ptr FCB+1 CMP AL,' ' JNZ SENDC2 JMP  ; RCVLP0: LAHF XCHG AL,AH PUSH AX CALL ILPRT DB 'Waiting.....',0 ; NOPRG: POP AX XCHG AL,AH SAHF CALL SEND ; RCVLP: CALL RCVRECD JB RCVEOT CALL REPORT ;show record received if not in quiet CALL WRRECD CALL INCRRNO CALL SEND MOV AL,Byte Ptr LISTFLG ;otherwise reset the printer toggle NOT AL MOV Byte Ptr LISTFLG,AL ;and store CALL CRLF CALL CRLF CALL LSTMSG ;tell if printer is on or off now CALL CRLF JMP TERML ;back to the terminal mode again ;..... BLKFILE ; SENDC2: CALL CNREC ;get number of records CALL OPENFIL MOV DL,120 ;wait 2 minutes maximum CALL WAITNAK ; SENDLP: CALL CKABORT ;want to terminate while sending file? CALL RDRECD JB SENDEOF CALL INCRRNO MOV AL,1 MOV Byte PACK JMPS RCVLP ; RCVEOT: CALL WRBLOCK CALL SENDACK CALL CLOSFIL JMP DONE ; SENDACK:MOV AL,ACK CALL SEND RET ; ;..... ; ; ;=================== FILE TRANSFER IN T-MODE =========================== ; ; ; File transfer routine - called ; ; NOLST: MOV AL,Byte Ptr BRKCHR ;PMMI break? CMP AL,CH JNZ L3A26 JMP BREAK L3A26: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI board? OR AL,AL JZ NOLST1 ;if not, skip the next few lines MOV AL,Byte Ptr CHGBAUD ;PMMI change baud? tr ERRCT,AL ; SENDRPT:CALL CKABORT ;want to terminate while sending file? CALL SENDHDR CALL SENDREC MOV AL,Byte Ptr CRCFLAG OR AL,AL JNZ SNDCRC CALL SENDCKS JMPS SNDCONT ; SNDCRC: CALL SENDCRC ; SNDCONT:CALL GETACK JB SENDRPT JMPS with CTL-T from terminal mode. Trans- ; fer may be cancelled while sending, by using CTL-X. ; TRANSFER: MOV BX, Offset FCB4 CALL INITFCB ;initializes FCBs pointed.. MOV BX, offset FCB+16 ;..to by 'BX' reg. CALL INITFCB ; ; ; Get name of fCMP AL,CH LAHF XCHG AL,AH PUSH AX PUSH BX JNZ L3A27 CALL JMP_NEWBAUD L3A27: POP BX POP AX XCHG AL,AH SAHF JNZ NOLST1 JMP TERML ;... ; ; NOLST1: MOV AL,Byte Ptr UNSAVECHR ;close input buffer? CMP AL,CH JZ NOLST2 ;if yes,  SENDLP ;..... ; ; SENDEOF:MOV AL,EOT CALL SEND CALL GETACK JB SENDEOF JMP DONE ;..... ; ; ;*********************************************************************** ; ; RECEIVE A CP/M FILE ; ;*************************************ile to send in "T" (terminal) mode ; GET: CALL ILPRT DB CR,LF,'File name to send? (CR to abort): ',0 MOV DX, offset CMDBUF CALL INBUF MOV AL,Byte Ptr CMDBUF+2 ;was file entered? CMP AL,' ' JNZ L3A36 JMP RETURN ;if not probably wanted todisable copy MOV AL,Byte Ptr SAVECHR ;open input buffer? CMP AL,CH JZ L3A29 JMP NOTOG L3A29: MOV AL,Byte Ptr NFILFLG ;do not allow save if.. OR AL,AL JNZ L3A30 JMP TERML ;..this flag is set. L3A30: JMPS NOLST3 ; NOLST2: XOR AL********************************** ; ; RCVFIL: MOV AL,Byte Ptr CRCDFLT ;get mode requested by operator MOV Byte Ptr CRCFLAG,AL ;store it ; RCVFIL1:CALL JMP_PARITY MOV AL,Byte Ptr BATCHFLG ;check if multiple file mode OR AL,AL JNZ RCVC1 quit L3A36: MOV DX, Offset CMDBUF MOV BX, Offset FCB4 CALL CMDLINE MOV DX, Offset FCB4 MOV CL,OPEN INT 224 CMP AL,0FFH ;return with 0FFH means 'NO SUCH FILE' JNZ L3A37 JMP TRANSL L3A37: MOV AL,Byte Ptr XONWAIT ;waiting for X-on ,AL ;stop copy into file ; NOLST3: MOV Byte Ptr SAVEFLG,AL CALL BUFMSG JMP TERM ;get next character ;..... ; ; ;*********************************************************************** ; ; SEND A CP/M FILE ; ;************************ ;if not, exit MOV AL,NO ;flag where to return.. MOV Byte Ptr SENDFLG,AL ;..for next file transfer CALL GETFN ;get the file name JNB RCVC2 ;carry set means no more files MOV AL,'B' ;stop batch MOV Byte Ptr BATCHFLG,AL ;mode optioto send next line? OR AL,AL JNZ DLYSAV ;if yes, skip additional delays ; ; ; Choice of normal speed or delays between characters / lines ; CALL ILPRT DB 'Want to include time delays? (Y/N): ',0 CALL KBDCHR CMP AL,'N' ;if 'N' send normal*********************************************** ; ; SENDFIL:XOR AL,AL ;set to checksum initially on send MOV Byte Ptr CRCFLAG,AL ;..initially on send CALL CKCHAR ;catch any garbage characters ; SENDFIL1: MOV AL,Byte Ptr BATCHFLG ;check n JMP DONE ; RCVC1: MOV AL,Byte Ptr FCB+1 ;make sure file is named CMP AL,' ' JNZ L3A35 JMP BLKFILE L3A35: JMPS RCVC3 ; RCVC2: CALL SHOWFIL ;show the file name MOV AL,' ' CALL STYPE CALL SNDPRG ;get progress and wait for quiet speed JZ DLYSAV XOR AL,AL ;otherwise use character/line delays ; DLYSAV: MOV Byte Ptr DLYFLG,AL ;store the decision CALL CRLF MOV DX, Offset CMDBUF+2 ;make sure cmdbuf has been selected MOV CL,SETDMA INT 224 ; ; ; Get 128-byte record if multiple file.. OR AL,AL ;..mode is set. JNZ SENDC1 CALL ILPRT DB 'Ready to send in batch mode',CR,LF,0 ; SENDFIL2: CALL JMP_PARITY MOV AL,YES ;indicate send for batch mode MOV Byte Ptr SENDFLG,AL MOV AL,Byte Ptr FSTFLG ;if fir line CALL CKCPM2 CALL CRLF CALL CKBAKUP ; RCVC3: CALL ERASFIL CALL MAKEFIL CALL WAITQ1 MOV AL,Byte Ptr BATCHFLG ;do not print message if in batch mode OR AL,AL JZ RCVFST CALL ILPRTQ DB 'File open, ready to receive',CR,LF,0 ; RCVF; READMR: MOV DX, Offset FCB4 MOV CL,READ INT 224 OR AL,AL ;check for a good read JZ READMR1 DEC AL ;check for end of file to send JZ RETURNS CALL ERXIT ;neither of those, was a read error DB '++ DISK READ ERROR ++','$' ; ; ; Succst time through.. OR AL,AL ;..scan the command line.. JNZ L3A31 CALL TNMBUF ;..for multiple names. L3A31: CALL SENDFN ;sends file name to receive LAHF XCHG AL,AH PUSH AX CALL CRLF CALL SHOWFIL MOV AL,' ' CALL STYPE POP AX XST: MOV AL,Byte Ptr CRCFLAG OR AL,AL JZ RCVNAKM ;if in 'CRC' mode CALL ILPRTQ ;then say so DB 'CRC in effect',CR,LF,0 MOV AL,CRC JMPS RCVLP0 ; RCVNAKM:CALL ILPRTQ ;else say 'CHECKSUM' mode DB 'Checksum in effect',CR,LF,0 MOV AL,NAK 9 essful read, so send the record ; READMR1:CALL SEND80C ;send one 128-char record CMP AL,EOFCHAR ;end of file - omit if object.. JZ RETURNS ;..code is to be sent. CMP AL,CANCEL ;cancellation? JNZ READMR ; RETURN: CALL ILPRT DB CR,LF,LF,' ; Add from 0 to 90 ms. delay between characters for slow (most use ; BASIC) bulletin board systems. Also used to add 0-900 ms. delay ; between lines. ; SPEED: MOV AL,Byte Ptr BYTDLY ;get delay between characters (0-9) JMPS L3A43 ;1=10 ms, 5= ; CKQUIT: MOV AL,Byte Ptr BATCHFLG ;using batch mode now? OR AL,AL JNZ CKQUIT1 JMP ABORT ;quit if using batch mode ; CKQUIT1:MOV AL,1 MOV Byte Ptr ERRCT,AL CALL ILPRT DB CR,LF,'Multiple errors encountered.',CR,LF DB 'Type Q to quit, (in Terminal-mode now)',CR,LF,LF,0 CALL SENDNOW ;insures last character is finished CALL CKCHAR ;catch any echo character on line JMP TERM ;finished, back to t-mode ;..... ; ; RETURNS:CALL ILPRT DB CR,LF,'[Transfer completed]',0 JMPS RE50 ms, 9=90 ms, etc. ; SPEED1: MOV AL,Byte Ptr CRDLY ;get delay after crlf (0-9) L3A43: OR AL,AL ;100 ms, 5=500 ms, 9=900 ms, etc. JNZ L3A44 RET ;if no delay needed, return L3A44: MOV CL,AL ;store number requested in c-reg. MOV ALR to retry: ',BELL,0 CALL KEYIN LAHF XCHG AL,AH PUSH AX CALL CRLF POP AX XCHG AL,AH CALL UCASE ;instead of 'ANI 5FH' CMP AL,'R' JNZ L3A52 JMP RCVRECD ;if 'R' keep trying L3A52: CMP AL,'Q' JNZ CKQUIT1 JMP ABORT ;..... ; TURN ;..... ; ; TRANSL: CALL ILPRT DB CR,LF,BELL,'++ FILE NAME ERROR ++ ',CR,LF,0 JMP GET ;..... ; ; ; Send one 128-byes record ; SEND80C:MOV CH,128 ;will send a maximum of 128 character MOV BX, Offset CMDBUF+2 ;they are in the cmdbuf are,Byte Ptr DLYFLG ;want any delays this file? OR AL,AL JZ SPEED2 RET ;if not, skip this section ; SPEED2: CALL SPEED3 ;outer loop DEC CL JNZ SPEED2 RET ;done whenever the c-reg. is zero ;... ; ; SPEED3: PUSH BX ;save current ; ; Show the file name as stored in the FCB but in CP/M format ; SHOWFIL:MOV AL, Byte Ptr QFLG OR AL,AL JNZ L4A1 RET L4A1: MOV BX, Offset FCB+1 ; SHOWNM: XOR AL,AL MOV Byte Ptr FTYCNT,AL MOV CL,11 ; PRNAM: CALL FTYTST INC BX DEC CL a ; SENDCH1:PUSH DX CALL SPEED ;0-90 ms. delay between characters POP DX MOV AL,Byte Ptr [BX] CMP AL,EOFCHAR JNZ L3A38 RET L3A38: CALL MODOUT ;send the character to modem CALL STAT ;test to see if OR AL,AL ;cancellation request'BX' value MOV BX,20 MOV AL,Byte Ptr XOFFTST OR AL,AL JZ SPEED4 MOV BX,20 ;adjust for 'X-OFF' testing MOV AL,Byte Ptr ECHOFLG OR AL,AL JZ SPEED4 MOV AL,Byte Ptr LOCFLG OR AL,AL JZ SPEED4 MOV BX,25 ;adjust for remote echo ; SPE JNZ PRNAM RET ;..... ; ; ; Give report of received records as they occur ; REPORT: MOV AL,Byte Ptr QFLG OR AL,AL JNZ L4A2 RET L4A2: MOV BX,Word Ptr RECDNO ;get record number INC BX CALL ILPRT DB CR,'Received # ',0 CALL DECOUTed JZ SKIP1 CALL KEYIN CMP AL,CANCEL JNZ L3A39 RET L3A39: ; SKIP1: INC BX DEC CH JNZ SENDCH1 RET ;..... ; ; ; Send the character to the output ; MODOUT: PUSH AX ; save character so we can use AX CMP AL,LF JNZ MODOUTL MOV AED4: CALL FIXCNT ;multiply delay by clock speed XCHG BX,DX ;transfer delay to 'DE' POP BX ;restore current 'BX' from"speed3" ; SPEED5: DEC DX ;inner loop MOV AL,Byte Ptr XOFFTST OR AL,AL JZ L3A46 CALL TXOFF L3A46: MOV AL,DL OR AL ;print record number in decimal CALL ILPRT DB ' ',0 ; MOV AL,Byte Ptr HEXSHOW OR AL,AL JNZ L4A3 RET L4A3: CALL ILPRT DB '(',0 CALL DHXOUT ;16 bit hex conversion and output CALL ILPRT DB 'H) ',0 RET ;..... ; ; FTYTST: MOV L,Byte Ptr ADDLF ;going to send the line feed to modem? OR AL,AL JNZ MODOUTL ;if yes, exit POP AX ;get the char. back (a line feed) CALL STYPE ;show on CRT, do not send to modem RET ; MODOUTL:MOV AL,Byte Ptr XOFFTST ;waiting for ,DH JNZ SPEED5 RET ;... ; ; TXOFF: CALL RCVREADY JZ L3A47 RET L3A47: CALL IN_MODDATP AND AL,7FH CMP AL,XOFF JNZ L3A48 CALL WAITXON L3A48: RET ;..... ; ; WAITXON:CALL RCVREADY ;have a character? (like x-on) JNZ WTXON1 ;if AL,Byte Ptr FTYCNT INC AL MOV Byte Ptr FTYCNT,AL CMP AL,9 ;are we at the file type? JZ SPCTST ;go if so ; ENDSPT: MOV AL,Byte PTr [BX] CMP AL,' ' ;test for space JZ L4A4 CALL STYPE ;type if not L4A4: RET ;..... ; ; SPCTST: MOVX-off, X-on ? OR AL,AL JZ L3A40 CALL TXOFF ;if yes, go check L3A40: CALL SENDRDY ;wait until modem is ready to send JNZ MODOUTL POP AX ;get the character back CALL STYPE ;send character to CRT CALL OUT_MODDATP ;send character to no char. see if want to abort CALL IN_MODDATP AND AL,7FH ;strip off any parity CMP AL,XON ;see if char. was x-on JNZ WTXON1 RET ;if yes, keep going ; WTXON1: CALL STAT ;test to see if requesting cancellation JZ WAITXON CALL KEYIN  AL,Byte Ptr [BX] CMP AL,' ' ;test for space in 1st file type byte JNZ L4A5 RET ;do not output period if space L4A5: MOV AL,'.' CALL STYPE JMPS ENDSPT ;output 1st file type byte ;..... ; ; ; Get sender's progress report if it is presemodem CMP AL,CR ;was it an end of line? JZ MODOUTN RET ;if yes, see if any delay is needed ; ; ; Delay to allow slow BBS systems (most use BASIC) to enter the line. ; Choice of 0-9 for about 100 ms. each, maximum of 900 ms. ; MODOUTN:MOV A ;can abort if the x-on never comes CMP AL,CANCEL ;ctl-x to abort? JNZ WAITXON ;if not, keep going RET ;..... ; ;================ END OF FILE TRANSFER IN T-MODE ======================= ; ; ;*************************************************nt and wait for line to get ; quiet ; SNDPRG: MOV CH,5 ;wait up to 5 seconds CALL RECV CALL STYPE ;show the progress report from sender JNB SNDPRG RET ;..... ; ; SENDFN: CALL ILPRTQ DB 'Awaiting name NAK',CR,LF,0 CALL GETACK JNB SL,Byte Ptr XONWAIT ;wait for X-on after CR? OR AL,AL JZ L3A42 JMP WAITXON ;if yes, handle separately L3A42: MOV DH,10 ; MODOUTT:PUSH DX CALL SPEED1 ;10 ms delay POP DX DEC DH JNZ MODOUTT ;10 loops for 100 ms. RET ;..... ; ;********************** ; ; SUBROUTINES ; ;*********************************************************************** ; ; Returns with the zero flag set if retry requested. If using multi- ; file (batch) modem, then no questions asked, just quit.9 ENDFN1 CALL SENDACK SENDFN1: MOV BX, Offset FILECT DEC Byte Ptr [BX] JS NOMRNM MOV BX,Word Ptr NBSAVE ;get file name.. MOV DX, Offset FCB ;..in FCB MOV CH,12 CALL MOVE MOV Word Ptr NBSAVE,BX CALL SENDNM ;send it OR AL,AL ;cget the name CMP AL,EOT ;if EOT, then no more files JZ NOMRNMG OR AL,AL ;clear carry RET ; NOMRNMG:STC RET ; ; GETNM: PUSH BX ; GETNM1: MOV AL,0FFH MOV Byte Ptr FLTRFLG,AL MOV CL,0 ;initialize checksum MOV BX, FCB+1 ; NAMELPGLP1: CALL TRTOBUF MOV BX, Offset FCB MOV DX, Offset FCBBUF CALL CMDLINE ;parse name to CP/M format ; TNLP2: CALL MFNAME ;search for names (wildcard format) JB NEXTNM MOV AL,Byte Ptr FCB+10 ;if CP/M 2 $sys file.. AND AL,80H ;..do notlear carry RET ;..... ; ; NOMRNM: MOV AL,EOT CALL SEND STC RET ;..... ; ; ; Wait for line to get quiet and gobble characters ; WAITQ1: MOV CH,1 CALL RECV JNB WAITQ1 RET ;..... ; ; SENDNM: PUSH BX ; SENDNM1:MOV DH,11 ;count c:MOV CH,5 CALL RECV ;get the character PUSH CX LAHF XCHG AL,AH PUSH AX MOV AL,0FFH MOV Byte Ptr TIMFLG,AL MOV CH,1 CALL RECV XOR AL,AL MOV Byte Ptr TIMFLG,AL POP AX XCHG AL,AH SAHF POP CX JNB GETNM3 CALL ILPRTQ DB 'Tim send JNZ TNLP2 MOV BX,Word Ptr NBSAVE ;get name MOV DX, FCB ;move it to FCB XCHG BX,DX MOV CH,12 CALL MOVE XCHG BX,DX MOV Word Ptr NBSAVE,BX ;addressof next name MOV BX, Offset FILECT ;count files found INC Byte Ptr [BX] JMharacters in name MOV CL,0 ;initialize checksum MOV BX, Offset FCB+1 ;address name ; NAMLPS: MOV AL,Byte Ptr [BX] ;send name AND AL,7FH ;strip high order bit so CP/M2.. CALL SEND ;..will not send R/O file designation. ; ACKLP: PUSH CX ;e out receiving filename',CR,LF,0 JMP GCKSER ; GETNM3: CMP AL,EOT ;if EOT, then no more files JNZ L4A7 JMP GNRET L4A7: CMP AL,EOFCHAR ;got end of name JZ ENDNAME LAHF XCHG AL,AH PUSH AX PUSH CX CALL SENDACK POP CX POP AX XCHPS TNLP2 ;..... ; ; NEXTNM: MOV BX, Offset NAMECT ;count names found DEC Byte Ptr [BX] JNZ TNLP1 MOV BX, Offset NAMEBUF ;save start of buffer MOV Word Ptr NBSAVE,BX MOV AL,Byte Ptr FILECT CMP AL,64+1 ;no more than 64 transfers JNB L4A9 save checksum MOV CH,5 ;wait for receiver to acknowledge.. CALL RECV ;..getting the letter. POP CX JB SCKSER CMP AL,ACK JNZ ACKLP INC BX ;next character DEC DH JNZ NAMLPS MOV AL,EOFCHAR ;tell receiver the end of name CALL SEND G AL,AH MOV Byte Ptr [BX],AL ;put name in FCB INC BX ;get next character MOV AL,BL ;don not let noise cause overflow.. CMP AL,7FH ;..into the program area. JZ GCKSER JMP NAMELPG ; ENDNAME:XOR AL,AL MOV Byte Ptr FLTRFLG,AL MOV AL,CL  RET L4A9: MOV AL,64 ;only transfer first 64 MOV Byte Ptr FILECT,AL RET ;..... ; ; ; Tells when buffer is opened/closed for memory save to write on disk ; BUFMSG: CALL ILPRT DB CR,LF,'** Memory buffer ',0 MOV AL,Byte Ptr SAVEFLG OR AL MOV DH,CL ;save checksum ; CKSMLP: MOV CH,5 ;wait up to 5 seconds CALL RECV ;get checksum CMP AL,DH JNZ SCKSER ;exit if bad name MOV AL,OKNMCH ;good name-tell receiver CALL SEND POP BX RET ;..... ; ; SCKSER: MOV AL,BDNMCH ;b ;send checksum MOV DH,CL CALL SEND ; NMLP1: MOV CH,5 ;wait up to 5 second to see if.. CALL RECV ;..the checksum is good CMP AL,OKNMCH ;yes if 'OKNMCH' sent JZ GNRET CMP AL,DH JZ NMLP1 ;in case it is echo of send CMP AL,CR JZ NM,AL JZ BUFMSG1 CALL ILPRT DB 'open **',CR,LF,LF,';',0 RET ; BUFMSG1:CALL ILPRT DB 'closed **',CR,LF,LF,0 RET ; BUFMSG2:CALL ILPRT DB CR,LF,'** Memory buffer available **',CR,LF,0 RET ;..... ; ; ; Clear the screen and return to the mad name-tell receiver CALL SEND CALL ILPRT DB CR,LF,'++ ERROR sending name ++',CR,LF,0 MOV DL,120 ;do handshaking over (2 minutes maximum) CALL WAITNLP ;don't print "WAITING READY SIGNAL" msg CALL SENDACK JMP SENDNM1 ;..... ; ; ; ThiLP1 CMP AL,LF JZ NMLP1 ; GCKSER: MOV BX, FCB ;clear FCB (except drive) since it.. CALL L4A6 ;..might be damaged. CALL ILPRTQ DB CR,LF,'** Checksum error **',CR,LF,0 XOR AL,AL MOV Byte Ptr FLTRFLG,AL CALL HSNAK ;do handshaking ovenu command ; EXITMENU: CALL CRLF CALL CLREOS ;clear line to clean up any mess JMP MENU0 ;..... ; ; ; Checks to see if the modem has a character ready ; RCVREADY: CALL IN_MODCTL1 CALL ANI_MODRCVB JMP CPI_MODRCVR ;..... ; ; ; Checks patch fixes a trivial problem with the display of the function ; key group on the menu. It uses some of the extra bytes available in ; this area from the CKSMLP fix. ; FIXFNK: MOV BYTE PTR MENU3+1,AL ;store the character in the menu display CMP ALer JMP GETNM1 ; GNRET: LAHF XCHG AL,AH PUSH AX XCHG AL,AH XOR AL,AL MOV Byte Ptr FLTRFLG,AL POP AX XCHG AL,AH SAHF POP BX RET ; HSNAK: MOV DL,180 ;3 minute wait for file name XOR AL,AL MOV Byte Ptr FLTRFLG,AL ; HSNAK1: CALs to see if the modem is ready to receive a character ; SENDRDY:CALL IN_MODCTL1 CALL ANI_MODSNDB JMP CPI_MODSNDR ;..... ; ; SENDNOW:CALL EXITTEST ;see if want to quit now CALL SENDRDY ;ready to send a character? JNZ SENDNOW ;if not ready,'[' ;'ESC' character, printed JNB FIXFNK1 ;if 'ESC' or more, exit JMP INTER1 ;otherwise include a '^' ; FIXFNK1: JMP INTER2 ; ; Patch to close FCB3 instead of FCB when in disk-capture mode. ; WRERRSP:CALL WRTFIL2 ;close FCB3 file JMPL CKABORT ;want to abort? MOV AL,NAK ;send 'NAK' until receiving 'ACK' CALL SEND MOV CH,1 ;wait up to 1 second for a character CALL RECV CMP AL,ACK ;'ACK' is what we were waiting for JNZ L4A8 RET L4A8: DEC DL JNZ HSNAK1 JMP ABO wait some more RET ;exit if ready ;..... ; ; ; Send the log-on message when requested ; SENDLOG:MOV BX,Word Ptr LOGONPTR ;'BX' points to start of logon message CALL LOGLP JMP TERML ;... ; ; LOGLP: CALL SENDNOW ;wait until modem is r WRERR1 ;go write 'DISK FULL' message and quit EXTRA DB '123456789 ' ;10 extras from CKSMLP (there were 27) ; ; GETFN: MOV BX, FCB CALL L4A6 ;does not initialize drive CALL ILPRTQ DB 'Awaiting file name',CR,LF,0 CALL HSNAK CALL GETNM ;RT ;back to command line ; ;..... ; ; TNMBUF: MOV AL,1 ;call from 'SENDFIL' only once. MOV Byte Ptr FSTFLG,AL XOR AL,AL MOV Byte Ptr FILECT,AL CALL SCAN MOV BX, Offset NAMEBUF MOV Word Ptr NBSAVE,BX ;save address of 1st name ; TN: eady MOV AL,Byte Ptr [BX] ;get logon byte OR AL,AL ;last character in string is '0' JNZ L4A10 RET ;return if finished L4A10: CALL OUT_MODDATP ;otherwise send the character CALL LOGLP1 ;check for echo character and display it LAHF  buffer open CALL CHKPRNT ;put on printer if running ; CHKCR: MOV AL,CR CMP AL,CH JNZ TERML ;if not cr, all done MOV AL,Byte Ptr ECHOFLG ;in echo mode now? OR AL,AL JNZ CHKLF ;if yes add a line feed MOV AL,Byte Ptr ADDLF ;goin; CHKSAVE1: MOV AL,BH MOV BX, Offset BUFTOP ;get the address at top of buffer CMP AL,BH JNZ L4A24 CALL D_CTL_S ;if different, buffer is not full L4A24: RET ;..... ; ; ; Memory buffer is full, send a X-OFF (CTL-S, DC3), save any extra in;next location in message INC BX SAHF JMPS LOGLP ;get next character ;..... ; ; LOGLP1: CALL JMP_INMODEM ;get the echo character JNB L4A11 CALL JMP_INMODEM ;if none, try once more L4A11: JNB L4A12 RET ;if no character don't try tog to add a line feed in 'L' mode? OR AL,AL JNZ CHKLF JMP TERM ;if not, exit ; CHKLF: MOV CH,LF JMPS NOTOG ;send locally and to remote ;..... ; ; TERML: CALL RCVREADY ;character on the receive-ready line? JZ L4A16 JMP TERM ;if not, - ; coming characters, then dump to disk, reset buffer to include those ; characters. ; D_CTL_S:CALL SENDNOW ;modem ready for a character? MOV AL,XOFF ;send a ctl-s to stop remote computer CALL OUT_MODDATP CALL CHKPRNT ;insure character get print L4A12: AND AL,7FH ;strip off any parity JMP STYPE ;display the character, then return ;..... ; ; ; Check for exit character ; EXITTEST: CALL STAT ;anything on keyboard? JNZ L4A13 RET L4A13: CALL KEYIN ;get it, then Mexit L4A16: CALL IN_MODDATP ;get the character AND AL,7FH ;strip parity JNZ L4A17 JMP TERM ;don't bother with nulls L4A17: CMP AL,RUB JNZ L4A18 JMP TERM ;don't bother with rubouts for fill L4A18: MOV CH,AL ;store temporarily Ms to the printer MOV BX, offset BUFFDSK ;address of aux. buffer CALL GETDSK ;put any extra chars. into aux. buffer PUSH DX ;save the number of aux. chars. MOV AL,1 ;show we put something in the buffer.. MOV Byte Ptr WRFLG,AL ;..to protOV CH,AL ;save to protect the 'A' reg. ; EXITTST1: MOV AL,EXITCHR ;exit character CMP AL,CH ;asking to exit to menu? JZ L4A14 RET ;if not, back to work L4A14: POP BX ;clear the stack from 'CALL' JMPS EXITMENU ;exit to the menu ;.OV AL,Byte Ptr IGNORCTL ;ignoring all but necessary ctl-chars? OR AL,AL JZ GIVLF ;if zero, display them all MOV AL,CH CMP AL,' ' JNB GIVLF ;display all printing characters CMP AL,'G'-40H ;^g for bell JNB L4A19 JMP TERM ;ignore ctl-ect erasing an empty file MOV BX,Word Ptr HLSAVE ;find current end of buffer CALL WRTDSK1 ;write the records POP DX ;get aux. char. count back MOV BX, offset BUFFER ;start again at bottom of buffer XOR AL,AL ;set 'A' to zero CMP AL,DH.... ; ; LSTMSG: CALL ILPRT DB 'Printer buffer is ',0 MOV AL,Byte Ptr LISTFLG ;see if printer should be on or off OR AL,AL JZ LSTMSG1 CALL ILPRT DB 'ON',CR,LF,0 RET ;... ; ; LSTMSG1:CALL ILPRT DB 'OFF',CR,LF,0 RET ;..... ; ; characters less than ^g L4A19: CMP AL,CR+1 JNAE GIVLF JMP TERM ;ignore ctl-charsacters more than ^m ; GIVLF: MOV AL,CH ;get the character back CALL STYPE ;show it on the CRT CALL CHKSAVE ;saving for disk file? CALL CHKPRNT ;printe ;see if any count in 'D' JZ D_CTL_Q ;if nothing, exit and continue MOV CX, offset BUFFDSK ;address of aux. buffer ; ; ; Move the characters from the auxiliary buffer to the main buffer and ; display ; D_CTL_S1: MOV SI,CX ;get the charac ; Special function key handler. This routine is entered with the ; function key number (0..9) in A. The corresponding function key is ; then transmitted. ; SENDFK: PUSH BX ;save register MOV BX, Offset FNCTBL ;point to function key codes ; SFr running? MOV AL,Byte Ptr ECHOFLG ;going to echo the character? OR AL,AL JZ NOECH ;if not, do not resend ; GIVLF1: CALL SENDCHR ;send char. in 'B' to modem ; NOECH: MOV AL,CR CMP AL,CH ;was it a 'CR' just now? JZ L4A21 JMP TERM ter there MOV AL,[SI] MOV BYTE PTR [BX],AL ;store in main buffer CALL STYPE ;show on CRT PUSH BX PUSH DX PUSH CX LAHF XCHG AL,AH PUSH AX XCHG AL,AH MOV CH,AL CALL CHKPRNT POP AX ;get the character again XCHG AL,AH POP CX K1: CMP AL,Byte Ptr [BX] ;this the one? LAHF ;point to next byte INC BX SAHF JNZ SFK1 ;loop until found CALL LOGLP ;send the char POP BX XOR AL,AL ;reset the function flag MOV Byte Ptr FNKFLG,AL JMPS TERML ;..... ; ; ; Send k;if not, all done so exit L4A21: MOV AL,Byte Ptr ECHOFLG ;in the echo mode? OR AL,AL JNZ L4A22 JMP TERM L4A22: CALL SENDNOW ;modem ready for a character? MOV CH,LF JMPS GIVLF ;send lf ;..... ; ; ; See if putting character into me POP DX POP BX CMP AL,LF JNZ L4A25 CALL TYPESCLN L4A25: LAHF ;next buffer position INC BX SAHF LAHF ;next aux. buffer position INC CX SAHF DEC DH ;one less to go JNZ D_CTL_S1 ;if not zero, keep going MOV CH,0 ;falls teyboard character to modem, also to console if "E" or "L". If ; "E", include a LF after a CR, if either, include a LF if toggle is set. ; NOTOG: CALL SENDCHR ;send char. in 'B' to modem MOV AL,Byte Ptr LOCFLG ;using the local mode? OR AL,AL mory for a disk file ; CHKSAVE:MOV AL,Byte Ptr SAVEFLG ;saving to disk? OR AL,AL JNZ L4A23 RET ;if not, exit L4A23: MOV BX,Word Ptr HLSAVE ;get last address MOV Byte Ptr [BX],CH ;store this character INC BX ;increment for next charachrough to 'CHKPRNT' next ; D_CTL_Q:MOV Word Ptr HLSAVE,BX ;next position to store in buffer CALL SENDNOW MOV AL,XON ;allow remote input to continue JMP OUT_MODDATP ;..... ; ; ; Gets any incoming characters after sending an XOFF and JNZ LTYPE ;if yes, show the character MOV AL,Byte Ptr ECHOFLG ;in echo mode? OR AL,AL JZ TERML ;if not, see if it was a 'CR' ; LTYPE: MOV AL,CH ;get the char. back CALL STYPE ;show on the local CRT CALL CHKSAVE ;to store local ifter MOV Word Ptr HLSAVE,BX ;remember that location MOV AL,LF CMP AL,CH ;this character a line feed? JNZ CHKSAVE1 ;..type ";" after each line feed.. MOV AL,CR ;insure at left column with a lf CALL STYPE CALL TYPESCLN ;show a ';' on CRT :  stores at BX. ; Returns with number of characters stored in D-reg. ; GETDSK: MOV DH,0 ;character count in buffer MOV DL,128 ;maximum for buffer length ; GETDSK1:CALL JMP_INMODEM ;get any character JNB L4A26 RET ;if none, finished L4A26 DX PUSH CX LAHF XCHG AL,AH PUSH AX XCHG AL,AH MOV CH,AL CALL CHKSAVE POP AX XCHG AL,AH POP CX POP DX POP BX CMP AL,LF JNZ L4A29 CALL TYPESCLN L4A29: LAHF ;next buffer position INC BX SAHF LAHF ;next aux. buffer Ptr HLSAVE1,BX ;..to bottom of buffer to start over MOV Word Ptr HLSAVE2,BX RET ;..... ; ; ; Compare the input and output pointers to see if the same address ; CMP_I_O:MOV BX,Word Ptr HLSAVE1 ;get input pointer address XCHG BX,DX ;put : CMP AL,' ' JNB GETDSK2 ;if greater, handle normally CMP AL,CR+1 ;ignore ctl-chars. > cr JNB GETDSK1 ; GETDSK2:MOV Byte Ptr [BX],AL ;store LAHF ;next buffer location to use INC BX SAHF INC DH ;increment character count DEC DL  position INC CX SAHF DEC DH ;one less to go JNZ P_CTL_S2 ;if not zero, keep going ; P_CTL_Q:MOV Word Ptr HLSAVE1,BX ;next position to store in buffer MOV BX, Offset PBUFF ;start of buffer location MOV Word Ptr HLSAVE2,BX ;output to in 'DE' MOV BX,Word Ptr HLSAVE2 ;get output pointer address MOV AL,BH CMP AL,DH JZ L4A34 RET ;return if different L4A34: MOV AL,BL CMP AL,DL RET ;..... ; ; GETMAX: MOV AL,Byte Ptr BDOS+2 ;'MSP' of 'BDOS' address MOV Byte Pt ;room for one less JNZ GETDSK1 ;if room in buffer, keep going RET ;if buffer is filled, exit ;..... ; ; ; See if printing the character, if yes, put into buffer ; CHKPRNT:MOV AL,Byte Ptr LISTFLG ;printer in use? OR AL,AL JNZ L4A27 start of buffer CALL SENDNOW ;wait until modem is ready MOV AL,XON ;send start character.. JMP OUT_MODDATP ;..to remote computer, back to work ;..... ; ; ; Obtain Printer Status using Direct Bios Call LISTST: PUSH DX MOV DX, OFFSET REGLr MAXRAM,AL ;save RET ;..... ; ; ; This subroutine will loop until the modem receives a character or 100 ; milliseconds. It returns with a character in 'A' reg. but if no char- ; acter was recieved it returns after a timeout with carry set. ; RET ;return if not L4A27: MOV BX,Word Ptr HLSAVE1 ;get input address MOV Byte Ptr [BX],CH ;save this character there INC BX ;increment the buffer location MOV Word Ptr HLSAVE1,BX ;store for next character MOV AL,Byte Ptr MAXIST MOV Byte Ptr REGLIST,15 ; BIOS function 15 MOV Word Ptr REGLIST+1,0 ; Clear them anyway MOV Word Ptr REGLIST+3,0 ; As MPM get upset MOV CX,50 ; Direct Bios Call INT 224 POP DX RET REGLIST DB 0 ; Function Code DW 0 ; value (CX)  INMODEM: PUSH BX MOV BX,33 ;about 100 milliseconds CALL FIXCNT MOV CH,BH ;delay is in 'BX' MOV CL,BL ;transfer to 'BC' POP BX ;get original value of 'BX' back ; INMODEM1: CALL RCVREADY ;see if there is a character ready JNZ INMRAM ;see if at top of buffer yet CMP AL,BH JNZ L4A28 CALL P_CTL_S ;if different, buffer is not full L4A28: RET ;..... ; ; ; Memory buffer is full, send a X-OFF (CTL-S, DC3), save any extra in- ; coming characters, then dump to disk, resDW 0 ; value (DX) ; ; ;..... ; ; ; List the character on the printer if it is ready, then see if at the ; top of the buffer. ; GOLIST: CALL LISTST ;get the printer status OR AL,AL JNZ L4A30 RET ;return if printer not ready ; ; ; ComODEM2 ;if no character, exit CALL IN_MODDATP ;get the character AND AL,7FH ;strip off any parity RET ;return with character in 'A' reg. ; INMODEM2: DEC CX ;otherwise keep timing MOV AL,CH OR AL,CL JNZ INMODEM1 ;loop until timeout et buffer to include those ; characters. ; P_CTL_S:CALL SENDNOW ;wait until modem is ready MOV AL,XOFF ;send a ctl-s to stop remote computer CALL OUT_MODDATP MOV BX, Offset BUFFPNT ;address of aux. buffer CALL GETDSK ;put any extra chars. pare input and output pointers. If at same address, nothing to ; print. ; L4A30: CALL CMP_I_O ;if the same, nothing to print JNZ GOLIST1 RET ; ; ; If not the same, print the character ; GOLIST1:PUSH BX ;save current buffer address MOV DLif needed STC ;shows a timeout occured RET ;..... ; ; ; Send a space tone to the phone line for a short time. ; BREAK: MOV AL,Byte Ptr PMMIMODEM ;using the PMMI modem? OR AL,AL JZ BREAK1 ;if not, exit MOV AL,Byte Ptr MODCTLB ;getinto aux. buffer MOV AL,DH ;get the aux. buffer char. count MOV Byte Ptr DSTORE,AL ;save for later RET ;..... ; ; ; Output has now caught up to the input and both are at top of buffer ; P_CTL_S1: MOV AL,Byte Ptr DSTORE ;get the aux. bu,Byte Ptr [BX] ;get the character to display MOV CL,BLIST ;list routine INT 224 POP BX ;restore current buffer address INC BX ;increment pointer for next position MOV Word Ptr HLSAVE2,BX ;store for next time through here ; ; ; See if t the last modem control byte AND AL,BRKMSK ;set the transmit break bit low CALL OUT_MODCTL2 ;send it to the modem MOV CH,2 CALL TIMER ;send a space tone for 200 ms. MOV AL,Byte Ptr MODCTLB ;get the last modem control byte CALL OUT_MODCTLffer char. count MOV DH,AL ;put into 'D' reg. XOR AL,AL ;set 'A' to zero CMP AL,DH ;see if any count in 'D' MOV BX, Offset PBUFF ;address at start of printer buffer JZ P_CTL_Q ;if nothing, exit and continue MOV CX, Offset BUFFPNT ;addrehe output is at the end of the buffer now. If yes, go put ; the auxiliary characters into the start of the buffer. ; MOV AL,Byte Ptr MAXRAM ;check for end of buffer area CMP AL,BH JNZ L4A32 JMP P_CTL_S1 ;if at end, restore aux. buffer L4A32 ;restore to normal JMP TERM ;back to work ;... ; ; BREAK1: CALL JMP_BREAK ;get the user'S BREAK ROUTINE JMP TERM ;back to work ;..... ; ; ;======================================================================= ; WRITE BUFFER TOss of aux. buffer ; ; ; Move the characters from the aux. buffer to the main buffer and display ; P_CTL_S2: MOV SI,CX ;get the character there MOV AL,[SI] MOV Byte Ptr [BX],AL ;store in main buffer CALL STYPE ;show on CRT PUSH BX PUSH2: ; ; ; See if the output has caught up with the input - if so, reset the ; pointers to the start of the buffer ; CALL CMP_I_O JZ L4A33 RET ;if not, back to work L4A33: MOV BX, Offset PBUFF ;if output caught input, reset both.. MOV Word;  DISK ; ; Make sure this record is included in the count. ; WRTDSK: MOV BX,Word Ptr HLSAVE MOV Byte Ptr [BX],EOFCHAR ;ascii file, store end-of-file char. MOV DX,127 ADD BX,DX ; WRTDSK1:MOV DX,-( Offset BUFFER) ;subtract the start of the buffer.gs, return to menu ;..... ; ; ; Show you are in memory-save for disk write ; TYPESCLN: MOV AL,';' JMP STYPE ;show on CRT, return ;..... ; ; ; Save the registers, call BDOS then restore the registers ; BDOSRT: PUSH CX PUSH DX PUSH BX V Byte Ptr [BX],CH RET ;..... ; ; CKCPM2: MOV CL,CPMVER ;bdos 12 -- version number -- cp/m 2.2? INT 224 OR AL,AL JNZ L5A2 RET L5A2: MOV CL,SETDMA MOV DX, Offset TBUF INT 224 MOV CL,SRCHF MOV DX, Offset FCB INT 224 CMP AL,0FFH . ADD BX,DX ;by adding a minus number to buffer end MOV AL,BL ;divide hl by 128.. OR AL,AL RCL AL,1 ;..to get the.. MOV BL,BH ;..number of records MOV BH,0 LAHF XCHG AL,AH PUSH AX SHL BX,1 POP AX XCHG AL,AH SAHF MOV AL,0 INT 224 POP BX POP DX POP CX RET ;..... ; ; INITFCB:MOV Byte Ptr [BX],0 ;entry at +2 will leave drive # intact L4A6: INC BX ;will initialize an FCB.. MOV CH,11 ;..pointed to by BX-reg. fills 1st pos. ; LOOP11: MOV Byte Ptr [BX],' '  JNZ L5A3 RET L5A3: ; CALL GETADD MOV DX,9 ADD BX,DX ;point to R/O attribute byte MOV AL,Byte Ptr [BX] AND AL,80H ;test most significant byte JNZ MKCHG ;if set, make change INC BX ;check system attribute byte MOV AL,Byte Ptr [B ADC AL,BL MOV BL,AL ;number of records in 'BX' ; ; ; See if buffer is empty. If yes, see if we need to erase an empty ; file or have already written something. ; MOV DX, Offset BUFFER MOV SI,DX MOV AL,[SI] CMP AL,EOFCHAR ;'EOF' in fir;..with 0, next 11 with.. INC BX ;..blanks, and last.. DEC CH ;..21 with nulls. JNZ LOOP11 MOV CH,21 ; LOOP21: MOV Byte Ptr [BX],0 INC BX DEC CH JNZ LOOP21 RET ;..... ; ; ; Scans CMDBUF coutning names and putting delimiter (space)X] AND AL,80H JNZ L5A4 RET ;not $SYS or $R/O attribute L5A4: DEC BX ; MKCHG: MOV DX,-8 ADD BX,DX ;point BX to filename + 1 MOV DX, Offset FCB+1 ;move directory name to FCB.. MOV CH,11 ;..without changing drive. CALL MOVE MOV BX,st address means.. JNZ WRTDSK2 ;..nothing in buffer to write MOV AL,Byte Ptr WRFLG ;first time by this way? OR AL,AL JZ NOWRITE ;if yes, show erasing file RET ;otherwise go close file ;..... ; ; ; Write to disk. Start from BUFFE after last ; name ; SCAN: PUSH BX MOV BX, Offset NAMECT MOV Byte Ptr [BX],0 MOV BX, Offset CMDBUF+1 ;find end of cmd line.. MOV CL,Byte Ptr [BX] ;..and put space there. MOV CH,0 MOV BX, Offset CMDBUF+2 LAHF ADD BX,CX RCR SI,1 SAHF  Offset FCB+9 ;R/O attribute MOV AL,Byte Ptr [BX] AND AL,7FH ;strip R/O attribute MOV Byte Ptr [BX],AL INC BX ;system attribute MOV AL,Byte Ptr [BX] AND AL,7FH MOV Byte Ptr [BX],AL MOV DX, FCB MOV CL,30 ;set new attributes in directR (in 'DE'). Number of records to ; write in 'BX'. ; WRTDSK2:MOV CL,SETDMA CALL BDOSRT PUSH DX MOV CL,WRITE MOV DX, Offset FCB3 ;location of filename to write to CALL BDOSRT POP DX OR AL,AL JNZ WRTDSK2A ;error if disk is full ** specia RCL SI,1 MOV Byte Ptr [BX],' ' MOV BX, Offset CMDBUF+1 MOV CH,Byte Ptr [BX] INC CH INC CH ; SCANLP1:LAHF INC BX SAHF DEC CH JZ DNSCAN MOV AL,Byte Ptr [BX] CMP AL,' ' JNZ SCANLP1 ; SCANLP2:LAHF ;eat extra spaces INC BX SAory INT 224 ; ; Called by 'CKBAKUP' below, return done here . ; PLANCHG:MOV BX, FCB ;change name to type "BAK" MOV DX, FCB2 MOV CH,9 ;move drive and name (not type) CALL MOVE MOV BX,75H ;start of type in FCB2 MOV Byte Ptr [BX],'B' l patch XCHG BX,DX ;put the current address in 'BX'.. PUSH DX ;..and number of records left in.. MOV DX,128 ;..for now ADD BX,DX ;add for next record write, now in 'BX' POP DX ;restore number of records left XCHG BX,DX ;records to 'HF DEC CH JZ DNSCAN MOV AL,Byte Ptr [BX] CMP AL,' ' JZ SCANLP2 MOV Word Ptr BGNMS,BX ;save start of names in cmdbuf INC CH LAHF DEC BX SAHF ; SCANLP3:LAHF INC BX SAHF DEC CH JZ DNSCAN MOV AL,Byte Ptr [BX] CMP AL,' '  INC BX MOV Byte Ptr [BX],'A' INC BX MOV Byte Ptr [BX],'K' MOV DX, FCB2 MOV CL,ERASE ;erase any previous backups INT 224 MOV BX, FCB2 ;FCB2 drive field should.. MOV Byte Ptr [BX],0 ;..0 for rename. MOV DX, FCB MOV CL,23 ;rename IBX' again, address to 'DE' DEC BX ;one less record left MOV AL,BH OR AL,BL ;done writing when 'H' and 'H' both zero JNZ WRTDSK2 ;otherwise do another disk write RET ; WRTDSK2A: JMP WRERRSP ;..... ; ; ; Error while writing a reco JNZ SCANLP3 MOV AL,Byte Ptr NAMECT ;counts names INC AL MOV Byte Ptr NAMECT,AL ; SCANLP4:LAHF ;eat spaces INC BX SAHF DEC CH JZ DNSCAN MOV AL,Byte Ptr [BX] CMP AL,' ' JZ SCANLP4 JMPS SCANLP3 ;..... ; ; DNSCAN: MOV Byte PNT 224 RET ;..... ; ; CKBAKUP:MOV AL,Byte Ptr BAKUPBYTE OR AL,AL JNZ L5A5 RET L5A5: MOV CL,SRCHF MOV DX, FCB INT 224 INC AL JNZ L5A6 RET ;file not found L5A6: JMPS PLANCHG ;in 'CKCPM2' - ret done there ;..... ; ; ;*****rd, show why it is aborting ; WRERR: MOV CL,CANCEL ;send cancel char. to sending station CALL SEND CALL CLOSFIL ;close the current file WRERR1: CALL ERXIT ;also will reset stack DB '++ DISK FULL, SAVING PARTIAL FILE ++','$' ;..... ; ; ; Itr [BX],' ' ;space after last char POP BX RET ;..... ; ; ; Places next name in buffer so 'CMDLINE' may parse it ; TRTOBUF:MOV BX,Word Ptr BGNMS MOV CH,0 MOV DX, Offset FCBBUF+2 ; TBLP: MOV AL,Byte Ptr [BX] CMP AL,' ' JZ TRBFEND MOV SI****************************************************************** ; ; RECEIVE A RECORD FROM SENDING STATION ; ;*********************************************************************** ; ; If CRC is in effect, there is a 10-second timeout to the ff no data to store on the disk, close the empty file and erase it ; NOWRITE:CALL WRTFIL2 ;close the empty file CALL NOASK ;erase the empty file CALL ILPRT DB '++ Nothing to save, erasing file ++' DB CR,LF,BELL,0 JMP DONETCA ;reset any fla,DX MOV [SI],AL INC BX INC DX INC CH ;count chars in name JMPS TBLP ;..... ; ; TRBFEND:INC BX MOV AL,Byte Ptr [BX] ;eat extra spaces CMP AL,' ' JZ TRBFEND MOV Word Ptr BGNMS,BX MOV BX, Offset FCBBUF+1 ;put # chars before name MO; irst SOH. ; It then tries six more times to let the sender know the system is ; capable of receiving a 'CRC' check. At the end of that time a NAK is ; sent which tells the sender to use CHECKSUM checking instead of CRC. ; This allows automatic compa,0 ; RCVPRN: CALL SHOWERR ;display error count ; RCVSERR:CALL WAITQ1 ;wait for 1 second with no characters CALL CKABORT ;want to stop receiving now? MOV AL,Byte Ptr CRCFLAG ;get 'CRC' flag OR AL,AL ;'CRC' in effect? MOV AL,NAK ;put'++ Bad record # in header ',0 JMP RCVPRN ; RCVDATA:MOV AL,DH MOV Byte Ptr RCVRNO,AL MOV AL,1 MOV Byte Ptr DATAFLG,AL MOV CL,0 MOV BX,0 MOV Word Ptr CRCVAL,BX MOV BX,80H ; RCVCHR: MOV CH,5 ;Wait up to 5 seconds for a character CALL tability with systems implementing CRC - ; (Cyclic Redundancy Checking). The search for SOH will cycle through ; one record interval and ignore noise or characters sent by the remote ; for any purpose (such as progress reporting). So extraneous charac 'NAK' in 'A' reg. JZ RCVSER1 ;no, send the 'NAK' MOV AL,Byte Ptr FIRSTME ;get first time switch OR AL,AL ;has first 'SOH' been received? MOV AL,NAK ;put 'NAK' in 'A' reg. JNZ RCVSER1 ;yes, then send 'NAK' MOV AL,CRC ;tell sender 'RECV JNB L5A18 JMP RCVSTOT L5A18: MOV Byte Ptr [BX],AL INC BL JNZ RCVCHR XOR AL,AL MOV Byte Ptr DATAFLG,AL MOV AL,Byte Ptr CRCFLAG OR AL,AL JNZ RCVCRC MOV DH,CL MOV CH,5 ;wait up to 5 seconds for an answer CALL RECV JNB L5A19ters ; that are sometimes sent by remote-end protocol will be gobbled up until ; the first SOH. EOT is tested only as the first returned character af- ; ter each sector. ; SRCHSOH EQU 160 ;number of times to loop search for SOH ; RCVRECD:MOV AL,1CRC' is in effect ; RCVSER1:CALL SEND ;..the 'NAK' or 'CRC' request MOV AL,Byte Ptr ERRCT ;abort if we have reached error limit INC AL MOV Byte Ptr ERRCT,AL ;store for next time CMP AL,ERRLIM ;see if at limit yet JNB L5A11 JMP RC JMP RCVSTOT L5A19: CMP AL,DH JNZ RCVCERR ; CHKSNUM:MOV AL,Byte Ptr RCVRNO MOV CH,AL MOV AL,Byte Ptr RECDNO CMP AL,CH JZ RECVACK INC AL CMP AL,CH JZ L5A20 JMP ABORT L5A20: RET ;..... ; ; RCVCRC: MOV DL,2 ;number of 'CRC' b MOV Byte Ptr ERRCT,AL ;initialize the error count ; RCVSQ: MOV CH,10 ;10 seconds allowed to receive 1st char. MOV DX,SRCHSOH ;initialize loof for up to 160 secs. CALL RECV ;get the 1st character JNB L5A7 JMP RCVSTOT ;timeout errorVSQ ;if not, keep going L5A11: MOV AL,Byte Ptr RETRY ;see if retry after 10 errors is set OR AL,AL JNZ L5A12 JMP ABORT ;if 'YES', abort L5A12: JMP CKQUIT ;if 'NO' check for continued use RCVSABT:MOV SP,STACK ;reset the stack justytes ; RCVCRC2:MOV CH,5 ;wait up to 5 seconds for a character CALL RECV JNB L5A21 JMP RCVSTOT L5A21: DEC DL JNZ RCVCRC2 CALL CRCCHK OR AL,AL JZ CHKSNUM MOV AL,Byte Ptr QFLG OR AL,AL JNZ L5A22 JMP RCVSERR L5A22: ; RCVCRER:CAL if not rcvd in 10 seconds L5A7: MOV CL,AL ;save the character for now CMP AL,EOT ;see if end of transmission STC ;set carry JNZ L5A8 RET ;return with carry set L5A8: ; SOHLUP: MOV AL,0FFH MOV Byte Ptr CHRFLG,AL MOV Byte Ptr TIM in case CALL CLOSFIL ;close the partial file CALL NOASK ;delete partial file CALL ILPRT DB CR,LF,LF DB '++ RECEIVED FILE CANCELLED ++',CR,LF,BELL DB '++ UNFINISHED FILE DELETED ++',CR,LF,0 JMP DONETCA RCVSTOT:MOV AL,Byte Ptr QFLG ORL ILPRT DB '++ CRC error ',0 JMP RCVPRN ; RCVCERR:MOV AL,Byte Ptr QFLG OR AL,AL JNZ RCVCPR JMP RCVSERR ; RCVCPR: CALL ILPRT DB '++ CHECKSUM error ',0 JMP RCVPRN ; RECVACK:CALL SENDACK JMP RCVRECD ; ; ; Get the error count and displFLG,AL MOV AL,DL ;get search count-down value CMP AL,SRCHSOH ;see if it is the 1st returned character MOV AL,CL ;get the first character now JZ NORECV ;skip RECV routine if 1st character MOV CH,1 CALL RECV MOV CH,AL JNB TSTSOH ; NO AL,AL JZ RCVSCRC ; RCVSPT: CALL ILPRT DB CR,LF,'++ Timeout ',0 CALL SHOWERR ; RCVSCRC:CALL RCVSCRC2 JMP RCVSERR ; ; ; Routine will switch from 'CRC' to Checksum if 'ERCNT' reaches 'ERRCRC' ; and 'FIRSTIME' is false ; RCVSCRC2: MOV AL,Bay on CRT ; SHOWERR:PUSH BX MOV BX,Word Ptr ERRCT MOV BH,0 CALL DECOUT POP BX CALL ILPRT DB ' ++',CR,LF,0 MOV AL,Byte Ptr ERRCT CMP AL,ERRLIM JNAE L5A24 JMP ABORT L5A24: RET ;..... ; ; SENDHDR:MOV AL,Byte Ptr QFLG OR AL,AL RECV: MOV CH,AL XOR AL,AL ;else set the value that forces timeoutw MOV Byte Ptr CHRFLG,AL ; TSTSOH: MOV AL,CH ;get the character CMP AL,SOH ;see if it is SOH LAHF XCHG AL,AH PUSH AX XCHG AL,AH XOR AL,AL MOV Byte Ptr TIMFLG,AL yte Ptr ERRCT CMP AL,ERRCRC JZ L5A13 RET L5A13: MOV AL,Byte Ptr FIRSTME OR AL,AL JZ L5A14 RET L5A14: MOV AL,Byte Ptr CRCFLAG OR AL,AL JNZ L5A15 RET L5A15: NOT AL MOV Byte Ptr CRCFLAG,AL MOV Byte Ptr CRCDFLT,AL CALL ILPRTQ  JZ SENDHNM CALL ILPRT DB CR,'Sending # ',0 PUSH BX ;store current address MOV BX,Word Ptr RECDNO ;get record number CALL DECOUT ;print it in decimal CALL ILPRT DB ' ',0 ; MOV AL,Byte Ptr HEXSHOW OR AL,AL JZ L5A25 CALL ILPRT ;restore this flag POP AX XCHG AL,AH SAHF JNZ L5A9 JMP RCVSOH ;got SOH, get rcd # and its complement L5A9: MOV AL,DH OR AL,DL ;see if counted-down to zero LAHF DEC DX SAHF JNZ SOHLUP ;go around again if not MOV AL,Byte Ptr  DB '** Switching to Checksum mode **',CR,BELL,LF,0 RET ;..... ; ; ; Got SOH - get block #, block # complemented ; RCVSOH: MOV AL,0FFH MOV Byte Ptr FIRSTME,AL ;indicate 1st soh was received MOV CH,5 ;timeout = 5 seconds CALL RECV ;get  DB '(',0 CALL DHXOUT ;16 bit hex conversion & output CALL ILPRT DB 'H) ',0 L5A25: ; POP BX ;restore current address ; SENDHNM:MOV AL,SOH ;send 'SOH' character to the output CALL SEND MOV AL,Byte Ptr RECDNO ;send record number toCHRFLG ;see if timeout needs to be forced OR AL,AL JNZ L5A10 JMP RCVSTOT ;go do timeout and countthem L5A10: MOV AL,Byte Ptr QFLG OR AL,AL JZ RCVSERR ; RCVSEH: CALL CRLF MOV AL,CH CALL HEXO CALL ILPRT DB 'H received not SOH - 'record JB RCVSTOT ;got timeout MOV DH,AL MOV CH,5 ;timeout = 5 seconds CALL RECV JNB L5A16 JMP RCVSTOT L5A16: NOT AL CMP AL,DH JZ RCVDATA MOV AL,Byte Ptr QFLG OR AL,AL JNZ RCVBSE JMP RCVSERR ; RCVBSE: CALL ILPRT DB CR,LF,<  the output CALL SEND MOV AL,Byte Ptr RECDNO NOT AL ;complement the record number JMP SEND ;send this value to the output ;..... ; ; SENDREC:MOV AL,1 MOV Byte Ptr DATAFLG,AL MOV CL,0 MOV BX,0 ;new record, clear 'CHECKSUM' value MO ACKERR1 RET ;if not, return ; ACKERR1:CALL ERXIT DB CR,LF,'++ SEND-FILE CANCELLED ++','$' ;..... ; ; ; Reached error limit ; GETATOT:CALL ILPRT DB CR,'++ TIMEOUT - no ACK - ',0 CALL SHOWERR ;display error count JMPS ACKERR ;..... herwise erase the file ; NOASK: MOV DX, FCB MOV CL,ERASE INT 224 RET ;..... ; ; ERRORW: POP BX ;restore stack from "call ERASFIL" CALL ILPRT DB '++ NO WILDCARDS ALLOWED FOR TEXT FILES ++' DB CR,LF,BELL,0 JMP MENU ;..... ; ; BLKFILV Word Ptr CRCVAL,BX ;new record, clear 'CRC' value MOV BX, Offset TBUF ;store at 0080H ; SENDC: MOV AL,Byte Ptr [BX] CALL SEND INC BL JNZ SENDC XOR AL,AL MOV Byte Ptr DATAFLG,AL RET ;..... ; ; SENDCKS:MOV AL,CL JMP SEND ;..... ; ; ; CKABORT:MOV AL,Byte Ptr QFLG OR AL,AL JNZ L5A29 RET L5A29: CALL STAT JNZ L5A30 RET L5A30: CALL KEYIN CMP AL,CANCEL JZ ABORT RET ; ; ; Aborts send or receive routines and returns to command line ; ABORT: MOV SP, Offset STACKE:CALL ILPRT ;no file named for send or receive DB '++ NO FILE SPECIFIED ++',CR,LF,BELL,0 JMP MENU ;..... ; ; MAKEFIL:MOV DX, FCB MOV CL,MAKE INT 224 INC AL JZ L5A35 RET L5A35: CALL ERXIT DB '++ ERROR -- Can''t open file ++',CR,LF ; SENDCRC:PUSH BX MOV BX,Word Ptr CRCVAL MOV AL,BH CALL SEND MOV AL,BL CALL SEND POP BX XOR AL,AL ;reset the carry bit RET ;..... ; ; ; After a record is sent, a character is returned telling if it was re- ; ceived properly or not.  ; ABORTL: MOV CH,1 ;1-second delay to clear input CALL RECV JNB ABORTL MOV AL,CANCEL ;show you are cancelling CALL SEND ; ABORTW: MOV CH,1 ;1-second delay to clear input CALL RECV JNB ABORTW MOV AL,' ' CALL SEND MOV AL,'B' ;tu DB '++ Directory is perhaps full ++','$' ; CNREC: MOV CL,FILSIZ ;compute file size function in cp/m 2.x MOV DX, FCB ;point to file control block INT 224 MOV BX,Word Ptr .FCB+33 ;get record count MOV Word Ptr RCNT,BX ;store it MOV BX,0 ;z An ACK allows the next record to be sent. A ; NAK causes the current record to be resent. If no character (or any ; character other than ACK or NAK) is received after a short wait (10 ; to 12 seconds), a timeout error message is shown and the record rn multi-file mode.. MOV Byte Ptr BATCHFLG,AL ;..off so routine ends. MOV Byte Ptr ABORTFLG,AL ;shows an abort was made XOR AL,AL MOV Byte Ptr NFILFLG,AL ;stop copy into memory for disk file MOV AL,Byte Ptr OPTION ;receiving a file nowero 'BX' MOV Word Ptr .FCB+33,BX ;reset random record in FCB RET ;..... ; ; OPENFIL:XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV DX, FCB MOV CL,OPEN INT 224 INC AL JZ L5A36 JMP SENDTIME ;send transfer time, # of records, etc. L5A36: CALLwill ; be resent. The GETACK routine can gobble up a string of up to 191 ; characters while searching for an 'ACK' or a 'NAK'. ; GETACK: MOV DL,192 ;number of characters to gobble ; ACKLUP: MOV AL,0FFH MOV Byte Ptr CHRFLG,AL ;set the charact? CMP AL,'R' JNZ L5A32 JMP RCVSABT ;if yes, cancel the unfinished file L5A32: CALL ILPRT DB CR,LF,LF,'++ FILE CANCELLED ++',CR,LF,BELL,0 JMP DONETCA ;..... ; ; ; Increment the record count ; INCRRNO:PUSH BX MOV BX,Word Ptr RECDNO  ERXIT ;file did not open DB '++ FILE NOT FOUND ++','$' ;..... ; ; CLOSFIL:MOV DX, FCB ;get the file name MOV CL,CLOSE INT 224 ; close the file INC AL JZ L5A37 RET L5A37: JMP ERXIT1 ;no file to close, exit ;..... ; ; ; Updater flag MOV Byte Ptr TIMFLG,AL ;set the time flag MOV CH,1 CALL RECV MOV CH,AL ;save the character JNB ACKTST XOR AL,AL MOV Byte Ptr CHRFLG,AL ;reset the character flag, was none ; ACKTST: XOR AL,AL MOV Byte Ptr TIMFLG,AL MOV  ;get record number LAHF ;bump it INC BX SAHF MOV Word Ptr RECDNO,BX ;store it MOV AL,BL POP BX RET ;..... ; ; ; First check for any wild cards and disallow, just to be safe. Do not ; want a group of files being accidently erasede record read ; RDRECD: MOV AL,Byte Ptr RECINBF ;decrement 'RECORDS IN BUFFER' count DEC AL MOV Byte Ptr RECINBF,AL JS RDBLOCK MOV BX,Word Ptr RECPTR ;find where last move stopped MOV DX,128 CALL MOVE128 ;move 128 characters MOV WoAL,CH ;get the character back CMP AL,ACK JNZ L5A26 RET L5A26: CMP AL,NAK JZ GETACK1 ; NOAKNK: DEC DL ;one less to go JNZ ACKLUP ;loop around again if not zero MOV AL,Byte Ptr CHRFLG OR AL,AL JNZ GETACK1 JMP GETATOT ; GETACK1:. ; ERASFIL:MOV BX, FCB ;file name is stored here MOV CH,11 ;maximum of 11 chars for filename.ext ; ERASFIL1: INC BX ;next location in file name MOV AL,Byte Ptr [BX] ;get the char. CMP AL,'?' ;check for any wild card chars. JZ ERRORW rd Ptr RECPTR,BX ;store new address for next move RET ;..... ; ; ; Buffer empty so read in another block from the disk ; RDBLOCK:MOV AL,Byte Ptr EOFLG CMP AL,1 STC JNZ L5A38 RET L5A38: MOV CL,0 MOV DX, Offset BUFFER ; RDRECLP:PUSMOV AL,Byte Ptr BENHERE XOR AL,CH JZ ACKER0 ;do not say 'ACK error' if 1st 'NAK' MOV AL,Byte Ptr QFLG OR AL,AL JZ ACKERR CALL ILPRT DB '++ ',0 MOV AL,CH CMP AL,NAK JZ GETACK3 CALL HEXO CALL ILPRT DB 'H',0 JMPS GETACK4 ; GETA ;error if one is found DEC CH ;number of tries left JNZ ERASFIL1 ;if not zero, keep checking MOV AL,Byte Ptr BATCHFLG ;don't ask for erase.. OR AL,AL ;..in multi-file mode,.. JZ NOASK ;..just do it. MOV DX, FCB MOV CL,SRCHF INT 2H CX PUSH DX MOV CL,SETDMA INT 224 MOV DX, FCB MOV CL,READ INT 224 POP DX POP CX OR AL,AL JZ RDRECOK DEC AL JZ REOF CALL ERXIT DB '++ FILE READ ERROR ++','$' ; RDRECOK:MOV BX,128 LAHF ADD BX,DX RCR SI,1 SAHF RCL SI,1CK3:CALL ILPRT DB 'NAK',0 ; GETACK4:CALL ILPRT DB ' received not ACK - ',0 CALL SHOWERR ; ACKER0: XOR AL,AL MOV Byte Ptr BENHERE,AL ; ACKERR: MOV AL,Byte Ptr ERRCT INC AL MOV Byte Ptr ERRCT,AL CMP AL,ERRLIM+1 ;at error limit yet? JNB24 INC AL JNZ L5A33 RET ;file erased ok, return L5A33: CALL ILPRT ;otherwise make sure it'S OK DB 'File exists - erase? (Y/N): ',BELL,0 CALL KBDCHR CMP AL,'Y' JZ L5A34 JMP MENU ;if not a 'Y' do not erase L5A34: CALL CRLF ;ot<  XCHG BX,DX INC CL CALL DSKSIZ ;establish buffer size JZ RDBFULL JMPS RDRECLP ;... ; ; REOF: MOV AL,1 MOV Byte Ptr EOFLG,AL MOV AL,CL ; ; ; Buffer full or received "End Of File (EOF)" ; RDBFULL:MOV Byte Ptr RECINBF,AL MOV BX, Off will delete any line noise induced characters LONG before ; the ACK/NAK would be received. ; RECVDG: CALL CKCHAR ;catch any garbage characters ; RECV: PUSH DX ; ; ; Get back quickly to gobble 2nd character if TIMFLG is set by the GETNM ; routin; Waits for the first character received while waiting to send a file. ; If a character is not received in one second, it loops again until a ; char. is received or it times out. The count is set for two minutes ; before timeout. This gives the receivset BUFFER MOV Word Ptr RECPTR,BX MOV CL,SETDMA MOV DX, Offset TBUF INT 224 JMP RDRECD ;..... ; ; ; Write a record ; WRRECD: MOV BX,Word Ptr RECPTR XCHG BX,DX MOV BX,128 CALL MOVE128 XCHG BX,DX MOV Word Ptr RECPTR,BX ;new recoe - or just step through quickly after the first wait for 'SOH' ; in the 'SOHLUP' routine. ; MSEC: PUSH BX MOV BX, Offset TIMFLG MOV DL, Byte Ptr [BX] INC DL MOV BX,Word Ptr QUIKTIM JZ DOQUIK MOV BX,Word Ptr TIMVAL ; DOQUIK: XCHG BX,DX Ping station ample time to name ; a file, etc. ; WAITNAK:CALL ILPRT DB 'Waiting ready signal',CR,LF,0 CALL CRLF ; WAITNLP:CALL CKABORT MOV CH,1 ;wait up to 1 second for a character CALL RECV CMP AL,CANCEL ;want to quit? JNZ L5A42 JMP rd pointer MOV AL,Byte Ptr RECINBF ;increment 'RECORDS IN BUFFER' count INC AL MOV Byte Ptr RECINBF,AL MOV CL,AL ;store the record count for now CALL DSKSIZ ;establish buffer size JZ WRBLOCK RET ;buffer not full, return ; ; ; WriOP BX ; MWTI: CALL RCVREADY JZ MCHAR MOV AL,DH OR AL,DL LAHF DEC DX SAHF JNZ MWTI DEC CH JNZ MSEC POP DX CALL CKABORT STC RET ;..... ; ; ; Get the character from the modem, but filter out 'ACK' and '.' chars. ; if recievingABORT L5A42: CMP AL,CRC ;'CRC' request? JZ WAITCRC ;yes, go set 'CRC' flag CMP AL,NAK JZ WAITCHK DEC DL JNZ WAITNLP JMP ABORT ;... ; ; WAITCRC:CALL ILPRTQ DB 'CRC request received',CR,LF,0 MOV AL,1 MOV Byte Ptr CRCFLAG,AL ;mte a block to disk ; WRBLOCK:MOV AL,Byte Ptr RECINBF ;get the number of records in the buffer OR AL,AL JNZ L5A40 RET ;if zero, don't try to move to disk L5A40: MOV CL,AL ;otherwise store in 'C' reg. MOV DX,Offset BUFFER ;start of buffe a file name. ('FILTRFLG' is set by the 'GETNM' routine.) ; MCHAR: CALL IN_MODDATP ;get the character that is waiting POP DX LAHF ;save the character for later use also XCHG AL,AH PUSH AX XCHG AL,AH CMP AL,ACK ;see if it is 'ACK' JZ ake sure in 'CRC' mode then RET ;..... ; ; WAITCHK:MOV AL,Byte Ptr BATCHFLG ;in batch mode? OR AL,AL JNZ L5A43 RET L5A43: CALL ILPRTQ DB 'Got checksum request',CR,LF,0 RET ;..... ; ; WAITCHK1: CALL ILPRTQ DB 'Name NAK received'r to move to disk ; DSKWRT: PUSH CX PUSH DX PUSH BX MOV CL,SETDMA INT 224 MOV CL,WRITE MOV DX, FCB INT 224 POP BX POP DX POP CX OR AL,AL JZ L5A41 JMP WRERR ;error if disk is full L5A41: MOV BX,128 ;add in another page AISACK CMP AL,'.' ;see if it is a period JNZ DOUPD ;neither, so update 'CRC' ; ISACK: PUSH BX PUSH DX MOV BX,Offset FLTRFLG ;see if need to each 'ACK' or period MOV DL,Byte Ptr [BX] INC DL POP DX POP BX JZ MWTI ;yes, so do i,CR,LF,0 RET ;..... ; ; ; Finished with the file transfer ; DONE: MOV AL,Byte Ptr BATCHFLG ;in batch mode? OR AL,AL JZ L5A44 JMP DONETC ;exit if not L5A44: MOV AL,Byte Ptr QFLG OR AL,AL JNZ L5A45 JMP NMSTRNS L5A45: MOV CH,12 DD BX,DX XCHG BX,DX DEC CL ;one less record left to move to disk JNZ DSKWRT XOR AL,AL MOV Byte Ptr RECINBF,AL ;zero the 'RECORDS IN BUFFER' count MOV BX, Offset BUFFER ;reset location to next buffer start MOV Word Ptr RECPTR,BX RET ;.t ; DOUPD: CALL CRCUPD ;calculate 'CRC' ADD AL,CL MOV CL,AL MOV AL,Byte Ptr RSEEFLG OR AL,AL JZ MONIN MOV AL,Byte Ptr VSEEFLG OR AL,AL JNZ NOMONIN MOV AL,Byte Ptr DATAFLG OR AL,AL JZ NOMONIN ; MONIN: POP AX ;get the character  ;zero out FTRNMSG MOV BX,(Offset FTRNMSG) MOV AL,0 ; ZEROLP: MOV Byte Ptr [BX],AL INC BX DEC CH JNZ ZEROLP MOV CH,12 ;put file name in FTRNMSG MOV BX, FCB+1 MOV DX,(Offset FTRNMSG) ; LOADMSG:MOV AL,4 ;start of file type? CMP AL,C.... ; ; ; Determine if the buffer size is for file transfer or for ASCII capture ; to disk then compare with current record length ; DSKSIZ: MOV AL,Byte Ptr XFLG ;see if transferring files now OR AL,AL MOV AL,CL ;get the current record cagain XCHG AL,AH SAHF LAHF ;resave it for later use also XCHG AL,AH PUSH AX CALL CKABORT ;show the character on the CRT ; NOMONIN:CALL CKABORT POP AX ;get the character back once more XCHG AL,AH OR AL,AL ;reset the carry flag H JZ PERIOD ;put in period if so MOV AL,Byte Ptr [BX] CMP AL,' ' ;don't put in space JZ SKPSP MOV SI,DX ;store in FTRNMSG MOV [SI],AL INC DX ; SKPSP: INC BX DEC CH MOV AL,CH OR AL,AL ;end of file name? JZ FTRNMSG0 ;display ount JZ DSKSIZ1 ;if yes, exit MOV AL,CL CMP AL,BUFSIZ*8 ;buffer size for ASCII capture to disk RET ;return with flag set for the compare ;... ; ; DSKSIZ1:MOV AL,Byte Ptr SAVSIZ ;get the file transfer buffer size.. CMP AL,CL ;..fro RET ;return with the character and flag set ;..... ; ; ; Send a character to the modem ; SEND: PUSH AX MOV AL,Byte Ptr SSEEFLG OR AL,AL JZ MONOUT MOV AL,Byte Ptr VSEEFLG OR AL,AL JNZ NOMONOT MOV AL,Byte Ptr DATAFLG OR AL,AL JZ Nfile name JMPS LOADMSG ;loop for another character ;..... ; ; PERIOD: MOV AL,Byte Ptr [BX] CMP AL,' ' ;is file type empty? JZ FTRNMSG0 ;go if so MOV AL,'.' ;else put period in message MOV SI,DX MOV [SI],AL INC DX DEC CH JMPS LOm special storage area and compare RET ;return with flag set for the compare ;..... ; ; ; Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage ; characters on the line. For example, having just sent a record, cal- ; ling RECVDGOMONOT ; MONOUT: POP AX PUSH AX CALL SHOW ; NOMONOT:POP AX PUSH AX CALL CRCUPD ;update the 'CRC' calcuation ADD AL,CL MOV CL,AL ; SENDW: CALL SENDRDY JNZ SENDW POP AX JMP OUT_MODDATP ;send character to modem, done ;..... ; ; = ADMSG ;..... ; ; FTRNMSG0: CALL ILPRT DB CR,LF ; FTRNMSG RS 12 DB 0 CALL ILPRT DB ' Transferred',CR,LF,LF,BELL,0 ; NMSTRNS:MOV AL,Byte Ptr .FCB ;save drive no. MOV Byte Ptr DISKNO,AL MOV BX, FCB ;blank out file control blocks Cl mode ;..... ; ; DONETCD:CALL ILPRT DB CR,LF,'<< DISCONNECTED >>',BELL,CR,LF,0 CALL JMP_GOODBYE ;set 'DTR' low for 300 ms. MOV AL,Byte Ptr PMMIMODEM OR AL,AL JZ L6A6 CALL JMP_DISCONNT L6A6: MOV AL,Byte Ptr AUTODIAL ;using a Hayes-typCHG BX,DX MOV AL,BH OR AL,BL JZ L6A10 CALL DECOUT L6A10: MOV AL,DL ADD AL,'0' CALL CTYPE POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ; ;----> DHXOUT: - double precision hex output routine ; DHXOUT: PUSH BX ALL INITFCB MOV AL,Byte Ptr DISKNO ;put drive number back MOV Byte Ptr .FCB,AL MOV BX,Offset RESTSN ;restore record numbers.. MOV DX,Offset RECDNOB ;..for new file transfer. MOV CH,(Offset RECDNOE)-(Offset RECDNOB) ;routine also done in menu.e modem? OR AL,AL JZ L6A7 CALL JMP_DISCONNT ;if yes, disconnect L6A7: JMP MENU0 ;back to command line ;..... ; ; MOVEFCB:MOV BX, FCB+16 MOV DX, FCB MOV CH,16 CALL MOVE XOR AL,AL MOV Byte Ptr .FCBSNO,AL MOV Byte Ptr .FCBEXT,AL LAHF XCHG AL,AH PUSH AX MOV AL,BH ;get ms byte CALL HEXO ;output high order byte MOV AL,BL ;get ls byte CALL HEXO ;output low order byte POP AX XCHG AL,AH SAHF POP BX RET ;..... ; ; ; Prints a hex value in 'A' on the CRT  CALL MOVE CALL SENDNOW ;insures last character is finished CALL CKCHAR ;catch any echo characters on line MOV AL,Byte Ptr SENDFLG ;goes to either send or.. OR AL,AL ;..receive file, depending.. JZ L6A1 JMP SENDFIL2 ;..upon which roRET ;..... ; ; SHOW: CMP AL,LF JZ CTYPE CMP AL,CR JZ CTYPE CMP AL,9 JZ CTYPE CMP AL,' ' JB SEEHEX CMP AL,7FH JB CTYPE ; SEEHEX: LAHF XCHG AL,AH PUSH AX MOV AL,'(' CALL CTYPE POP AX XCHG AL,AH SAHF CALL HEXO MOV AL,; HEXO: LAHF XCHG AL,AH PUSH AX XCHG AL,AH RCR AL,1 RCR AL,1 RCR AL,1 RCR AL,1 CALL NIBBL POP AX XCHG AL,AH ; NIBBL: AND AL,0FH CMP AL,10 JB ISNUM ADD AL,7 ; ISNUM: ADD AL,'0' ;add in ASCII bias JMP CTYPE ;..... ; ; ;utine set.. L6A1: JMP RCVFIL1 ;..the flag in multi-file mode. ;..... ; ; DONETC: CALL CKABORT ;slight delay for next message CALL ILPRT DB CR,LF,'[Transfer completed]',CR,LF,BELL,0 ; DONETCA:MOV AL,Byte Ptr XITFLG ;special 'X' flag set')' JMPS CTYPE ;..... ; ; CTYPE: PUSH CX PUSH DX PUSH BX MOV DL,AL MOV CL,WRCON INT 224 POP BX POP DX POP CX RET ;..... ; ; CRLF: LAHF XCHG AL,AH PUSH AX MOV AL,CR CALL STYPE MOV AL,LF CALL STYPE POP AX XCHG AL,A Displays the control-characters shown in the menu ; SHFTYPE:LAHF XCHG AL,AH PUSH AX CALL ILPRT DB 'CTL-',0 POP AX XCHG AL,AH ADD AL,40H ;convert binary to ASCII chars. CALL STYPE ;show on the CRT JMPS ILPRT ;..... ; ; ; Write ? OR AL,AL JNZ L6A2 JMP BYEBYE ;if yes, disconnect and reboot L6A2: MOV AL,Byte Ptr DISCFLG ;normal 'D' flag set? OR AL,AL JZ DONETCD ;if yes, disconnect, get next command ; DONETCB:CALL JMP_NOPARITY ;reset to no parity XOR AL,AL H SAHF RET ;..... ; ; STAT: PUSH CX PUSH DX PUSH BX ; VSTAT: MOV DL,0FEH ; Direct Console I/O Status function flag MOV CL,6 INT 224 POP BX ; vois la POP DX POP CX OR AL,AL RET ;..... ; ; KEYIN: PUSH CX PUSH DX PUSH BX a string of characters to the CRT ; ILPRT: POP SI ; ILPRT1: LODS BYTE PTR [SI] ;get the character OR AL,AL ;see if a "0" for end of string JZ ILPRT2 ;if yes, all done CALL CTYPE ;show on CRT JMPS ILPRT1 ; ILPRT2: PUSH SI ;restore the MOV Byte Ptr CRCFLAG,AL ;reset back to checksum MOV Byte Ptr FIRSTME,AL ;reset first-time 'SOH' flag MOV Byte Ptr FSTFLG,AL ;reset multi-file trans MOV Byte Ptr NFILFLG,AL ;turn off the memory save for disk file MOV Byte Ptr SAVEFLG,A ; VKEYIN: MOV DL,0FFH ; KEYIN FLAG FOR direct CONSOLE I?O MOV CL,6 INT 224 OR AL,AL JZ VKEYIN POP BX ;..by 'INITADR' routine POP DX POP CX RET ;..... ; ; STYPE: LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX address RET ;..... ; ; ; Write a string of characters unless in the Quiet mode ; ILPRTQ: POP SI ; ILPRTQ1:LODS Byte Ptr [SI] ;get the character OR AL,AL ;see if a "0" for end of string JZ ILPRTQ2 ;if yes, all done MOV BL,Byte Ptr L ;stop memory save in term routine. MOV AL,Byte Ptr VSEEFLG ;view flag set? OR AL,AL JNZ DONETCC ;if not, exit NOT AL MOV Byte Ptr QFLG,AL ;VSEEFLG also sets the QFLG MOV Byte Ptr VSEEFLG,AL ;reset the flag ; DONETCC:MOV BX, ; VTYPE: MOV DL,AL ; Direct Conout requirtes Char in DL MOV CL,6 INT 224 POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ; ; Get a character from the keyboard, convert to upper-case if needed, ; and show on CRT ; KBDCHQFLG OR BL,BL JZ ILPRTQ1 CALL CTYPE ;show on CRT if not in quiet mode JMPS ILPRTQ1 ; ILPRTQ2:PUSH SI ;restore the address RET ;..... ; ; PRTMSG: MOV CL,PRINT ;print the string INT 224 RET ;..... ; ; ; Displays error statement t Offset QFLG ;in quiet mode? MOV AL,Byte Ptr [BX] OR AL,AL MOV Byte Ptr [BX],'Q' ;reset the flag to normal JNZ L6A3 JMP MENU ;if yes, go back to command line L6A3: MOV AL,Byte Ptr ABORTFLG ;come here from a timeout? OR AL,AL JZ L6A4 R: CALL KEYIN ;get a keyboard character CALL UCASE ;convert to upper case if needed CALL STYPE ;show on CRT RET ;..... ; ; UCASE: CMP AL,61H ;changes lower case character.. JNB L6A8 RET ;..in 'A'reg. to upper case. L6A8: CMP ALhen resturns to command mode ; ERXIT: POP DX CALL PRTMSG MOV AL,BELL CALL STYPE CALL CRLF ; ERXIT1: MOV AL,1 MOV Byte Ptr ABORTFLG,AL ;shows an unintentional abort MOV AL,Byte Ptr BATCHFLG ;in batch mode? OR AL,AL JZ L6A12 JMP DON JMP MENU ;if yes, go to command mode L6A4: MOV AL,Byte Ptr JMPCMD ;requesting return to command mode? OR AL,AL JNZ L6A5 JMP MENU ;if yes go to command mode L6A5: CALL CRLF ;turn up a new line JMP TERM ;otherwise return to termina,7AH+1 ;see if more than small 'Z' JNAE L6A9 RET L6A9: AND AL,5FH RET ;..... ; ; DECOUT: LAHF XCHG AL,AH PUSH AX PUSH CX PUSH DX PUSH BX MOV CX,-10 MOV DX,-1 ; DECOU1: ADD BX,CX INC DX JB DECOU1 MOV CX,10 ADD BX,CX X= ETCB ;if not, exit L6A12: JMP ABORT ;abort other computer ;..... ; ; ; Exits directly to CP/M ; EXIT: MOV AL,Byte Ptr OLDUSER ;get original user number back MOV DL,AL CALL SETUSER MOV CL,SETDMA MOV DX, ofFSET TBUF ;restore originalmust have a maximum length ; at least one more than the greatest number of characters that will be ; needed. CMDLINE:LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX CALL INITIAL ;fills FCBs with blanks and nulls XCHG BX,DX ecified.. MOV AL,[SI] DEC DX CMP AL,':' JNZ DEFDR ;..else zero for default drive .. MOV SI,DX ;..('INIT' put zero) MOV AL,[SI] AND AL,5FH SUB AL,40H ;calculate drive (A=1, B=2,...).. MOV Byte Ptr [BX],AL ;..and place it in FCB. LA buffer area INT 224 MOV CX,1A00H ;a little delay timer ; EXIT1: DEC CX ;one less loop to make MOV AL,CH OR AL,CL JNZ EXIT1 ;loop again till both are zero CALL CKCON ;catch any extra keyboard characters MOV AL,Byte Ptr NFILFLG ;sa ;get start of command line in hl. INC BX ;address # bytes in cmd line. MOV DL,Byte Ptr [BX] ;load de pair with # bytes. MOV DH,0 INC BX ADD BX,DX ;point to byte after last char.. MOV Byte Ptr [BX],CR ;..in cmd line and store delimiter. PHF ;address first byte of.. INC DX SAHF LAHF ;..in command line,.. INC DX SAHF ; DEFDR: LAHF ;..and name field in FCB INC BX SAHF RET ;..... ; ; TRANS: MOV SI,DX ;transfer from command line to FCB.. MOV AL,[SI] INC DX ving for a disk file? OR AL,AL JZ L6A13 CALL WRTFIL1 ;if yes, close the file L6A13: EXIT2: MOV CL,0 ;if not, reboot MOV DL,0 INT 224 ;..... ; ; ; Catch any extra keyboard characters coming through BDOS ; CKCON: MOV CL,CONST ;see OP BX ;restore BX and DE. POP DX PUSH DX PUSH BX INC DX ;address start of command. INC DX CALL DRIVE ; NAME1: MOV CL,8 ;transfer first filename to FCB. CALL TRANS CMP AL,CR JZ DONEL CMP AL,' ' ;if space, then start of.. JZ N ;..up to number of chars specified.. CMP AL,CR ;..by 'C' reg. keep scanning field.. JNZ L6A16 RET ;..without transfer until a delimiting.. L6A16: CMP AL,'.' ;..field char such as '.', blank, or.. JNZ L6A17 RET ;..CR (for end of commif any characters waiting INT 224 OR AL,AL JNZ L6A15 RET ;if not, exit L6A15: MOV CL,RDCON ;otherwise get the character INT 224 XOR AL,AL ;discard the character JMPS CKCON ;see if any others ;..... ; ; MOVE128:MOV CH,128 ; MAME2 ;..second filename. POP BX ;filetype must be after.. PUSH BX ;..eighth byte of name. MOV CX,9 ADD BX,CX MOV CL,3 ;transfer type of first file CALL TRANS CMP AL,CR JZ DONEL ; NAME2: MOV SI,DX ;eat multiple spaces.. MOV AL,mand line). L6A17: CMP AL,' ' JNZ L6A18 RET L6A18: DEC CL JS TRANS ;once c-reg is less than zero, keep.. MOV Byte Ptr [BX],AL ;..reading cmd line but do not.. INC BX ;..transfer to FCB. JMPS TRANS ;... ; ; SCANL: MOV CH,8 ;scan OVE: MOV AL,Byte Ptr [BX] MOV SI,DX MOV [SI],AL LAHF INC BX SAHF LAHF INC DX SAHF DEC CH JNZ MOVE RET ;..... ; ; ; Sends the character in 'A' to the modem ; SENDCHR:CALL SENDNOW ;wait until modem is ready for character MOV A[SI] CMP AL,' ' ;..between names. JNZ NAME3 INC DX JMPS NAME2 ; NAME3: POP BX ;second name starts in 16th byte. PUSH BX ;point BX to this byte. MOV CX,16 ADD BX,CX CALL DRIVE MOV CL,8 CALL TRANS CMP AL,CR JZ DONEL POP BX file name addressed by BX. ; TSTNAM: MOV AL,Byte Ptr [BX] CMP AL,'*' ;if '*' found, fill in rest of field.. JZ FILL1 ;..with '?' for ambiguous name. INC BX DEC CH JNZ TSTNAM JMPS TSTTYP ;... ; ; FILL1: CALL FILL ; TSTTYP: MOV CH,3 L,CH ;get the original character back JMP OUT_MODDATP ;send the character to modem, return ;..... ; ; ; Initializes CP/M file control blocks AT 5CH and 6CH ; SETFCB: MOV DX, Offset CMDBUF MOV BX, FCB JMPS CMDLINE ;..... ; ; ; Adjusts loo ;second type starts in 25th byte. PUSH BX MOV CX,25 ADD BX,CX MOV CL,3 CALL TRANS ; DONEL: POP BX PUSH BX INC BX ;point to 1st char of 1st name in FCB CALL SCANL ;check for * (ambiguous names) POP BX PUSH BX MOV CX,17 ;..to 1 ;scan and fill type field for name.. ; TSTTYPL:MOV AL,Byte Ptr [BX] ;..specified above. CMP AL,'*' JZ FILL2 LAHF INC BX SAHF DEC CH JNZ TSTTYPL RET ;..... ; ; FILL2: CALL FILL RET ;..... ; ; FILL: MOV Byte Ptr [BX],'?' ;routinep counter for the selected clock speed. Returns with delay ; in 'BX'. ; FIXCNT: MOV AL,Byte Ptr CLOCK ;get the user's clock speed PUSH DX ;save the current 'DE' value PUSH BX POP DX ;get same value into 'DE' as in 'BX' ; CNTMUL: LAHF st char of second name in FCB ADD BX,CX CALL SCANL POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ; ; Subroutines for CMDLINE section ; INITIAL:PUSH BX ;initializes FCB with 1 null (for first drive).. PUSH CX ;..11 b transfers '?'. LAHF INC BX SAHF DEC CH JNZ FILL RET ;======================================================================= ; ; LISTS DIRECTORY AND GIVES FREE SPACE REMAINING ON THE REQUESTED DRIVE. ; ; ; Disk system reset - currently b ;add 'DE' to 'BX' ADD BX,DX RCR SI,1 SAHF RCL SI,1 DEC AL ;one less to go JNZ CNTMUL POP DX ;restore current 'DE', delay in 'BX' RET ;..... ; ; ;======================================================================= ; ; Loads alanks, 4 nulls, 1 null (for 2nd drive).. MOV Byte Ptr [BX],0 ;..11 blanks, and 4 nulls. LAHF INC BX SAHF MOV CH,11 MOV AL,' ' CALL INITFILL MOV CH,5 XOR AL,AL CALL INITFILL MOV CH,11 MOV AL,' ' CALL INITFILL MOV CH,4 XOR AL,Aypassed, if you wish this feature, put ; JMP DIRLIST2 instead of JMP DIRLIST3 in the eighth line. The ; current disk (plus the A: drive) will then reset each DIR re- ; quest. You can also reset the disk with the LOG command when ; when inserting a dif command line addressed by 'DE' registers (max # characters in ; line in 'DE', number of characters in line in DE+1, line starts in ; DE+2) into FCB addressed by 'BX' registers. The FCB should be at least ; 33 bytes in length. The command line buffer L CALL INITFILL POP CX POP BX RET ;..... ; ; INITFILL: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ INITFILL RET ;..... ; ; DRIVE: INC DX ;check 2nd byte of filename. if it.. MOV SI,DX ;..is a ":", then drive was sp> ferent one. This saves a reset each time ; DIR might be requested. ; DIRLIST:CALL GETDISK ADD AL,'A' ;change to ascii MOV Byte Ptr DRNAME,AL ;show for drive name MOV Byte Ptr ACTDRV,AL ;show for space remaining on drive ; DIRLIST1: JMPS DIR ADD BX,2 MOV AL,ES: BYTE PTR [BX] ;Get Block Shift Factor MOV BSHIFTF,AL INC BX ;bump to block mask MOV AL,ES: BYTE PTR [BX] ;get it MOV BMASK,AL ADD BX,2 MOV DX,ES: WORD PTR [BX] ;get max block number MOV Word Ptr BMAX,DX ;put it away  bytes free on drive ' ACTDRV DB ' :',CR,LF,'$' ; ; ; Uninitialized storage ; BMAX Rb 2 ;highest block number on drive BMASK Rb 1 ;rec/blk - 1 BSHIFTF Rb 1 ;number of shifts to multiply by rec/blk ;..... ; ; ;=============================LIST3 ; DIRLIST2: MOV CL,RESET ;13 reset disk system (resetdk) INT 224 ; ; ; Directory list routine ; DIRLIST3: MOV DX, Offset CMDBUF ;put command line in FCBb.. MOV BX, FCB ;..addressed by BX-reg.. CALL CMDLINE ;..and then... MOV B MOV CL,DSKALL ;address of CP/m Allocation vector INT 224 XCHG BX,DX ;get its length MOV BX, Word Ptr BMAX INC BX MOV CX,0 ;initialize block count to zero GSPBYT: PUSH DX ;save allocation address XCHG BX,DX MOV AL,ES: BYTE PTR [BX] ========================================== ; ; Duplicates 'READ BUFFER' routine same as CP/M function 10, but does ; not use CTL-C (reason for the routine). Does allow controls U, R, E ; and H (BACKSPACE). Outputs bell if the input is greater than thX, Offset FCB4 CALL INITFCB MOV AL,Byte Ptr .FCB2 ;get drive number MOV Byte Ptr FCB4,AL MOV AL,Byte Ptr .FCB2+1 CMP AL,' ' ;if a space (blank) get all names LAHF XCHG AL,AH PUSH AX JNZ L6A19 CALL QSTMARK L6A19: POP AX XCHG AL,AH XCHG BX,DX MOV DL,8 ;set to process 8 blocks GSPLUP: RCL AL,1 ;test bit JC NOTFRE INC CX NOTFRE: MOV DH,AL ;save bits DEC BX MOV AL,BL OR AL,BH JZ ENDALC ;quit if out of blocks MOV AL,DH ;restore bits DEC DL ;count dowe ; buffer. ; INBUF: LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH BX PUSH CX PUSH DX ;'DE' registers must be pushed last ; INBUFA: CALL CLEARBUF ;clear the buffer area POP DX ;get address of buffer on retries PUSH DX ;restore stack  SAHF JZ L6A20 CALL MOVNAME ;else move name into FCB L6A20: CALL DRIVEL MOV CL,SETDMA MOV DX, TBUF INT 224 MOV AL,Byte Ptr NOOFCOL ;number of columns into 'A' reg. MOV Byte Ptr NAMECT,AL ;CRLF after 'NOOFCOL' number of columns n 8 bits JNZ GSPLUP ;do another bit POP DX ;bump to next count.... INC DX ;...of allocation vector JMP GSPBYT ;process it ; ENDALC: POP DX ;clear allocation vector pointer from stack MOV BX,CX ;copy block to bx MOV AL,Byte Ptr B XOR AL,AL LAHF ;address count field INC DX SAHF MOV SI,DX ;initialize with a zero in count byte MOV [SI],AL LAHF INC DX SAHF XCHG BX,DX ;address first buffer byte with 'BX' ; INBUFB: CALL KEYIN ;(waits for char) CALL UCASE  MOV DX, Offset FCB4 MOV CL,SRCHF ;do first search INT 224 INC AL ;0FFH --> 0 if no file(s) found JNZ DIRLOOP CALL ILPRT DB '++ FILE NOT FOUND ++',0 JMP STORAGE ;still show storage on default drive ; DIRLOOP:CALL GETADD LAHF ;poiSHIFTF ;get block shift factor SUB AL,3 ;convert from record to K JZ PRTFREE ;skip shifts of 1K blocks FREKLP: ADD BX,BX ;multiply blocks by 'K per block' DEC AL JNZ FREKLP ; PRTFREE:CALL DECOUT ;(# of free k bytes now in 'BX') MOV D ;convert to upper case if needed CMP AL,CR ;is it (enter command)? JNZ L6A24 JMP INBUFR ;if so, then return. L6A24: CMP AL,08H ;CTL-H backspaces over deleted character JZ DELETE CMP AL,7FH ;is it a delete? JZ DELETE CMP Ant to first letter of filename INC BX SAHF MOV DX,(Offset PRTNAME) MOV CX,8 CALL MOVER LAHF INC DX SAHF MOV CX,3 CALL MOVER CALL ILPRT ; PRTNAME DB ' ','.',' ',0 ; 8 spaces, period, 3 spaces ; NEXTSR: MOV DX, oFFSET FCB4X,(Offset FREEMSG) JMP PRTMSG ;..... ; ; ; Subroutines for 'DIRLIST' section ; QSTMARK:MOV AL,'?' ;if blank in FCB, put in 11 ?'S. MOV CH,11 MOV BX, oFFSET FCB4+1 ; QSTLP: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ QSTLP RL,'U'-40H ;is it a CTL-U? JNZ L6A25 JMP INBUFO ;output #, CR, LF, and start over L6A25: CMP AL,'R'-40H ;CTL-R retypes line JNZ L6A26 JMP RETYPE L6A26: ; INBUFC: MOV CH,AL ;save inputted character XCHG BX,DX ;save 'BX' in 'DE' POP  MOV CL,SRCHN ;do next search INT 224 INC AL ;if 0FFH --> 0 then.. JZ STORAGE ;..directory-read finished. LAHF XCHG AL,AH PUSH AX PUSH DX PUSH BX MOV AL,Byte Ptr NAMECT DEC AL MOV Byte Ptr NAMECT,AL ;name count updated ORET ;..... ; ; MOVNAME:MOV BX, FCB2+1 MOV DX, Offset FCB4+1 MOV CX,11 CALL MOVER RET ;..... ; ; GETADD: DEC AL ;un-do the inr above ADD AL,AL ;times 32 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,TBUF ;add buffer offset BX ;get address of buffer in 'BX' PUSH BX ;restore stack INC BX ;address count byte INC Byte Ptr [BX] ;increase count byte DEC BX ;address maximum MOV AL,Byte Ptr [BX] ;put maximum in 'A' INC BX ;address count CMP AL,Byte Ptr [BX]  AL,AL JNZ L6A21 CALL CRLF ;terminate line of file names L6A21: JNZ FENCE MOV AL,Byte Ptr NOOFCOL ;restart columns-per-line count MOV Byte Ptr NAMECT,AL JMPS NOFENCE ;fence not needed ; FENCE: CALL ILPRT DB ' : ',0 ;fence if not a MOV BL,AL MOV BH,0 RET ;..... ; ; DRIVEL: MOV AL,Byte Ptr FCB4 ;if no drive, use OR AL,AL ;default drive in drname. JZ PRNTHD LAHF XCHG AL,AH PUSH AX XCHG AL,AH DEC AL MOV DL,AL MOV CL,SELDSK INT 224 POP AX XCHG AL;compare count to maximum JNB L6A27 JMP ALERTL ;if maximum, ring bell and wait for cr. L6A27: XCHG BX,DX ;restore buffer pointer to 'BX' MOV Byte Ptr [BX],CH ;put inputted character in buffer MOV AL,CH ;output it CMP AL,EXITCHR ;exit cht end of line or.. ; ;..LAST FILENAME NOFENCE:POP BX POP DX POP AX XCHG AL,AH SAHF JMPS DIRLOOP ;..... ; ; ; Determine storage remaining on default drive ; STORAGE: CALL CRLF MOV CL,DSKPAR ;current disk parameter block INT 224 ,AH ADD AL,40H ;make 1=a, 2=b, etc., and.. MOV Byte Ptr DRNAME,AL ;..overwrite default stored below. MOV Byte Ptr ACTDRV,AL ; PRNTHD: CALL ILPRT DB 'Drive ' ; DRNAME DB ' :',CR,LF,0 RET ;..... ; ; ; Initialized storage ; FREEMSG DB 'k> aracter? JNZ L6A28 JMP INBUFR ;if yes, all done L6A28: CMP AL,20H ;printing character? JNAE L6A29 CALL STYPE ;if yes, print it L6A29: LAHF ;bump pointer INC BX SAHF JMPS INBUFB ;get next character ;... ; ; DELETE: XCHG B ;..... ; ; ;======================================================================= ; ; In-line compare. Compares string addressed by 'DE' to string after ; call (ends with zero). Return with carry set means strings not the ; same. All registerMFFLG1,AL RET ;..... ; ; MFNAME3:DEC AL AND AL,3 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,81H MOV BL,AL MOV BH,0 PUSH BX ;save name pointer MOV DX, Offset MFNAME6+1 MOV CX,11 CALL MOVER POP BX MOV DX, X,DX ;save buffer pointer in 'DE' POP BX ;address beginning of buffer PUSH BX ;restore stack INC BX ;address count field MOV AL,Byte Ptr [BX] SUB AL,1 ;decrease count MOV Byte Ptr [BX],AL JB NODEL ;don't delete past beginning of bs except 'A'-reg are unaffected. ; INLNCOMP: POP BX ;point 'SI' to 1st char. PUSH DX ; ILCOMPL:MOV AL,Byte Ptr [BX] ;'BX' points to in-line string. OR AL,AL ;end of string if zero. JZ SAME MOV SI,DX MOV AL,[SI] CMP AL,Byte Ptr [BX] FCB+1 MOV CX,11 CALL MOVER XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV Byte Ptr .FCBRNO,AL RET ;..... ; ; MFNAME4: MOVER: MOV AL,Byte Ptr [BX] ;used if an 8080 CPU is active MOV SI,DX MOV [SI],AL INC BX INC DX DEC CX MOV AL,CH OR Auffer XCHG BX,DX ;restore buffer pointer to 'BX' DEC BX ;point to last byte inputted MOV AL,Byte Ptr [BX] ;get character being deleted MOV Byte Ptr [BX],' ' ;restore blank CMP AL,' ' ;see if non-printing character JB DELETE1 ;if yesJNZ NOTSAME INC BX INC DX JMPS ILCOMPL ;... ; ; NOTSAME:XOR AL,AL ;if not same, finish thru.. ; NSLP: INC BX ;..string so return will.. CMP AL,Byte Ptr [BX] ;..go to instruction after.. JNZ NSLP ;..string and not remainder of string. L,CL JNZ MFNAME4 RET ;..... ; ; (END OF MULTI-FILE ACCESS ROUTINE) ;======================================================================= ; CALCULATE FILE TRANSFER TIME ; ; ; Shows the time to transfer a file at various baud rates. (110-, skip the CRT backup MOV AL,BKSP CALL STYPE ;true erase if 08H MOV AL,' ' CALL STYPE MOV AL,BKSP CALL STYPE DELETE1: JMP INBUFB ;..... ; ; MORE DB '12345' ;5 bytes extra from DELETE routine fix ; NODEL: INC Byte Ptr [BX] ;do STC ; SAME: POP DX LAHF ;avoids a NOP instruction.. INC BX SAHF PUSH BX ;..when returning. RET ;..... ; ; ;======================================================================= ; ; Multi-file access subroutine. Allows processing19200) ; SENDTIME: CALL ILPRT ;print following message: DB 'File open: ',0 MOV BX,Word Ptr RCNT ;get record count. CALL DECOUT ;print decimal number of records ; MOV AL,Byte Ptr HEXSHOW OR AL,AL JZ SENDTIME1 CALL ILPRT DB ' (n't leave count negative XCHG BX,DX ;restore pointer to 'BX' MOV AL,BELL ;says can go no further CALL STYPE JMP INBUFB ;..... ; ; INBUFO: MOV AL,'#' ;announces the line has been removed CALL STYPE CALL CRLF JMP INBUFA ;..... ; ;  of multiple files ; (i.e., *.ASM) from disk. Builds the correct name in the FCB each time ; it is called. The command is used in programs to process single or ; multiple files. The FCB is set up with the next name, ready to do ; normal processing (',0 CALL DHXOUT ;now print size in hex. CALL ILPRT DB 'H)',0 ; SENDTIME1: CALL ILPRT DB ' records' DB CR,LF,'Send time: ',0 MOV AL,Byte Ptr MSPEED ;get the speed indicator MOV DH,0 MOV DL,AL ;set up for table access MOV BX,(Offset RETYPE: POP DX PUSH DX LAHF ;point to current number.. INC DX SAHF MOV SI,DX ;..of characters. MOV AL,[SI] MOV CH,AL MOV AL,'#' CALL STYPE CALL CRLF MOV AL,CH ;test if zero input OR AL,AL JNZ CTLRLP JMP INBUFB ;... ; open, read, etc.) when routine is called. Carry is ; set if no more names are found. MFNAME: PUSH CX PUSH DX PUSH BX MOV CL,SETDMA MOV DX, TBUF INT 224 POP BX POP DX POP CX XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV AL,Byte Ptr MFFLG1  BTABLE) ;point to baud factor table LAHF ;index to proper factor ADD BX,DX SAHF LAHF ;factor in 'DE' ADD BX,DX SAHF MOV DL,Byte Ptr [BX] LAHF INC BX SAHF MOV DH,Byte Ptr [BX] MOV BX,Word Ptr RCNT ;get # of records CAL; CTLRLP: LAHF INC DX SAHF MOV SI,DX MOV AL,[SI] CALL STYPE DEC CH JNZ CTLRLP JMP INBUFB ;..... ; ; ALERTL: MOV AL,BELL ;alarm for full buffer CALL STYPE DEC Byte Ptr [BX] XCHG BX,DX JMP INBUFB ;..... ; ; PCRLF: CALL CRLOR AL,AL JNZ MFNAME1 MOV AL,1 MOV Byte Ptr MFFLG1,AL MOV BX, FCB MOV DX, Offset MFNAME5 MOV CX,12 CALL MOVER MOV AL,Byte Ptr .FCB MOV Byte Ptr MFNAME6,AL ;save disk in current FCB MOV BX, Offset MFNAME5 MOV DX, FCB MOV CX,12 CAL DVHLDE ;divide BX by value in DE (records/min) PUSH BX MOV BX,CX CALL DECOUT ;print the minutes portion CALL ILPRT DB ' mins, ',0 MOV BX,(Offset RECDBL) ;point to divisors for seconds MOV DX,0 ; calculation MOV AL,Byte Ptr MSPEED F JMP INBUFB ;..... ; ; INBUFR: CALL CRLF ;1st new line after a command character POP DX POP CX POP BX POP AX XCHG AL,AH SAHF RET ;..... ; ; CLEARBUF: POP DX ;accounts for call POP BX ;address buffer in 'BX' PUSH BX ;rLL MOVER PUSH CX PUSH DX PUSH BX MOV CL, SRCHF MOV DX, FCB INT 224 POP BX POP DX POP CX JMPS MFNAME2 ;... ; ; MFNAME1:MOV BX, Offset MFNAME6 MOV DX, FCB MOV CX,12 CALL MOVER PUSH CX PUSH DX PUSH BX MOV CL,SRCHF MOV D ;get index for baud rate MOV DL,AL LAHF ;index into table ADD BX,DX RCR SI,1 SAHF RCL SI,1 MOV AL,Byte Ptr [BX] ;get multiplier POP BX ;get remainder CALL MULHLA ;multiply the 'BX' x 'A' CALL SHFTHL CALL SHFTHL CALL SHFTHestore.. PUSH DX ;..stack MOV CH,Byte Ptr [BX] ;save maximum in 'B' LAHF ;point to first.. INC BX SAHF LAHF ;..buffer byte. INC BX SAHF MOV AL,' ' ; CLEARL: MOV Byte Ptr [BX],AL LAHF INC BX SAHF DEC CH JNZ CLEARL RETX, FCB INT 224 POP BX POP DX POP CX MOV BX,Offset MFNAME5 MOV DX,FCB MOV CX,12 CALL MOVER PUSH CX PUSH DX PUSH BX MOV CL,SRCHN MOV DX, FCB INT 224 POP BX POP DX POP CX ; MFNAME2:INC AL STC JNZ MFNAME3 MOV Byte Ptr ? L CALL SHFTHL MOV BH,0 CALL DECOUT ;print the seconds portion CALL ILPRT DB ' secs at ',0 CALL PRTBAUD CALL ILPRTQ DB 'To cancel: use CTL-X',CR,LF,0 RET ; BTABLE DW 5,13,20,26,29,48,85,152,280,480,0 ;records/min for.. RECDBL DB 192,7X, OFFSET CRCTBL ;address at start of 'CRC' lookup table MOV CL,0 ; CRCGEN1:XCHG BX,DX ;store table location into 'DE' MOV BX,0 ;clear 'BX' pair MOV AL,CL PUSH CX MOV CH,8 XOR AL,BH MOV BH,AL ; CRCGEN2:SHL BX,1 ;index into the tableg ; MENU1: MOV BX, OFFSET RESTSN ;restore record numbers.. MOV DX, OFFSET RECDNOB ;..for new file transfer. MOV CH, (OFFSET RECDNOE)-(OFFSET RECDNOB) CALL MOVE MOV BX,OFFSET RESTROPT ;restore option table MOV DX,OFFSET OPTBL MOV CH, (O4,48,37,33,20,11,6,3,2,0 ;110-19200 baud ;..... ; ; ; Shows baud rates set for 'time to send' file transfer ; PRTBAUD:MOV BX,(Offset BAUDSPD) MOV DH,0 MOV AL,Byte Ptr MSPEED ;get baud rate code MOV DL,AL ;x1 ADD AL,AL ;x2 ADD AL,AL  JNB CRCGEN3 MOV AL,16 ;using x^ 16 + x^12 + x^5 + 1 algorithm XOR AL,BH MOV BH,AL MOV AL,32+1 XOR AL,BL MOV BL,AL ; CRCGEN3:DEC CH JNZ CRCGEN2 ;make 8 loops, one for each bit ; ; ; Value now in 'BX', table address still stored in FFSET OPTBE)-(OFFSET OPTBL) CALL MOVE XOR AL,AL MOV Byte Ptr FSTFLG,AL MOV Byte Ptr TIMFLG,AL MOV Byte Ptr FLTRFLG,AL ;reset multi-file trans MOV Byte Ptr MFFLG1,AL ;reset mfaccess routine.. JMP XPRT ;..... ; ; ; * * * * * * * * *  ;x4 ADD AL,DL ;x5 ADD AL,DL MOV DL,AL LAHF ;point to correct rate ADD BX,DX RCR SI,1 SAHF RCL SI,1 XCHG BX,DX MOV CL,PRINT INT 224 CALL ILPRT DB ' bps ',CR,LF,0 RET ;..... ; ; BAUDSPD DB '110$',0,0,'300$',0,0,'450$',0'DE'. Exchange, and ; store the 'CRC' value in the two tables after splitting. ; POP CX ;finished borrowing the 'B' reg. XCHG BX,DX ;address back in 'BX', 'CRC' in 'DE' MOV Byte Ptr [BX],DH ;store 1st part of 'CRC' value INC BH ;move up 25* * * * * * * * * * * * * * * * * * * * * * * * * * ; ; MENU OF COMMANDS ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; MENU2: CALL CLRTST CALL ILPRT DB ' Single Letter Commands',CR,LF,LF DB,0,'600$',0,0,'710$',0,0 DB '1200$',0,'2400$',0,'4800$',0,'9600$',0,'19200$' ;..... ; ; ;----> DVHLDE: Divides 'BX' by value in 'DE', ; Upon exit: 'BC'=quotient,'BL'=remainder ; DVHLDE: PUSH DX ;save divisor MOV AL,DL NOT AL ;negate divis6 bytes MOV Byte Ptr [BX],DL ;store 2nd part of 'CRC' value DEC BH ;move back 256 bytes LAHF ;increment to next location INC BX SAHF INC CL ;done when 'C' reg. turns zero again JNZ CRCGEN1 ;now go do the next location RET ;.....  ' ? - Display current settings',CR,LF MENU3 DB ' ^ - Function key intercept character, ' DB 'then (0-9)',CR,LF DB ' M - Display the menu',CR,LF DB ' E - Terminal mode with echo',CR,LF DB ' L - Terminal mode with local echo',CR,LF DB ' T -or MOV DL,AL MOV AL,DH NOT AL MOV DH,AL LAHF ;'DE' is now two's complemented INC DX SAHF MOV CX,0 ;init quotient ; DIVL1: LAHF ;subtract divisor from dividend ADD BX,DX RCR SI,1 SAHF RCL SI,1 LAHF ;bump quotient INC; ; ; Update the CRC value from a character in the 'A' register ; CRCUPD: LAHF ;save all registers just in case XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX MOV BX,Word Ptr CRCVAL ;get current value XCHG BX,DX ;put in  Terminal mode',CR,LF DB ' For copying text to disk use T (E or L) ' DB 'FILENAME.TYP',CR,LF DB ' Start or Stop toggles described on subsequent' DB ' screen.',CR,LF DB ' R - Receive CP/M file using Christensen Protocol' DB CR,L CX SAHF JB DIVL1 ;loop till sign changes LAHF ;adjust quotient DEC CX SAHF POP DX ;retrieve divisor LAHF ;adjust remainder ADD BX,DX RCR SI,1 SAHF RCL SI,1 RET ;..... ; ; ;----> MULHLA: Multiply the value in 'BX' by 'DE' for now MOV CH,0 XOR AL,DH MOV CL,AL ;now have the character in 'BC' pair MOV BX, Offset CRCTBL ;start of 'CRC' lookup-table ADD BX,CX ;index into the 'CRC' table MOV AL,Byte Ptr [BX] ;get the value from the table XOR AL,DL MOV DHF DB ' S - Send CP/M file using Christensen Protocol',CR,LF DB ' COMMAND: R (or S) FILENAME.TYP',CR,LF DB ' R and S can use the following subcommands:' DB CR,LF DB ' B - Bulk transfer using wildcards ' DB '(e.g., *.the value in 'A' ; Return with answer in 'BX' ; MULHLA: XCHG BX,DX ;multiplicand to 'DE' MOV BX,0 ;init product INC AL ;adjust multiplier for zero test ; MULLP: DEC AL JNZ L7A5 RET L7A5: LAHF ADD BX,DX RCR SI,1 SAHF RCL SI,1,AL INC BH ;move 256 bytes for 2nd table location MOV DL,Byte Ptr [BX] ;put value there into 'E' register XCHG BX,DX ;put 'DE' into 'BX' MOV Word Ptr CRCVAL,BX ;updated 'CRC' value with this character POP BX ;restore all registers POP*)',CR,LF DB ' D - Disconnect when done' DB CR,LF DB ' Q - Quiet mode (no messages to console)' DB CR,LF DB ' V - View or bytes on console' DB CR,LF DB ' X - When done, disconnect, go to JMPS MULLP ;..... ; ; ; Shift 'BX' register pair one bit to the right ; SHFTHL: RCR BX,1 RET ;..... ; ; ; (END OF FILE TRANSFER TIME ROUTINE) ;======================================================================= ; CRC SUBROUTI DX POP CX POP AX XCHG AL,AH SAHF RET ;..... ; ;==================== END OF CRC SUBROUTINE ============================ ; ; ;=========================START OF MENU ================================ ; ; MENU0: MOV AL,Byte Ptr NFILFLG OR  CP/M' DB CR,LF,LF DB ' The single letter commands may also be used on ' DB 'the',CR,LF DB ' command line when the program is initially ' DB 'executed.',CR,LF,LF,0 ; THREELTR: CALL JMP_NXTSCRN CALL ILPRT DB ' ThreNES ; ; ; Check 'CRC' bytes of record just received ; CRCCHK: PUSH BX MOV BX,Word Ptr CRCVAL MOV AL,BH OR AL,BL POP BX JNZ L7A7 RET L7A7: MOV AL,0FFH RET ;..... ; ; ; Generate the CRC tables for fast calculations ; CRCGEN: MOV BAL,AL JZ MENU ;exit if not saving memory for disk file CALL ILPRT ;else print message DB CR,LF,'** File still open, use DEL, DIR, WRT, E, L ' DB 'or T ** ',CR,LF,BELL,0 JMPS MENU1 ; MENU: XOR AL,AL MOV Byte Ptr ABORTFLG,AL ;null the fla? e Letter Commands',CR,LF,LF DB 'CPM - Exit from this program to CP/M',CR,LF DB 'DIR - List directory and space free (may specify ' DB 'drive)',CR,LF DB 'ERA - Erase file (may specify drive)',CR,LF DB 'LOG - Change default drive/user no. (specify RT DB ' Local Commands while in Terminal Mode' DB CR,LF,LF,0 MOV AL,Byte Ptr BRKCHR CALL SHFTYPE DB ' - Send a break tone for 300 ms.',CR,LF,0 MOV AL,Byte Ptr PMMIMODEM OR AL,AL JZ SKIPLF1 MOV AL,Byte Ptr CHGBAUD CALL SHFTYPE PRT1: MOV CL,CURDSK ;current disk function INT 224 ADD AL,'A' ;make ASCII CALL STYPE CALL GETUSER ;get current user number OR AL,AL JZ XPRT2 ;skip if user 0 MOV BH,0 MOV BL,AL CALL DECOUT ;show current user area ; XPRT2: MOV AL' DB 'drive/user)',CR,LF DB ' and reset disks. e.g. LOG A0: or LOG B: ' DB '(user # unchanged)',CR,LF DB 'SPD - Set file output speed in terminal mode' DB CR,LF,0 ; CALL SORPTST JNZ NOTIME CALL ILPRT DB 'TIM - Select Baud rate forDB ' - Change baud rate',CR,LF,0 ; SKIPLF1:MOV AL,EXITCHR CALL SHFTYPE DB ' - Exit to command mode',CR,LF,0 MOV AL,Byte Ptr TRANLOGON OR AL,AL JZ NOTRNLOG MOV AL,Byte Ptr LOGCHR CALL SHFTYPE DB ' - Send log-on message',CR,LF,0 ; NOTR,'>' CALL STYPE MOV AL,'>' CALL STYPE CALL ILPRT DB 'COMMAND: ',0 XOR AL,AL MOV Byte Ptr XFLG,AL ;null the buffer-length flag ; ; ; Get the command line parameters ; GETCMD: MOV DX,OFFSET CMDBUF ;enter command CALL INBUF MOV AL "time-to-send" msg.',CR,LF,0 ; NOTIME: MOV AL,Byte Ptr TOGGLECRC OR AL,AL JZ NOTOCRC CALL ILPRT DB 'TCC - Toggle CRC/Checksum mode on receive',CR,LF,0 ; NOTOCRC:MOV AL,Byte Ptr TOGGLELOC OR AL,AL JZ NOTOGLOC CALL ILPRT DB 'TLC - ToggleNLOG: MOV AL,Byte Ptr NOCONNCT CALL SHFTYPE DB ' - Disconnect from the phone line',CR,LF,0 MOV AL,Byte Ptr LSTTST OR AL,AL JZ NOTLIST MOV AL,Byte Ptr LSTCHR CALL SHFTYPE DB ' - Toggle printer',CR,LF,0 ; NOTLIST:MOV AL,LF CALL STYPE ,Byte Ptr CMDBUF+2 CMP AL,EXITCHR ;exit character JZ XPRT1 ; GETCMD1:CMP AL, Byte Ptr Fncky ;function key intercept character JNZ L7A9 JMP FUNCT ; (supplied from 'INTCPT' table) L7A9: CMP AL,'?' JNZ L7A10 JMP CURPAR L7A10: CMP AL,' local command immediate or after ',0 MOV AL,Byte Ptr EXTCHR CALL SHFTYPE DB CR,LF,0 ; NOTOGLOC: MOV AL,Byte Ptr TOGGLELF OR AL,AL JZ NOTOGRUB CALL ILPRT DB 'TLF - Toggle LF after CR in "L" or "T" mode for ' DB 'a disk file',CR,LF,0 ;  MOV AL,Byte Ptr SAVECHR CALL SHFTYPE DB ' - Start copy into buffer',CR,LF,0 MOV AL,Byte Ptr UNSAVECHR CALL SHFTYPE DB ' - Stop copy into buffer',CR,LF,LF DB ' Start & Stop may be toggled as often as ' DB 'desired.',CR,LF DB  ' JNZ L7A11 JMP L7A8 ;skip the extra line feed L7A11: MOV AL,Byte Ptr CMDBUF+3 CMP AL,':' ;see if request for new drive/user JNZ L7A12 JMP SETDRV L7A12: MOV DX,OFFSET CMDBUF+2 ;point to command CALL INLNCOMP DB 'CPM',0 JNAE L7A1 NOTOGRUB: MOV AL,Byte Ptr TOGGLERUB OR AL,AL JZ NOTOGLF CALL ILPRT DB 'TRB - Toggle rubout to backspace conversion',CR,LF,0 ; NOTOGLF:MOV AL,Byte Ptr TOGXOFF OR AL,AL JZ NOTOGXOF CALL ILPRT DB 'TXO - Toggle XOFF testing in terminal mod' A ";" at start of line indicates buffer ' DB 'is copying.',CR,LF DB ' XOFF automatically used to stop input ' DB 'when writing',CR,LF DB ' full buffer to disk, XON sent to ' DB 'resume.',CR,LF,LF,0 MOV A3 JMP EXIT L7A13: CALL CRLF ;(1st CR/LF at 'INBUFR') CALL INLNCOMP DB 'LOG',0 JNAE L7A14 JMP LOGNEW L7A14: CALL INLNCOMP DB 'DIR',0 JNAE L7A15 JMP DIR L7A15: CALL INLNCOMP DB 'ERA',0 JNAE L7A_16 JMP ERASEF L7A16: CALL INe ' DB 'file output',CR,LF,0 ; NOTOGXOF: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ NONUM MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ NOTOGX2 ; NOTOGX1:CALL ILPRT DB 'NUM - List remote systems',CL,Byte Ptr TRANCHR CALL SHFTYPE DB ' - Transfer ASCII file to remote',CR,LF,LF,0 MOV AL,Byte Ptr LOCNXTCHR OR AL,AL MOV AL,Byte Ptr EXTCHR JNZ REMDFLT CALL SHFTYPE DB ' - Send local control character to remote' DB CR,LF,LF,0 JMPS CKSPLNCOMP DB 'SPD',0 JNAE L7A17 JMP SETSPD L7A17: CALL INLNCOMP DB 'TIM',0 JNAE L7A18 JMP SETTIM L7A18: CALL INLNCOMP DB 'TCC',0 JNAE L7A19 JMP TOGCRC L7A19: CALL INLNCOMP DB 'TRB',0 JNAE L7A20 JMP TOGRUB L7A20: CALL INLNCOR,LF,0 ; NOTOGX2:MOV AL,Byte Ptr SETUPTST OR AL,AL JZ NONUM CALL ILPRT DB 'SET - Set modem baud rate',CR,LF,0 ; NONUM: CALL ILPRT DB 'BYE - Disconnect, then return to CP/M' DB CR,LF,0 MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR ACL ; REMDFLT:CALL SHFTYPE DB ' - Next character will be used for local control' DB CR,LF,0 ; CKSPCL: CALL JMP_SPCLMENU ;may have a special menu in the overlay ; ;FALLS ON THROUGH TO 'XPRT' ; ; ; (END OF COMMAND MENU) ;================MP DB 'TLC',0 JNAE L7A21 JMP TOGLOC L7A21: CALL INLNCOMP DB 'TLF',0 JNAE L7A22 JMP TOGLF L7A22: CALL INLNCOMP DB 'TXO',0 JNAE L7A23 JMP TOGTXOFF L7A23: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ NONUM1 ;iL,AL JNZ NONUM0 ;if yes, display 'CAL' MOV AL,Byte Ptr AUTODIAL ;usina a Hayes-type modem? OR AL,AL JZ NOPMMI ;exit if neither ; NONUM0: CALL ILPRT DB 'CAL - Dial number',CR,LF,0 ; NOPMMI: CALL ILPRT DB 'DSC - Disconnect from the phon======================================================= ; START OF COMMAND LINE HANDLING ; ; ; Check first to see if a file was opened for copying incoming to disk ; XPRT: CALL CRLF ;turn up a blank line to look nice L7A8: MOV AL,Byte Ptr Nf yes, exit MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,AL JNZ NONUM1 ;if yes, exit CALL INLNCOMP DB 'NUM',0 JNAE L7A24 JMP NUMPRN L7A24: ; NONUM1: MOV AL,Byte Ptr SETUPTST OR AL,AL JZ NXTOPT1 CALL INLNCOMP DB 'SEe line',CR,LF,LF DB ' The following are terminal text ' DB 'buffer commands:',CR,LF,LF,0 ; SKIPLF: CALL ILPRT DB 'DEL - Delete memory buffer and file',CR,LF DB 'WRT - Write memory buffer to disk file',CR,LF,LF,0 CALL NXTSCRN CALL ILPFILFLG ;have a file open for text mode copy? OR AL,AL JZ XPRT1 ;if not, exit ; CALL GETSPC ;otherwise show remaining space CALL ILPRT DB ' Bytes of buffer free',CR,LF,LF,0 ; ; ; Show disk drive and user number, then command line ; X@ T',0 JNAE L7A25 JMP SETUPENT L7A25: ; NXTOPT1:CALL INLNCOMP DB 'WRT',0 JNAE L7A26 JMP WRTFIL L7A26: CALL INLNCOMP DB 'DEL',0 JNAE L7A27 JMP NEWFILE L7A27: CALL INLNCOMP DB 'BYE',0 JNAE L7A28 JMP BYEBYE L7A28: CALL INLNCOMPLL STYPE JMPS FUNCT3 ; FUNCT5: CALL CRLF DEC CH JNZ FUNCT2 CALL CRLF JMP XPRT ;..... ; ; BYEBYE: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JZ L7A30 CALL JMP_GOODBYE ;if yes, disconnect L7A30: MOV AL,Byte Ptr AUTODI CALL CHRCHK ;check the char. CALL L7A37 ; LOGNEW2:CALL SAVEUSER MOV CL,RESET INT 224 MOV AL,Byte Ptr DISKSAV MOV DL,AL MOV CL,SELDSK INT 224 MOV AL,Byte Ptr SAVUSR MOV DL,AL CALL SETUSER JMP XPRT ;..... ; ; CHRCHK: CMP AL,' DB 'DSC',0 JNAE L7A29 JMP DONETCD L7A29: MOV AL,Byte Ptr PMMIMODEM ;using a PMMI modem? OR AL,AL JNZ NXTOPT0 ;if yes, exit MOV AL,Byte Ptr AUTODIAl ;using a Hayes-type modem? OR AL,AL JZ NXOPT2 ;exit if neither modem-type ; NXTAL ;using a Hayes-type modem? OR AL,AL JZ L7A31 CALL SMRESET ;if yes, disconnect L7A31: CALL JMP_GOODBYE ;user's custom-area goodbye routine CALL ILPRT DB CR,LF,'<< Exit to CP/M >>',CR,LF,0 JMP EXIT ;return to CP/M ; SMRESET:MOV CH, ' JZ CHRCHK1 CMP AL,':' ;in case of A: or A1: or A11: (etc.) JZ CHRCHK1 RET ; CHRCHK1:POP AX ;reset the 'CALL' on the stack JMPS LOGNEW2 ;..... ; ; FINDUSER: MOV CH,0 ;zero the 'B' reg. for 1st time through L7A37: CALL NUMCHK OPT0:CALL INLNCOMP ;'DE' set from 1st 'INLNCOMP' call DB 'CAL',0 JB NXOPT2 MOV AL,' ' ;fool the system MOV Byte Ptr CMDBUF+3,AL ;..'TBUF' so that it.. JMPS DOOPT ;..looks at option for dial ; NXOPT2: MOV AL,Byte Ptr CMDBUF+2 MOV BX, Of20 CALL TIMER MOV BX, Offset SM_DISC CALL SENDOUT MOV CH,20 CALL TIMER MOV AL,' ' ; ; If showing the +++ and ATH and ATD, etc. move the three semicolons up ; one line. ; DB 90H,90H,90H ;;; CALL STYPE MOV BX,(Offset SM_ATZ) CALL SENDO ;if neither, see if a valid number MOV CL,AL ;save MOV AL,CH ;get save first digit ADD AL,AL ;x2 ADD AL,AL ;x4 ADD AL,AL ;x8 ADD AL,CH ;x9 ADD AL,CH ;x10 ADD AL,CL MOV CH,AL ;save RET ;..... ; ; SAVEUSER: MOV AL,Cfset COMPLIST CALL COMPARE ;compares list pointed to by BX.. JB NOTVLD ;carry set = no match ; DOOPT: CALL SETFCB ;loads command buffer into FCB CALL PROCOPT ;check out the options JMP RESTART ;go to work ;..... ; ; NOTVLD: CALL NTUT ; SMRESET1: MOV CH,2 CALL RECV JNB SMRESET1 RET ;..... ; ; SM_ATZ DB 'ATZ',CR,'$' ;..... ; ; DIR: MOV CL,CURDSK INT 224 MOV Byte Ptr DISKSAV,AL CALL DIRLIST MOV AL,Byte Ptr DISKSAV MOV DL,AL MOV CL,SELDSK INT 224 JMP XPH CMP AL,15+1 ;user numbers are 0-15 JNAE L7A39 JMP NOTVLD L7A39: MOV Byte Ptr SAVUSR,AL RET ;..... ; ; NUMGET: MOV DX, Offset CMDBUF CALL INBUF MOV AL,Byte Ptr CMDBUF+2 ;get number CMP AL,' ' JNZ L7A40 RET L7A40: ; NUMCHK:VLDMSG JMP XPRT ;..... ; ; NTVLDMSG: CALL ILPRT DB '++ Invalid command ++',CR,LF,BELL,0 RET ;..... ; ; FUNCT: MOV AL,Byte Ptr INTCPT ;get the function key intercept char. AND AL,07FH ;strip off any parity LAHF ;save the charactRT ;..... ; ; ERASEF: MOV DX, OFFSET CMDBUF ;put cmd line into FCB at 'BX' MOV BX, FCB CALL CMDLINE CALL MOVEFCB ;move FCB+16 to FCB MOV AL,Byte Ptr .FCB+1 CMP AL,' ' JNZ L7A34 JMP NOTVLD ;go if no file specified L7A34: MOV DX, FC SUB AL,'0' ;remove ascii bias CMP AL,9+1 JNB L7A41 RET ;ok if 9 or less L7A41: POP BX ;remove 1st call from the stack POP BX ;remove 2nd call from the stack JMP NOTVLD ; GETUSER:MOV DL,0FFH ;get current user ; SETUSER:MOV CL,Uer for now XCHG AL,AH PUSH AX CALL CLRTST CALL ILPRT DB ' SPECIAL FUNCTION KEY TABLE' DB CR,LF,LF,0 POP AX ;get the character back XCHG AL,AH CMP AL,' ' ;see if a printing character JNB FUNCT1 ;if a printing character, shoB MOV CL,SRCHF INT 224 INC AL ;0 if file not found JNZ ERAFILE ;ok, go erase CALL ILPRT DB '++ File not found ++',CR,LF,BELL,0 JMP XPRT ;..... ; ; ERAFILE:MOV DX, FCB MOV CL,ERASE INT 224 CALL ILPRT DB 'File erased',CR,LF,0 SER ;set up bdos call INT 224 RET ;..... ; ; GETDISK:MOV CL,CURDSK ;get current drive INT 224 RET ;..... ; ; NORESET:CALL ILPRT DB '++ Terminal mode file open ++',CR,LF DB '++ Use WRT or DEL before LOG command ++',CR,LF Dw it LAHF XCHG AL,AH PUSH AX CALL ILPRT DB 'CTL-',0 POP AX XCHG AL,AH ADD AL,40H ;convert binary to ASCII character ; FUNCT1: CALL STYPE ;show on the CRT CALL ILPRT DB ' current function key intercept character',CR,LF,LF,0 ; ; JMP XPRT ;..... ; ; LOGNEW: MOV AL,Byte Ptr NFILFLG ;file open for memory save to disk? OR AL,AL JZ L7A35 JMP NORESET ;if yes, do not reset disk drive now L7A35: MOV AL,Byte Ptr CMDBUF+6 ;any disk drive specified? CMP AL,' ' JNZ LOGB CR,LF,BELL,0 XOR AL,AL JMP XPRT ;..... ; ; SETSPD: CALL ILPRT DB 'Delay between chars. (0-9): ',0 ; NOKEYS: CALL STAT JZ NOKEYS CALL KEYIN CALL STYPE CALL SAVEA SUB AL,'0' CMP AL,10 JNAE L7A42 JMP NOTVLD L7A42: MOV Byte Ptr ; Shows the functions of the (0-9) keys ; MOV BX, Offset FNCTBL-1 ;index into the function key table MOV CH,10 ;has ten entries ; FUNCT2: INC BX ;next table location MOV AL,Byte Ptr [BX] ;get the binary function number ADD AL,'0' ;convertNEW1 ;if not a blank, exit CALL GETDISK ;if not, use current drive ADD AL,'A' ;to compensate for next line ; LOGNEW1:SUB AL,'A' CMP AL,15+1 ;for drives 0-15 JNAE L7A36 JMP NOTVLD ;if more than 15, display error message L7A36: MOV B BYTDLY,AL ; CALL ILPRT DB 'Delay at end of line (0-9): ',0 ; NOKEYS1:CALL STAT JNZ L8A1 JMP NOKEYS1 L8A1: CALL KEYIN CALL STYPE CALL SAVEA SUB AL,'0' CMP AL,10 JNAE L8A2 JMP NOTVLD L8A2: MOV Byte Ptr CRDLY,AL ; SPDMSG: CALL binary to ASCII digits CALL STYPE MOV AL,' ' CALL STYPE ; FUNCT3: INC BX ;next table location MOV AL,Byte Ptr [BX] OR AL,AL ;see if a binary zero JZ FUNCT5 CMP AL,CR JNZ FUNCT4 CALL ILPRT DB '',0 JMPS FUNCT3 ; FUNCT4: CAyte Ptr DISKSAV,AL ;store requested drive CALL GETUSER ;pick up current user number MOV CH,AL ;save it MOV AL,Byte Ptr CMDBUF+7 ;get new user number CALL CHRCHK ;check the char. CALL FINDUSER MOV AL,Byte Ptr CMDBUF+8 ;get 2nd digit@  ILPRT DB CR,LF,'Char. delay (terminal file mode) is: ',0 MOV AL,Byte Ptr BYTDLY MOV CH,AL MOV AL,CH PUSH BX MOV BL,AL MOV BH,0 CALL DECOUT POP BX CALL ILPRT DB '0 ms. per character',CR,LF DB 'Line delay (terminal file mode) is: ' RET ;..... ; ; TOGCRC: MOV AL,Byte Ptr TOGGLECRC ;allowing CRC/CHECKSUM toggle? OR AL,AL JNZ L8A9 JMP NOTVLD ;if not, exit L8A9: MOV AL,Byte Ptr CRCDFLT ;get present value and switch it NOT AL MOV Byte Ptr CRCDFLT,AL CALL TOGCRC1 'Therefore ',0 CALL XOFFMSG JMP XPRT ;..... ; ; GETANS: MOV DX,(Offset CMDBUF) CALL INBUF MOV AL,Byte Ptr CMDBUF+2 ;get answer CMP AL,' ' CMC ;set the carry flag JNZ L8A15 RET L8A15: MOV CH,AL CMP AL,'N' MOV AL,0 JNZ L8A16 ,0 MOV AL,Byte Ptr CRDLY MOV CH,AL PUSH BX MOV BL,AL MOV BH,0 CALL DECOUT POP BX CALL ILPRT DB '00 ms. per character',CR,LF,0 JMP XPRT ;...... ; ; SAVEA: LAHF XCHG AL,AH PUSH AX CALL ILPRT DB CR,LF,0 POP AX XCHG AL,AH  ;show on CRT it has been changed JMP XPRT ;..... ; ; TOGCRC1:CALL ILPRT DB 'Mode: ',0 MOV AL,Byte Ptr CRCDFLT ;see if set for 'CRC' or 'CHECKSUM' OR AL,AL JZ CHEKMSG CALL ILPRT DB 'CRC',CR,LF,0 RET ;..... ; ; CHEKMSG:CALL ILPRT RET L8A16: MOV AL,CH CMP AL,'Y' MOV AL,1 JNZ L8A17 RET L8A17: POP AX ;preserve stack JMP NOTVLD ;..... ; ; XOFFMSG:CALL ILPRT DB 'XOFF testing ',0 MOV AL,Byte Ptr XOFFTST OR AL,AL JNZ XOTSTON CALL ILPRT DB 'NOT ',0 ; XOSAHF RET ;..... ; ; SETDRV: MOV AL,Byte Ptr CMDBUF+2 ;get the disk drive SUB AL,'A' ;convert to binary value CMP AL,15+1 ;for drives 0-15 JNAE L8A3 JMP NOTVLD L8A3: MOV DL,AL MOV CL,SELDSK ;select requested drive INT 224 MOV AL, DB 'CHECKSUM',CR,LF,0 RET ;..... ; ; TOGRUB: MOV AL,Byte Ptr TOGGLERUB OR AL,AL JNZ L8A10 JMP NOTVLD L8A10: MOV AL,Byte Ptr CONVRUB NOT AL MOV Byte Ptr CONVRUB,AL CALL TOGRUB1 JMP XPRT ;..... ; ; TOGRUB1:MOV AL,Byte Ptr CONVRUTSTON:CALL ILPRT DB 'used',0 ; XONMSG1:CALL ILPRT DB ' in terminal mode file output',CR,LF,0 RET ;..... ; ; XONMSG: CALL ILPRT DB 'XON ',0 MOV AL,Byte Ptr XONWAIT OR AL,AL JNZ XONMSG2 CALL ILPRT DB 'NOT ',0 ; XONMSG2:CALL ILPRT Byte Ptr CMDBUF+5 ;get user number, if any CMP AL,' ' ;keep current user area? JNZ L8A4 JMP XPRT L8A4: SUB AL,'0' ;convert to binary value CMP AL,1 ;if a '1', could be units or tens JNZ SETDRV1 ;if not, numbers stop at 15 so exit MOVB OR AL,AL JZ NORUBMSG CALL ILPRT DB 'Rub is backspace',CR,LF,0 RET ;..... ; ; NORUBMSG: CALL ILPRT DB 'Rub is rub',CR,LF,0 RET ;..... ; ; TOGLOC: MOV AL,Byte Ptr TOGGLELOC OR AL,AL JNZ L8A11 JMP NOTVLD L8A11: MOV AL,Byte PDB 'automatically tested after CR',0 JMPS XONMSG1 ;... ; ; SETUPENT: MOV AL,Byte Ptr SETUPTST OR AL,AL JNZ L8A18 JMP NOTVLD L8A18: MOV DX,(Offset CMDBUF)+1 CALL JMP_SETUPR MOV AL,Byte Ptr AUTODIAL ;using a Hayes-type modem? OR AL,A AL,Byte Ptr CMDBUF+6 ;check for a 2nd digit CMP AL,'0' JB SETDRV2 ;if less, not a valid number, ignore SUB AL,'0'-10 ;leave the '10' in as two digits used ; SETDRV1:CMP AL,15+1 ;user areas are 0-15 JNAE L8A5 JMP NOTVLD L8A5: MOV DL,AL tr LOCNXTCHR NOT AL MOV Byte Ptr LOCNXTCHR,AL CALL TOGLOC1 JMP XPRT ;..... ; ; TOGLOC1:CALL ILPRT DB 'Use ',0 MOV AL,Byte Ptr LOCNXTCHR OR AL,AL MOV AL,Byte Ptr EXTCHR JZ LOCMSG CALL SHFTYPE DB ' before local command',CR,LF,0 REL JNZ L8A19 JMP XPRT ;if not, exit, otherwise.. L8A19: MOV CH,'A' ;..send 'AT',CR to autodial modem.. CALL SENDCHR ;..to insure its baud rate.. MOV CH,'T' ;..matches that just selected. CALL SENDCHR MOV CH,CR CALL SENDCHR JMP XPR CALL SETUSER JMP XPRT ;back to work ; SETDRV2:MOV AL,1 JMPS SETDRV1 ;..... ; ; SETTIM: CALL SORPTST JZ L8A6 CALL ILPRT L8A6: CALL ILPRT DB 'Use 0-8 to give baud rate for ''S'' mode ' DB 'time-to-send message,',CR,LF DB 'where 0=1T ;... ; ; LOCMSG: CALL SHFTYPE DB ' to send local command to remote',CR,LF,0 RET ;..... ; ; TOGLF: MOV AL,Byte Ptr TOGGLELF OR AL,AL JNZ L8A12 JMP NOTVLD L8A12: MOV AL,Byte Ptr ADDLF NOT AL MOV Byte Ptr ADDLF,AL CALL TOGLF1 JMT ;..... ; ; NEWFILE:MOV AL,Byte Ptr NFILFLG ;file open for disk save? OR AL,AL JZ NOFILOPN ;if not, show "no file open" message MOV AL,Byte Ptr FCB3+1 ;check that file was requested CMP AL,' ' JZ NOFILOPN ;if no file, do not erase MOV DX10, 1=300, 2=450, 3=600, 4=710, 5=1200, ' DB '6=2400, ',CR,LF,'7=4800 8=9600 and 9=19200 Baud.' DB CR,LF,LF,'Enter value: ',0 CALL NUMGET CMP AL,9+1 ;only looking for 0-9 answers JNAE L8A7 JMP NOTVLD L8A7: MOV Byte Ptr MSPEED,AL CALL SETP XPRT ;..... ; ; TOGLF1: CALL ILPRT DB 'LF ',0 MOV AL,Byte Ptr ADDLF ;adding lf after cr? OR AL,AL JNZ LFMSG ;if yes, exit CALL ILPRT DB 'NOT ',0 ; LFMSG: CALL ILPRT DB 'sent after CR in "L" or "T" for a disk file',CR,L,(Offset FCB3) ;otherwise erase the old file MOV CL,ERASE INT 224 XOR AL,AL MOV Byte Ptr NFILFLG,AL ;no file mentioned, reset flags MOV Byte Ptr SAVEFLG,AL MOV BX,(Offset FCB3) CALL INITFCB MOV BX,(Offset BUFFER) ;reset flags to bottom of rTIM1 JMP XPRT ;..... ; ; SETTIM1:CALL SORPTST JNZ SETTIM2 CALL ILPRT DB 'Rate for the S mode time-to-send message is set to ',0 JMPS SETTIM3 ;... ; ; SETTIM2:CALL ILPRT DB 'Modem speed is ',0 ; SETTIM3:JMP PRTBAUD ;..... ; ; SORF,0 RET ;..... ; ; TOGTXOFF: MOV AL,Byte Ptr TOGXOFF OR AL,AL JNZ L8A13 JMP NOTVLD L8A13: CALL ILPRT DB 'Use XOFF testing? (Y/N): ',0 CALL GETANS JB NOCHG3 MOV Byte Ptr XOFFTST,AL ; NOCHG3: CALL XOFFMSG CALL ILPRT DB CR,LF,'Uam just.. MOV Word Ptr HLSAVE,BX ;..to insure they are there JMP XPRT ;..... ; ; WRTFIL: MOV AL,Byte Ptr NFILFLG ;saving memory for a disk file? OR AL,AL JZ NOFILOPN ;not saving a file, don't bother writing CALL WRTFIL1 ;close the file MPTST:MOV AL,Byte Ptr SETUPTST ;if setup is 'YES' or PMMIMODEM is.. MOV CH,AL ;..'YES' or autodial modem is 'YES'.. MOV AL,Byte Ptr PMMIMODEM ;..return with zero bit not set. OR AL,CH JZ L8A8 RET L8A8: MOV AL,Byte Ptr AUTODIAL OR AL,CH se XON waiting after (Y/N): ',0 CALL GETANS JB NOCHG4 MOV Byte Ptr XONWAIT,AL ; NOCHG4: CALL XONMSG MOV AL,Byte Ptr XONWAIT OR AL,AL JNZ L8A14 JMP XPRT L8A14: NOT AL MOV Byte Ptr XOFFTST,AL ;do not allow both CALL ILPRT DB A OV Byte Ptr SAVEFLG,AL MOV Byte Ptr WRFLG,AL MOV BX,(Offset FCB3) CALL INITFCB ;blank out 'FCB' to written file MOV BX,(Offset BUFFER) ;can't be erased MOV Word Ptr HLSAVE,BX ;reset to buffer start for next time JMP XPRT ;... ; ; WRTFIL1:HF RET ;..... ; ; SPACES: MOV AL,' ' ;space MOV SI,DX MOV [SI],AL LAHF ;1 INC DX SAHF MOV SI,DX MOV [SI],AL LAHF ;2 INC DX SAHF MOV SI,DX MOV [SI],AL LAHF ;3 INC DX SAHF RET ;..... ; ; ; ; COMPARE:MOV  'B' DISCFLG DB 'D' JMPCMD DB 'J' LOCCHFLG DB 'L' ORIGFLG DB 'O' QFLG DB 'Q' RSEEFLG DB 'R' SSEEFLG DB 'S' VSEEFLG DB 'V' XITFLG DB 'X' EPARITY DB '0' ;even parity sub-option (only in S or R mode) OPARITY DB '1' ;odd parity sub-option (only MOV AL,Byte Ptr FCB3+1 ;check that file was requested CMP AL,' ' JNZ L8A20 RET L8A20: CALL WRTDSK ;write buffer to disk if not empty WRTFIL2: MOV DX,(Offset FCB3) ;close the file MOV CL,CLOSE INT 224 XOR AL,AL MOV Byte Ptr NFILFLG,AL CH,Byte Ptr [BX] ;compares 'A' reg. with list.. ; COMPLP: INC BX ;..addressed by BX. first element.. CMP AL,Byte Ptr [BX] ;..of list must be number of elements.. JZ VALID ;..being compared. returns with.. DEC CH ;..carry set if 'A' reg. does in S or R mode) OPTBE EQU (Offset $) ;..transfer when program initially called. ; ; ; The following must be in the same order as the table above: ; RESTROPT DB 'A','B','D','J','L','O','Q','R','S','V','X','0','1' ; ; ; The next 14 bytes equal the ;file written, reset flags RET ;..... ; ; NOFILOPN: CALL ILPRT DB '++ No File Open ++',CR,LF,BELL,0 JMP XPRT ;..... ; ; ; THIS ROUTINE DISPLAYS THE PHONE NUMBERS IN THE LIBRARY ; NUMPRN: PUSH BX CALL CLRTST CALL ILPRT DB ' not.. 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 knumber of bytes between RECDNOB and ; RECDNOE. ; RESTSN DB 0,0,0,0,0,0 DW (Offset BUFFER) DB 0,0,0,0,0,NAK ; RECDNOB EQU (Offset $) ;start of table marker RCVRNO DB 0 ;\ RECDNO DB 0,0 ; \ ERRCT DB 0 ; \ ERRCDE DB 0 ; \ EOFLG DB 0  Library of Phone Numbers of Remote Systems' DB 0 MOV CL,18 ;number of lines to move MOV BX, (OFFSET NUMBLIB) ;address of source memory MOV DX,(Offset BUFFER) ;address of target memory CALL NEWLINE ;start with CRLF MOV SI,DX ;+LF MOV [Seypress CMP AL,'C'-40H ;control-c to abort? JNZ CLRTST POP BX ;clear stack of return address CALL CRLF ;turn up a blank line JMP XPRT ;..... ; ; CLRTST: MOV AL,Byte Ptr SCRNTEST OR AL,AL JZ LOTSALF JMP CLRSCRN ;..... ; ; LOTSAL ; \ 14 bytes between table markers RECPTR DW (Offset BUFFER) ; / RECINBF DB 0 ; / MAXEXT DB 0 ; / RCNT DB 0,0 ; / DATAFLG DB 0 ;/ BENHERE DB NAK ; RECDNOE EQU (Offset $) ;end of table marker ; ; ; Additional 16-bit initialiI],AL LAHF ;and bump it INC DX SAHF ; NUMPRN1:LAHF ;skip PMMI dialing letter INC BX SAHF LAHF ;and equal sign INC BX SAHF MOV CH,LIBLEN-2 ;number of bytes to move CALL MOVE ;move to buffer CALL SPACES ;2 entries + 3 spF:MOV AL,CR CALL STYPE MOV CH,12 MOV AL,LF ; LFLOOP: CALL STYPE DEC CH JNZ LFLOOP RET ;..... ; ; CURPAR: CALL CLRTST CALL ILPRT DB ' Current Settings',CR,LF,LF,0 CALL TOGCRC1 CALL TOGRUB1 MOV AL,Byte Ptr LSTTST zed storage ; CRCVAL DW 0 DIALCT DW 0 HLSAVE DW (Offset BUFFER) HLSAVE1 DW (Offset PBUFF) HLSAVE2 DW (Offset PBUFF) ; ; ; Additional general purpose initialized storage ; ABORTFLG DB 0 ACKFLG DB 0 CRCFLAG DB 0 CRFLAG DB 0 CURRENT DB 52 ;PMaces = 63 characters PUSH BX ;save source address PUSH DX ;save destination address LAHF ;skip next two characters INC BX SAHF LAHF INC BX SAHF MOV DX,(17*LIBLEN) ;get offset of 17 times entry length LAHF ;add it to the sourcOR AL,AL JZ NOLIST1 CALL LSTMSG ; NOLIST1:CALL SETTIM1 CALL ILPRT DB 'Terminal mode file buffer is ',0 MOV AL,Byte Ptr NFILFLG ;saving memory for a disk file? OR AL,AL JNZ ACTIVE ;if yes, go say "active" CALL ILPRT DB 'in',0 ;if notMI 300 baud speed value (defaults to 300) DLYFLG DB 0 ECHOFLG DB 0 EXACFLG DB 0 FIRSTME DB 0 FNCKY DB '^' ; Function Key Intercept character FNKFLG DB 0 ;function key activity flag FSTFLG DB 0 LISTFLG DB 0 LOCFLG DB 0 MFFLG1 DB 0 MODCTLB DB e address ADD BX,DX RCR SI,1 SAHF RCL SI,1 POP DX ;restor destination address MOV CH,LIBLEN-2 ;get length of library entry CALL MOVE ;move another entry POP BX ;restore source address CALL NEWLINE ;start next line DEC CL ;one, say "inactive" ; ACTIVE: CALL ILPRT DB 'active',CR,LF,'Unused portion of buffer is ',0 CALL GETSPC CALL ILPRT DB ' bytes',CR,LF,0 CALL TOGLOC1 CALL TOGLF1 CALL XOFFMSG CALL XONMSG CALL SPDMSG CALL CRLF CALL CRLF CALL CRLF JMP 07FH NFILFLG DB 0 ONERR DB 0 OPTION DB 0 ORIGSAV DB 0 RINGBKFL DB 0 SAVEFLG DB 0 UARTCTLB DB ORIGMOD ;for originate mode WRFLG DB 0 XFLG DB 0 CMDBUF DB 80H,0 ;command buffer control area ; ; ; General purpose unitialized storage area ;  less line to print JNZ NUMPRN1 ;if not finished, do another MOV AL,'$' MOV SI,DX MOV [SI],AL MOV CL,PRINT MOV DX,(Offset BUFFER) ;point to table of numbers to print INT 224 CALL CRLF CALL CRLF POP BX JMP XPRT ;finished, back to pXPRT ;..... ; ; GETSPC: MOV BX,(Offset BUFTOP) ;top of memory buffer MOV DX,Word Ptr HLSAVE ;current buffer location SUB BX,DX CALL DECOUT ;print the space remaining RET ;..... ; ; ;********************************************************RS 128 ;storage area for 'CMDBUF' BGNMS RS 2 TIMFLG RS 1 FLTRFLG RS 1 CHRFLG RS 1 TIMVAL RS 2 QUIKTIM RS 2 DISKNO RS 1 DISKSAV RS 1 DSTORE RS 1 FILECT RS 1 FTYCNT RS 1 MAXRAM RS 1 NAMECT RS 1 NBSAVE RS 2 OLDUSER RS 1 SENDFLG RS 1 SAVUSR rompt ;..... ; ; NEWLINE:MOV AL,CR ;puts CRLF at memory pointed by 'DE' MOV SI,DX ;store it MOV [SI],AL MOV AL,LF ;line feed LAHF ;bump pointer INC DX SAHF MOV SI,DX ;store lf MOV [SI],AL LAHF ;bump pointer INC DX SA*************** ; ; D - A - T - A A - R - E - A ; ;*********************************************************************** ; ; COMPLIST DB 6,'S','R','T','E','L','M' ;..... ; ; ; OPTION TABLE ; OPTBL EQU (Offset $) ANSWFLG DB 'A' BATCHFLG DBA RS 1 ; FCB3 RS 33 FCB4 RS 33 FCBBUF RS 15 MFNAME5 RS 12 ;requested name MFNAME6 RS 12 ;current name RS 100 ;stack depth ; ; EVENPAGE EQU ((Offset $)+255)/256*256 ;sets buffers on even page ; ; ORG EVENPAGE ; ; STACK EQU (Offset EVENnterrupt BDOSBP EQU 24A0H ;bdos data page base \ MONTH EQU 24C0H ;month location in bdos \ DAYS EQU 24C3H ;days location in bdos \ using the proper system YEARS EQU 24C6H ;years location in bdos > call will eliminaea all HOURS EQU 2SECTRAN EQU 16 ;sector translate SETDMAB EQU 17 ;set dma segment address GETSEGB EQU 18 ;get mem desc table offset GETIOB EQU 19 ;get i/o byte SETIOB EQU 20 ;set i/o byte ; ascii constants CR EQU 0DH ;carriage return LF EQU 0AH ;line feedPAGE)-2 ;store original stack pointer CRCTBL RS 512 ;two tables of 128 bytes each BUFFDSK RS 128 ;buffer for disk save BUFFPNT RS 128 ;buffer for printer BUFFER RS 1024*BUFSIZ ;send/receive file buffer BUFTOP RS 0 ;filled in when length is fo4C9H ;hours location in bdos / this - do a syscall 31h MINS EQU 24CBH ;minutes location in bdos / SECS EQU 24CDH ;seconds location in bdos / NXTAVL EQU 1 ;offset into memtable for available memory BCONST EQU 2806H ;bios console status jmp lo ESC EQU 1BH ;escape character CTRLC EQU 'C'-40H ;control c CPMEOM EQU '$' ;end of message ; flag values for i/o routines CHRRDY EQU 00000001B ;character ready at modem XCHRRDY EQU 11111110B ;mask to turn off chrrdy ONLINE EQU 00000010B ;phund PBUFF EQU (Offset $) ;printer buffer starts here NAMEBUF EQU (Offset $) ;batch-mode filenames buffer ;..... ; ; ; BDOS EQUATES ; RDCON EQU 1 WRCON EQU 2 BLIST EQU 5 PRINT EQU 9 RDBUF EQU 10 CONST EQU 11 CPMVER EQU 12 RESET EQU 13 SELcation BCONIN EQU 2809H ; " " input " " BCONOUT EQU 280CH ; " " output " " JUMP EQU 0E9H ;intra-segment direct jump instruction JUMPF EQU 0EAH ;inter-segment direct jump instruction CALLN EQU 0E8H ;intra-segment call instructone answered, system on line XONLINE EQU 11111101B ;mask to turn off xonline UPCON EQU 00000100B ;upper case only UPCOFF EQU 00000000B ;lower case ok UPCMSK EQU 11111011B ;upper case mask ANYNULL EQU 11110000B ;mask to test for nulls ; ***!!! theDSK EQU 14 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 SETDMA EQU 26 DSKALL EQU 27 DSKPAR EQU 31 USER EQU 32 FILSIZ EQU 35 REIPL EQU 0 BDOS EQU 5 FCB EQU 5Cion CALLF EQU 09AH ;inter-segment call instruction COMDRIV EQU 0 ;drive for cmd (com) files (0 = drive a:) BBSUSR EQU 0EH ;user area for bbs file (user #14) SYSUSR EQU 0 ;user area for system files DFTDRV EQU 0736H ;location in bdos for default  following equates are all hardware dependent !!!*** ; *** serial port equates *** DATPORT EQU 0E1H ;modem data port STPORT EQU 0E0H ;modem status port RPORT EQU 0E2H ;modem mode port CPORT EQU 0E3H ;modem command port ; switch hook & modemH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32 FCBRNO EQU FCB+32 FCB2 EQU 6CH TBUF EQU 80H ;..... ; ; END drive # DFTUSR EQU 0737H ;location in bdos for default user # ; cpm system calls SRESET EQU 0 ;reset SCONIN EQU 1 ;console input SCONOUT EQU 2 ;console output SDCIO EQU 6 ;direct console i/o SGIOB EQU 7 ;get i/o byte SSIOB EQU 8 ;set i/o commands out to stport BYE EQU 0 ;hangup ANSW EQU 2 ;off hook answer mode BIT8 EQU 0CH ;eight data bits NOPY EQU 10H ;no parity TSB EQU 40H ;2 stop bits NORM EQU BIT8+NOPY ;normal 8 bits no parity P110 EQU BIT8+NOPY+TSB ;same w/2 stop bits  byte SPRTSTR EQU 9 ;print string SRDBUF EQU 0AH ;read console buffer SCONST EQU 0BH ;get console status SRSTDSK EQU 0DH ;reset disk system SSELDSK EQU 0EH ;select disk drive SGETDRV EQU 19H ;get current drive SUSER EQU 20H ;set/get user # S ; modem status input on rport DTD EQU 1 ;dial tone detect RDET EQU 2 ;ring detect CTS EQU 4 ;carrier detect CONN EQU 10H ;connected 0=yes 1=no ; control port filter masks LE300 EQU 7FH ;less than or equal to 300 baud GT300 EQU 5FH ;gre PAGESIZE 71 TITLE 'BYE86' ; This program was given to Bill Spoolhoff by the author, Ed Bertness, ; SYSOP of the San Antonio HUG. It was origionally written to run under ; CP/M-86 on the HEATH ZENITH Z-100. It was modified for use with a ; COMPCHAIN EQU 2FH ;chain program SSYSDAT EQU 31H ;get system data address SBIOS EQU 32H ;direct bios call SGETDMA EQU 34H ;get dma base ; bios call # for direct bios call system call CBOOT EQU 0 ;cold boot initialize WBOOT EQU 1 ;warm boot CONater than 300 baud ; baudrate divisors B300 EQU 52 ;300 baud B600 EQU 26 ;600 baud ; pmmi status masks TRDY EQU 1 DAV EQU 2 OE EQU 10H FE EQU 20H ANYERR EQU FE OR OE ; miscellaneous equates MHZ EQU 8 CWAIT EQU 20 ; ***keyboard UPRO S-100 CP/M 8-16 system. Do not delete the authors' copyright ; notice in the welcome message note in further editions or versions. ; ; Use of this program in commercial enterprise for monetary gain is ; strictly forbidden under the U.S. copyrigST EQU 2 ;get console status CONIN EQU 3 ;input console character CONOUT EQU 4 ;output console character PRNTR EQU 5 ;write character to printer PUNCH EQU 6 ;write punch character READER EQU 7 ;read reader character HOME EQU 8 ;move to track 0equates*** KEYST EQU 055H ;keyboard status port KEYRDY EQU 1 ;keyboard has data available ;======================================================================= ; ; program starts here ; ;=============================================ht laws. Please send any re- ; visions of this program to Atlas Micro Associates "MCI" BBS-RCP/M. We ; will serve as a collection point for forwarding to the author for fur- ; ther distribution. ; ; *** system equates *** ; BDOS EQU 0E0H ;bdos i0 SELDSK EQU 9 ;select disk drive SETTRK EQU 10 ;set track number SETSEC EQU 11 ;set sector number SETDMA EQU 12 ;set dma offset address READ EQU 13 ;read selected sector WRITE EQU 14 ;write selected sector LISTST EQU 15 ;return list status B ========================== CSEG ORG 100H ; entry point START: CALL GETOSEG ;go get operating system base address CALL CHKUSR ;q - are we set to user 0? JE USROK ;yes - don'T BOTHER TO SET IT CALL SETDU ; else set user 0 USROK: CALL in the 'BIOS' to keep this code resident at all times. ; ; enter: none ; exit: es: = operating system segment ; ax = segment # of next available memory ; bx = offset in segment 40 to read/write lower memory bound GETMSEG:MOV BCALL1,GETSEGB ;geet from beginning of o.s. to fix ; dx = # of bytes offset from beginning of o.s. to fix ; ds: = segment where we expect to find bye86, if loaded ; es: = operating system segment MEMFIX: PUSH CX ;save segment # for new i/o calls SUB CX,SYSSEG CHKDRV ;q - are we set to drive 0? JE DRVOK ;yes - don'T SET IT CALL SETDU ; else set drive 0 DRVOK: CALL GETMSEG ;get first segment of free memory CALL CHECK ;q? have we been loaded once? JZ NOFIX ;yes - forget this stuff CALL SETSEG t offset to bios memory area MOV CL,SBIOS MOV DX,OFFSET BCALL1 INT BDOS ADD BX,NXTAVL ;pointer is offset 1 into table MOV AX,SYSSEG MOV ES,AX MOV AX,ES:[BX] ;ax contains seg of next available mem RET ; check to see if bye has already bee ;rationalize segment # to 40h (operating sys) MOV AX,CX ;\ MOV CL,4 ; > compute offset relative to 40h SHL AX,CL ;/ MOV DX,AX CALL MOVEIT ;move routines low memory POP DS ;put segment # in ds MOV CX,DX ; and offset in cx MOV AX,(OFFS; else compute new segment for mem pointers CALL MEMFIX ; move memory and adjust jumps, calls, etc. CALL SIGNON ; sign on system NOFIX: CALL CARDET ;q - did remote type "bye"? JNZ BYPASS ;yes- say goodbye and hangup CALL HANGUP2 ; else don'n loaded once ; ; enter: es: = operating system segment ; ax = segment # of next available memory (lower bound) ; bx = offset in segment 40 to read/write lower memory bound ; exit: ax = segment # of next available memory (lower bound) ; bx = oET FLAG) - (OFFSET CONSTE) ;compute new offsets ADD AX,DX ;for the locations MOV BX,(OFFSET PTCHF1) - (OFFSET CONSTE) ;flag, ptchf1 - ptchfa, MOV DS:[BX],AX ;& patch1 MOV BX,(OFFSET PTCHF2) - (OFFSET CONSTE) ;write them in their MOV DS:[BX],AX ;T SAY GOOD-BYE AND HANG UP BYPASS: CALL HANGUP ;say good bye,turn off modem CALL ANSLOOP ;and wait for call WAITCAR:CALL CARDET ;q - detect carrier? JNZ CAROK PUSH CX MOV CX,CWAIT*10 ;wait for the carrier DEL1: CALL CARDET JNZ CAROK ffset in segment 40 to read/write lower memory bound ; dx = length of moved portion in paragraphs ; es: = segment of fix - if there CHECK: PUSH AX MOV DX,(PGMLEN+15)/16 ;get length of pgm in paragraphs SUB AX,DX MOV ES,AX MOV SI,CS:OFFSET Inew locations in low MOV BX,(OFFSET PTCHF3) - (OFFSET CONSTE) ;memory. ptchf1 - a MOV DS:[BX],AX ;all point to the same MOV BX,(OFFSET PTCHF4) - (OFFSET CONSTE) ;location. MOV DS:[BX],AX ; MOV BX,(OFFSET PTCHF5) - (OFFSET CONSTE) ; MOV DS:[BX] CALL DELAY ;delay loop LOOP DEL1 POP CX JMP BYPASS ;no carrier go back and hangup CAROK: CALL SETBD ;do speed detection CALL SETFLG ;let i/o system know we'RE ON LINE CALL HELLO ;send greeting & version # CALL GETNUL ;get # of nulls DMSG MOV DI,(OFFSET IDMSG) - (OFFSET CONSTE) MOV CX,(OFFSET ENDMSG) - (OFFSET IDMSG) REPE CMPSB JNZ SEGOK MOV NEWSEG,AX POP AX RET SEGOK: POP AX MOV NEWSEG,AX RET ; set new segment for lower memory bound ; enter: ax = segment # of,AX ; MOV BX,(OFFSET PTCHF6) - (OFFSET CONSTE) ; MOV DS:[BX],AX ; MOV BX,(OFFSET PTCHF7) - (OFFSET CONSTE) ; MOV DS:[BX],AX ; MOV BX,(OFFSET PTCHF8) - (OFFSET CONSTE) ; MOV DS:[BX],AX ; MOV BX,(OFFSET PTCHF9) - (OFFSET CONSTE) ; MOV DS:[BX] CALL GETUPC ;check lower case capability EXIT: CALL PRLDMSG ;say we are loading RBBS MOV AX,SYSSEG ;\ MOV ES,AX ; \ set user # of MOV BX,DFTUSR ; / com file - rbbs MOV ES:BYTE PTR [BX],BBSUSR ;/ in this instance ; move the command next available memory (lower bound) ; bx = offset in segment 40 to read/write lower memory bound ; dx = length of moved portion in paragraphs ; es: = segment of fix, if there ; exit: ax = length of available memory ; bx = offset in segment 40,AX ; MOV BX,(OFFSET PTCHFA) - (OFFSET CONSTE) ; MOV DS:[BX],AX ; MOV BX,(OFFSET PATCH1) - (OFFSET CONSTE) ; MOV AX,[BX] ; ADD AX,DX ;the following routines MOV DS:[BX],AX ;set up the pointers MOV BX,BCONST ;to the old and new MOV DX,(OFF line into the dma area and do a program chain sys call MOV CL,SGETDMA INT BDOS MOV SI,OFFSET CMDLINE MOV CX,(OFFSET ENDCMD) - (OFFSET CMDLINE) + 1 MOV DI,BX REP MOVSB MOV CL,SCHAIN INT BDOS ; get segment in which operating system  to avail mem length ; cx = segment # of next available memory (lower bound) ; dx = length of moved portion in paragraphs ; es: = operating system segment SETSEG: PUSH DX MOV CX,AX MOV AX,SYSSEG MOV ES,AX ADD DX,CX MOV ES:[BX],DX POPSET CONSTE)-(OFFSET CONSTE) ;bios routines. fixit MOV AX,(OFFSET CON1)-(OFFSET CONSTE) ;computes the offset CALL FIXIT ;from the old jump to MOV BX, BCONIN ;the new jump and MOV DX,(OFFSET CONINE)-(OFFSET CONSTE) ;writes it in the old MOV AX,(Oresides GETOSEG:MOV CL,SSYSDAT INT BDOS MOV AX,ES MOV SYSSEG,AX RET ; check that we'RE IN USER AREA 0 CHKUSR: MOV CL,SUSER MOV DL,0FFH INT BDOS CMP AL,0 RET ; check that we'RE LOGGED ONTO DRIVE 0 CHKDRV: MOV CL,SGETDRV  DX ADD BX,2 MOV AX,ES:[BX] SUB AX,DX MOV ES:[BX],AX RET ; memfix - move the necessary portions of bye86 and patch required jumps ; in 'BIOS' ; ; enter: ax = ? ; bx = offset in segment 40 to avail mem length ; cx = segment # of next FFSET CON2)-(OFFSET CONSTE) ;bios jump location. CALL FIXIT ;it then computes the MOV BX, BCONOUT ;offset from the new MOV DX,(OFFSET CONOUTE)-(OFFSET CONSTE) ;location to the loca- MOV AX,(OFFSET CON3)-(OFFSET CONSTE) ;tion the old jump took CAINT BDOS CMP AL,0 RET ; set drive and user to 0 SETDU: MOV AX,SYSSEG MOV ES,AX MOV BX,DFTDRV MOV ES:BYTE PTR [BX],0 INC BX MOV ES:BYTE PTR [BX],0 RET ; move essential stuff to reside just above bios and patch memory ; pointersavailable memory (lower bound) ; dx = length of moved portion in paragraphs ; es: = operating system segment ; exit: (after moveit) ; ax = (pop) seg # next avail mem ; bx = offset in segment 40 to avail mem length ; cx = # of paragraphs offsB LL FIXIT ;and saves it in the MOV CX,(OFFSET CON2A) - (OFFSET CON1) ;new routine. MOV BX,(OFFSET CON1) - (OFFSET CONSTE) + 1 ; ** this routine MOV AX,DS:[BX] ;computes the offset SUB AX,CX ;for the call at loca- MOV BX,(OFFSET CON2A) - (OFFSET rn off dtr - forcing modem to hang up ** HANGUP: CALL SIGNOFF HANGUP2:MOV AX,NEWSEG MOV ES,AX MOV BX,(OFFSET FLAG) - (OFFSET CONSTE) MOV AL,ES:[BX] AND AL,XONLINE MOV ES:[BX],AL MOV AL,BYE OUT STPORT,AL ;reset port OUT CPORT,AL RET gain SPDOK: LEA DX,FRSTMSG MOV CL,SPRTSTR INT BDOS ABORT: RET ; ************************************ ; *** end of system dependent code *** ; ************************************ ; print the sign on message HELLO: LEA DX,GRTING MCONSTE) + 1 ;tion con2a of the new MOV DS:[BX],AX ;routines in low memory RET ; routine to patch 3 bios jump locations - enter with bx = offset ; (relative to 400h) of 'BIOS' jump instruction in 'BX', and offset ; (relative to beginning of avail ; delay routine DELAY: PUSH CX MOV CX,4167*MHZ ;timing constant * clock mhz DELAY1: LOOP DELAY1 POP CX RET ; ** answer loop - monitor modem port for ring - keep track of keyboard ; for a 'CTL-C' ** ANSLOOP:IN AL,RPORT ;get ring statuOV CL,SPRTSTR INT BDOS RET PRLDMSG:LEA DX,LDMSG MOV CL,SPRTSTR INT BDOS RET ; check keyboard status from local console - returns zero flag set if ; character ready KBDST: MOV CL,SCONST INT BDOS TEST AL,1 RET ; get local keyable low memory) of new 'BIOS' jump ; in 'AX'. ; ; entry: ; ds: base of available memory - where the new routines ; will be moved ; es: beginning of operating system (seg 40h, 400h absolute) ; ax offset of jump vector in new routine relative tos NOT AL ;reverse for pmmi logic TEST AL,RDET ; ringing? JNZ ANSWER ; - yes, go answer CALL KBDST ; - no, go check keyboard for abort ; has key been typed? JZ ANSLOOP ; - no, go back and check for ring CALL GETCHAR ; - yes, get charaboard character - keyboard status should have indicated ; that a character is ready GETCHAR:MOV CL,SCONIN INT BDOS RET ; remove bye86 from memory and put everything back the way it was REMOVE: MOV AX,SYSSEG MOV ES,AX MOV AX,NEWSEG SUB ds ; bx offset of old console routine relative to es ; cx offset of new program area relative to es (40h) ; dx offset of new console routine relative to ds ; FIXIT: PUSH CX PUSH DX MOV DX,AX INC BX MOV AX,ES:[BX] ADD AX,2 ADD AX,BX cter CMP AL,CTRLC ; ^c? JNZ ANSLOOP ; - no, go back and check for ring LEA DX,QUERY ; - yes, ask if for real MOV CL,SPRTSTR INT BDOS CALL GETCHAR ;get response CALL FIXUPC CMP AL,'Q' ; quit? JNZ ANSLOOP ; - no, go back to check ring  AX,SYSSEG MOV CL,4 SHL AX,CL MOV DX,AX MOV BX,(OFFSET CON1) - (OFFSET CONSTE) + 1 MOV CX,(OFFSET BCONST) + 1 CALL REMOV1 MOV BX,(OFFSET CON2) - (OFFSET CONSTE) + 1 MOV CX,(OFFSET BCONIN) + 1 CALL REMOV1 MOV BX,(OFFSET CON3) - (OFFSET C ADD CX,DX ADD CX,3 SUB AX,CX INC DX XCHG BX,DX MOV DS:[BX],AX XCHG BX,DX POP DX POP CX MOV AX,BX ADD AX,2 ADD DX,CX SUB DX,AX MOV ES:[BX],DX RET ; routine to relocate program ; ; enter: dx = # of bytes offset from begin POP AX ;clear stack JMP REMOVE ; ** answer phone and set proper baud rate ** ANSWER: IN AL,RPORT ;was it a ring or relay bounce NOT AL ;reverse for pmmi logic TEST AL,RDET ;test it JZ ANSLOOP ;no go back and wait for a real ring ENDRIONSTE) + 1 MOV CX,(OFFSET BCONOUT) + 1 CALL REMOV1 CALL REMOV2 MOV BCALL1,GETSEGB ;get offset to bios memory area MOV CL,SBIOS MOV DX,OFFSET BCALL1 INT BDOS ADD BX,NXTAVL ;pointer is offset 1 into table MOV AX,NEWSEG MOV ES:[BX],AX ADning of o.s. to fix ; cs: = cs ; es: = operating system segment ; exit: program relocated ; ax = cs: ; cx = pgmlen ; ds: = cs: MOVEIT: MOV DI,DX MOV SI,OFFSET CONSTE MOV CX,PGMLEN REP MOVSB RET ;******************************NG:CALL DELAY ;delay till it stops ringing IN AL,RPORT ;check again NOT AL ;pmmi logic TEST AL,RDET JNZ ENDRING ;loop till ringing stops ANSWER1:MOV AL,LE300 ;filter value for 300 bps (dtr) OUT CPORT,AL CALL DELAY ;give it time to turn oD BX,2 MOV AX,ES:[BX] ADD AX,(PGMLEN + 15)/16 MOV ES:[BX],AX MOV CL,SRESET MOV DL,0 INT BDOS REMOV1: ADD BX,DX MOV AX,ES:[BX] ADD AX,BX SUB AX,CX MOV BX,CX MOV ES:[BX],AX RET ; remove all the patches to the bios and reset memo************************************ ;*** hardware dependent code follows *** ;*** the following routines will work on a heath h100 computer *** ;****************************************************************** ; ** print signon - set time, daten MOV AL,P110+ANSW ;answer it OUT STPORT,AL CALL DELAY ;give it time to answer IN AL,DATPORT ;clear modem port IN AL,DATPORT ;make sure it is clear RET ; set the baud rate SETBD: MOV AL,LE300 ;filter value for less than or = 300 bps OUry pointers REMOV2: PUSH DX LEA DX,TURNOFF MOV CL,SPRTSTR INT BDOS MOV CX,PGMLEN MOV AX,0 POP BX ZERO: MOV ES:[BX],AX INC BX LOOPNZ ZERO RET ; set the flag byte in the new i/o routines to show that the modem is ; on line SETFLG, and statistics in 25th line ** SIGNON: MOV AX,SYSSEG ;get operating system segment MOV DS,AX MOV SI,OFFSET MONTH MOV AX,CS MOV ES,AX MOV DI,OFFSET CAL MOV CX,8 REP MOVSB INC SI MOV DI,OFFSET TIME MOV CX,8 REP MOVSB MOV AX,CS T CPORT,AL MOV AL,NORM ;set for 8 bits,no parity,1 stop bit OUT STPORT,AL MOV AL,B300 ;set the divisor to 300 bps OUT RPORT,AL CHKBD1: IN AL,RPORT ;is carrier still there NOT AL ;pmmi logic TEST AL,CTS JZ ABORT ;no IN AL,STPORT ;yes,: MOV AX,NEWSEG MOV ES,AX MOV BX,(OFFSET FLAG) - (OFFSET CONSTE) MOV AL,ES:[BX] OR AL,ONLINE MOV ES:[BX],AL RET ; get the number of nulls required after cr GETNUL: LEA DX,NULMSG MOV CL,SPRTSTR INT BDOS CALL GETCHAR SUB AL,'0' CMMOV DS,AX MOV ES,AX LEA DX,LOADMSG MOV CL,SPRTSTR INT BDOS RET ; ** check modem port to see if there is a carrier ** CARDET: IN AL,RPORT ;get ring port NOT AL ;reverse for pmmi logic TEST AL,CTS ;see if car is present RET ; ** tunow check it for data available TEST AL,DAV JZ CHKBD1 ;no try again IN AL,DATPORT ;yes, then take it AND AL,07FH ;strip the parity CMP AL,CR ;is it a carriage return JNZ NOTHI ;no JMP SPDOK ;yes NOTHI: JMP SETBD ;if it was no do it aC P AL,0AH JNC GETNUL MOV CL,4 SHL AL,CL MOV CL,AL MOV AX,NEWSEG MOV ES,AX MOV BX,(OFFSET FLAG) - (OFFSET CONSTE) MOV AL,ES:[BX] OR AL,CL MOV ES:[BX],AL RET ;get upper case conversion option GETUPC: LEA DX,UPCMSG MOV CL,SPRTSTR  AL,07FH ;strip the parity AND FLAG,XCHRRDY ;same here, no instructions between PTCHF5 EQU (OFFSET $) - 3 ;these two RET ; 'BIOS' comes here to output character - dual output to local and ; remote consoles CONOUTE:TEST FLAG,ONLINE ;do not put R KEY TO RESUME',CR,LF,CPMEOM NULMSG DB CR,LF,'HOW MANY NULLS DOES YOUR TERMINAL REQUIRE? (0-9) - ' DB CPMEOM UPCMSG DB CR,LF,'CAN YOUR TERMINAL DISPLAY LOWER CASE? (Y OR N) - ' DB CPMEOM LOADMSG DB CR,LF,'LOADED ',CR,LF,CPMEOM CAL DB 0,0,0,0,0, INT BDOS CALL GETCHAR CALL FIXUPC CMP AL,'Y' MOV AH,UPCOFF JZ SETUPC CMP AL,'N' MOV AH,UPCON JNZ GETUPC SETUPC: PUSH AX MOV AX,NEWSEG MOV ES,AX MOV BX,(OFFSET FLAG) - (OFFSET CONSTE) MOV AL,ES:[BX] AND AL,UPCMSK POP DX ORany instructions between PTCHF6 EQU (OFFSET $) - 3 ;these two JZ CONX3 PUSH CX PUSH AX OUTE1: IN AL,RPORT ;check for carrier NOT AL ;pmmi reverse logic TEST AL,CTS JZ NOCAR ;no IN AL,STPORT ;yes,now check the out status TEST AL,TR0,0,0,' ' TIME DB 0,0,0,0,0,0,0,0,' COUNT = 00000 ' DB ' ' DB CPMEOM LDMSG DB CR,LF,'LOADING BULLETIN BOARD SYSTEM - ' DB 'PLEASE STAND BY.',CR,LF,CPMEOM FRSTMSG DB '//',CPMEOM TURNOFF DB CPMEOM CMDLINE DB  AL,DH MOV ES:[BX],AL RET ;print the sign off message SIGNOFF:LEA DX,GDBYE MOV CL,SPRTSTR INT BDOS RET ; 'BIOS' comes here first to check console status - if modem port has a ; character, return to calling routine with al = 0ffh. elseDY ;are we ready to xmit JZ OUTE1 ;no then check again MOV AL,CL ;yes,move output char. from c to a AND AL,07FH ;strip parity TEST FLAG,UPCON ;no instructions between this one PTCHF7 EQU (OFFSET $) - 3 ;and this patch pointer JZ NOTUPC 'MENTER' ENDCMD DB 0 ENDDU DB 0 SYSSEG DW 0 NEWSEG DW 0 BCALL1 DB 0 BCALL2 DW 0 BCALL3 DW 0 OLDPTR DW 0  jump to ; normal bios status check for local keyboard. CONSTE: TEST FLAG,ONLINE ;put no instructions between the flag PTCHF1 EQU (OFFSET $) - 3 ;test and this patch pointer JZ CONX1 IN AL,RPORT ;check modem for carrier NOT AL ;pmmi logic TES CALL FIXUPC NOTUPC: OUT DATPORT,AL ;output it w/not all upper case CMP AL,CR JNZ NONULS TEST FLAG,ANYNULL ;do not separate this flag test PTCHF8 EQU (OFFSET $) - 3 ;and this patch pointer JZ NONULS MOV AL,FLAG ;same PTCHF9 EQU (OFFSET AL,CTS JNZ CNSTE1 ;yes JMP QUIT ;no CNSTE1: IN AL,STPORT ;now see if data is available TEST AL,DAV JNZ RMSTAT ;yes CONX1: CON1 DB JUMP DW 0 RMSTAT: OR FLAG,CHRRDY ;do not put any instructions between PTCHF2 EQU (OFFSET $) - 3 ;T $) - 2 ;here MOV CL,4 SHR AL,CL XOR CX,CX MOV CL,AL OUTLP: IN AL,STPORT ;still ready to xmit TEST AL,TRDY JZ OUTLP MOV AL,0 OUT DATPORT,AL ;output a null LOOPNZ OUTLP NONULS: POP AX POP CX CONX3: CON3 DB JUMP DW 0 these two MOV AL,0FFH ;yes modem has a character RET ;*********************************************************************** ;*** the following routines are all relocated to just above the bios *** ;********************************************FIXUPC: CMP AL,'a' JB UPC1 CMP AL,'z' JA UPC1 AND AL,05FH UPC1: RET NOCAR: POP AX POP CX QUIT: AND FLAG,XONLINE ;here's another group PTCHFA EQU (OFFSET $) - 3 ;of MOV CL,SGETDMA ;instructions INT BDOS ;that MOV SI,(OFFSET IDMS*************************** ; 'BIOS' comes here first for console input. check modem port for ; character. if modem has character available, return to the calling ; routine, else go to 'BIOS' for local console input. CONINE: TEST FLAG,ONLINE ;donG) - (OFFSET CONSTE) ;you PATCH1 EQU (OFFSET $) - 2 ;should MOV DI,BX ;not MOV CX,(OFFSET ENDMSG) - (OFFSET IDMSG) + 1 ;separate REP MOVSB ;these MOV CL,SCHAIN ;also INT BDOS ;do not separate FLAG DB 0 IDMSG DB 'BYE' ENDMSG DB 0 Pxx't put any instructions between PTCHF3 EQU (OFFSET $) - 3 ;these two JZ CONX2A IN AL,RPORT ;check for carrier NOT AL ;pmmi logic TEST AL,CTS JNZ CONIN1 ;yes JMP QUIT ;no CONIN1: IN AL,STPORT ;now check for data available TEST AL,DAGMLEN EQU (OFFSET $) - (OFFSET CONSTE) ; ******************************* ; *** end of relocatable area *** ; ******************************* ; data area GRTING DB CR,LF,LF,'WELCOME TO BYE86 - VER. 1.0 - 7/8/84' DB CR,LF,'COPYRIGHT 1984 wttt uuQu YAA.h7&4`/1V JNZ RDMDAT ;yes TEST FLAG,CHRRDY ;again no instructions between PTCHF4 EQU (OFFSET $) - 3 ;these JNZ RDMDAT CONX2A: CON2A DB CALLN DW 0 TEST AL,CHRRDY JZ CONINE CON2 DB JUMP DW 0 RDMDAT: IN AL,DATPORT ;take the data AND- ED BERTNESS',CR,LF,CPMEOM GDBYE DB CR,LF,LF,'GOOD BYE - THANKS FOR CALLING' DB CR,LF,'ATLAS MICRO ASSOCIATES'' MCI' DB CR,LF,'BULLETIN BOARD SYSTEM',CR,LF,LF,LF,CPMEOM QUERY DB CR,LF,'IF YOU WISH TO EXIT PROGRAM - TYPE ''Q''' DB CR,LF,'- ANY OTHEC .hñ <ñ<.h6&C&.l2l.h&P+Žzu.jXX.jR.h&Z&+&Q.+hʸ»(AW^z‰(( (%M ([-+GQRC&ʃ+BډZY+&Ë.hؾ$ȎFȎ؎ Ш.j&$&Q8YШu"t<u { N (5 (,8.l2l.j&&&&+&R_ [&C.j& &Íe \,0< s.j& &Í 3