TDYבF[\+CP/M 2.2 for Bill Bailey's much modified Altair 8800SSDD 512 byte sector, 1-15, 1:1G>@:JG!(!Nx@(+G:Qo~2D!x4> 0400 {23x4>0#3w40+0 |{ :DO:JG4>] C\XRLOCBIOS ©RIGHT (C) 1979, DIGITAL RESEARCH !x_͌> ͒> Ò> Ò͘~#͌ì _2<ԯ2Ձ Շ!۶2:2a{_:۷ʖ:۷>Ľʖ:=2–!B!6#5ʖ:Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!i#͘*~ "ַ"͌#>?͌͘ =_.:;<> Oօo$>!Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6" #~?  xDIR ERA TYPESAVEREN USER !yO#< Ty#O 3ׯ21y_͸2y2ͽ:Է i1͘A͌>>͌92^ :۷¥.!_~#fow]٭ڎڥ!v"!çREAD ERRORçNO FILE^:۷ ! ~ 3#0 Wx x ր ւ G ~ # 3x~#B!Y~ɯ2:۷=!۾ý:۷=!۾:ý^T! '~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x s ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ  ٯw4!Y~ʆ͌†t=ʆf ^ T ٯ2o&)|+!<ͧÆNO SPACE^ :Ty!B*O=?_s#"^sG!~Yڸpsp2mÆÆf ͧFILE EXISTS _: É: :۷ʉ=2)ͽÉ T!@k!}|qK=qf^!~2>`~2ۯ2\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LO3ADCOMf^: !۶  $$$ SUB$ ܙܥܫܱ"C{2!"E9"1A߯22!ty)K!G_^#V*Cސ~E ,F&-AGMSߛ!!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$:BA2!~6 O͐  :߷E B 2>: ߷b# : ߷y! 4 5~yy5 6yҐ^H@Oy H H: –ͬ  #H: ! ߾ Hù H H $O͐: 2 *CN# x: 2 p&x~+é7ݯ2 H! >w_: ! ߾5ͤNkͱ¦ͱxʊ#Nx: ߷! ߖ2 ͤ! 5™#wO~x½p Hy<< ʑ :!qMD#M 2E>:! ^#V w#P:BO|^#V#"##"##"##"!O*!O*|!6ʝ6>*w#w*w#w'û*! J*""!N#F*^#V*~#foyx*{_zW+*ˁyx#*DM*s#r*s#ryOxG*0MD!!N: EG>O: \S*C :qn& ^#V>O^"*}:*)=":O:页o"*C *C!ͮ~2~2ͦ:2ͮ:O:w:w |g}o*鯆# ):BO!yoxg*:BO}!N#F "*#*s#r^ ~!J! J*:o$*C~i6iw**{#zr+s{ozg**͕** ,w͜͸Ͳ!!N#F$**O!~#:A߾#~$=2Ek͌::/GyO>2!q*C"͡ʔ*JҔ^:Oyʃ?|x | s-|N-# S:2E!~Яw>T D^6k-äPYy 5*{zBK5ڋ>*Cw~#+w#w+ɯ2E22i^ *C :~w~͔͔# #  w ~>2!E5T*C!"C"C!w# F! w͌x2͢*C ~<wʃG:!ʎì 4~ʶ¬:<ʶ$ʶïZͻx>2>2ͻ:!Z2:E߷ẅ́͊Ͳ>2>2T*CGͻ:ẅ́n>2;O ^DM;}H>"*C ::ddslO s#r:E߷͊:==»y==»*Ww#*"͸*:G#š"͸:!w4!iw:Z!E~=262*C!!~~#~O~G#n,-.‹! w! yG!x͢.:E<ʄ! q!pQ:E<. ʄ$.:E<ʄi6}2ExN! ~态O>G~G!~G} *C!r#r#r ^ͥ_y#x#{s+p+q-*C ͥ!!q#p#w*:BOYG}*MD "ã:!B߾w!>2*C~=2u:B2~2wE:A*C߶w>"k!""2B!"!rQQQâ~?ͦ~?rQ*"CQ-Q͜QüQrQ$Q*):B"*)*)Q;*"E:;:A2AQÓQÜQ*C}/_|/*W}_*"}o|g":ʑ*C63:ʑw:2E**E}DQ>2'@ æÐ>'Òâ7Q E!ͣͯ1 go"@!"B !Ww#VO_:X2J!"Lz̓;3"LT!B~ڰw+4#ʰ:J@°:Q= ʰ4:Qz>22!"!"!"L!"":Oy2K>!Gy2!o)))){y2y*I2J*@:Cgy2@>2CqdO+F!SxP!_@P!x2@] ]|2C}2@"Iw#w w#wy!y9y2Ly29­y2My=2y>ҽ>29`i:#Vy2 B_V# #떁o<2!g7) 2%2$| CHECK SUM ERROR OCCURED ON LS-100 BOARD AT TRACK H SECTOR H 9?~_#&{:L:M*N!L~5>~:Kɯ2$y2%g[*"*"}L<2!ʀ5[t2<2#2"!6ʤ[@t: [z2Q*"@*"B:2J:#ă!"w2*P%7*!> =*:$<2w# :%=:"2̈́!"w:L: <>!^#VO&7&:!oE!4!"Á!=R^#V:#V:h<2!#dy>2K ̝ Ê_:K{2H03w#3w#3w#3w#¬ 2H0~3#~3#~3#~3#+~2H0402G:@A2!ͣk:B21O:A=3:Jͯ4 >LƈO1W#~G>ZGy*LX*I|ͯ!0+|z!N>ͧʘ>@ضwk21f~2I2J#:Qw7¶ w4> >~04w@>+w#13~濱4:C:@!U&^&~&PKNQTHKNQ j?? ?0?4?< @+ KNQTH KN*Q9` h x? ? 00 w$?(? ?:?H?P?  :Qy:: :: :z}!~O#!ͼj>> gPRINTER ERROR :0 ͼ.ͿN#yҰͬ!ͯɯ2!!ͼI/O ASGT ERRORST ERDRIVE NOT READCANNOT BOO Ýæü1T4A!6ͼ!"ú62k CP/M Vers 2.2TæüÝ!6# x\>2>2!͢>p>>U>>>)>/>͝ʦG:JxMͷ͢*} !F6xy D!~#~# ~##^#V!""y2y gy owqy8p:G1͹.ͪ&͂!(.M͹g}jL*ͪ alg|~MͲg}Ó|%&$> &}-.O,>P.!.ͣ&͒!( :2:2 O9O9 TO9O9ww|H}Y^!^r Hrq#|{}rr:< Œ2:›> =2"}:< ڴ *>L !|%'(.T]>$'(M .OT]}-_ 1T]>N,_ 1w w P~# ==P~# OOwww ~:<  [ O}! O~#fo P@0€ p`İPŠ@Ɛ0ǀ p`ɰ Q c  fO)(="QWERT(YI^_qifjklmt1y@U[]_e^m]u\}{ڃ@҉[ґ  0123'4C5[6s7ʋ8ʣ9ʻæ!~ʦO#!ͼY:J/2Jæ æ!N#xæ@!3CcNl@x1æ æ æ æ æ æ æ*~ #E گ ʫ ^#V. ï ~ CZMEIABDHSP!"M"+"!91*~!O~6=G#^#V#~x (#"!N#FW( *J>7Å*M|N+"M N:LHͅÅD Å >* *͓ b" . *"] !/~##ʁtZ*F#n!Is!^#V&&##&))::^#V#*^#V>+)x-8_)*)þ))>+><77"9.Yͯ * M^2U :2:2ͳ:_³ͯ !6! @!!BH @@ABH B! "BHI$$BI$BI $ HI D$HD$$ H B!$D$"$B$DA!0ABI$H B$I $HI$H$! $I $I$$A !A@$I$"!$H$I$I "! $A$  HHAA"I @BB $A"$$$I$$H!!! BH" !I B  $$]uk!BD! $!BI D@"!$I$$H"!I$I$I$UUU$$A$ /x: ߷! ߖ2 ͤ! 5™#wO~x½p Hy<< ʑ :!qMD#2E>p! ^#V w#P:BO|^#V#"##"##"##"!O*!O*|!6ʝ6>*w#w*w#w'^CCBOOT ASMLVGRAPH COMMODE17 COMASM COM@COMPRES COM0ROMBAS10PRN012345678:;<=SUBMIT COM 0DUU ASM DECHEX ASCDUU COM6DUU DOCm !ROMBAS10HEXE9EROMBAS10PRNj>?@ABCDF2ROMBAS10ASM5GHIJKLMNOPQR\]PIP COM:"#MBASIC COM>$%&'(+; ;CP/M 2.2 BOOT FOR CCS 2442 MULTIMODE DISK CONTROLLER ; TITLE 'CCS 2422 MULTIMODE DISK CONTROLLER BOOT FOR CP/M 2.2' PAGE 56 MACLIB Z80 ; ; THIS BOOT LOADER WILL LOAD THE CP/M SYSTEM IN FROM THE SYSTEM TRACKS ; OF AN 8" DISK. IT IS INDEPENDENT OF SECTOR SIZE OR DENSITY. ; ORG 80H ; MSIZE: EQU 20 ;MEMORY SIZE IN KILOBYTES BIAS: EQU (MSIZE-20)*1024 CCP: EQU 2C00H+BIAS BIOS: EQU CCP+1600H ;BASE OF BIOS ; SPT: EQU 44H CUNIT: EQU 4AH IDSV EQU 4EH ; ; DCMD: EQU 30H DSTAT: EQU DCMD D 9CH ;MASK FOR READ ERRORS JRNZ START ;TRY AGAIN IF ERROR MOV A,H ;SEE IF ALL IN CMP D JNC BIOS ;JUMP IF SO MOV A,E ;NO, CHECK FOR TRACK OVERFLOW INR E ;INCREMENT SECTOR POINTER CMP C JRNZ LOAD4 ;JUMP IF NO OVERFLOW LDA SPT ;ELSE, GO TO NEXT TRACK MOV C,A ;SET THE CORRECT SPT LDA CUNIT MOV B,A ;RESET THE SELBIT OUT DCTRL MVI A,STEPI ;GET A STEP IN COMMAND MVI E,1 ;RESET SECTOR COUNTER JR LOAD0 ;GO DO THE STEP IN ; TBL: DB 26,15,8,4 ;8" SECTORS PER TRACK TABLE MTBL: DB 18,IqGMBASIC SUB)LVGRAPH ASC*LVGRAPH ASMW+,-FFT ASC)./EXIT DTASWAVE DTATGRFFT ASC>UVWAVE ASCWEEFFT ASCXSD COM YDDT COM&Z[PCC420 ASCMBASIC SUB^76F COM_WS COM|`bcdCCSINIT COM a(SCTR: EQU DCMD+2 DDATA: EQU DCMD+3 DCTRL: EQU DCMD+4 ; BANK: EQU 40H ; ; RSTOR: EQU 0DH RDSEC: EQU 88H STEPI: EQU 5DH ; START: MVI A,1 ;TURN OFF THE SHADOW ROM OUT BANK LDA CUNIT ;GET THE SELECT BITS MOV B,A ANI 10H ;SEE IF IT IS A MINI LXI H,MTBL ;ADDRESS OF MINI SECTORS PER TRACK JRZ LOAD2 ;JUMP IF MINI DRIVE LXI H,TBL ;ADDRESS OF 8" SECTORS PER TRACK LOAD2: MOV C,M ;GET THE TRACK 00 SPT MOV A,B ;REGET THE SELBITS ANI 40H ;SEE IF DOUBLE DENSITY JRZ LOAD3 ;JUMP IF NOT DCX y%10,5,2 ;5" SECTORS PER TRACK TABLE -O, CHECK FOR TRACK OVERFLOW INR E ;INCREMENT SECTOR POINTER CMP C JRNZ LOAD4 ;JUMP IF NO OVERFLOW LDA SPT ;ELSE, GO TO NEXT TRACK MOV C,A ;SET THE CORRECT SPT LDA CUNIT MOV B,A ;RESET THE SELBIT OUT DCTRL MVI A,STEPI ;GET A STEP IN COMMAND MVI E,1 ;RESET SECTOR COUNTER JR LOAD0 ;GO DO THE STEP IN ; TBL: DB 26,15,8,4 ;8" SECTORS PER TRACK TABLE MTBL: DB 18, ߉WSMSGS OVRZefghijkWSOVLY1 OVR lmnopqrstLVGRAPH DOC u$$$ SUBvSS5-1/4 COMwCCCOPY COMxLVGRAPH BAK yINTCURVEASCUEEFFT ASCVLOG2 BAKWCURVE ASCXINTCUBE ASCYLOG2 ASCZ2TINBAS06ASMf[]^_`abcdefgALOG2 ASC\ LOGBAS07PRN   H ; ELSE, ADJUST POINTER FOR DDEN SPT LOAD3: XRA B ;BUILD TRACK 00 SELBITS MOV B,A ;SAVE IN (B) LDA IDSV+3 ;GET SECTOR SIZE ADD L ;OFFSET THE POINTER MOV L,A MOV A,M ;GET THE CORRECT SECTORS PER TRACK STA SPT ;SAVE IT LXI H,CCP-1 ;GET THE CP/M LOAD ADDRESS LXI D,(BIOS+600H)+2 ;STOP PAGE ADDRESS, START SECTOR MOV A,B ;REGET THE SELBITS OUT DCTRL MVI A,RSTOR ;HOME THE DISK LOAD0: OUT DCMD LOAD1: IN DCTRL ;WAIT TIL DONE RAR JRNC LOAD1 IN DSTAT ;GET THE STATUS ANI 98H ;MASK FOR H *" 2 2 |< " % * C{K2* " * |'_#x * ~?’ !s DGDQBʷY|nA2SSDB!h :=!": * T1>* > @IK 2 ê 2 *  D " : ?IK 2<= Z~ ̽(;" ҌSW]2" ^8$ܭ"ʪ: * " * B" t##s#r#F w# y !6"*" kC*"* " *bk~####~  32#s#r  LOGBAS07HEX 1LOBAK10 ASM&hjklmnopqrstuvALOG2-10ASCi2LOGBAS10ASM3wxyz{}~DIVIDE LOB|LOGBAS10$$$XP33 MULMUL MUL ERRORS JRNZ START ;TRY AGAIN IF ERRORS LOAD4: MOV A,E ;GET THE START SECTOR OUT DSCTR IN DDATA ;CLEAR ANY BOGUS STATUS BITS MOV A,B ;GET THE SELECT BITS ORI 80H ;SET THE AUTO-WAIT BIT OUT DCTRL MVI A,RDSEC ;START THE TRACK READ GOING OUT DCMD LOAD5: INX H ;INCREMENT THE POINTER IN DDATA ;GET THE DATA MOV M,A ;STORE IT IN DCTRL ;SEE IF INTRQ RELEASED THE WAIT RAR ;CHECK FOR INTRQ JRNC LOAD5 ;JUMP IF VALID DATA DCX H ;ADJUST THE MEMORY POINTER IN DSTAT ;CHECK THE STATUS ANI8ODO *DM~#+##~#foD`i~#fo??2 2 ;F~"j @s: ~@?>,ju2EڀG#uO#u #u# ʋSʦTuO>ôuU#uB>,u!AO ^#V#uOʓ# y(u.!>ғ+>͈2 ͈H!+^>2 ̆͆>͈l~.ʐ: 0 : ~@ʼ.@>͈Z}͈|͈H~.: *' |>}e. Ұõ͈!' !# ~͈HHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: >ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2mͯ m!62m!62m!62m!62m'2:2:TҒ:2!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ ready open?Disk I/O errorFile already exists??Disk fullInput past endBad record numberBad file name?Direct statement in fileToo many files JpP8`1` B:]1!w #y x 7!W`mßʚϚ՚!@>w# x'y'-!͡A͡͡͡l͡͡͡O͡͡͡͡Kͭ͡͡͡ͽxd!ژ^͡#x•<͡x²^͡#xj^͡#x͘3CcNl!~!->wix~!->wix~w #x-y-~!g>w #xGyGi͇iGogJ~#xtII!I}ƀo>gxœI-!I}ƀr!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6:͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ 2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 *~]y)):DE9WAzD5D9E TCD E"D   < DDDD=9"D"yLLMPM@$$YXTZZSRbSYdXY|T{TSYjIII{(*f(6 88&W7899N9K HFIII"MIFFy))*l* QQQUDV\VgQjQmQ;LM$Xq"9BLdhiNBTSUTϫLOSONԚLEAҒINSNDBV+V,V-O HRAL̶OMMOθHAIιATI͆EFSTҭEFINԮEFSNǯEFDB̰EƘELETŪNāLSŢRASŦDIԧRROҨRRX O/QO҂IELILERIOTωO TωOSUEEXB, Who>gxәI!I$>w#x!J> w#x!R>Gw#>Rw#>Fw 6 FILE NOT FOUND $ GRF !>w#zx!>w>2#zˆ!> w#zª!>w#zºܚܚܚ*}>o|>gO>GyOx_yOkb))))))}oyO&!; ~Oɀ @O l "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q   gNPUԅƋNSTNNMNKEYILEԈINűOASEPRINԞLISԟPOISԓO O0EEFTO1ERGOKI2KS3KD4IDEXԃUL̖AMEהOUԝΕPEοCTPTIOκUOKřRINԑOEEEAćUΊESTORŌETURΎE͏ESUMũSEIGHTNENUͬESEANDOMIZŻTOАWAХAVPCTEGQI TRTRINGPACEYSTEͽROΣROFƤABHEA SINSAARPTIDTȡAIԗHILŴENĵRITŷO۾yy||PF<2(z{*y):*)%,,c-G.r)%%'n')0+$+P+2)NEXT without FORSyntax errorRETURN without GOSUBOut of DATAIllegal funct 7 y in Ok Break!9~#…  w N#F#i`zʙ D w   *|<ʺ :  MD=96543>7@?2C: * "   221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'! Ͳ:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>` :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :]:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<:<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!ion callOverflowOut of memoryUndefined line numberSubscript out of rangeDuplicate DefinitionDivision by zeroIllegal directType mismatchOut of string spaceString too longString formula too complexCan't continueUndefined user functionNo RESUMERESUME without errorUnprintable errorMissing operandLine buffer overflow??FOR Without NEXT??WHILE without WENDWEND without WHILEGraphics statement not implementedFIELD overflowInternal errorBad file numberFile not foundBad file modeFile alhH *" 2 2 |< " % * C{K2* " * |'_#x * ~?’ !s DGDQBʷY|nA2SSDB!h :=!": * T1>* > @IK 2 ê 2 *  D " : ?IK 2<= Z~ ̽(;" ҌSW]2" ^8$ܭ"ʪ: * " * B" t##s#r#F w# y !6"*" kC*"* " *bk~####~  32#s#r-!6]:ͧz2~e:~2O! 6*~& 6$>!~_z*~& w!~5Bx:yͧ*v+"vv ~_{ozg 001 $$$$ SUB6ͭ:}"!}5́ͭ́3*yM"h:}^a a2}O>Vͧ^:}>*z& ~ !z4í!{q*v#"v͙dͧ*vv :{w:x<2xO>}|ͧDM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{ozgO{ozgi`N#Fogo&og H ©=¨'' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*8ODO *DM~#+##~#foD`i~#fo??2 2 ;F~"j @s: ~@?>,ju2EڀG#uO#u #u# ʋSʦTuO>ôuU#uB>,u!AO ^#V#uOʓ# y(u.!>ғ+>͈2 ͈H!+^>2 ̆͆>͈l~.ʐ: 0 : ~@ʼ.@>͈Z}͈|͈H~.: *' |>}e. Ұõ͈!' !# ~͈w-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:!:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020 :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&6> QBz\@@_W@W~#!ʹ@#?&ʴ@ʒ@+>s?+~#.?_ʨ@\Q?j?$?*j?x#ڽ?~$> ?#W!@~#.?#?,@z@W?~#>.j?# !@~##?@T]^###xG#z+A@xA@~-<@A@>Wʝ@CxJzd1DG+27y@2 ;v@, 2~#N#fi_xp?Ø@@@3?QBH@~#@Ê@ý@>@ʝ@:**' AqIGG*' <`@=G> `@@@z>+@ u!1^#x !2CBRCH DDT VERS 2.2$10 !~=W!xe ~#Xbxʇ {z~#o}o҃i.2_!fp+q*e2_2_!hp+q*g!jp+q*i!lp+q*k!np+q*m2_!ppJ̴RELGR HEX8LGRAPH COM9GRAFTST ASC :RELGR ASM>CIRCLE ASC =ASM COM@;<RELGR BAK*MBASIC COM>?@ABCD 2*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚ͯ !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H d11*" COPYRIGHT(C) 1978, DIGITAL RESEARCH M ! á 4êü /L9ASMPRNHEX 1  ͧ!t6>!t%\= >!t6:t<2t=O! ~2u b:<2O>9b!60+~9b!60+4:uat:u_2u:uMʉSͧ!v6!"v!|6:|Ҁ!x6 2}:} Hk:} h:}$6 2}$*}M3:}02}O> ͧ3!z6ͭ:}"!}5́ͭ́3*yM"h:}^a a2}O>Vͧ^:}>*z& ~ !z4í!{q*v#"v͙dͧ*vv :{w:x<2xO>}|ͧ:H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*ag`!4w_#~ ʸ A:4~~# ¼ > \ ?ʻ w# !ͼ ? !ͼ 8:  '<ͭ'<>V$>O$:Ğà\ÞØ`rÍÖ![w#w#b!"!F#v2[G*##~w*##~<*}q!~ڬ6![^![^#fk"͎͘!G#*####*^#Vû!^*"*Ͱ>2lyPLnR>UX:l̅2l͓*>E 2C!" """ :ʼ:*1 |R|ͦ0FIL: R  R* } *" :¿::¿üX!C^#fk[@ :Œ:=ʌG!ʆF#H vÛc*| EH bͺ,^1 ͦ *""1 EH DH ͺ,1 ͦ :  1:  " > 2  ; ORG 100H BEGIN: ;0100 JMP SETSTK TV0: ;0103 JNZ TV1 ;011FH NOT "@" ARRAY INX D ;IT IS THE "@" ARRAY CALL PARN ;06BCH @ SHOULD BE FOLLOWED DAD H ;BY (EXPR) AS ITS INDEX JC QHOW ;0166H IS INDEX TOO BIG PUSH D ;WILL IT OVERRUN XCHG ;RAM? LXI H,(VARBGN-RAM); FIND SIZE OF FREE RAM CALL COMP ;AND CHECK THAT JC ASORRY ;080EH IF SO SAY "SORRY" TV00: ;0117 LXI H,VARBGN ;0F00H IF NOT GET ADDRESS CALL SUBDE ;079CH OF @(EXPR) AND PUT IT POP D ;IN HL RET ;C FLAG IS CLEA!)ͼ !ͼ :5͡ :6:6͡ :7͡ :\ ʻ 24!dͮ 25ͮ 27ͮ 26!8 ( ʃ !Y 1  :7ʞ !z 8  !"2D2X2#! 8 !ͼ z{* ! !"!8 w#  +6# *#"~!ͼ G:6QxJQS*!w#"! 1 !"!Y~~# …¡z!ͼ wʹ* ! w#" ! 8 !" ! zz_O4:  :6y){zA"*![N![ N#Fr+sq#p/>G=#w#w3#w#w!JSYMBOL TABLE OVERFLOW G*##~w*##~͎*_###s#r^#V`à 4 Wm ()*+,-/ABCDEHLMDBDIDSDWEIIFINORSPACIADCADDADIANAANDANICMACMCCMPCPIDAADADDCRDCXENDEQUHLTINRINXJMPLDALXIMODMOVMVINOPNOTORAORGORIOUTPOPPSWRALRARRETRLCRRCRSTSBBSBISETSHLSHRSTASTCSUBSUIXORXRAXRICALLENDMLDAXLHLDPCHLPUSHSHLDSPHLSTAXXCHGXTHLENDIFMACROTITLE  PF FP! ( 2/:|: |Ë  |*" ͩ !6="1 :  1}1:n:>BʋSSͦSSxS 1:  1"" ͦ 1 |R >O U!" 1 1!|_!^#fk $8AP`ixH ñññ81Ľ y0îH ñGîG  ñH ñ(Ľ yîH ñîîĽ y0îîH ñG 1: :,; c*| } 8OqRED TV1: ;011F CPI 1BH ;NOT @ IS IT A 2? CMC ;IF NOT RETURN C FLAG RC INX D ;IF A THROUGH Z TV11: ;0124 LXI H,VARBGN ;0F00H COMPUTE ADDRESS OF RLC ;THAT VARIABLE ADD L ;AND RETURN IT IN HL MOV L,A ;WITH C FLAG CLEARED MVI A,0 ADC H MOV H,A RET TC1: ;012F INX H ;COMPARE THE BYTE THAT JZ TC2 ;013AH FOLLOWS THE RST INST. PUSH B ;WITH THE TEXT (DE->) MOV C,M ;IF NOT =, ADD THE 2ND MVI B,0 ;BYTE THAT FOLLOWS THE DAD B ;RST TO THE OLD PC POP B ;I.E. DO A RELATIVE  d:! G~#x=2> > ! >x6 #='G! ~ p( O*}O>4?:7w:#ĸ*"!͸* }w>ͪg( ʆ1 Y :7ʗ8 z !<ͼ CP/M ASSEMBLER - VER 2.0 NO SOURCE FILE PRESENT NO DIRECTORY SPACE SOURCE FILE NAME ERROR SOURCE FILE READ ERROR OUTPUT FILE WRITE ERROR CANNOT CLOSE FILES END OF ASSEMBLY G:7xʘ!#~ʄl͸Ä**!O {zʊ͸*"!!#^4!$wͯͯWƐ'@'ê>:ͪ!#^Ww*!{͚|͚}͚͚{!$~#͚͚> ͪ> ͪ ?'  v:P@< !  PP27 ( *"  NZZ NCC POPEP M x_BH!œ#¶ ¦{KÈCÈ<:JCR:  !6 s!m#  ɯ<:O=_Z!F!V#fjQ̓E!^#Vo&)~#FxGyѯ<àn8n!~ڢͅ6~44O! s#r!~ ڿ6ͅ^4!mw!wp!~ͅ!55N! N#fio&)^#fk NĽ y0G G t :):,.>C :|: Jü;r :R: ʼʋ!ʼR!ʼʋ>SR{ozg!~4ʧͦ !6 ! **̈́**̈́\iͩ !w#H USE FACTOR !* "z{*"* "I !" :1 R O*UR X* G:xl :  *̩ : l x͖ *#"EH DH 0:~ ! ^4! w͆ Æ *! 6z͖ {͖ 4>R>V>D >P >L >N   DCX D ;JUMP IF NOT = TC2: ;013A ;IF =,SKIP THOSE BYTES INX D ;AND CONTINUE INX H XTHL RET TSTNUM: ;013E +++TSTNUM+++ LXI H,0 ;TEST IF THE TEXT IS MOV B,H ;A NUMBER CALL IGNBLK ;IF NOT, RETURN 0 IN TN1: ;0143 B AND HL CPI '0' ;30H IF NUMBERS, CONVERT RC ;TO BINARY IN HL AND CPI ':' ;3AH SET A TO # OF DIGITS RNC MVI A,0F0H ANA H ;IF H>255, THERE IS NO JNZ QHOW ;0166H ROOM FOR NEXT DIGIT INR B ;B COUNTS # OF DIGITS PUSH B MOV B,H ;HL=10*HL+ MOV C,L ;WHE q@2 0 0:x0_<2! wI2 2> 2 >2ɯ22 !~@_6^4#: w~$w: 0 q: A: A͋q: a{_2  2 - !ɯ2I:  ;*:  ͭͷ ͭ͋>9q>9: '!2 >9 7:! 6 >2>2: 2 Qͭ:Ğ! :lj<͖<j<|<: OʊQ>ÖH >2 2 û: B­>ôD> ¸!52 !"!N#~#A07O! ~*!) " z'{ͅ>ɯo>g"k!m6ů{_zW5>)D*kOxGd !m?FDM!xGyOڂÃ)sn55)=â|g}o=î--#zg{ozg{ozg{oÓ:: ;,!ɯ22=2l!"]!~H5_!m~0:ą:  *":  :‰:̅ԅ!^#=ʅVq”*qͦ1& O:lµ̅>2ly:_!w~!s!m~ùy !~=w_!m~ ͅu/!1^#x !3CcNl iCIRCLE ASC=RC/TIME ASCFGRAFTST ASC :LVGRAPH ASCELINEGRF ASCIMODE24 PRN;RELBDR PRN*MBASIC COM>?@ABCDzRE 10+ IS DONE BY DAD H ;SHIFT AND ADD DAD H DAD B DAD H LDAX D ;AND IS FROM INX D ;STRIPPING THE ASCII ANI 0FH ;CODE ADD L MOV L,A MVI A,0 ADC H MOV H,A POP B LDAX D ;DO THIS DIGIT AFTER JP TN1 ;0143H DIGIT. $ SAYS OVERFLOW QHOW: ;0166 +++ERROR "HOW"+++ PUSH D AHOW: ;0167 LXI D,HOW ;016DH JMP ERROR ;07E4H HOW: ;016D DB 'HOW?',0DH OK: ;0172 DB 'OK',0DH WHAT: ;0175 DB 'WHAT?',0DH SORRY: ;017B DB 'SORRY',0DH ;THIS IS THE MAIN LOOP THAT> copyright(c) 1977, digital research $Error On Line $SUBNo 'SUB' File Present$Disk Write Error$Command Buffer Overflow$Command Too Long$Parameter Error$Invalid Control Character$Directory Full$Cannot Close, Read/Only?$!9"!͇͊!p+q* ͊!p+q*͍2!p+q*͍2!p+q*͊!p+q*͍!p+q*͍!p+q*͍2!s+p+q+p+q:=2ʦ** w*#"*#"!p+q(+*DM*p*& 6:ep\:=BTHE TABLE CONSISTS OF A NUMBER OF ITEMS. EACH ITEM ;IS A STRING OF CHARACTERS WITH BIT 7 SET TO 0 AND ;A JUMP ADDRESS HI-LO WITH BIT 7 OF THE HIGH BYTE ;SET TO 1 ; ;END OF TABLE IS AN ITEM WITH A JUMP ADDRESS ONLY. IF THE ;STRING DOES NOT MATCH, THIS IS THE DEFAULT. ; TAB1: ;01F9 DIRECT COMMANDS DB 'LIST' DB (LIST SHR 8) +128 DB LIST AND 0FFH DB 'RUN' DB (RUN SHR 8) +128 DB RUN AND 0FFH DB 'NEW' DB (NEW SHR 8) +128 DB NEW AND 0FFH DB 'LOAD' DB (LOAD SHRQ;DUU-01.ASM - Disk Utility Universal. ; ;Based upon DU.ASM V7.5 Revised 1/23/81 ; which in turn was based upon the versions of ; DU on CP/MUG volumes 40 and 46. ; ;Modified for CP/M UG 7/31 and 09/27/81 Ward Christensen ; ;DISK UTILITY - By Ward Christensen ; ;PROCESSOR: ASM OR MAC ; ;DEPENDENCIES: None known - see comments below. ; ;REVISIONS (LAST FIRST): ; ;10/23/81 Deleted "U" command. No longer used by ; "F" (its only purpose). I forgot to delete it ; when "F" was rewritten.} COLLECTS THE TINY BASIC PROGRAM ;AND STORES IT IN MEMORY. ; ;AT START, IT PRINTS OUT "OK", AND INITIALIZES THE ;STACK AND SOME OTHER INTERNAL VARIABLES. THE STACK, IN THIS ;VERSION IS MODIFIED DURING INITIALIZATION TO REFLECT THE ;SIZE OF MEMORY. ;THEN IT PROMPTS ">" AND READS A LINE. IF THE LINE STARTS ;WITH A NON-ZERO NUMBER, THIS NUMBER IS THE LINE NUMBER. THE ;LINE NUMBER AND THE REST OF THE LINE ; IS STORED IN MEMORY. IF A LINE Wͧ!t6>!t%\= >!t6:t<2t=O! ~2u b:<2O>9b!60+~9b!60+4:uat:u_2u:uMʉSͧ!v6!"v!|6:|Ҁ!x6 2}:} Hk:} h:}$6 2}$*}M3:}02}O> ͧ3!z6ͭ:}"!}5́ͭ́3*yM"h:}^a a2}O>Vͧ^:}>*z& ~ !z4í!{q*v#"v͙dͧ*vv :{w:x<2xO>}|ͧD 8) +128 DB LOAD AND 0FFH DB 'SAVE' DB (SAVE SHR 8) +128 DB SAVE AND 0FFH DB 'BYE' DB 80H,0 TAB2: ;021A DIRECT/STATMENT DB 'NEXT' DB (NEXT SHR 8) +128 DB NEXT AND 0FFH DB 'LET' DB (LET SHR 8) +128 DB LET AND 0FFH DB 'OUT' DB (OUT1 SHR 8) +128 DB OUT1 AND 0FFH DB 'POKE' DB (POKE SHR 8) +128 DB POKE AND 0FFH DB 'WAIT' DB (WAIT SHR 8) +128 DB WAIT AND 0FFH DB 'IF' DB (IFF SHR 8) +128 DB IFF AND 0FFH DB 'GOTO' DB (GOTO SHR 8) +128 DB GOTO AND 0FFH DB 'GOL ; ;-> Made sure + and - check the "NOTPOS" flag; that ; was a "loophole" that could "mislead" you. ; ;-> Added ability to put Hex into default decimal ; fields. Needed this to transfer files, where ; their hex length is known, i.e. a file 29h ; sectors long in contiguous extents may be ; read into memory via: <<;+;/29h ; ;-> Added "E" (erase screen) command. Store the ; char sequence, 0ffH terminated, at 104h. ; Useful as in "e;+;d;z20;/" to dump, sit, loop. ; The screen clear "e" causes th ITH THE SAME ;LINE NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE. ;IF THE REST OF THE LINE IS "CR" ONLY, IT IS NOT STORED AND ;AND ANY EXISTING LINE WITH THE SAME NUMBER IS DELETED. ; ;AFTER A LINE IS INSERTED, REPLACED, OR DELETED, THE PROGRAM ;LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILL BE ;TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE NUMBER, ;AND CONTROL IS TRANSFERED TO "DIRECT". ; ;THE MEMORY LOCATION "CURRNT" POINTS TO THE LINE NUMBER ;THAT IS -!6]:ͧz2~e:~2O! 6*~& 6$>!~_z*~& w!~5Bx:yͧ*v+"vv ~_{ozg 001 $$$$ SUB6ͭ:}"!}5́ͭ́3*yM"h:}^a a2}O>Vͧ^:}>*z& ~ !z4í!{q*v#"v͙dͧ*vv :{w:x<2xO>}|ͧ SUB' DB (GOSUB SHR 8) +128 DB GOSUB AND 0FFH DB 'RETURN' DB (RETURN SHR 8) +128 DB RETURN AND 0FFH DB 'REM' DB (REM SHR 8) +128 DB REM AND 0FFH DB 'FOR' DB (FOR SHR 8) +128 DB FOR AND 0FFH DB 'INPUT' DB (IP1 SHR 8) +128 DB IP1 AND 0FFH DB 'PRINT' DB (PRINT SHR 8) +128 DB PRINT AND 0FFH DB 'STOP' DB (STOP SHR 8) +128 DB STOP AND 0FFH DB (DEFLT SHR 8) +128 DB DEFLT AND 0FFH DB 'YOU CAN ADD MORE' TAB4: ;027F FUNCTIONS DB 'RND' DB (RND SHR 8) +128 DB RND AN e display to "sit". ; ;-> Set "@" when using "F" command, so for example ; to erase a file: "ffoo.zot;ch@,e5";w ; Also change "not found" of "F" command so it ; aborts, thus preventing, in the above ex., the ; actual change-and-write. ; ;10/21/81 "Z" command: make it wait a ; decimal # of tenths of a second not hex. ; ;-> Add "<<" command, to save a sector, bumping ; the sector address saved at. The ">>" command ; will get back the oldest saved sector. ; Any time "<" is executed, all sa G CURRENTLY BEING INTERPRETED. WHILE WE ARE IN ;THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND ; RSTART: ; LXI SP,TRAM ;STACK POINTER IS AT TOP OF RAM ST1: ; CALL CRLF1 ;+CRLF+ JUMP TO HERE LXI D,OK ;0172H DE->STRING SUB A ;A=0 CALL PRTSTG ;087FH PRINT STRING UNTIL CR LXI H,ST2+1 ;0195H LITERAL 0 SHLD CURRNT ;09C1H CURRNT->LINE # = 0 ST2: ;0194 ; LXI H,0 SHLD LOPVAR ;09C9H SHLD STKGOS ;09C3H ST3: ;019D MVI A,'>' ;3EH PROMPT '>' AND CALL GETLN ;0814H READ A LIANST A TABLE ;WHEN A MATCH IS FOUND, CONTROL IS TRANSFERED TO THE SECTION ;OF CODE ACCORDING TO THE TABLE ;AT 'EXEC' DE SHOULD POINT TO THE STRING AND HL SHOULD POINT ;TO THE TABLE-1 AT 'DIRECT' DE SHOULD POINT TO THE STRING ;HL WILL BE SET TO POINT TO TAB1-1, WHICH IS THE TABLE FOR ;ALL DIRECT AND INDIRECT STATEMENT COMMANDS. ; ;A '.' IN THE STRING WILL TERMINATE THE TEST AND THE PARTIAL ;MATCH WILL BE CONSIDERED AS A MATCH E.G. 'P.','PR.','PRIN.' ;ALL MATCH 'PRINT'. ; ;D 0FFH DB 'INP' DB (INP SHR 8) +128 DB INP AND 0FFH DB 'PEEK' DB (PEEK SHR 8) +128 DB PEEK AND 0FFH DB 'USR' DB (USR SHR 8) +128 DB USR AND 0FFH DB 'ABS' DB (ABS SHR 8) +128 DB ABS AND 0FFH DB 'LOG2' DB (LOG2 SHR 8) +128 DB LOG2 AND 0FFH DB 'ALOG2' DB (ALOG2 SHR 8) +128 DB ALOG2 AND 0FFH DB 'SIZE' DB (SIZE SHR 8) +128 DB SIZE AND 0FFH DB (XP40 SHR 8) +128 DB XP40 AND 0FFH DB 'YOU CAN ADD MORE' TAB5: ;02B1 "TO" IN "FOR" DB 'TO' DB (FR1 SHR 8) +128 DB FRved sectors ; are "tossed". Use this for "buffer reset". ; ; For example, to transfer a single-density track 0 ; to the buffer, then to another disk: ; ; t0;s1;< position, restore buffer ; <<;+;/26 save, step in 26 times ; lb;t0;s1 log in drive b, position ; >>;w;+;/26 restore, write, step, repeat 26 ; ---- ;-> The "M" command needs space to read the directory...... ; into. It uses the space FOLLOWING the highest active ; read sector. If you get "out of memory" on the "M" ; command, you wPds ; finds the next occurrence of the file. I think ; this obsoletes the "U" command, because the only ; reason I could see for the "U" command was the ; directory search of the old "U" command. (WLC) ; ;07/31/81 I compared this version (DU-V75) against my ; current version, using a character-by-character ; split-screen video compare. The "significant" ; changes turned out to be buried in "insignificant" ; changes, i.e. case changes of comments, etc. I guess ; I "over-reacted" to the significanption feature, no conditional ;assembly options are included. The only alteration that ;needs to be done is to use DDT to set the byte at 103h ;to zero for systems using a 2 mHz clock or non-zero for ;4 mHz clock. This only affects the time delay us"ed in ;the 'sleep' command. ; ;*** ;* * ;* This program has been heavily modified * ;* to allow it to work without modification * ;* on most versions of CP/M 1.4 and, hopefully, * ;* all vers)ems where the BIOS leaves garbage in H. (BRR) ; ;01/13/81 Updated help messages for '#' and 'N' commands. ; Modified sign-on message. (RGF) ; ;01/12/81 Fixed problem with sector translation under ; CP/M 1.4. (RGF) ; ;01/11/81 Fixed problem with CP/M 1.4. Added 'N' command. ; Hard-code 'FASTCLOCK' as a boolean at 103h. Add ; fix for sector number being 0 in system tracks, ; as suggested by Keith Petersen, W8SDZ. Added '#' ; command and memory-full check. Changed login to ; posiill have to issue "<" to reset the ; buffer. ; ;-> Added symbol "@" to mean "the address at which ; the last "=" (search) matched. Thus to scan for ; an "LIX" somewhere on the disk, and change it ; to an LXI: ; =LIX;CA@,LXI ; (Change ascii "@ where it matched" to LXI) ; ; Note that + and - may be used with "@", i.e. ; =LXI<9>H,9;CA@+6,5 ; would change the "9" to a "5". ; ; May also be used with the CHfrom-thru,value, ; but DUU would take the "-" as arithmetic on the ; "@", and not as "thrut stylistic ; changes in DU, and "changed the program back" to "my ; style" - i.e. deleted "type any char to continue", ; colons after labels, less meaningful short labels, ; etc. Noise lines, i.e. ";" lines before continu- ; ation labels, etc. made "+", "-", "/" all be back to ; decimal numbers. (single density "+26" goes in a ; track, not "+1a"). Also deleted historical comments ; which are no longer relevant such as specific ; controller mods which are now replaced by Ron ; Fowler's excellent ,ions of CP/M 2.x. * ;* If you have difficulty getting this program * ;* to run, AND if you are using CP/M 2.x, AND * ;* if you know your BIOS to be bug-free, leave * ;* a message on Technical CBBS of Dearborn, * ;* Michigan (313)-846-6127 with a description * ;* of the problem and a summary of your hard- * ;* ware configuration. * ;* One known possible problem involves the * ;* system tracks on some systems, and results * ;* from the system sectors being skewed. There * ;* is Ntion to directory track at every log. This ; is necessary to set up the 'FIRST0' flag. (RGF) ; ;01/08/81 Corrected error in MAP routine that caused map ; to fail when >255 groups allocated. Changed ; 'REPEAT' to allow up to 65535 repeats. (RGF) ; 09/27/81 changed REPEAT back from HEX to decimal. ; ;01/06/81 Modified to allow use with ALL systems, without ; conditional assembly, thru use of disk parameter ; block. By Ron Fowler, Westland, Mich. ; ;01/05/81 Modified '+' and '- r". Thus a "hack" need be ; used: ch@+0-@+1f,e5 The "@+0" allows ; the "-" to be taken in the context of "thru". ; ch@-@+1f,e5 would be interpreted as ; "@ minus (@+1f)", which isn't what you want. ; ;10/10/81 "F" command showed (S)ector 1 Ctoo ; high because it called NEXTSEC before ; displaying it ; ;== TO CP/MUG AS OF HERE == ; ;10/01/81 Corrected minor bug in "M" command so that ; it now properly positions in input buffer if it ; is ^C interrupted. Thus "universal" disk handling. (WLC) ; ; One warning: This program assumes track 0 to be ; the same format as the rest of the disk. This is ; valid for hard disks, but for most floppy systems, ; (take that to mean "all I have seen") track 0 is ; single density. On my tarbell, doing "t0;s1", which ; should be the sector occupied by the BOOT, DUU ; "hangs". I found I have to do "t0;s2" to get the ; first sector. Also, attempts to go beyond the 26 ; sectors track 0 have on it, will hang the system.  _O way for a program executing under CP/M * ;* to know about this. This program assumes the * ;* standard convention of no skew being used on * ;* the system tracks. This usually isn't a prob- * ;* lem because the SYSGEN program can be used to * ;* get the system from the disk so that it can * ;* be modified. * ;* This program should work under standard * ;* versions of CP/M 1.4. The only requirement * ;* is that the BIOS "SETSEC" routine not modify * ;* the sector number passed to i g' commands as follows: ; 1) + at end of disk now wraps to start ; 2) - at start wraps back to end ; 3) argument for + & - now good to 65535 ; (RGF) ; 07/31/81 UN-DID THIS. (WLC) ; ;01/03/81 Modified logic in console status test to allow ; any non-zero value to indicate char waiting. ; (RGF) ; ; 09/27/81 WLC question about the above mod - "Why was ; it done?" The CP/M alteration guide says "CONST ; ...return[s] a 0FFH in register A if a character is ; ready to read, an 00H in registe  "m;ffoo.asm" or some ; such will work if the "M"-map is interrupted. (WLC) ; ;09/30/81 Moved the stack back to being in the program, ; insted of "below BDOS". Changing the stack from ; beingd in the program, to being below BDOS, ; introduced the (rare but potential) bug of the ; directory read overlaying the stack. I don't ; understand the reason why it was changed in the 1st ; place. (WLC) ; ;09/27/81 Changed "F" command to work with 2.2 to find ; a file in the directory. "F" with no operan ; 09/27/81 Ward C. ; ;See DU.DOC for description and detailed instructions. ; Also, some details are near the end of this ; file in the form of the help text. ; ;This version of DU is compatible with CP/M 1.4 and 2.x ;and does not require alteration for various hardware ;configurations. It adjusts itself automatically to ;the correct number of sectors, tracks, directory size, ;etc. It has been tested on 5-1/4" and 8" floppy, and ;10 megabyte hard disk systems. ; ;Because of the automatic adat in the B * ;* register. Again, system tracks with skewed * ;* sectors will be a problem. * ;* If you add any features or make any useful * ;* changes to this program, please modem a copy * ;* to the above CBBS, so the currency of the * T ;* program can be maintained. * ;* * ;* Ron Fowler * ;* * ;**}* ; ;01/23/81 Changed SETSEC to ignore high-order result of ; SECTRN if SPT<256. This fixes some translation ; problr A if no console ; characters are ready..." Why allow "any non-zero value"???? ; ; ;01/02/81 Made compatible with MACRO80 assembler ; (labels made unique within 6 chars, and separated ; multi-statement lines). (RGF) ; 07/31/81 UN-DONE. THIS IS AN "ASM" PROGRAM. I ; "SLEEP", NOT "SLEP", AND "PROMPT" NOT "PRMPT". ; Since all CP/M systems come with ASM, I see nothing ; wrong with taking advantage of all meaningful ; characters a label may have, even if it excludes ; assembly by the occasionl MD---- ;Sorry for the lack of comments in the code ;portion of this program - it was just hacked ;together to satisfy my needs, but lots of ;other people found it useful. Its external ;documentation is good, but its sadly lacking ;comments on the instructions. (WLC) ; -- ; ;System equates ; BASE EQU 0 ;SET TO 4200H FOR HEATH OR TRS-80 ALTCPM ; FCB EQU BASE+5CH BDOS EQU BASE+5 PRINT EQU 9 GVERS EQU 12 RESETDK EQU 13 SELDK EQU 14 SRCHF EQU 17 ;SEARCH FIRST SUSER EQU 32 GETD SHLD SECTBL ;SET UP SKEW TABLE POINTER ; HELLO CALL ILPRT DB CR,LF,'DISK UTILITY ver 7.5+mods 10/23/81' DB CR,LF DB 'Universal Version (DUU)',CR,LF DB CR,LF DB 'Type ? for help',CR,LF DB 'Type X to exit' DB CR,LF,0 CALL GETSTP ;SET UP PARAMETERS CALL NOCONT ;SHOW "F" NOT ALLOWED LXI H,BASE+80H ;TO INPUT BUFF MOV A,M ORA A JZ PROMPTR ;NO COMMAND ;GOT INITIAL COMMAND, SET IT UP MOV B,A ;SAVE LENGTH DCR B JZ PROMPTR LXI D,INBUF INX H ;SKIP LEN INX H ;SKIP ' ' CAECALL ILPRT DB CR,LF,'Sec/trk:',9,0 LHLD SPT CALL DEC CALL ILPRT DB CR,LF,'Grpsize:',9,0 LDA BLM INR A MOV L,A MVI H,0 CALL DEC CALL ILPRT DB ' (sectors per group)',CR,LF DB 'Tot grps:',9,0 LHLD DSM CALL DEC CALL ILPRT DB CR,LF,'Dir entries:',9,0 LHLD DRM INX H CALL DEC CALL ILPRT DB CR,LF,'Sys tracks:',9,0 LHLD SYSTRK CALL DEC CALL ILPRT DB CR,LF,CR,LF,'Sectors in "<<" buffer: ',0 LHLD NUMSAVD MVI H,0 CALL DEC CALL ILPRT DB CR,LF,'Number gotten v-80 user, (who must have ; ASM anyway). ; ;11/04/80 Forced write type 1 (pre-read and immediate ; write) so deblocking BIOS's don't mess up. Ignore ; bit 7 in = command unless form was used. ; Display unprintables as in V command. Show ; user no. in M command (will always be 00 for 1.4) ; and only print parentheses if E5 present. (BRR) ; ;10/30/80 Fixed bug in backspace/control-X. Corrected more ; bit-7 stuff. Added 'U' command to change user no. ; under CP/M 2.x. Added pausexSK EQU 25 GETDPB EQU 31 ; TRNOFF EQU 15 ;CP/M 1.4 OFFSET FROM BASE ;OF BDOS TO SECTRAN ROUTINE SKWOFF EQU 1AH ;CP/M 1.4 OFFSET TO SKEW TABLE S2OFF EQU 14 ;OFFSET INTO FCB FOR S2 BYTE DPBOFF EQU 3AH ;CP/M 1.4 OFFSET TO DPB WITHIN BDOS S2MASK EQU 0FH ;MASK FOR EXTENDED RC BITS OF S2 DPBLEN EQU 15 ;SIZE OF CP/M 2.x DISK PARM BLOCK ; ; ;Define ASCII characters ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED TAB EQU 09H ;TAB BS EQU 08H ;BACKSPACE ; ORG BASE+100H ; JMP PASTCK ;JUMP OLL MOVE MVI A,CR STAX D LXI H,INBUF JMP PROMPTI ; PROMPTC CALL CRLF JMP PROMPT ; PROMPRC CALL CRLF PROMPTR XRA A STA QFLAG CALL RDBUF PROMPTI MVI A,255 STA TOGO ;LOOP COUNT FOR "/" STA TOGO+1 PROMPT EQU $ SETSTK LXI SP,STACK XRA A ;ZERO 2-UP PRINT STA TWOUP ;..SWITCH MVI A,1 STA FTSW ;TELL SEARCH NOT TO INCR PUSH H LXI H,BASE+100H SHLD BUFAD ;FOR RDBYTE POP H CALL CTLCS ;ABORT? JZ PROMPRC ;..YES, READ BUFFER MOV A,M CPI CR JZ PROMPTR CPI ';' ;LOGICAL CR?ia ">>": ',0 LHLD NUMREST MVI H,0 CALL DEC CALL CRLF POP H JMP PROMPT ; ;The following command resets the disk ;system thru CP/M, and may be usable for ;changing the disk density or format. ;This can only be done if your BIOS resets ;the auto-density select parameters at ;every track-zero access. ; NEWDSK PUSH H CALL NOCONT MVI C,RESETDK CALL BDOS LDA DRIVE MOV C,A POP H CALL SELECT JMP PROMPT ; ;QUIET MODE ; QUIET STA QFLAG ;NOW QUIET JMP PROMPT ; ;REPEAT BUFFER s in help file. (BRR) ; ;09/16/80 Fix backspace in line enter routine, add MAXDIR ; equate, general cleanup of ASM file. (KBP) ; ;06/22/80 Put in 'Q' command. Fix so 'P' (printer) ; mode outputs L/F's. (WLC) ; ;05/21/80 Make sector, track, be decimal, not hex. ; Also dis-allow a read until positioned. ; (DU otherwise not in sync with CP/M) (WLC) ; ;02/24/80 Mod login command to not really do log, just ; drive select. (WLC) ; ;01/08/80 Reposition after 'M' command. (WLC) ; ;01 UVER CLOCK BYTE AND I.D. ; CLOCK DB 1 ;<---PUT NON-ZERO HERE FOR 4 MHZ CLOCK ; ;====> Store your erase-screen chars here, 0ffH terminated <=== ; CLEAR DB 1AH,0FFH,0,0,0,0,0 ;CRT ERASE SEQUENCE ; PASTCK LXI SP,STACK MVI C,GVERS ;GET CP/M VERSION NR CALL BDOS MOV A,H ;COMBINE THE TWO BYTE... ORA L ;...VERSION NR FOR A FLAG STA VER2FL ;SAVE IT ; ;Set up local jumps to BIOS LHLD BASE+1 ;WARM BOOT POINTER LXI D,3 ;READY FOR ADD DAD D SHLD VCONST+1 DAD D SHLD VCONIN+1 DAD D SHL , INX H JZ PROMPT CALL UPCASE STA DUMTYPE ;TYPE OF DUMP (A,D,H) CPI '+' ! JZ PLUS CPI '-' ! JZ MINUS CPI '=' ! JZ SEARCH CPI '<' ! JZ SAVE CPI '>' ! JZ RESTORE CPI '#' ! JZ STATS CPI '?' ! JZ HELP CPI 'A' ! JZ DUMP CPI 'C' ! JZ CHG CPI 'D' ! JZ DUMP CPI 'E' ! JZ ERASE CPI 'F' ! JZ POSFIL CPI 'G' ! JZ POS CPI 'H' ! JZ DUMP CPI 'L' ! JZ LOGIN CPI 'M' ! JZ MAP CPI 'N' ! JZ NEWDSK CPI 'P' ! JZ PRINTFF CPI 'Q' ! JZ QUIET CPI 'R' ! JZ DOREAD CPI 'S' ! JZ POS CPI    CONTENTS ; REPEAT CALL DECIN ;NN SPECIFIED? MOV A,D ORA E JZ NNN ;NO. LHLD TOGO INX H ;TEST FOR FIRST TIME MOV A,H ORA L ;WAS IT 0FFFFH? JNZ NNN ;NO COUNTING XCHG ;GET COUNT SHLD TOGO ;SET COUNT NNN LHLD TOGO XCHG LXI H,INBUF ;READY TO REPEAT INX D ;TEST FOR 0FFFFH MOV A,D ORA E JZ PROMPT ;CONTINOUS DCX D ;COUNT DOWN DCX D ;MAKE UP FOR PREV INX D XCHG SHLD TOGO MOV A,H ;ALL DONE? ORA L XCHG ;GET BACK INBUF PTR JNZ PROMPT ;NO, KEEP GOING JMP PROMPTR ;AL |/07/79 Add VIEW command. (WLC) ; ;01/06/80 Rewrite 'F' command. (WLC) ; ;10/10/79 Save regs in BIOS calls, translate input to upper case ; add commands: < save sector ; > restore sect ; / repeat ; allow change from-thru. (WLC) ; ;02/25/79 Put sector read into 'S' command. (WLC) ; ;11/26/78 Add disk # to login command. (WLC) ; ;11/12/78 Add login command. (WLC) ; ;08/06/78 Originally written to reconstruct blown ; disks on CBBS via remote access. (WLC) ; ; ; --MD VCONOUT+1 DAD D SHLD VLIST+1 DAD D ;PUNCH DAD D ;RDR DAD D SHLD VHOME+1 DAD D SHLD VSELDK+1 DAD D SHLD VSETTRK+1 DAD D SHLD VSETSEC+1 DAD D SHLD SETDMA+1 DAD D SHLD VREAD+1 DAD D SHLD VWRITE+1 LDA VER2FL ORA A JZ DOCPM1 DAD D ;LISTST DAD D SHLD VSCTRN+1 JMP HELLO ; DOCPM1 LHLD BDOS+1 MVI L,0 ;BDOS ON PAGE BOUNDARY PUSH H LXI D,TRNOFF ;CP/M 1.4 SECTRAN ROUTINE OFFSET DAD D SHLD VSCTRN+1 POP H LXI D,SKWOFF ;CP/M 1.4 SKEW TABLE OFFSET DAD D'T' ! JZ POS CPI 'V' ! JZ VIEW CPI 'W' ! JZ DOWRITE CPI 'X' ! JZ BASE CPI 'Z' ! JZ SLEEP CPI '/' ! JZ REPEAT ; WHAT XRA A STA QFLAG CALL ILPRT DB '?',CR,LF,0 JMP PROMPTR ; ;Memory full error ; MEMFULL XRA A STA QFLAG CALL ILPRT DB '+++ Out of memory +++',CR,LF DB ' (may be due to many "<<" stacked sectors)' DB CR,LF,0 JMP PROMPTR ; ;Print disk statistics ; STATS PUSH H CALL ILPRT DB 'Disk Information:',CR,LF DB 'Tracks:',9,9,0 LHLD MAXTRK INX H CALL DEC  ML DONE ; ;TOGGLE PRINT FLAG ; PRINTFF LDA PFLAG XRI 1 STA PFLAG JMP PROMPT ; ;SLEEP ROUTINE, IN TENTHS OF A SEC ; SLEEP CALL DECIN ;GET COUNT IF ANY MOV A,E ;ANY? ORA A JNZ SLEEPLP MVI E,10 SLEEPLP LXI B,8000 ;APPROX .1 SEC @ 2MHz LDA CLOCK ORA A JZ SLEEP2 LXI B,16000 ;APPROX .1 SEC @ 4 MHz SLEEP2 DCX B MOV A,B ORA C JNZ SLEEP2 PUSH D CALL CTLCS POP D JZ PROMPRC DCR E JNZ SLEEPLP JMP PROMPT ; ;CHECK FOR CONTROL-C OR S ; CTLCS CALL CONST ORA A JNZ G  TO DE RDIRLP PUSH B PUSH D MOV B,D MOV C,E LDA BDOS+2 ;CHECK MEM AVAIL DCR A CMP D JC MEMFULL CALL SETDMA LHLD CURTRK XCHG CALL SETTRK LHLD CURSEC XCHG CALL SETSEC CALL READ CALL NEXTSEC POP D POP B LXI H,80H DAD D XCHG DCX B MOV A,B ORA C JNZ RDIRLP LXI B,BASE+80H CALL SETDMA POP H RET ; ;MA THE DIRECTORY ; MAP CALL NOCONT ;CAN'T CONTINUE "F" COMMAND CALL READDIR ;READ IN DIRECTORY MVI C,0 ;INIT START GRP # LDA AL0 ;READ DIR GRP BITS C !SP2 MVI A,')' MAPNSP2 CALL TYPE ;")" IF ERASED FILE JMP FLIP ; NONAME CALL ILPRT DB ' ++FREE++ ',0 FLIP LDA TWOUP XRI 1 STA TWOUP JZ CRLF DELIM MVI A,':' CALL TYPE JMP SPACE ; ;PRINT NAME, LENGTH IN B ; MAPN2 MOV A,M ANI 7FH ;STRIP POSSIBLE 2.x ATTRIBUTE BIT INX H CPI ' ' ;PRINTABLE? JC MAPN2H ;..NO, IN HEX CPI 7EH ;7E IS LEADIN ON SOME CRTS JC MAPN2A MAPN2H CALL BHEX JMP MAPN2Z ; MAPN2A CALL TYPE MAPN2Z DCR B JNZ MAPN2 RET ; ;FIND WHICH FILE GROUP P PROMPTR ; SAVECUR CALL RESETBF ;RESET BUFF POINTERS ; SAVENS LDA BDOS+2 DCR A CMP D JZ MEMFULL LXI H,BASE+80H MVI B,128 CALL MOVE MVI A,1 ;..SHOW STA SAVEFLG ;..SAVED EXISTS POP H JMP PROMPT ; ;RESTORE THE CURRENT SECTOR ; RESTORE LDA SAVEFLG ORA A JZ NOSAVE ;NONE TO SAVE MVI A,'>' CALL NEXTEST ;SEE IF WANT NEXT PUSH H LHLD NXTREST JNZ RESTN ;OLD SECTOR ; ;REQUEST TO RESTORE "NEXT" SECTOR ; XCHG ;SAVE POINTER IN HL LDA NUMSAVD ;COMPARE # SAVED LXI H,NUM `ETC ORI 1 ;NO CHAR, RETN NZ RET GETC CALL CONIN ANI 1FH ;ALLOW ASCII CPI 'S'-40H CZ CONIN CPI 'C'-40H RET ;0 SET IF CTL-C ; ;Find our way at initialization ; GETSTP MVI C,GETDSK CALL BDOS ;GET CURNT DSK MOV C,A ; WE HAVE TO SELECT JMP SELECT ; TO GET THE DPH ; LOGIN CALL NOCONT CALL DOLOG JMP PROMPT ; DOLOG MOV A,M ;DISK REQ? LXI D,0 CPI CR JZ LGNODK CPI ';' JZ LGNODK CALL UPCASE INX H SUI 'A' MOV C,A SELECT PUSH H MOV A,C STA DRIVE ;REMEMBER LATER ALL COLECT ;COLLECT COUNT OF DIR GRPS.. LDA AL1 ;..IN REGISTER C CALL COLECT MVI B,0 ;BC NOW HAS A DEFAULT START GRP # CALL HEXIN PUSH H ;SAVE INBUF PTR MOV A,E ;GET START ORA D ;NOTHING? JZ MAPDF ;..YES, DFLT MOV B,D MOV C,E ; MAPDF CALL HEXB MVI A,'-' CALL TYPE CALL GETGRP ;GET GRP(C) TO HL MAPCONT INX B ;NEXT GRP # PUSH H LHLD DSM ;GET HIGHEST GRP # INX H ;PLUS 1 FOR COMPARISON MOV A,L ;WHEN BC REACHES DSM+1.. CMP C ;..THEN WE HAVE EXCEEDED.. JNZ MAPC1 ;..THE DISK (BC) BELONGS TO ; GETGRP LHLD DRM ;MAX DIR ENTRY # INX H ;MAKE 1-RELATIVE SHLD FILECT LHLD NXTSAVE ;DIR. READ IN AFTER SAVE BUFFER GETGLP PUSH H ;SAVE POINTER TO NAME MOV A,M ;PICK UP DN BYTE LXI D,14 ;NOW GET RECORD COUNT DAD D ; S2 PORTION .. MOV A,M ; IS 0 IN CP/M 1.4 CPI 0E5H JZ GETGNF ANI 0FH MOV E,A INX H MOV A,M ORA E JZ GETGNF MVI E,16 ;FIRST SET FOR 8-BIT GRPS LDA DSM+1 ORA A JZ SMALGRP MVI E,8 ;NOPE, BIG GROUPS SMALGRP MOV D,A ;SAVE GRP SIZE INDICATOR mREST ; TO INR M ; # RESTORED CMP M JC NOSAVE ;EXIT IF ERROR LXI H,80H DAD D ;GO TO NEXT BUFFER SHLD NXTREST XCHG ;OLD (UN-INCREMENTED) TO HL ; RESTN LXI D,BASE+80H MVI B,128 CALL MOVE ;FROM (HL) TO (DE) LEN. IN (B) POP H JMP PROMPT ; NOSAVE XRA A STA QFLAG CALL ILPRT DB '++NO "<" SAVE COMMAND ISSUED',CR,LF DB ' OR RESTORING MORE THAN SAVED' DB CR,LF,0 CALL RESETBF ;RESET BUFF POINTERS JMP PROMPTR ; ;RESET "<<" AND ">>" BUFFER POINTERS ; RESETBF XRA A STA NUM WHERE WE ARE VSELDK CALL $-$ ;ADDR FILLED IN BY 'INIT' LDA VER2FL ORA A ;IF NOT CP/M 2.x ... JZ SELSKP ;..THEN SKIP THIS JUNK MOV A,H ORA L JZ WHAT ;SELECT ERROR MOV E,M ;GET THE SECTOR TABLE PNTR INX H MOV D,M INX H XCHG SHLD SECTBL LXI H,8 ;OFFSET TO DPBPTR DAD D MOV A,M ;PICK UP DPB POINTER INX H ; TO USE MOV H,M ; AS PARAMETER MOV L,A ; TO LOGIT SELSKP CALL LOGIT LHLD SYSTRK ;RESET TRACK AND SECTOR XCHG ; TO DIRECTORY CALL SETTRK ; ON EVERY LXI D,1 ; b CAPACITY.. MOV A,H CMP B MAPC1 POP H JZ MAPEND ;..AND WE ARE DONE PUSH H CALL GETGRP ;GET ANOTHER POP D ;SEE IF SAME CALL CTLCS JZ MAPEND2 MOV A,D CMP H JNZ MAPDIFF MOV A,E CMP L JZ MAPCONT ;SAME, CONTINUE ; ;DIFFERENT FILE ENCOUNTERED ; MAPDIFF DCX B CALL HEXB INX B XCHG CALL MAPNAME JMP MAPDF ; ;END OF MAP ; MAPEND DCX B ;GET LAST CALL HEXB CALL MAPNAME ; ;END OF MAP - REPOSITION TO PREVIOUS GROUP ; MAPEND2 CALL CRLF LHLD GROUP XCHG JMP POSGRP2 < GETGL2 INX H ;POINTING INTO DM FIELD CALL GRPCMP ;COMPARE BC GRP # AGAINST 1 DM FLD JZ GETGOT ;JUMP IF FOUND ONE DCR E ;ELSE COUNT DOWN JNZ GETGL2 ;GO TEST SOME MORE GETGNF POP H ;NOT THIS ONE! LXI D,32 ;SO GO TO NEXT DAD D XCHG LHLD FILECT ;THERE IS LIMIT TO EVERYTHING DCX H SHLD FILECT MOV A,H ORA L XCHG ;RE-ALIGN JNZ GETGLP ; ;Group is not allocated to any file LXI H,0 ;SAY SO RET ; ;GOT THE FILE ; GETGOT POP H RET ; ;SAVE THE CURRENT SECTOR. IF "<" SAVE ONLY SAVD STA NUMREST LXI H,SAVEBUF SHLD NXTSAVE SHLD NXTREST RET ; ;MOVE (HL) TO (DE) LENGTH IN B ; MOVE MOV A,M STAX D INX H INX D DCR B JNZ MOVE RET ; ;TEST IF CURR CHAR IN BUFFER IS = (A). ; BUMP HL IF SO ; NEXTEST CMP M ;MATCH? RNZ ; NO, RET INX H ; YES SKIP IT RET ; THEN RETURN ; NOWRITE XRA A ;GET 0 STA WRFLG ;CAN'T WRITE NOW RET ; ;NO MATCH IN SEARCH, TRY NEXT CHAR ; SRNOMAT POP H CALL CTLCS ;ABORT? JNZ SEARCH ; NO LXI H,INBUF ;YES MVI M,CR JMP C  LOGIN CALL SETSEC ; CHANGE LHLD PHYSEC ;THIS LOGIC WILL TELL MOV A,H ; IF FIRST SEC ORA L ; IS PHYSICAL 0 STA FIRST0 CALL CALCSUB POP H ; LGNODK CALL NOWRITE RET ; ;READ IN THE DISK DIRECTORY ; READDIR PUSH H CALL NOWRITE ;POSITIONING LOST LHLD SYSTRK SHLD CURTRK LXI H,1 SHLD CURSEC LHLD DRM ;GET DIR SIZE FROM DPB INX H ;MAKE 1-RELATIVE CALL ROTRHL CALL ROTRHL ;DIVIDE BY 4 (4 NAMES/SECTOR) MOV B,H MOV C,L LHLD NXTSAVE ;POSITION AFTER SAVE BUFFER XCHG ;MOVE  ;..WHICH POPS INBUF AND CONTINUES ; ;PRINT FILE NAME POINTED TO BY HL ; MAPNAME CALL SPACE MOV A,H ORA L ;NONE? JZ NONAME MOV A,M ;SEE IF ALLOC CPI 0E5H ;FREE? MVI A,' ' JNZ MAPNSP1 MVI A,'(' MAPNSP1 CALL TYPE PUSH H ;SAVE POINTER MOV A,M CALL HEX ;SHOW USER NUMBER CALL SPACE INX H ;SKIP USER BYTE PUSH B MVI B,8 CALL MAPN2 MVI A,'.' CALL TYPE MVI B,3 CALL MAPN2 POP B CALL SPACE MOV A,M ;GET EXT CALL HEX POP H MOV A,M CPI 0E5H MVI A,' ' JNZ MAPN = ONE, AND ; RESET THE SAVED STACK. IF "<<" SAVE, POINT ; TO NEXT BUFFER ADDR. ; SAVE LDA WRFLG ORA A JZ BADW ;NONE TO SAVE MVI A,'<' ;TEST NEXT CHAR CALL NEXTEST ; FOR '<' PUSH H LHLD NXTSAVE XCHG JNZ SAVECUR ;SAVE, SECT ADDR IN DE LXI H,80H DAD D ;HL = NEXT SECT SHLD NXTSAVE ;SAVE NEXT SECT ADDR LDA NUMSAVD INR A STA NUMSAVD JNZ SAVENS DCR A STA NUMSAVD XCHG SHLD NXTSAVE XRA A STA QFLAG CALL ILPRT DB '++ Can''t save more than 255 sectors' DB CR,LF,0 JM  /ALCGRP ;SHOW WHERE STOPPED ; ;SEARCH FOR CHARACTER STRING ; SEARCH CALL NOCONT PUSH H ;SAVE STRING POINTER XRA A ;STORE 0 STA SECDISP ; INTO SECT DISPL. SRCHL CALL RDBYTE ;GET A BYTE MOV B,A ;SAVE IT MOV A,M ;CHECK NEXT MATCH CHAR. CPI '<' ;WILL IT BE HEX? MOV A,B ;RESTORE DISK CHAR JZ SRCHL1 ANI 7FH ;NEXT CHAR IS ASCII...STRIP BIT 7 SRCHL1 PUSH PSW CALL GETVAL ;GET SEARCH VALUE MOV B,A POP PSW CMP B ;MATCH? JNZ SRNOMAT ;NO MATCH INX H MOV A,M ;DONE? CPI CR JZ SREQU   CPI LF JZ VIEWPR CPI TAB JZ VIEWPR VIEWHX MOV A,M ;NOT ASCII...PRINT AS CALL BHEX JMP VIEWNP ; VIEWPR CALL TYPE VIEWNP INR L JNZ VIEWCHR DCR E JZ VIEWEND PUSH D ;SAVE COUNT CALL NEXTSEC LHLD CURSEC XCHG CALL SETSEC LHLD CURTRK XCHG CALL SETTRK CALL READ POP D ;RESTORE COUNT JMP VIEWLP ; VIEWEOF CALL ILPRT DB CR,LF,TAB,'++EOF++',CR,LF,0 VIEWEND POP H CALL CRLF JMP CALCGRP ; ;DUMP IN HEX OR ASCII ; DUMP LDA WRFLG ORA A JNZ DUMPOK BADDMP XRA  CALL DECIN POSTRK PUSH H LHLD MAXTRK CALL SUBDE POP H JC OUTLIM CALL SETTRK CALL NOWRITE ;TRACK DOESN'T READ MVI A,1 STA NOTPOS ;SHOW NOT POSITIONED JMP CALCGRP ; POSSECD CALL DECIN MOV A,D ORA E JZ WHAT ;DON'T ALLOW SECTOR 0 POSSEC PUSH H LHLD SPT CALL SUBDE POP H JC WHAT CALL SETSEC CALL READ XRA A STA NOTPOS ;POSITIONED OK ; CALCGRP CALL CALCSUB JMP INQ ; ;CALCULATE GROUP FROM TRACK AND SECTOR ; CALCSUB PUSH H LHLD SYSTRK XCHG LHLD CURTRK CALL MENT ;# OF DIR ENTRIES LXI B,80H+BASE CALL SETDMA PFRD CALL NEXTSEC LHLD CURTRK XCHG CALL SETTRK LHLD CURSEC XCHG CALL SETSEC CALL READ LXI H,80H+BASE PFNRD LXI D,FCB+1 ;TO NAME INX H ;SKIP DISK BYTE ; ;SEE IF THIS NAME MATCHES ; MVI B,11 ;NAME LENGTH PFMATLP LDAX D ;GET NAME CHAR CPI '?' JZ PFMAT ;MATCH ANY CMP M ;MATCH EXACTLY? JZ PFMAT ORI 80H ;TRY MATCH WITH HI BIT CMP M JNZ PFNMAT ; NO PFMAT INX H INX D DCR B JNZ PFMATLP ; ;GOT NAME ; CALL CALCSUB ^ CPI ';' JNZ SRCHL ;GOT MATCH SREQU XRA A STA QFLAG CALL ILPRT DB '= AT ',0 LDA BUFAD ANI 7FH CALL HEX CALL CRLF JMP CALCGRP ; ;GET VALUE FROM INPUT BUFFER ; GETVAL MOV A,M CPI '<' ;HEX ESCAPE? RNZ ;NO, RETURN ;"<<" MEANS ONE "<" INX H MOV A,M CPI '<' RZ ;GOT HEX PUSH D CALL HEXIN ;GET VALUE CPI '>' ;PROPER DELIM? MOV A,E ;GET VALUE POP D JNZ WHAT ;ERROR RET ; ;READ A BYTE AT A TIME ; RDBYTE PUSH H LDA FTSW ;FIRST READ? ORA A JNZ READ1 LHLD kA STA QFLAG CALL ILPRT DB '++Can''t dump, no sector read.',CR,LF,0 EXPL XRA A STA QFLAG CALL ILPRT DB 'Use G command following F,',CR,LF DB 'or R or S following T',CR,LF,0 JMP PROMPTR ; DUMPOK MOV A,M CPI ';' JZ DUMPDF ;DFLT CPI CR JNZ DUMPNDF ; ;USE DEFAULT DUMPDF LXI B,BASE+80H LXI D,0FFH JMP DUMP1 ; DUMPNDF CALL DISP MOV B,D MOV C,E CPI CR JZ DUMP1 CPI ';' JZ DUMP1 INX H ;SKIP ',' CALL DISP ; ;BC = start, DE = end ; DUMP1 PUSH H ;SAVE COMMAND POINTE SUBDE XCHG LHLD SPT CALL MULT XCHG LHLD CURSEC DCX H DAD D LDA BLM MOV B,A MOV A,L ANA B STA GRPDISP LDA BSH MOV B,A CALCLOP CALL ROTRHL DCR B JNZ CALCLOP SHLD GROUP POP H RET ; POSGRPH CALL HEXIN POSGRP PUSH H LHLD DSM CALL SUBDE POP H JC OUTLIM XCHG SHLD GROUP XCHG XRA A STA GRPDISP PUSH H POSGRP2 CALL GTKSEC CALL SETTRK XCHG CALL SETSEC CALL READ XRA A STA NOTPOS ;NOW POSITIONED POP H JMP INQ ; GTKSEC MOV H,D MOV L,E LDA % ;COMPUTE GROUP CALL INQSUB ;SHOW WHICH ONE MOV A,L ;GET DISPLACEMENT ANI 060H ;TO START OF NAME STA SECDISP ORI 80H ;PUT IT BACK 80-FF MOV L,A SHLD FCONT ;SAVE FOR "F"IND NEXT LXI D,32 ;DUMP LENGTH XCHG DAD D ;SET UP FOR DUMP XCHG XRA A STA NOTPOS ;SHOW NOW POSITIONED MVI A,'D' STA DUMTYPE STA WRFLG ;ALLOW REWRITE JMP DUMPLP ;DUMPLP POPS H (CMD BUF ADDR) ; ;NOT FOUND ; PFNOTF XRA A STA QFLAG CALL ILPRT DB '++FILE NOT FOUND',CR,LF,0 POP H ;GET CMD BUFF PTR CAL }BUFAD MOV A,L ORA A ;IN BUFFER? JM NORD ;YES, SKIP READ ; ;HAVE TO READ ; CALL NEXTSEC READ1 XRA A STA FTSW ;NOT FIRST READ LHLD CURSEC XCHG CALL SETSEC LHLD CURTRK XCHG CALL SETTRK CALL READ CALL CALCSUB LXI H,BASE+80H ; ;CHECK IF THE BYTE "SECDISP" IS 0. IF SO, WE ARE ;READING FIRST BYTE OF "=" COMMAND SEARCH. ;SO SAVE THE ADDRESS, SO THE "@" SYMBOL MAY ;BE USED IN A CH OR CA COMMAND TO REFERENCE ;"WHEREVER" THE MATCH WAS FOUND. ; NORD LDA SECDISP ORA A JNZ NOR ER MOV H,B MOV L,C DUMPLP MOV A,L ANI 7FH CALL HEX CALL SPACE CALL SPACE LDA DUMTYPE CPI 'A' JZ DUMPAS PUSH H ;SAVE START DHEX MOV A,M CALL HEX MOV A,L ANI 3 CPI 3 CZ SPACE MOV A,L ANI 7 CPI 7 CZ SPACE MOV A,E CMP L JZ DPOP INX H MOV A,L ANI 0FH JNZ DHEX DPOP CALL CTLCS JZ PROMPRC LDA DUMTYPE CPI 'H' JZ DNOAS ;HEX ONLY POP H ;GET START ADDR DUMPAS CALL ASTER DCHR MOV A,M ANI 7FH CPI ' ' JC DPER CPI 7EH JC DOK DPER MVI A,'.' DOK CA ^ BSH GLOOP DAD H DCR A JNZ GLOOP LDA GRPDISP ADD L ;CAN'T CARRY MOV L,A ; ;Divide by nr of sectors, quotient=track, remainder=sector ; XCHG LHLD SPT CALL NEG XCHG LXI B,0 ; DIVLP INX B DAD D JC DIVLP DCX B XCHG LHLD SPT DAD D PUSH H LHLD SYSTRK DAD B XCHG POP H INX H RET ; ;ZAP ABILITY TO DO "F" (FIND NEXT) BECAUSE ANOTHER ;DISK COMMAND LOST POSITIONING. ; NOCONT PUSH H LXI H,0 SHLD FCONT POP H RET ; ;POSITION TO FILENAME BY "MANUALLY" READI L NOWRITE CALL NOCONT MVI A,1 STA NOTPOS JMP PROMPTR ; ;CONTINUING FIND ; PFCONT PUSH H LHLD FCONT MOV A,H ORA L JNZ PFNMAT POP H XRA A STA QFLAG CALL ILPRT DB '++Can''t continue F command',CR,LF,0 JMP PROMPTR ; ;NO MATCH, GET NEXT CHAR ; PFNMAT XCHG ;SAVE BUFF POINTER LHLD NUMENT ;GET # DIR ENTRIES DCX H SHLD NUMENT MOV A,H ORA L JZ PFNOTF ;NOT FOUND XCHG ;BUFF BACK TO HL MOV A,L ;GET DISPLACEMENT ANI 0E0H ;BACK TO START OF ENTRY ADI 32 ;ONE ENTRY D2 MOV A,L ;GET DISP STA SECDISP NORD2 MOV A,M INX H SHLD BUFAD POP H RET ; ;VIEW THE FILE IN ASCII STARTING AT ;CURRENT SECTOR, STEPPING THRU THE DISK ; VIEW CALL NOCONT LDA WRFLG ORA A JZ BADDMP CALL DECIN ;GET SECTOR COUNT PUSH H MOV A,E ORA A JNZ VIEWLP INR E ;DFLT=1 VIEWLP LXI H,BASE+80H ;TO DATA VIEWCHR CALL CTLCS JZ VIEWEND MOV A,M CPI 1AH JZ VIEWEOF ANI 7FH CPI 7EH JNC VIEWHX ;SHOW RUBOUT AND TILDE AS HEX CPI ' ' JNC VIEWPR CPI CR JZ VIEWPR LL TYPE MOV A,E CMP L JZ DEND INX H MOV A,L ANI 0FH JNZ DCHR DEND CALL ASTER CALL CRLF PUSH D CALL CTLCS POP D JZ PROMPTR MOV A,E CMP L JNZ DUMPLP POP H JMP PROMPT ; DNOAS POP B CALL CRLF MOV A,E CMP L JNZ DUMPLP POP H JMP PROMPT ; ;POSITION ; POS CALL NOCONT PUSH PSW MOV A,M CPI ';' JZ POSINQ CPI CR JNZ POSOK POSINQ POP PSW JMP INQ ; POSOK POP PSW CPI 'T' JZ POSTRKD CPI 'S' JZ POSSECD CPI 'G' JZ POSGRPH JMP WHAT ; POSTRKD NG ;THE DIRECTORY. THIS OVERCOMES THE 2.2 PROBLEM ;OF BEING UNABLE TO DETECT WHAT SECTOR WAS ;FOUND AFTER "SEARCH FIRST" BDOS FUNCTION ; POSFIL MOV A,M ;GET CHAR AFTER 'F' CPI CR JZ PFCONT ;NO NAME CPI ';' ;NEXT COMMAND? JZ PFCONT LXI D,FCB XRA A ;LOGGED IN DISK STAX D INX D MVI B,8 CALL MVNAME MVI B,3 CALL MVNAME PUSH H LHLD SYSTRK ;TO SHLD CURTRK ; DIR LXI H,0 ;INIT TO 0, CALLS SHLD CURSEC ; NEXTSEC B4 USING LHLD DRM ;# OF DIR ENTRIES-1 INX H ; EXACT # SHLD NU  MOV L,A JNC PFNRD ;NO READ, STILL IN SECTOR JMP PFRD ;TO NEXT SECTOR ; MVNAME MOV A,M INX H ;IN CASE HAVE TO SKIP CPI '.' ; '.' JZ PADSP CPI '*' ; OR '*' JZ PADQ ;FILL W/"?" DCX H ; CPI CR JZ PADSP CPI ';' JZ PADSP CALL UPCASE STAX D INX H INX D DCR B JNZ MVNAME MOV A,M CPI CR RZ CPI ';' RZ INX H CPI '.' RZ JMP WHAT ; PADSP MVI A,' ' JMP PAD ; PADQ MVI A,'?' ; PAD STAX D INX D DCR B JNZ PAD MOV A,M ;SKIP '.' CPI '.' ; AFTER '*' RNZ 9ed to check ; if a disk is readable) or "=xxx" (which scans ; forward for a match) by "definition" shouldn't ; "wrap and run forever". ; JC BOUNDS ; XCHG SHLD CURTRK LXI H,1 ; NEXTOK SHLD CURSEC POP D POP H 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 H LHLD SYSTRK XCHG LHLD CURTRK CALL SUBDE JC NOGRP CALL ILPRT DB 'G ALL HEX ;ECHO IN HEX POP PSW ;GET NEW STAX D ;SAVE NEW MOV A,C ;SEE IF 'THRU' ORA A JZ CHGHNTH ;..NO. CMP E ;..YES, DONE? JZ PROMPTC LHLD HEXAD ;..NO: MORE CHGHNTH INR E JNZ CHGHEX MOV A,M CPI CR JZ PROMPTC CPI ';' JZ PROMPTC JMP WHAT ; DOREAD CALL READ JMP PROMPT ; CANTRD XRA A STA QFLAG ;NOT QUIET CALL ILPRT DB '++Can''t read or go +/-: not positioned',CR,LF DB 'Position by:',CR,LF DB 9,'Track then Sector, or',CR,LF DB 9,'Group or to file name via F',CR,LF, d ;TERMINATOR? JZ HINLP ;YES, SKIP IT CPI '0' JC WHAT CPI '9'+1 JC HINNUM CPI 'A' JC WHAT CPI 'F'+1 JNC WHAT SUI 7 HINNUM SUI '0' XCHG DAD H DAD H DAD H DAD H ADD L MOV L,A XCHG JMP HINLP ; HDIN INX H ;SKIP '#' DECIN CALL SCANH ;SEE IF xxxH JZ HEXIN LXI D,0 DINLP MOV A,M CALL UPCASE CPI CR RZ CPI ';' RZ CPI ',' RZ CPI '-' ;'THRU'? RZ INX H CPI '0' JC WHAT CPI '9'+1 JNC WHAT SUI '0' PUSH H MOV H,D MOV L,E DAD H ;X2 DAD H ;X  ; IN "*.*" INX H RET ; PLUS LDA NOTPOS ORA A JNZ CANTRD CALL NOCONT LXI D,1 ;DFLT TO 1 SECT MOV A,M ;GET NEXT CHAR CPI CR ;CR? JZ PLUSGO ;..YES, DFLT TO 1 CPI ';' JZ PLUSGO CALL DECIN ;GET DECIMAL # MOV A,D ORA E JZ WHAT PLUSGO CALL NEXTSEC DCX D ;MORE TO GO? MOV A,D ORA E JNZ PLUSGO ;..YES ; ;OK, INCREMENTED TO SECTOR. SETUP AND READ ; PLUSMI PUSH H LHLD CURSEC XCHG CALL SETSEC LHLD CURTRK XCHG CALL SETTRK POP H CALL READ JMP CALCGRP ; MIN M=',0 LHLD GROUP MOV B,H MOV C,L CALL HEXB MVI A,':' CALL TYPE LDA GRPDISP CALL HEX MVI A,',' CALL TYPE NOGRP CALL ILPRT DB ' T=',0 LHLD CURTRK CALL DEC CALL ILPRT DB ', S=',0 LHLD CURSEC CALL DEC CALL ILPRT DB ', PS=',0 LHLD PHYSEC CALL DEC CALL CRLF POP H RET ; CHG MOV A,M ;GET TYPE (HEX, ASCII) CALL UPCASE PUSH PSW ;SAVE "H" OR "A" INX H CALL DISP ;GET, VALIDATE DISP TO DE INX H LXI B,0 ;SHOW NO 'THRU' ADDR CPI '-' ;TEST DELIM FR. DISP JNZ 0 JMP PROMPT ; DOWRITE CALL WRITE JMP PROMPT ; BHEX PUSH PSW MVI A,'<' CALL TYPE POP PSW CALL HEX MVI A,'>' CALL TYPE RET ; HEXB LDA DSM+1 ORA A JZ HEXX MOV A,B CALL HEX HEXX MOV A,C HEX PUSH PSW RAR RAR RAR RAR CALL NIBBL POP PSW NIBBL ANI 0FH CPI 10 JC HEXNU ADI 7 HEXNU ADI '0' JMP TYPE ; ;Decimal output routine ; DEC PUSH B PUSH D PUSH H LXI B,-10 LXI D,-1 DECOU2 DAD B INX D JC DECOU2 LXI B,10 DAD B XCHG MOV A,H ORA L CN J4 DAD D ;X5 DAD H ;X10 ADD L MOV L,A MOV A,H ACI 0 MOV H,A XCHG POP H JMP DINLP ; ;SCAN TO SEE IF xxxH WAS SPECIFIED ; SCANH MOV D,H MOV E,L ;XFER HL TO DE SCANHL LDAX D CALL UPCASE CPI 'H' RZ INX D ;TO NEXT CPI '0' RC CPI '9'+1 JC SCANHL CPI 'A' RC CPI 'F'+1 JC SCANHL ORA A ;SET NON ZERO RET ; ;REQUEST TO GET DISPLACEMENT IN SECTOR ;AT WHICH LAST "=" COMMAND MATCHED. ; GETDISP INX H ;SKIP "@" MOV A,M CPI '-' JZ DISPPM CPI '+' JZ DISPPM US LDA NOTPOS ORA A JNZ CANTRD CALL NOCONT LXI D,1 ;SET DFLT MOV A,M ;GET CHAR CPI CR ;CR? JZ MINGO ;..YES, DFLT=1 CPI ';' JZ MINGO CALL DECIN ;..NO, GET ## MOV A,D ORA E JZ WHAT MINGO PUSH H LHLD CURSEC DCX H MOV A,H ORA L JNZ MINOK LHLD CURTRK MOV A,H ORA L JNZ SEASH LHLD CURSEC INX H SHLD CURSEC BOUNDS XRA A STA QFLAG CALL ILPRT DB 'Out of bounds',CR,LF,0 JMP PROMPTR ; SEASH DCX H SHLD CURTRK LHLD SPT MINOK SHLD CURSEC POP H DCX D M a CHGNTH ;NO THRU PUSH D ;SAVE FROM CALL DISP ;GET THRU INX H ;SKIP END DELIM MOV B,D MOV C,E ;BC = THRU POP D ;GET FROM JMP CHGAH ; CHGNTH CPI ',' JNZ WHAT ; CHGAH POP PSW CPI 'H' JZ CHGHEX CPI 'A' JNZ WHAT ;CHANGE ASCII CHGALP MOV A,M CPI CR JZ PROMPTC CPI ';' JZ PROMPTC LDAX D CPI ' ' JC CHGAHX CPI 7EH JNC CHGAHX JMP CHGA2 ; CHGAHX CALL BHEX JMP CHGA3 ; CHGA2 CALL TYPE CHGA3 SHLD BACK ;IN CASE "THRU" CALL GETVAL ;ASCII OR STAX D ;UPDATE CH TZ DEC MOV A,E ADI '0' CALL TYPE POP H POP D POP B RET ; SPACE MVI A,' ' JMP TYPE ; ASTER MVI A,'*' JMP TYPE ; ;Inline print routine ; ILPRT XTHL ILPLP CALL CTLCS ;ABORT? JZ PROMPRC MOV A,M CPI 1 ;PAUSE? JNZ ILPOK CALL CONIN CPI 3 ;ABORT? JZ PROMPTR JMP ILPNX ; ILPOK CALL TYPE ILPNX INX H MOV A,M ORA A JNZ ILPLP INX H XTHL RET ; ;DISP CALLS HEXIN, AND VALIDATES A SECTOR ;DISPLACEMENT, THEN CONVERTS IT TO AN ADDRESS ; DISP CALL HEXIN PUSH PSW ;S  LDA SECDISP ;GET DISPLACEMENT ANI 7FH ;MAKE IT RELATIVE TO 0 MOV E,A ;SAVE IT MVI D,0 ;SET DE = TO IT MOV A,M ;GET ENDING DELIM RET ; ;GOT + OR - DISPLACEMENT ; DISPPM PUSH PSW ;SAVE +/- INX H ;TO NEXT CALL HEXIN ;GET VALUE TO DE POP PSW ;GET +/- CPI '-' ;IF -, CZ COMDE ; COMPLEMENT DE LDA SECDISP ADD E ANI 7FH ;PRESERVE SECT DISPL MOV E,A MVI D,0 ;DE = 0-7F MOV A,M ;GET DELIMITER FOR RET ; FURTHER TESTS ; ;COMPLEMENT DE ; COMDE MOV A,D CMA MOV D,A MOV A,E OV A,D ORA E JNZ MINGO JMP PLUSMI ; ;Go to next sector ; NEXTSEC PUSH H PUSH D LHLD CURSEC INX H XCHG LHLD SPT CALL SUBDE XCHG JNC NEXTOK LHLD CURTRK INX H XCHG LHLD MAXTRK CALL SUBDE ; ;07/31/81 Delete wrap to start (hangs on my system, ; hangs on Micromation). ...but mostly because ; the "front" of the disk has n-o-t-h-i-n-g to ; do with the "back" of the disk, so why wrap? ; ; A less "emotional" and more "practical reason, ; is that commands such as "q+;/" (us AR INX H ;TO NEXT INPUT CHAR ;See if 'THRU' requested MOV A,C ORA A JZ CHGANTH CMP E ;DONE?.. JZ PROMPTC ;..YES LHLD BACK CHGANTH INR E JNZ CHGALP MOV A,M CPI CR JZ PROMPTC CPI ';' JZ PROMPTC JMP WHAT ; ;CHANGE HEX ; CHGHCOM INX H ; CHGHEX MOV A,M CPI CR JZ PROMPTC CPI ';' JZ PROMPTC CPI ',' ;DELIM? JZ CHGHCOM PUSH D SHLD HEXAD ;IN CASE 'THRU' CALL HEXIN ;POSITIONS TO DELIM MOV A,E ;GET VALUE POP D ;..ADDR PUSH PSW ;SAVE VALUE LDAX D ;GET OLD C AVE DELIMITER MOV A,D ORA A JNZ BADISP MOV A,E ORA A JM BADISP ADI 80H ;TO POINT TO BUFFER AT BASE+80H MOV E,A MVI D,BASE/256 POP PSW ;GET DELIM RET ; BADISP XRA A STA QFLAG ;NOT QUIET CALL ILPRT DB '++BAD DISPLACEMENT (NOT 0-7F)' DB CR,LF,0 JMP PROMPTR ; HEXIN LXI D,0 MOV A,M CPI '#' ;DECIMAL? JZ HDIN ;MAKE DECIMAL CPI '@' JZ GETDISP HINLP MOV A,M CALL UPCASE CPI CR RZ CPI ';' RZ CPI ',' RZ CPI '-' ;'THRU'? RZ CPI '>' RZ INX H CPI 'H' p CMA MOV E,A INX D ;1'S COMP ==> 2'S COMP RET ; ;READ IN A CONSOLE BUFFER FULL ; RDBUF MVI A,':' CALL TYPE ; RDBF1 LXI H,INBUF MVI B,0 RDBLP CALL CONIN MOV C,A ;SAVE FOR BS TEST ; ;Evaluate control characters ; CPI 'U'-40H ! JZ RDCTLU CPI CR ! JZ RDCR CPI 'H'-40H ! JZ RDBS CPI 7FH ! JZ RDBS CPI 'R'-40H ! JZ RDCTLR CPI 'X'-40H ! JZ RDCTLX CPI ' ' ! JC RDBCCC ;CHECK ^C MOV M,A INX H INR B JM FULL CALL TYPE JMP RDBLP ; FULL DCR B DCX H MVI A,'*' ;SIGNAL WE -$ ;ADDR FILLED IN BY 'INIT' POP H POP D POP B RET ; ;CONSOLE OUT WITH TAB EXPANSION ; TYPE PUSH B PUSH D PUSH H MOV C,A ;FOR OUTPUT ROUTINE CPI TAB JNZ TYPE2 TYPETAB MVI A,' ' CALL TYPE LDA TABCOL ANI 7 JNZ TYPETAB JMP TYPERET ; ;FILTER OUT CONTROL CHARACTERS TO ;PREVENT GARBAGE DURING VIEW OF FILE ; TYPE2 CPI ' ' JNC TYPEQ CPI CR JZ TYPEQ CPI LF JNZ TYPENCR TYPEQ LDA QFLAG ORA A CZ VCONOUT ;UPDATE COLUMN USED IN TAB EXPANSION MOV A,C ;GET CHAR CPI  XRA A STA QFLAG CALL ILPRT DB '++not within tracks 0-',0 PUSH H LHLD MAXTRK CALL DEC POP H CALL ILPRT DB '++' DB CR,LF,0 CALL NOWRITE JMP PROMPTR ; SETDMA JMP $-$ ;ADDR FILLED IN BY 'INIT' ; READ MVI A,1 STA WRFLG PUSH H VREAD CALL $-$ ;ADDR FILLED IN BY 'INIT' ORA A JZ READOK XRA A STA QFLAG CALL ILPRT DB '++READ failed, sector may be invalid++' DB CR,LF,0 READOK POP H RET ; WRITE LDA WRFLG ORA A JNZ PWRITE BADW XRA A STA QFLAG CALL ILPRT DB ' fer to the displacement of the match:' DB CR,LF DB ' =LIX;ca@,LXI;w would change LIX to LXI' DB CR,LF DB ' @+xx and @-xx are allowed, too.' DB CR,LF DB '< save current sector into mem. buff.' DB CR,LF DB ' (Resets memory pointer used by "<<").' DB CR,LF DB '<< save current sector, bump mem addr.' DB CR,LF DB ' NOTE: this buffer is at 2000H, so you' DB CR,LF DB ' can exit DUU and get at the sectors.' DB CR,LF DB ' ALSO NOTE: # reports # of saved sects.' DB CR,LF DB '> rest _'RE FULL CALL TYPE JMP RDBLP ; ;GOT CR ; RDCR MOV M,A ;SAVE IT CALL TYPE ;ECHO IT MVI A,LF ;ECHO.. CALL TYPE ;..LF LXI H,INBUF RET ; ;GOT DELETE OR BS, ECHO IF BS ; RDBS XRA A ;AT FRONT.. ORA B ;..OF LINE? JZ RDCTLU ;..YES, ECHO ^U DCX H DCR B MOV A,C CPI 'H'-40H ;BS? JZ BACKUP ;ECHO THE BS MOV A,M ;ECHO.. CALL TYPE ;..DELETED CHAR JMP RDBLP ; BACKUP CALL WIPER JMP RDBLP ; RDCTLX INR B RDCX1 DCR B JZ RDBF1 CALL WIPER JMP RDCX1 ; WIPER PUSH B PUSH D CR JNZ TYPENCR MVI A,0 STA TABCOL JMP TYPELST ; VCONOUT JMP $-$ ;ADDR FILLED IN BY 'INIT' ; TYPENCR CPI ' ' ;CTL CHAR? JC TYPELST ;..NO CHANGE IN COL LDA TABCOL INR A STA TABCOL TYPELST LDA PFLAG ANI 1 CNZ LIST ;FROM C REG. TYPERET POP H POP D POP B RET ; LIST PUSH B ;SAVED REGS PUSH D PUSH H VLIST CALL $-$ ;ADDR FILLED IN BY 'INIT' POP H POP D POP B RET ; HOME PUSH H VHOME CALL $-$ ;ADDR FILLED IN BY 'INIT' POP H RET ; ;Set track # in DE ; SETTRK PU ++CANNOT WRITE UNLESS READ ISSUED' DB CR,LF,0 JMP EXPL ; PWRITE PUSH H MVI C,1 ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED VWRITE CALL $-$ ;ADDR FILLED IN BY 'INIT' ORA A JZ WRITEOK XRA A STA QFLAG CALL ILPRT DB '++WRITE failed++',CR,LF,0 WRITEOK POP H RET ; ;HELP ; 10/21/81 Put BACK tabs instead of all ; the spaces. Sure wish I knew ; what motivated people to do such ; SENSLESS changes! ; 09/27/81 DELETED "type any char to continue". ; (I find ^S an adequate means. Fi ore saved sector' DB CR,LF DB '>> restore oldest saved sector, setup for next' DB CR,LF DB '? give help' DB CR,LF DB 'A[ff,tt] ASCII dump (hex ff, tt, 7F max)' DB 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 CHfrom-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 'E Send erase-  PUSH H LXI D,BSMSG ;BACKSPACE, SPACE, BACKSPACE MVI C,PRINT CALL BDOS POP H POP D POP B RET ; BSMSG DB BS,' ',BS,'$' ; ;CHECK FOR ^C TYPED - MAY HAVE FORGOTTEN "X" EXITS ; RDBCCC CPI 'C'-40H JNZ RDBLP CALL ILPRT DB '^C Ignored - Use X command to ' DB 'exit to CP/M',0 ; ;GOT CTL-R, RETYPE ; RDCTLR MVI M,CR CALL CRLF LXI H,INBUF MVI B,0 RDCRL MOV A,M CPI CR JZ RDBLP CALL TYPE INR B INX H JMP RDCRL ; ;GOT CTL-U OR BACKUP TO BEGINNING OF LINE. ; RDCTLU MV jSH H LHLD MAXTRK CALL SUBDE POP H JC OUTLIM XCHG SHLD CURTRK XCHG MOV B,D MOV C,E PUSH H VSETTRK CALL $-$ ;ADDR FILLED IN BY 'INIT' POP H RET ; SETSEC PUSH H PUSH D LHLD SYSTRK XCHG SHLD CURSEC LHLD CURTRK CALL SUBDE POP B MOV H,B MOV L,C JNC NOTSYS LDA FIRST0 ;SEE IF FIRST SEC 0 ORA A JNZ GSETSEC ;NO, JUMP AWAY DCX H ;YES, SO DECREMENT JMP GSETSEC ; REQUESTED, THEN GO ; NOTSYS LHLD SECTBL XCHG DCX B VSCTRN CALL $-$ ;ADDR FILLED IN BY 'INIT' %rst ; time I asked for "H" with DU-77, and ; DID use ^S it took it as the "any char" ; and instead of stopping IT WENT. ) ; HELP CALL ILPRT DB 'USE ^S to hold printing, ^C to abort it' DB CR,LF,CR,LF DB 'Operands in brackets [...] are optional;' DB CR,LF DB '"xx" means hex; "nn" means decimal. Where hex' DB CR,LF DB 'is the default, enter #nn for decimal.' DB CR,LF DB 'Change decimal input to hex via xxH (or Hxx).' DB CR,LF,CR,LF DB '+[nn] step in [nn] sectors;' DB CR screen (string at 104H, FF ends)' DB CR,LF DB 'Fn.t Find file' DB CR,LF DB 'F Find next extent of file' DB CR,LF DB 'Gxx CP/M Allocation Group xx' DB CR,LF DB 'H[ff,tt] hex dump' DB CR,LF DB 'L Log in drive' DB CR,LF DB 'Lx Log in drive x' DB CR,LF DB 'M[xx] Map [from group xx]' DB CR,LF DB 'N New disk' DB CR,LF DB 'P Toggle printer switch' DB CR,LF 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 9I A,'^' CALL TYPE MVI A,'U' CALL TYPE CALL CRLF JMP RDBUF ; CRLF MVI A,CR CALL TYPE MVI A,LF JMP TYPE ; UPCASE CPI 60H RC ANI 5FH ;MAKE UPPER CASE RET ; ;SCREEN CLEAR ROUTINE ; ERASE LXI D,CLEAR ERLP LDAX D ;GET CHAR CPI 0FFH JZ PROMPT ;DONE MOV C,A PUSH D PUSH H CALL VCONOUT POP H POP D INX D JMP ERLP ; CONST PUSH B PUSH D PUSH H VCONST CALL $-$ ;ADDR FILLED IN BY 'INIT' POP H POP D POP B RET ; CONIN PUSH B PUSH D PUSH H VCONIN CALL $  LDA SPT+1 ;IF SPT<256 (HI-ORD = 0) ORA A ; THEN FORCE 8-BIT TRANSLATION JNZ VSCTR1 ; ELSE KEEP ALL 16 BITS MOV H,A VSCTR1 LDA VER2FL ;SEE IF VERSION 2.x ORA A ;SET FLAGS JNZ GSETSEC ;JUMP IF CP/M 2.x MVI H,0 ;CP/M 1.4 GOOD TO ONLY 8 BITS MOV L,C ;MOST BIOS'S RETURN THE ; PHYSICAL SEC # IN REG C GSETSEC SHLD PHYSEC ;THIS MAY BE REDUNDANT IN ; MOST 1.4 VERSIONS, BUT ; SHOULD CAUSE NO PROBLEMS MOV B,H MOV C,L VSETSEC CALL $-$ ;ADDR FILLED IN BY 'INIT' POP H RET ; OUTLIM ,LF DB '-[nn] step out [nn] sectors' DB CR,LF DB '# print disk parameters for curr drive.' DB CR,LF DB ' & # of saved (via "<<") sectors' DB CR,LF DB '=sss search for ASCII sss from curr sector.' DB CR,LF DB ' Caution: upper/lower case matters.' DB CR,LF DB ' Use for hex: <3b> for ";";' DB CR,LF DB ' To find "IN 0" use: =<0> or' DB CR,LF DB ' for "(tab)H,0(CR)(LF)" use: =<9>H,0' DB CR,LF DB ' NOTE: After using "=", you may use "@" to' DB CR,LF DB ' re  Track nn' DB CR,LF DB 'V[nn] View [nn] ASCII sectors' DB 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 times]' DB CR,LF,CR,LF DB 'Cancel a function with C 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;z20;/' DB CR,LF DB ' would step in, dump, sleep 2 sec, ' DB CR,LF DB ' and repe  #TRAM EQU 8800H ;TOP OF RAM 8737 = 8 BUFFER EQU (TRAM-100H+37H) ;BUFFER AREA IN RAM 87AF = A STKLMT EQU (TRAM-100H+0AFH) ;LIMIT ADDRESS OF THE STACK 8680 = 6 VARBGN EQU (TRAM-180H) ;TOP OF VARIABLE AREA IN RAM   ;  ; 0100 ORG 100H  -BEGIN: ;0100 0100 C3060D JMP SETSTK  HTV0: ;0103 0103 C22101 JNZ TV1 ;011FH NOT "@" ARRAY 0106 13 . INX D ;IT IS THE "@" ARRAY 0107 CD1607 0 013C 13  INX D ;AND CONTINUE 013D 23  INX H 013E E3  XTHL 013F C9  RET  TTSTNUM: ;013E +++TSTNUM+++ 0140 210000 LXI H,0 ;TEST IF THE TEXT IS 0143 44 G MOV B,H ;A NUMBER 0144 CD740C CALL IGNBLK ;IF NOT, RETURN 0 IN  STN1: ;0143 B AND HL 0147 FE30 CPI '0' ;30H IF NUMBERS, CONVERT 0149 D8 W RC ;TO BINARY IN HL AND 014A FE3A CPI ':' ;3AH SET A TO # OF DIGITS 014C D0  RNC 014D 3EF0 M ͽ#ING INITIALIZATION TO REFLECT THE   ;SIZE OF MEMORY.  = ;THEN IT PROMPTS ">" AND READS A LINE. IF THE LINE STARTS  @ ;WITH A NON-ZERO NUMBER, THIS NUMBER IS THE LINE NUMBER. THE  < ;LINE NUMBER AND THE REST OF THE LINE  B ; IS STORED IN MEMORY. IF A LINE WITH THE SAME  A ;LINE NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE.   ;IF THE REST OF THE LINE IS at until control-c typed.' DB CR,LF,CR,LF DB 'See DU.DOC for complete examples.' DB CR,LF,CR,LF,0 JMP PROMPT ; ; Subroutines ; GRPCMP MOV A,C INR D DCR D JZ CMP8 CMP M INX H RNZ MOV A,B CMP8 CMP M RET ; ;2's complement HL ==> HL ; NEG MOV A,L CMA MOV L,A MOV A,H CMA MOV H,A INX H RET ; ;HL/2 ==> HL ; ROTRHL ORA A MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A RET ; ;Collect the number of '1' bits ;in A as a count in C ; COLECT MVI B,8 ; COLOP /CALL PARN ;06BCH @ SHOULD BE FOLLOWED 010A 29 Z DAD H ;BY (EXPR) AS ITS INDEX 010B DA6A01 JC QHOW ;0166H IS INDEX TOO BIG 010E D5 " PUSH D ;WILL IT OVERRUN 010F EB XCHG ;RAM? 0110 218006 LXI H,(VARBGN-RAM); FIND SIZE OF FREE RAM 0113 CD6C0C CALL COMP ;AND CHECK THAT 0116 DA890A JC ASORRY ;080EH IF SO SAY "SORRY"  TV00: ;0117 0119 218086 LXI H,VARBGN ;0F00H IF NOT GET ADDRESS 011C CD070A CALL SUBDE ;079CH OF @(EXPR) AND PUT IT XVI A,0F0H 014F A4 ] ANA H ;IF H>255, THERE IS NO 0150 C26A01 JNZ QHOW ;0166H ROOM FOR NEXT DIGIT 0153 04 & INR B ;B COUNTS # OF DIGITS 0154 C5  PUSH B 0155 44 ( MOV B,H ;HL=10*HL+ 0156 4D ( MOV C,L ;WHERE 10+ IS DONE BY 0157 29  DAD H ;SHIFT AND ADD 0158 29  DAD H 0159 09  DAD B 015A 29  DAD H 015B 1A & LDAX D ;AND IS FROM 015C 13 < INX D ;STRIPPING THE ASCII 015D E60F ANI 0FH ;CODE  " "CR" ONLY, IT IS NOT STORED AND  ; ;AND ANY EXISTING LINE WITH THE SAME NUMBER IS DELETED.   ;  @ ;AFTER A LINE IS INSERTED, REPLACED, OR DELETED, THE PROGRAM  < ;LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILL BE  A ;TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE NUMBER,  + ;AND CONTROL IS TRANSFERED TO "DIRECT".   ;  1 ;THE MEMORY LOCATION "CURRNT" POINTS TO THE LIN 2RAL JNC COSKIP INR C ; COSKIP DCR B JNZ COLOP RET ; ;HL-DE ==> HL ; SUBDE MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A RET ; ;Quick Kludge multiply ;HL=DE ==> HL ; MULT PUSH B PUSH D XCHG MOV B,D MOV C,E MOV A,B ORA C JNZ MULCON LXI H,0 ;FILTER SPECIAL CASE JMP MLDONE ; OF MULTIPLY BY 0 ; MULCON DCX B MOV D,H MOV E,L ; MULTLP MOV A,B ORA C JZ MLDONE DAD D DCX B JMP MULTLP ; MLDONE POP D POP B RET ; ;Routine to fill in disk params ;wi  011F D1  POP D ;IN HL 0120 C9  RET ;C FLAG IS CLEARED  BTV1: ;011F 0121 FE1B CPI 1BH ;NOT @ IS IT A 2? 0123 3F % CMC ;IF NOT RETURN C FLAG 0124 D8 RC 0125 13  INX D ;IF A THROUGH Z  PTV11: ;0124 0126 218086 LXI H,VARBGN ;0F00H COMPUTE ADDRESS OF 0129 07  RLC ;THAT VARIABLE 012A 85 % ADD L ;AND RETURN IT IN HL 012B 6F H MOV L,A ;WITH C FLAG CLEARED 012C 3E00 MVI A,0 012E 8C > 015F 85  ADD L 0160 6F , MOV L,A 0161 3E00 MVI A,0 0163 8C  ADC H 0164 67  MOV H,A 0165 C1  POP B 0166 1A U LDAX D ;DO THIS DIGIT AFTER 0167 F24701 JP TN1 ;0143H DIGIT. $ SAYS OVERFLOW  +QHOW: ;0166 +++ERROR "HOW"+++ 016A D5 PUSH D  UAHOW: ;0167 016B 117101 LXI D,HOW ;016DH 016E C35D0A JMP ERROR ;07E4H  .HOW: ;016D 0171 484F573F0D DB 'HOW?',0DH  OK: W E NUMBER  9 ;THAT IS CURRENTLY BEING INTERPRETED. WHILE WE ARE IN  < ;THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND   ;  KRSTART: ; 0185 310088 LXI SP,TRAM ;STACK POINTER IS AT TOP OF RAM  pST1: ; 0188 CD5A0C CALL CRLF1 ;+CRLF+ JUMP TO HERE 018B 117601 LXI D,OK ;0172H DE->STRING 018E 97 i SUB A ;A=0 018F CD360B CALL PRTSTG ;087FH PRINT STRING UNTIL CR 0192 219901 LXI H,ST2+1 ;019     A;DISASSEMBLY OF SHERRY BROTHERS VERSION OF PALO ALTO TINY BASIC  ;BILL BAILEY JUNE 1 1983  !;MODIFIED STARTING JUNE 25 1983  );BASE TWO LOGORITHMS ADDED JUNE 24 1984  .;MULTIPLY AND DIVIDE SPEEDED UP JULY 10 1984  ";RESTARTS REMOVED AUGUST 19 1984  *;CONVERT TO ROMABLE CODE DECEMBER 2 1984  ;  ; 8000 = & RAM EQU 8000H ;START OF RAM 8800 = | ADC H 012F 67  MOV H,A 0130 C9  RET  TC1: ;012F 0131 23 ] INX H ;COMPARE THE BYTE THAT 0132 CA3C01 JZ TC2 ;013AH FOLLOWS THE RST INST. 0135 C5 ' PUSH B ;WITH THE TEXT (DE->) 0136 4E Z MOV C,M ;IF NOT =, ADD THE 2ND 0137 0600 MVI B,0 ;BYTE THAT FOLLOWS THE 0139 09 # DAD B ;RST TO THE OLD PC 013A C1 $ POP B ;I.E. DO A RELATIVE 013B 1B  DCX D ;JUMP IF NOT =  %TC2: ;013A ;IF =,SKIP THOSE BYTES 6&;0172 0176 4F4B0D DB 'OK',0DH  0WHAT: ;0175 0179 574841543F DB 'WHAT?',0DH  1SORRY: ;017B 017F 534F525259 DB 'SORRY',0DH  ? ;THIS IS THE MAIN LOOP THAT COLLECTS THE TINY BASIC PROGRAM   ;AND STORES IT IN MEMORY.   ;  > ;AT START, IT PRINTS OUT "OK", AND INITIALIZES THE  @ ;STACK AND SOME OTHER INTERNAL VARIABLES. THE STACK, IN THIS   ;VERSION IS MODIFIED DUR2F5H LITERAL 0 0195 228686 SHLD CURRNT ;09C1H CURRNT->LINE # = 0  tST2: ;0194 ; 0198 210000 LXI H,0 019B 228E86 SHLD LOPVAR ;09C9H 019E 228886 SHLD STKGOS ;09C3H  vST3: ;019D 01A1 3E3E MVI A,'>' ;3EH PROMPT '>' AND 01A3 CD8F0A CALL GETLN ;0814H READ A LINE 01A6 D5  PUSH D ;DE->END OF LINE  ~ST33: ;01A3 01A7 113787 LXI D,BUFFER ;0F37H DE->BEGINING OF LINE 01AA CD4001 CALL TSTNUM ;013EH TEST IF IT IS A $5000 L=INT(X/4096) : M=INT((X-L*4096)/256) 5010 N=INT((X-L*4096-M*256)/16) 5020 O=INT(X-L*4096-M*256-N*16) 5030 IF L< 10 THEN L$=CHR$(48+L) 5040 IF L> 9 THEN L$=CHR$(65+L-10) 5050 IF M< 10 THEN M$=CHR$(48+M) 5060 IF M> 9 THEN M$=CHR$(65+M-10) 5070 IF N< 10 THEN N$=CHR$(48+N) 5080 IF N > 9 THEN N$=CHR$(65+N-10) 5090 IF O< 10 THEN O$=CHR$(48+O) 5100 IF O> 9 THEN O$=CHR$(65+O-10) 5110 RETURN 5120 END  IF N > 9 THEN N$=CHR$(65+N-10) 5090 IF O< 10 THEN O$=CHR$(48+O) 5100 IF O> 9 THEN O$=CHR$(65͓ !" >- Ͷ Aګ ҫ _!7^#V~  \p Z z ů2[\͓͢ ҫ ͐ =« f " ͓ ҫ ͐ ʻf " =ʻf "=« ý> 2͐ f "]=f =« *]}o"_  *]"a. ~ #E }"]*a 6 *]}#|#*]E ͐ « f f f {zA|« W}d ͐ f f f DMʡڏ"=ʡͲ=ʡYPͲ1**!O~4#~#F#x~#s#r#w>͐ « f f  . ᯕo>g.$10 FOR RN=12 TO 24 STEP 2 20 FOR RM=0 TO 10 STEP 2 30 LPRINT "PS",,"PC","PCC",,"RN="RN,"RM="RM 40 FOR PS=-22 TO 280 STEP 4 50 PC=PS+(((PS-125)^2)*RN/125^2-RN) 60 PCC=-(RM*(PC-125)/48)+RM*(PC-125)^3/90.9^3+PC 62 X=PS*8+1200 : GOSUB 5000 70 LPRINT PS,L$;M$;N$;O$,PC, 72 X=PCC*8+1200 : GOSUB 5000 75 LPRINT PCC,L$;M$;N$;O$ 80 NEXT PS 90 LPRINT : LPRINT : LPRINT : LPRINT 100 NEXT RM 110 NEXT RN 120 STOP 5000 L=INT(X/4096) : M=INT((X-L*4096)/256) 5010 N=INT((X-L*4096-M*256)/16) 5020 O=INT(X-L*40960NUMBER 01AD CD740C CALL IGNBLK ; 01B0 7C & MOV A,H ;HL = VALUE OF # OR 01B1 B5 ORA L ;0 IF NO NUMBER 01B2 C1 E POP B ;BC->END OF LINE 01B3 CAEA02 JZ DIRECT ;02D5H 01B6 1B $ DCX D ;BACKUP DE AND SAVE 01B7 7C ) MOV A,H ;VALUE OF LINE # THERE 01B8 12  STAX D 01B9 1B  DCX D 01BA 7D  MOV A,L 01BB 12  STAX D 01BC C5 $ PUSH B ;BC,DE->BEGIN. END 01BD D5  PUSH D 01BE 79  MOV A,C 01BF 93  SUB y=!z{w# % w!P͠ y͓}*w#"͌ @.@<!Eͷ~P !ͷ’P͌Q!ͷªP}QxQ!ͷ͓G@Q! ͷ y͓Gþ!ͷ ͓Q!ͷ͓Q͌Q!.ͷ6y#G͙Qà!2ͷQ͓͌Q!>ͷq eg͙Q:zJEËC–EQyQxQRQ** {zҷ*~#" <AOGƐ'@'OxƐ'@'ON# & 2|2\  !]w# ʫ .&  0 6 #& .K !e K w# ʫ : U 6 #K 6AW w#] !e~H#~E#~X*}|́ "!́ ͐ !ʬ =« f kʫ j \͢F w# ͋ t ʫ : W& _& & O { `i"F & & w# & ͋ « t Y t Y GтWx ͢!o ~Z #N  *. *.  NEXT PC͐ =« f  . ~ Ͷ ʻ .͓ =« f |« }w#Ä >2L͐ ! =« f }ʫ +"MD Å D  !  #-M*256-N*16) 5030 IF L< 10 THEN L$=CHR$(48+L) 5040 IF L> 9 THEN L$=CHR$(65+L-10) 5050 IF M< 10 THEN M$=CHR$(48+M) 5060 IF M> 9 THEN M$=CHR$(65+M-10) 5070 IF N< 10 THEN N$=CHR$(48+N) 5080 IF N > 9 THEN N$=CHR$(65+N-10) 5090 IF O< 10 THEN O$=CHR$(48+O) 5100 IF O> 9 THEN O$=CHR$(65+O-10) 5110 RETURN 5120 END  IF N > 9 THEN N$=CHR$(65+N-10) 5090 IF O< 10 THEN O$=CHR$(48+NEXT RM 110 NEXT RN 120 STOP 5000 L=INT(X/4096) : M=INT((X-L*4096)/256) 5010 N=INT((X-L*4096-M*256)/16) 5020 O=INT(X-L*4096  E 01C0 F5 d PUSH PSW ;A=# OF BYTES IN LINE 01C1 CD0C0B CALL FNDLN ;0857H FIND THIS LINE IN SAVE 01C4 D5 \ PUSH D ;AREA DE->SAVE AREA 01C5 C2D801 JNZ ST4 ;01D2H NZ: NOT FOUND, INSERT 01C8 D5 m PUSH D ;Z: FOUND DELETE IT 01C9 CD2A0B CALL FNDNXT ;0873H FIND THE NEXT LINE DE->NEXT LINE 01CC C1 POP B ;BC ->LINE TO BE DELETED 01CD 2ADE0C LHLD TXTUNF ;09D5H HL->UNFILLED SAVE AREA 01D0 CDCB0B CALL MVUP ;0900H MOVE UP TO DELETE 01D3 60  MOV  ^z8O!B N#N ¾SP.* |} !9":q!"S Ag}S S i |« }!w s#r:[ʔ _!~ʦ ![4ç \͢¦ 2[ 7 >?  e͢!g"c> _͢a_!f~> 5*c~#"c 0 7   > >  ͢| } @ >. *_}o| , 0 ë ^#V#!Y ))))o P q s#r#!V4 !V6# ,® >2Vñ m ͅ m ͅ m ͅ « Vʫ ! XN!~    %H,B ;TEXTUNF->UNFILLED AREA 01D4 69 8 MOV L,C ; 01D5 22DE0C SHLD TXTUNF ;09D5H UPDATE  ST4: ;01D2 01D8 C1 ] POP B ;GET READY TO INSERT 01D9 2ADE0C LHLD TXTUNF ;09D5H BUT FIRST CHECK IF 01DC F1 . POP PSW ;THE LENGTH OF THE NEW LINE 01DD E5 PUSH H ;IS 3 (LINE # AND CR) 01DE FE03 CPI 3 ;THEN DO NOT INSERT 01E0 CA8501 JZ RSTART ;0181H MUST CLEAR THE STACK 01E3 85 ( ADD L ;COMPUTE THE NEW TXTUNF 01E4 6F MOV L,A 0IO!b q!vz͒q.?*!9"8"͉Z*" +*'/7?v"*2:EI SPHLDI XCHGPCHLXTHLRET HLT CMC STC CMA DAA RAR RAL RRC RLC NOP CPI ORI XRI ANI SBI IN SUI OUT ACI ADI CALLJMP LDA STA LHLDSHLDMOV ADD ADC SUB SBB ANA XRA ORA CMP INR DCR MVI LXI STAXINX DAD LDAXDCX RST PSW POP PUSHNZZ NCC POPEP M B C D E H L M A B D H SP PSW ??= M!Eâê ö  - Ð f  "J*"!"!"2O!" "]""!1!++""M>28!"9:] !í 1! _^! ^#V~ x+ >= = !~  . !   #x f L L ͓ͅ ҆ *" !6ï +"_*~ #E گ ʫ ^#V. ï ~ CZMEIABDHSP!"M"+"!91*~!O~6=G#^#V#~x (#"!N#FW( *J>7Å*M|N+"M N:LHͅÅD Å >* *͓ b" . *"] !/~##ʁtZ*F#n!Is!^#V&&##&))::^#V#*^#V>+)x-8_CT BUFFER TO READ FROM NUMSAVD DB 0 ;# IN BUFFER NUMREST DB 0 ;# WRITTEN SO FAR SECDISP DB 0 ;DISP IN SECTOR AT WHICH MATCH ; ;OCCURRED ; DS 120 ;STACK SPACE STACK: BACK DS 2 ;TO BACK UP IN "CA0-7F,X" NUMENT DS 2 ;# OF DIR ENTRIES FOR "F" TO SCCAN FCONT DS 2 ;FIND - CONTINUE SEARCH POINTER DUMTYPE DS 1 ; ; - ;The disk parameter block ;is moved here from CP/M ; DPB EQU $ ;DISK PARAMETER BLOCK (COPY) SPT DS 2 BSH DS 1 BLM DS 1 EXM DS 1 DSM DS 2 DRM DS 2 AL0 DS 1 AL1 DS 1th every drive change ; LOGIT LDA VER2FL ORA A ;IF NOT CP/M 2.x THEN JZ LOG14 ; DO IT AS 1.4 LXI D,DPB ; THEN MOVE TO LOCAL MVI B,DPBLEN ; WORKSPACE CALL MOVE JMP LOGCAL ; LOG14 LHLD BDOS+1 ;FIRST FIND 1.4 BDOS MVI L,0 LXI D,DPBOFF ;THEN OFFSET TO 1.4'S DPB DAD D MVI D,0 ;SO 8 BIT PARMS WILL BE 16 MOV E,M ;NOW MOVE PARMS INX H XCHG SHLD SPT XCHG MOV E,M INX H XCHG SHLD DRM XCHG MOV A,M INX H STA BSH MOV A,M INX H STA BLM MOV E,M INX H XCHG SH CKS DS 2 SYSTRK DS 2 ; ;End of disk parameter block ; INBUF DS 128 ; ;ORG TO 2000, SO SID/DDT MAY BE LOADED TO WORK ;WITH DATA SAVED BY MULTIPLE "<<" COMMANDS. ;(SHOULD DUU GROW, THIS WILL AUTOMATICALLY ;BE ORGed TO 3000H WHEN NECESSARY) ; ORG ($+0FFFH) AND 0F000H ; SAVEBUF EQU $ ;X000 ALIGNED SECT BUFF ; ;NOTE DIRECTORY READ IN HERE "SOMEWHERE" DEPENDING ;UPON WHERE NXTSAVE POINTS ; END 0 1E5 3E00 MVI A,0 01E7 8C  ADC H 01E8 67 ! MOV H,A ;HL->NEW UNFILLED AREA  ST44: ;01E3 01E9 118086 LXI D,VARBGN ;0F00H CHECK TO SEE IF THERE 01EC CD6C0C CALL COMP ;IS ENOUGH SPACE 01EF D2880A JNC QSORRY ;080DH SORRY, NO ROOM 01F2 22DE0C SHLD TXTUNF ;09D5H OK, UPDATE TXTUNF 01F5 D1 L POP D ;DE->OLD UNFILLED AREA 01F6 CDD60B CALL MVDOWN ;0909H 01F9 D1 $ POP D ;DE->BEGIN, HL->END 01FA E1  POP H 01FB CDCB0B CAL  LD DSM XCHG MOV E,M INX H XCHG SHLD AL0 XCHG MOV E,M XCHG SHLD SYSTRK ; LOGCAL LXI H,GRPDISP MOV A,M PUSH PSW LDA BLM MOV M,A PUSH H LHLD DSM XCHG CALL GTKSEC SHLD MAXSEC XCHG SHLD MAXTRK POP H POP PSW MOV M,A RET ; ;Temporary storage area ; BUFAD DW BASE+100H ;FORCES INITIAL READ HEXAD DW 0 ;TO RE-FETCH A VALUE TOGO DW 0FFFFH ;REPEAT COUNT (FFFF=CONT) TWOUP DB 0 PFLAG DB 0 ;1=PRINT GROUP DW 0 GRPDISP DB 0 SAVEFLG DB 0 CURTRK DW 0 CURSEC DW 1 P  KL MVUP ;0900H MOVE NEW LINE TO SAVE 01FE C3A101 JMP ST3 ;019DH AREA    $ ; +++TABLES+++DIRECT+++& EXEC+++   ;  < ;THIS SECTION OF THE CODE TESTS A STRING AGIANST A TABLE  @ ;WHEN A MATCH IS FOUND, CONTROL IS TRANSFERED TO THE SECTION  # ;OF CODE ACCORDING TO THE TABLE  @ ;AT 'EXEC' DE SHOULD POINT TO THE STRING AND HL SHOULD POINT  + ;TO THE TABLE-1 AT 'DIRECT' DE SHOULD POI HYSEC DW 1 TABCOL DB 0 FILECT DW 0 DIRPOS DB 0 FINDFLG DB 0 ;1=MUST POSITION AFTER FIND FTSW DB 1 ;SEARCH W/O INCREMENT NOTPOS DB 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 DRIVE DB 0 MAXTRK DW 0 MAXSEC DW 0 VER2FL DB 0 SECTBL DW 0 ;POINTER TO SECTOR SKEW TABLE NXTSAVE DW SAVEBUF ;NEXT SECT BUFFER TO STORE INTO ; (READDIR READS DIR IN HERE, TOO) NXTREST DW SAVEBUF ;NEXT SEK>NT TO THE STRING  > ;HL WILL BE SET TO POINT TO TAB1-1, WHICH IS THE TABLE FOR  0 ;ALL DIRECT AND INDIRECT STATEMENT COMMANDS.   ;  @ ;A '.' IN THE STRING WILL TERMINATE THE TEST AND THE PARTIAL  @ ;MATCH WILL BE CONSIDERED AS A MATCH E.G. 'P.','PR.','PRIN.'   ;ALL MATCH 'PRINT'.   ;  7 ;THE TABLE CONSISTS OF A NUMBER OF ITEMS. EACH ITEM   ;IS A STRING OF CHARACd'FFH 023E 4946 DB 'IF' 0240 85  DB (IFF SHR 8) +128 0241 9A 6 DB IFF AND 0FFH 0242 474F544F DB 'GOTO' 0246 83  DB (GOTO SHR 8) +128 0247 4B 8 DB GOTO AND 0FFH 0248 474F535542 DB 'GOSUB' 024D 84 DB (GOSUB SHR 8) +128 024E 9F : DB GOSUB AND 0FFH 024F 5245545552 DB 'RETURN' 0255 84 ! DB (RETURN SHR 8) +128 0256 C1 8 DB RETURN AND 0FFH 0257 52454D DB 'REM' 025A 85  DB (REM SHR 8) +128 025B 96 DB REM AND 0=48459532B :10027000544F508326860F594F552043414E2041FD :100280004444204D4F5245524E448727494E508991 :10029000525045454B897B5553528985414253877E :1002A000544C4F47328760414C4F473287C25349C5 :1002B0005A4589048705594F552043414E204144F2 :1002C00044204D4F5245544F84EC8A595354455065 :1002D00084F884FE3E3D862923862F3E86353D8662 :1002E000443C3D863C3C864A8650210002CD740C3D :1002F000D51A13FE2ECA0E0323BECAF1023E7F1B7F :10030000BEDA150323BED2040323D1C3ED023E7F20 :1003100023BED210037E236EE67F67F1E9CD530A38 :10032D840CDA590A228A86D5EB2A8E867C59 :10055000B5CA5A0ACD6C0CCA6405D1CDE50B2A8AFE :1005600086C34A055E23562A9086E519EB2A8E86B5 :100570007323722A9286F1B7F27C05EBCD1D0AD166 :10058000DA90052A94862286862A9686EBCD7C0C04 :10059000CDE50BCD7C0C2100003ECD640C7CB5C2BA :1005A0004203CD2C0BD23B03C385012A8C86F9E193 :1005B000228686D1D1D5CD440BC3C505CD840CDAB6 :1005C0000306C3D705D5CD840CDA590A1A4F971202 :1005D000D1CD360B791B12D5EB2A8686E521B505E0 :1005E00022868621000039228C86D53E3ACD8F0A9C :1005F000113787CD640C000000D1TERS WITH BIT 7 SET TO 0 AND  6 ;A JUMP ADDRESS HI-LO WITH BIT 7 OF THE HIGH BYTE  ;SET TO 1   ;  = ;END OF TABLE IS AN ITEM WITH A JUMP ADDRESS ONLY. IF THE  0 ;STRING DOES NOT MATCH, THIS IS THE DEFAULT.   ;          CTAB1: ;01F9 DIRECT COMMANDS 0201 4C495354 DB 'LIST' 0205 84 % DB (LIST SHR 8) +128 0206 41 (FFH 025C 464F52 DB 'FOR' 025F 84  DB (FOR SHR 8) +128 0260 DC 7 DB FOR AND 0FFH 0261 494E505554 DB 'INPUT' 0266 85  DB (IP1 SHR 8) +128 0267 B5 7 DB IP1 AND 0FFH 0268 5052494E54 DB 'PRINT' 026D 84 DB (PRINT SHR 8) +128 026E 59 8 DB PRINT AND 0FFH 026F 53544F50 DB 'STOP' 0273 83  DB (STOP SHR 8) +128 0274 26  DB STOP AND 0FFH 0275 86 DB (DEFLT SHR 8) +128 0276 0F , DB DEFLT AND 0FFH 0277 594F552043 DB 'YOU00021E00C22DE0CCD530AC38501CD530A1106 :10033000E00C210000CD140BDA8501EB228686EB60 :100340001313CD8D0C212102C3ED02CD640CD5CD4C :10035000530ACD0C0BC26B01F1C33B03CD740CE50A :10036000CD0604D5C5115C000E0FCD0500FEFFCAF9 :100370006A01AF327C0011DE0CD50E1ACD05000EDD :1003800014115C00CD0500FE01DA9E03C26A010E65 :1003900010115C00CD0500D1C1D1E1CD7C0CD12183 :1003A000800019EBC37903CD740CE5CD0604D5C5E7 :1003B000115C000E13CD0500115C000E16CD05007A :1003C000FEFFCA6A01AF327C0011DE0CD50E1ACDD9 :1003D00005000E15115C00EB732372E12228 :100600008686D1F1CD520C2C03C3B505CD7C0C1AD6 :10061000FE0DCA2006CD270ACD520C2C03C31506A9 :10062000CD7C0C21D302C3ED02CD5206D86FC9CDCB :100630005206C86FC9CD5206C8D86FC9CD52066FD1 :10064000C8D86CC9CD5206C06FC9CD5206D06FC98B :10065000E1C979E1C1E5C54FCD6706EBE3CD1D0AE0 :10066000D12100003E01C9CD520C2D06210000C34E :100670009906CD520C2B00CDA306CD520C2B15E5BF :10068000CDA306EBE37CAA7A19D1FA7A06ACF27A0A :1006900006C36A01CD520C2D8AE5CDA306CD110A01 :1006A000C38306CDFF06CD520C2A27E5CDFF0606F3 : 8 DB LIST AND 0FFH 0207 52554E DB 'RUN' 020A 83  DB (RUN SHR 8) +128 020B 2C 5 DB RUN AND 0FFH 020C 4E4557 DB 'NEW' 020F 83  DB (NEW SHR 8) +128 0210 1D 6 DB NEW AND 0FFH 0211 4C4F4144 DB 'LOAD' 0215 83  DB (LOAD SHR 8) +128 0216 5C 7 DB LOAD AND 0FFH 0217 53415645 DB 'SAVE' 021B 83  DB (SAVE SHR 8) +128 021C A7 I DB SAVE AND 0FFH 021D 425945 DB 'BYE' 0220 8000 DB 80H,0  TAB2: ;021A DIRECT :10010000C3060DC2210113CD160729DA6A01D5EB0A :10011000218006CD6C0CDA890A218086CD070AD1B0 :10012000C9FE1B3FD81321808607856F3E008C6770 :10013000C923CA3C01C54E060009C11B1323E3C9EC :1001400021000044CD740CFE30D8FE3AD03EF0A41D :10015000C26A0104C5444D292909291A13E60F85ED :100160006F3E008C67C11AF24701D5117101C35D62 :100170000A484F573F0D4F4B0D574841543F0D53C1 :100180004F5252590D310088CD5A0C11760197CD3E :10019000360B219901228686210000228E86228834 :1001A000863E3ECD8F0AD5113787CD4001CD740CE8 :1001B0007CB5C1CA CCD0500B7C26A01D13AC7 :1003E000DF0CBADAF803C2F0033ADE0CBBDAF8032A :1003F00021800019EBC3CC030E10115C00CD050069 :10040000C1D1E1CD7C0C215C0036002336203E6456 :10041000BDC20B042336542336422336492336000B :100420003E6BBDC21D04215D001AFE0DC8FE21DA1F :10043000590AFE5BD2590A7723133E65BDC22904CF :10044000C9CD4001CD530ACD0C0BDA8501CDB60BD9 :10045000CD8D0CCD140BC34A040E06CD520C3B06B9 :10046000CD5A0CC34203CD520C0D06CD5A0CC332EB :1004700003CD520C2307CD640C4DC38304CD440B34 :10048000C39404CD520C2C06CD400AC37104CD5  1 |2*""""""""R""":["8p*."8"< DISK UTILITY ver 7.5+mods 10/23/81 Universal Version (DUU) Type ? for help Type X to exit % !~G3##> !3 YY2r>2~212>2!"zͪ~ ;#c2#+s -ʲ =<>I#!?'A Cʦ D EiF. G4 H LMʄN(PsQ<RZS4 T4 VʕWXZ~/B2<? 2<+++ Out of memory +++ (may be due to //STATMENT 0222 4E455854 DB 'NEXT' 0226 85  DB (NEXT SHR 8) +128 0227 41 6 DB NEXT AND 0FFH 0228 4C4554 DB 'LET' 022B 86  DB (LET SHR 8) +128 022C 15 5 DB LET AND 0FFH 022D 4F5554 DB 'OUT' 0230 89  DB (OUT1 SHR 8) +128 0231 11 7 DB OUT1 AND 0FFH 0232 504F4B45 DB 'POKE' 0236 89  DB (POKE SHR 8) +128 0237 61 7 DB POKE AND 0FFH 0238 57414954 DB 'WAIT' 023C 89  DB (WAIT SHR 8) +128 023D 2F  DB WAIT AND 0wEA021B7C121B7D12C5D579939E :1001C000F5CD0C0BD5C2D801D5CD2A0BC12ADE0C3A :1001D000CDCB0B606922DE0CC12ADE0CF1E5FE03FB :1001E000CA8501856F3E008C67118086CD6C0CD26C :1001F000880A22DE0CD1CDD60BD1E1CDCB0BC3A129 :10020000014C495354844152554E832C4E455783DB :100210001D4C4F4144835C5341564583A742594589 :1002200080004E45585485414C455486154F5554D1 :100230008911504F4B45896157414954892F49468F :10024000859A474F544F834B474F535542849F5293 :10025000455455524E84C152454D8596464F528461 :10026000DC494E50555485B55052494E5A3E :100490000CCD7C0CCD640CC5CD740BC1C38304CDD5 :1004A000010CCD640CD5CD0C0BC26B012A8686E500 :1004B0002A8886E5210000228E8639228886C33B61 :1004C00003CD530A2A88867CB5CA590AF9E12288E5 :1004D00086E1228686D1CDE50BCD7C0CCD010CCDFD :1004E000270A2B228E8621C502C3ED02CD640C2281 :1004F000928621CB02C3ED02CD640CC3010521011C :10050000002290862A8686229486EB229686010A0D :10051000002A8E86EB6068393E097E23B6CA3A050A :100520007E2BBAC219057EBBC21905EB210000392A :10053000444D210A0019CDD60BF92A9686EBCD7CC5 :100540000CCs many "<<" stacked sectors) <Disk Information: Tracks: *#< Sec/trk: *$< Grpsize: :'>": *&Y%  :O2zW*~#|W"~*~!3z"~|:2{ˆ @:ʕ> x•ͪˆ~´͈̈O% ~ (;(c#AOy2: |^#V# :o*$ *$*1 #!"!~ ; \1 1 *1"!"*+#"͊ **͍!]# ?ʐ ʐ  #€ ͙ K }`2o"! 2>D2#2ë 2<++FILE NOT FOUND % >2*!| 2<++Can't continue F command *+"|ʽ } oz c ~#.` *e + ` ;` c#1 ~ ;#.> g >?g ~.#:`% ~ ʓ ;ʓ z z“ **͍Ó :`% ~ ; z*+| *| *#"2<Out of bounds  %2<++WRITE failed++ <USE ^S to hold printing, ^C to abort it Operands in brackets [...] are optional; "xx" means hex; "nn" means decimal. Where hex is the default, enter #nn for decimal. Change decimal input to hex via xxH (or Hxx). +[nn] step in [nn] sectors; -[nn] step out [nn] sectors # print disk parameters for curr drive. & # of saved (via "<<") sectors =sss search for ASCII sss from curr sector. Caution: upper/lower case matters. Use for hex: <3b> for ";"; .! T]x :($^*.:^#"$^#"+~#2&~#2'^#")^#"-^"1!~:'w*) ""w  .nd output with S or Ctl-S. Separate commands with ";". Example: g0 +;d;z20;/ would step in, dump, sleep 2 sec, and repeat until control-c typed. See DU.DOC for complete examples. y#x}/o|/g#ɷ|g}o }o|gBKx"!~#fo*1*|2͙ *1"!"*+#DM*BK:=͊**͍ ! xL͊% ,:-:.͟{ʥBK>-͒́*)#}½|́ͪz{ʰ å Y* 2|:~> >(͒~2#e>.͒e2~~> 4>)͒R< ++FREE++ :2Y>:͒2~# s~y|͒e*+#"*~~ʷ_#~ʷ:*ʫW#¬ *+"|‹!:><*-!":<20=2"2 +"*$"z Ü *#*$? *#* "!"K *1*w <G=*DM>:͒:>,͒< T=*<, S=*<, PS=*Y~c#`#- `#BK ,HA~ ; ~  ͒"@#y * ~ ;#~ ;,"|͟{yH*|~ ;͍2<++Can't read or go +/-: not positioned Position by: Track then Sector, or Group or to file name via F ><͒>>͒:*xy To find "IN 0" use: =<0> or for "(tab)H,0(CR)(LF)" use: =<9>H,0 NOTE: After using "=", you may use "@" to refer to the displacement of the match: =LIX;ca@,LXI;w would change LIX to LXI @+xx and @-xx are allowed, too. < save current sector into mem. buff. (Resets memory pointer used by "<<"). << save current sector, bump mem addr. NOTE: this buffer is at 2000H, so you can exit DUU and get at the sectors. ALSO NOTE: # reports # of saved sects. > restore saved sector >> re:ͳ *7+wF*|#6!26:?ͺÊ>X:VͽÊ>!*ey!5w+~#wz.!5"5"5P. G:a5Oxͱ:I x  yON#F ܔ ͱp+q ͔!o *7:IO&:H=! D3#:c5N%# H +9 .`ͫ" ? !!!!a5 È*`5>+,&í":`5 *`5-í">o͜:+A ]! <++ Can't save more than 255 sectors :=!>2:|>>*p:!4|!"2<++NO "<" SAVE COMMAND ISSUED OR RESTORING MORE THAN SAVED 22! ""~#ɾ#ɯ2ͪ!36 Ó % 2UG~{:h*z} 2**͍͙ !:Ž}2~#"z% : {©!ͪ ~~    ~͒,¬  **͍é<  0Ò  |{0͒> Ò>*Òͪ~T͈W͒#~=#͟zu{uƀ_ɯ2<++BAD DISPLACEMENT (NOT 0-7F) ~#@>~c ;,->#Hʭ0:AG0))))oí#"ʟ~c ;,-#0:0bk)))o|gT]cH0:$AG$#~-T+T:_~#͟-j:_~z/W{/_>:͒!3͈OI ʹ1 w#͒|+>*͒|w͒> ͒!3ɯI+y~͒||w  $ 4store oldest saved sector, setup for next ? give help A[ff,tt] ASCII dump (hex ff, tt, 7F max) C Change: CHaddr,byte,byte... (hex) or CAaddr,data... (Ascii) Allowed for imbedded hex. or CHfrom-thru,byte e.g. ch0-7f,e5 or CAfrom-thru,byte D[ff,tt] Dump (hex+ASCII) E Send erase-screen (string at 104H, FF ends) Fn.t Find file F Find next extent of file Gxx CP/M Allocation Group xx H[ff,tt] hex dump L Log in drive Lx Log in drive x M[xx] Map [from group xx] N New disk P Toggle  Re:B6dbf:C6h:D6j͔$2'$Ù*6G*66*78ʙQc#^#VʏʔQln++O:d5Gyʱ¸:Þ¿>~͙܀ > :a5   >^@ :c5 ̎ !45 ͳ !a5 P H 4*7w#!6*7B +4:H=q :I*7e"7*7eB 5*7 *I&*7[gg> -¤ !!O: y#*`50> XO !X5 ws"g":[5!  ++EOF++ YÓ : 2<++Can't dump, no sector read. 2<Use G command following F, or R or S following T ~;ʌ • è `BK ʨ ;ʨ #``i}22:#A ~}2}2{ #} ͪ:#H' 7~ ~ >.͒{ #} 7Yͪ{« Y{« % ~;C G E TZ Sv G *V>2Ó z*$͍2͙ E *1**$*+:'G}2:&G¾ "͟*)V"2 ͍2E bk:&)=4|<^C Ignored - Use X command to exit to CP/M6 Y!3~ |͒#;>^͒>U͒Yr> ͒> Ò`_OlO «> ͒:› Һ ʺ :y >2 :<2:*V"BK*1"*`i2:L+L* :%Bg:L&i"DMɯ2<++not within tracks 0-*<++ >22<++READ failed, sector may be invalid++ :2<++CANNOT WRITE UNLESS READ ISSUED Cprinter switch Q Quiet mode (no msgs) R Read current sector Snn Sector nn Tnn Track nn V[nn] View [nn] ASCII sectors W Write current sector X Exit program Z[nn] Sleep [nn tenths] /[nn] Repeat [nn times] Cancel a function with C or Ctl-C. Suspend output with S or Ctl-S. Separate commands with ";". Example: g0 +;d;z20;/ would step in, dump, sleep 2 sec, and repeat until control-c typed. See DU.DOC for complete examples. y#x}/o|/g#ɷ|g}o }o|gBKxYDUU.DOC by Ward Christensen (revised 10/23/81) Includes notes by Ron Fowler for DU-V75. HOW TO USE DU ver 7.5 DISK UTILITY (Extended and called DUU on CP/MUG v.71) DUU, Disk Utility-Universal, is an enhanced version of previous DU programs, on CP/MUG volumes 40 and 46. The primary change over the earlier CP/MUG versions is the additions by Ron Fowler, to make DU work with virtually any 1.4 or 2.2 system, single or double density. INDEX 0.0 Changes from DU-V75 1.0 INSTALLATION: 2.0 U;ear "e" causes the display to "sit". Set "@" when using "F" command, so for example to erase a file: "ffoo.zot;ch@,e5";w Also change "not found" of "F" command so it aborts, thus preventing, in the above ex., the actual change-and-write. 1.0 INSTALLATION: === The 7.0 and later versions of DU are designed to be installed with a minimum of trouble. In fact, in almost all cases, no changes to the source file should be necessary to get DU up and running. This is because DU uses the disk paramector (hex + ascii) A Dump sector in ASCII H Dump sector in hex Vnn Views (like CP/M TYPE) nn sectors # Shows disk parameters, also # of sectors stacked and used via "<<" and ">>" Changing: CHnn,val Change data in hex CAnn,val Change data in ascii ( with escape to hex) N insert new disk Unn Change user to nn Searching: Fname Find a file in the directory F Find next occurrence (extent) of same name =aaaa Scan for aaaa (in ASCII) from current sector on Misc: Znn Sle N-O-T-E the special symbol "@" contains the displacement at which the match occurred. It may thus be subsequently used in a C command, as in: =LIX;CA@,LXI;W would search for the string LIX, change it to an LXI, and write it back. > Gets saved buffer. < and > may be used to move a sector to another place. >> Restore "oldest" unrestored sector saved by "<<" command. This command may be "buried" in the middle of an infinite repeat "/", because it will stop operatiSE: 2.1 COMMANDS, BY FUNCTION (quick reference) 2.2 ALPHABETIC COMMAND SUMMARY 3.0 NOTES 4.0 INTERPRETATING DIRECTORY DATA 4.1 SINGLE DENSITY 4.2 DOUBLE DENSITY 0.0 CHANGES FROM DU-V75 === The primary change is that all routines which original- ly accepted a decimal number, such as /, +, -, and Z, which were changed to HEX in DU-V75, are now changed BACK to decimal. The "F" command now works completely under 1.4 and 2.2, and finds all users, and even erased files. Ambiguous filter block of CP/M to determine the characteristics of the disk environment. (see the disclaimer for certain non-standard versions of CP/M 1.4). The only parameter that should need to be changed will be the clock speed flag at 103H. Leave this byte zero if you have a 2 mhz clock. Patch it non-zero for 4 mhz. This is only needed for the "Z" (sleep) command. An alternative is just to use larger numbers when running 4mHZ or 5MHz. 2.0 USE: === An initial command string may optionally be placep (nn tenths of a second) such as to allow viewing data before it scrolls off Lx Log in disk x P Turn on/off printer output toggle Q Before any command does it "quietly" X Exit to CP/M /nn Repeat previous command nn times (indefinitely if nn omitted) 2.2 ALPHABETIC COMMAND SUMMARY === # Prints the disk parameters + advance 1 sector (if below track 2, this advances to next numerical, if 2 or >, advances based on CP/M's normal sector scrambling algorithm, i.e. so + wng when there are no more sectors in the buffer. ? Gives command summary A Dump sector, ASCII only CHaddr,val,val,val... change hex in sector CAaddr,char string... change ASCII in sector NOTE that may be hex imbedded in the Ascii: ca0,OK<1a> ----> Use W to write changes to disk. Note that the C command echoes the overlaid data for verification. CHaddr-addr,byte or CAaddr-addr,byte repeats a change D Dump sector, hex + ASCII Fname print directory fo e names are now allowed. After using "F" with a specifid name, F with no operands will find the next "occurrence" (i.e. extent, or earlier erased copy, etc) of a file. This is a matter of taste - I don't believe in "babying" CP/M users with "press any key to continue" when more than 16 lines has scrolled by. I removed these, so use ^S to suspend scrolling of the "?" (help) output. The "U" command has been deleted, since its only purpose was to change users for the sake of the old "F" command.  ed as an operand of the original DU command, i.e.: A>DU G0;D;G2;=OK<1A>;D For example, if you want to only MAP the disk, then exit: A>DU M;X Once DU is running, it expects single-letter commands much like SID or DDT. For ease of use, multiple commands may be placed on one line, separated by ";". In addition, a given command or string of commands may be repeated, either indef- initely (until ^C is pressed), or a given number of times. To avoid an accidental ^C from dropping  ill get the next logical sector of the file - backs up 1 logical sector Note + and - may take an amount: for example, +15 steps in 15 sectors. / Repeats entire command. Defaults /nn to "forever". nn may be 2 to 65535 < Saves current sector in a save buffer also resets buffer pointer used by << and >> << Saves current sector, bumps memory pointer. Thus subsequent "<<" saves "next" buffer in memory. Use "<" to reset, or ">>" to sequentially retrieve the buffers, such a r file "name", then positions to it's directory sector. F Find next occurrence of name in dir. Gnn Position to group nn and read. G Shows current position H Dump sector, hex only L Re-logs in the current disk. You may pull out a disk, put in a new, and "L" just to log it in. (See "LOGGING IN DISK" in NOTES below) Lx Logs in disk 'x', such as: LB M Dumps a map of the group allocations for files. Mn Shows which file is allocated to group "n". N Resets CP/  The new "F" command obsoleted the "U" command. Made sure + and - check the "NOTPOS" flag; that was a "loophole" that could "mislead" you. Added ability to put Hex into default decimal fields. Needed this to transfer files, where their hex length is known, i.e. a file 29h sectors long in contiguous extents may be read into memory via: <<;+;/29h Added "E" (erase screen) command. Store the character sequence, 0ffH terminated, at 104h. Useful as in "e;+;d;z20;/" to dump, sit, loop. The screen clout of DU, only an explicit "X" command will exit DU. 2.1 COMMANDS, BY FUNCTION === Help: ? request help Positioning: Gnn by allocation group Snn by sector Tnn by track +nn going ahead nn sectors -nn going back nn sectors I/O: R Reads sector W Writes sector < Puts current sector "away" into a buffer > Recalls previously saved sector Displaying: G Shows current group, track, sector M Maps the disk - where are the files Mxx Map starting at group xx D Dump the s\s to move several sectors from one place on disk to another, or to another disk, or just to memory (stored at 2000H where DDT or SID can subsequently access them) =string Ascii search, starting at current sector. hex may be imbedded, or used alone: To find "IN 0FEH": = Ignores bit 7 unless is used. Since ";" is a command delimiter, you have to use <3b> to search for a ";". Also, since "<" is a hex-escape char, use << to meane a single "<". M via the BDOS. This may make it possible under some implementations of CP/M to change the disk format (e.g., density, sides, etc) P Toggle printer switch on/off Q Quiet: Preceeding any command, suppresses console output R Reads the sector currently positioned to into memory. Note R (Read) is implicit in the G, +, and - commands, but N-O-T in the S and T commands (I did it because I was tired of disk reading after T command before I had a chance to issue the S commany, with its attendant "select density" functions, and Ron apparently put this back in. So, it now sometimes works for double density, but makes DU very "intolerant" of disks with un-readable directories. A solution is to log in a disk which is OK, and is of the same density as the blown disk, then put in the blown disk WITHOUT logging it in. However, you are now opening yourself up to possible problems because of the buffering of physical sectors in the BIOS. The best technique, (but not guaranFowing explains the format of a CP/M directory entry as shown by DU, using either the "F" (find file) command, or just doing "D" (dump) of the directory sectors, which are located in groups 0 and 1 on a single density disk. --7 Sample result of "FSID.COM" command: 40 00534944 20@ 20434F4D 0000003A *.SID COM...:* 50 33343536 3738393A 00 00 *3456789:.."* First line - 40 00534944 200 20434F4D 0000003A *.SID COM...:* || ||| P+ia for the data. 10/23/81 Ward C. *ch group stood for 2K, not 1K, so there were half as many groups for the same file. Be VERY careful when patching a directory under double density. I once made the mistake of putting, for example: ch10,38,39,3a,3b... When I went to read this file, it tried to access group 3938, with resultant angry exclamations from the disk stepper as it attempted to go south to Peord) Snn Position to sector nn, and read Tnn Seek to track nn (no read) Ux Logs user 'x' for next F command. Gives '?' error if not CP/M version 2.x. (Note "F" no longer needs this - finds ALL files - erased, any user, etc) V Views the current sector. (assumes ASCII data) Vnn Views nn sectors W Write back the current sector (N-O-T-E may not be used after an F command, as CP/M was used to find the file in the directory X Exit back to CP/M (Must press return). CtDteed), would be to seek to the unused inner tracks of the first disk, do the read, THEN change disks. That way if it writes anything, you won't have destroyed anything. ...assuming the disk is not completely full. Another technique, assuming the second disk does not contain a CP/M system, would be to seek to track 1, then do the read there, then change disks to the blown one. Regarding the << and >> commands: * Up to 255 sectors (only because its a 1 byte counter) may be saved by <<. * ANY  | || || | C | || ||^----hex file name-----^ || || ^file name^ || || || || in ASCII || ||  extent-^^ || || || || || || file size in sectors-^^ || || || ^^-00 = file active Other values (e.g 03) = User # || E5 = file erased ^^-displacement of line in directory sector Second line - 50 33343536 3738393A 00 00 *3456789:..* | | | 2Iv2DvLs:&vogss&"GvDsnrtst=s͈tt$s"EvLs*EvDs*Gv&[tvuʨutsTsvu[t}uqs33"Ev!sKât͚tځuŠsnr͚tڛuʕu*Gv"+v:&vg$o"Gv2Dv2Ivt*+v"Gv7t|Ҙs˜s:&vs+Lrs[t:Gvg:HvGu|sDM vuums"Ev:Gv&oA:HvtyGeu>2DvmsmsTs͈C8LyG;rQ8LQt;LNt͈Cs͈tt |t |t͈tGx*Bv}”t7+"BvẍCKt!Avtʾt t6 6Út6Gͭt>xɯx t#t+:Dv2IvGux  l-c was too easy to hit over modem lines, so I decided on 2-byte (X, CR) to exit. Z Sleep - causes the program to pause, such as to look at a dump. Z is 1 sec. Znn is nn tenths of a second on a 2 MHz 8080. 3.0 ====== NOTES ====== === * MULTIPLE COMMANDS: May be separated by ";" Example: the following commands will erase the b disk directory to all E5's: lb log in b drive g0 position to dir. ch0-7f,e5 fill with e5 < save the sector >;w;+;/16 restore, write, ne TIME "<" is executed, the buffers are "thrown away". * One ">>" to fetch a saved buffer and make it available for writing, may be issued for each previous "<<". * The "M" (directory map) command uses an area of memory for a buffer. To minimize problems, the Map buffer is placed a the END of the CURRENTLY HIGHEST USED "<<" buffer. On small systems, where a "lot" of buffers have been saved via "<<", the "M" command might report that it ran out of memory. Executing "<" (or ">>" sufficient ti , | | ^- allocation groups ^-----allocation group numbers-----^ just happened to be printable 4.2 DOUBLE DENSITY === The following is a sample of FSID.COM running on double density system: :FSID.COM 00 00534944 20@ 20434F4D 0000003A *.SID COM...:* 10 38003900 3A003B00 00 00 *8.9.:.;...* G=0000:00, T=2, S=1, PS=0 The primary difference is that the groups now occupy 2 bytes, i.e. "38 00" "39 00" ... This follows the INTEL and CP Gu #|t͝r+t:Dv1u||t:Gv)u|t>2Dv7=|t>2Dv:Hv|t|t)u> t`ueu}JuWu# }eu Gx*EvóGóG͈C>kD> kD!Þu͈C8L͈C:&vus  ¶u vu:Hvu|s8uo|uu%uEuͳoÊeu8t çpôp2vþp>2v25Ok$%p͹$!n5L#25yp>,cp͹$!5L#25>)c͔$ xt, repeat 16 ----This could be shortened to: lb;g0;ch0-7f,e5;< >;w;+;/16 * DUMP COMMANDS: All dump commands (D, A, H) may be optionally followed by a starting and ending address: D0,7F is the same as just D D3,5 A20,3F * LOGGING IN DISK: In the original DU, I logged in the disk the way DU now does. Then, I found that when you had a blown directory, you DIDN'T want to log the new disk in. Thus I changed DU to just change which disk was selected. Then along came double densit*mes for it to tell you there are no more sectors in the buffer) will then make room available at a lower address, for "M" to use for the directory. The following command could be used to move your directory out to the end of your disk. (to keep a "back up" copy). 1) Map the disk to find an open space at the end: Me0 map starting at e0. 2) Suppose E0 is wide open. Capture the directory: g0 <<;+;/26 4.0 INTERPRETATING DIRECTORY DATA === 4.1 SINGLE DENSITY === The folli/M convention of putting 16 bit values high-byte-first. Thus it means group 0038, 0039, etc. Note that in double density, each group stood for 2K, not 1K, so there were half as many groups for the same file. Be VERY careful when patching a directory under double density. I once made the mistake of putting, for example: ch10,38,39,3a,3b... When I went to read this file, it tried to access group 3938, with resultant angry exclamations from the disk stepper as it attempted to go south to Peoro*`5!5 .>2525:59q~!p!5 L#rqo?q(:5Rq:5kk*5"5>r2'!vͨjͤq{q*5|!p!pà&:5q*5|ʎq+"5:5[qg:5JÔJ?1 ͎rxͨsڼq͎rq͈C2'͗qҭq:5kk7!!:5:55r:5.rĨrr:5:5*7eÈCMh:5*7eC*7!5mrͮG:5:55ro /*7lÈC!n5x:5Srmrermr>+wy<<+w#y25~ʈrr>  > # pr+q#:5:5 r8LãrK?ÈC! p"60͍''/r@Yr>N!d5 7*7~ % *6~!%r͑!~!r2'221@:2!o6+6+6!6#6!6#6:G*o .!N6:^*M^!K6!6!6+6' :$::=2K  :ʤ\:ҷ\x'Ͳ:!\͢  :͈'! Ͳ:$: $͈Ͳ!N6' :!Cwͯ !6:^͢c!6{:/>!/H{ͯ :<2Š ::=HҮͯ !6:Ҿ:2 !6::/H͈;!6:> !/>` :2!q: " *M n :c4 *M n :2!c:Q !c:2: !:cw>!n !5 Y : { !6!q:!lwҙ  â :0O !q:O| :O| !6:]2l:o'2o:n'2n:m'2m*mMͣ *nMͣ *oMͣ :]:   *}2D" * * *&"!q:UY: Y:ҩ: ʩ:_2ʘ:€!6<:<2!ژ!6 >!]Ҥ; !6:Q::H: !6*M : !6!q:a/>z!÷:S:QHI:N<22: H@"2Í202O> c!6Í202O> ڍ*&O*& !sc*&P :w:·>!ұͯ :22:_!6=!6>'!E!4!p+q*0 !r+s+p+q*~$7*>*>H&>*#"*#"> 2:R͎:!6!6=2:ʙ!6:“H9Ž>!6-e!6ͻ2=2ʺ-é:>>"ͻ2:!!5ͻ2ͬ!\ͤr͡sys#?"sͩ$ 87B,s-2s>25G@s>2525NJs25WUs>25U`s>25> c"p$p͹$7~͡s#bk))ܝs0_ܝs"5|s!0?::5s!7s*7sÈC!7s*7ltüsIGyOxG7tt  t#s+at#ss#Ltt #0ttattѷt Btat# t~͡s>Ҳt~>ɛHHͯ :^!w:<2:0}:@E}:!S!W6: z!]6:cm!c6:_z!_6l ::,: HHҰͯ : 2ó:E:1:2v!q!*8!*6: >ͦ>ͦ!q:_  !p+q.*   !q*&!p+q*2!p+q*2!p+q*22!p+q*!p+q*!p+q*!p+q*2!p+q*/H:_2:!q:A/>Z!/H8: 2::=O>m:W!Q} Hmd>9>!6:2*M!E ^#V͎ڗO **~2*#"m2m͖ 2m!6m!6m!6 m2mͯ m!62m!62m!62m!62m'2:2:TҒ:2!6*ME:2::Ҳ:<22ý: 2:} >ͯ :i:2:d*M:[ w-:>>!p+q:,!6*DM9:<!6:z 2W!6D*&L :w:<2Ov*:>=20O> ڒ:0:AO>Ҥ::A }}Hͬ!wͻO`idͻV[2O>2:!X!6:!:=O!L NE!4 E E:/.*&L 6$L9k9.Xͯ *KM^020 :020:121'ͳ':²ͯ !G6!"!"7 *M^n/ :a/:H!6:ͯ !&6 @(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE)(INP:/OUT:SPACE) COPYRIGHT (C) 1979, DIGITAL RESEARCH, PIP VERS 1.5$$$ SUB =.:,<> _[]INPIRDPTRUR1UR2RDROUTLPTUL1PRNLSTPTPUP1UP2PUNTTYCRTUC1CONNULEOFDISK READ ERROR$DISK WRITE ERROR$VERIFY ERROR$NOT A CHARACTER SINK$READER STOPPING $NOT A CHARACTER SOURCE$ r!p+q* !q*& *M *M !p+q*!!p+q*"!p+q*$!6  !kp+q*j> >ڪ Þ !qp+q/ *pDM9: :M2r:N!r !:r *r& N!r4 !6:͔: :ͳ.!ws+p+q+p+q:w=2wN *s*u w*s#"s*u#"u' !"*M^7 !x6:!xھ **DM͆ 2yʭ :yʗ ͯ *"*6:2x÷ *"!x4d !"/ !j}=2| !"*KM^'_ !z6:|!z1 * *M:>!(:=2%> >>!F!5+N! ~2!4<2T>>!b}*bMͭz:b2!b6:<2é>!`ҥ*`MͭҞ!`6!6> :é:(!q:!wO! ~2*& :w>!:!4!6>:N<2N!> *N& N2 !p+q!6!6+6 !6: S: M!6g8:N2M*M8p!6!6!6>!ڕ*&P 6!4z!6!6#6#6!6*M8:ھ:*͇g2ê::¿::,͡A<2O> 2*">!b!ͯ >!`0ͯ !q:E:24J!46*}a!44EJ *KM^'́:‚ͯ !36'n::0:f9OY#9.3'ͳ.:020' 'ͳ'7 6'!j>A+!s!"@͓1!"<**"͓n "Dn"":!Q2҂:X!Wғä:ڤ*MEÓ:ұ@@:O2Mc;!6#6>!)*&P ~"::H:H ABORTED$BAD PARAMETER$INVALID USER NUMBER$RECORD TOO LONG$INVALID DIGIT$END OF FILE, CTL-Z?$CHECKSUM ERROR$CORRECT ERROR, TYPE RETURN OR CTL-Z$INVALID FORMAT$HEX$$$$NO DIRECTORY SPACE$NO FILE$COM$START NOT FOUND$QUIT NOT FOUND$CANNOT CLOSE DESTINATION FILE$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$$$$$$$NOT FOUND$COPYING -$REQUIRES CP/M 2.0 OR NEWER FOR OPERATION.$UNRECOGNIZED DESTINATION$CANNOT WRITE$INVALID PIP FORMAT$CANNOT READ$INVALID SEPARATOR$1 :2L> ̈́M9 l "}*}DM͆ ' ͯ *"!z4 :e !"͆ !z6:|!z '? 2*H#"H!{6:{ր!Ң *{& :{4 2!{4m *":ڹ ͯ !z4I '2!"!q: !4>!S :S! :2*M! ^#V͎ * :w*#" = = = = = ͯ  *M !6q  !6q  !6q  *& !6à  !6 à  !60à  *& !6  !6  !6  *& . 1 4 7 : = F P [ f q  *M8):[ͱ!N5!6ñ:5!6#6>!ڰ!6:<2O>/:!O!T *M͡H~K:¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g:[ ͱ!N5!6:%:<2*6 * 6å!q!6> !d*&I :]>!4A>:<2O* :w:?†!6!q!6?!:ҠgÐ!q*&*~!6:22: :]Hں:A2O>: 2ͯ :H:H"!6!4:_jYO jM*"S*" 3@bl*M1͓!""7 *M^͆ \͔!":͎H*#"ͧÝ/ :>͛9ͯ .*#":_!' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*G>[@T1>]@2ցALO! N#F#~: 2Ұ ګP: [* 3#2 Ґq…~#" &o" >2 !~##" +fv<2  G(" ! 20?<=:  * ###^#V,U: 2 * "' * ") U! (U1E AOG2'21EAG2x3Z: * #*D > 2 /$`i s y2 : 4ʂGWxDzkxz Ҋ! N#F*' *("% "# ͨ(*!: og~#fo(2 R"' W)!]͘(*ͳ(") "' Ä*͘(*l'2 .2Ee ڸ<=ʮW"Fj&ʄ2:2* ,12D(#͈ VQ!ͨ9D)|J)IʣB"I+UnD)} * j(ͨ9"' (~a{_&Z2vOH#~v2EҲ:0ùG7))))o Ù+28  )))0O )#~ց2(PX2#,#OBK2#D,O2#D,Z zJ`iDJ^# J!DJ^{#Vq#~#+N#͔#^{#Vʏ##s#r x# 2 *+#~##^#V2ʝ#O: y$#2©#2©#ez#$¦#e > ($DB!$DGT1L1+æ#Undefined line ¦#e###N#F>!#* +p+q+w: Õ#DBDADSDE: * * D ~0  2 <2 2~͆$#|$ÆAʗ$y)ó$!$DG.KJD#~.~˜$y)"87Random number seed (-32768- to 32767)$*" +2%%DM!  ::=H-\:N2O_og_{ozg^#V))) _{ozg^#V) d^#V|g}o n_{ozgO{ozgi`N#Fogo&og H ©=¨'' !'6!36' :1/!aE*#">z?C9IͲÁ.!6> !ڇ*&' ~2 ʀ: y.*M!4Q>!қ:=2á:2:Ҭ\>!ҿ:=2K:2K!:!:K\: \!p+q͈*"  "!>:yHG+2ȸ#"<֌WVͨ9D" : G: xf: ' q# ¨*' #^#V*DҜ* DҤ! DҤ>HFH(2DZzPY" : {:_ ͋ ~GD+K x[,  <2~Zz< 2* * "~5#####͋ J  fOgD,* fZ |J" 2 " ~,2ʍD+ͅ(ʧ2 * 2©©Õ>2Q+2QB"?ʎʎ,O; c1F67>O2y*D,:**' ͋ DO} ;)c>2,  N#fi-++<~(|Z y)}/o|/g"' 0: Ҍ7y)z ,{ʧ+F¯{o|Pº{o|<{o|2{/o|/}//o|//}o|g,:: 2 ͨ9: " " B!9(: * ~)D,* D,Ú2q (2 !9(!9.,$%#~#Y #^#V" 2y~3%$$$$$2%** "ͨ9+2%h%D,+=%":, 2- 2, !G6Ͷ(Í%Ͷ(s(x:* ʨ(ҧ%/<͘(ͨ((gg&|!' %G&(ʗ0.͎&(&G~_#~W#~OS&hcGy&JTeox%2* | &y&O&)zWyO%x\E(&!* w%%x!* :&F#~怩Oè( 4Ö0~_#~W#~O!+ ~/woG}_}W}Ov&CZQi& ozŠ&y-OҀ&Ð&-yOzW{_xGÊ&$cCu͍M r5D(J&1r'ͳ(>2* ͘(!&7͘(ͨ(!&7n'͘( *7͎J*7YH͎&J:kKJ*7YH͎87>JdKJM*7+"7J"7:G+~# `J> iJÊJͣH?IPK*7!7CKãJJqJ!7)K*7ͼJJڲJ2\7"7 ¦JsIg77797~J#J7>>:9!777:v7qJI!7,K*7gvsI"7 KsI?I*7ͣH͎UK*7)$$VKNKO>͕&xHͣH͎eK)|Lɯ2 v8M:WvK͈CŽK*72 v/2 v*7ژK*7[:WvʾK:v¾K*v|KPY͎ڽKDMɯ2WvI*72 vKxK~# ! v~6K2 v*7*7[x C *' 4*|H*' :/:G @22go"D#ʭQiL͙ͨ9:*QKJDF>V?Redo from start #~ "^x: !KDG* Q! R#ʃiL">2>2 F~,¹2 2ýD;GG: >?@> @QKJD6,+>2 2ͨ9~+(#2 : G:q OdJ}!s Oc* 2* D)>" : OBO/2 Oí9~ #~ #ÂJ͎ 2 x x +20 D,͋ 1 Q 2͋ 2^ 2͋ 2^ 2^ /<2y)z͋ 22 2 D,Ë 2o J+2{>2W]!"N#F#xʪ *|̅BN#F#Dک " T1~ > @!! QBç ~B#  [S(Í%D(.(y2A'"<'PX!%!*'!' ~#^'WyB'O|g}oxGV'x Gz4'CZQO͘(!-ͥ(D(ʟ0.(44+~2'+~2'+~2'AOW_2'}o|gxG>?Ұ'2'7y<=':'x'> )&{_zWyO)xG:'2'y“'!* 5“'%>.!6 N#G.x&(}!* Gx%(ƀw\'(w+D(/%o0ͳ(xڏ0G͍%!* 4Ï0:* :) /<!* Op#6%ͅ(+ !) ~wͅ(og) D(*' ||N(*' *) Ͷ("' `i") !' ^#V#N#F#' (: Gw#(!) ~7w?##wy7O!0 ((!0 ('  #=Hiʽ&@2vH> 4> ͈̈́î#͈:RJX>2 2 UH~|s@~#͈^!@}O|G!E>: y +=2 u͈#u2EҞ:Һ0Ҟ.ʞH~   > : <=`+~   #>d2 ͨ9D" : ! Ϳ(" !9w ? +V+^##* D " B* *D  {y)~i ͑(Þ)ͳ(QZ~>Ÿ)ͳ(D(OG+2 $2* "* 3E3ĐB" !9" ~: #~#ʨ #^#V":! P "^()2, ~,l>2- {:- =lH+2~,+2x6,\* 2 hD,ͨ9~,z: 2 *|Q½2WG"ʧ: Wʤ:,+FO: y!W2..+2,q+2d: 0D#~# #^#V" 2zDD(+Bͮ2, " * ~" ڪ_O: {}H !xV0zQz!' :  N#F#N#F#!# N#F#N#FKG* W " 2ì)͘(7ãy)ãxdd!]s*' ~Fã 2 W]!#~ "! _6![!_.6!!6!I!: G! >2 { W! !!<~d!#~#r! j*!:G@ #T]~ʀ!#!~!ʚ!y_­!: >2 ![¹!2 !: >2 !> yG{!~#_yG!!2 !2E0:?+2͸" ʩ6 ʬ6* c1: O *" H5">&{: F"!F"#~ ̽(~#x": L" i".s"Ds"EL"L"{ʁ"* !8$ҟ"T]DJ!h DG!* D±"`i" "N]~"N]D,͋ y):* :) Í% }# xD(!M(D(y!) y)#x+y+z+{z|N(O(}O(!0 (7 D(!M(D(O!) y#)+e)H)M(*'  )(!C6(%,)Û)~%:) 2) :* A*:* ¼)))|/g}/o)! :* )A*"' >2 )aj)* ͳ(5*x(!& F(&*' 5*|UX( *!"# "% >>) GOW_ͳ((ge*>g&|:&S&z< D(*s(*j(ҥ* )!* ~:' ~A*6{y%!* ~*O+~+µ*!*)*yͳ((+6+q*:) O!) >$-,2" Ð,!# ~5# D1 1H1(1!# H1(* |91* D! " ! "!c DGCG)1À11n16+ͅ(16-j(#60: W: 3 315!9 F : _ ʹ1x*¹1{¹1Aq21E1D10ʹ1,ʹ1.1+60{1+6${+p2 !9 6 ͘(*# *% 2. ͠2E~A2:!20!2 #~2>DG2"# `i"% #~+ʈ2-_20OxG҈2#~F2`xE}2y 12>2. Í2|12u212"# `i"% ͨ(#W͖4:. 22225560̽(\5+~02.Ľ( 3>"w#6+26-/</ 2) !$97:) 2) "~Ie&X4#]I͘(ͬ8͘(ͨ(ͦ8l'D(6s(:* k9QYn'!%!u97!9 J;xn{/|t1}=Z}~L~l+2D,92 N1E G2#~.:9:9092E:G#~:9092E9.9x' 2~&:*:%$!#y_! V+z2 2: =ʽ;F:~(A;3A;2 : 2 ʚ:*  " À:ox:: x:;& @:(A ]A`A:<:WA!wA`A`A<2Oɯ2:> aA> aA2:yG¥A: ʷA=2 >A ºA> @: ªA A:G: AQBAA<2 O*|$BW\'SS: 7P:!kC!h DG:uD/2uD: QB6! > @> @*|gB:sB2ɯ2 :=@zB%B%B2wD5D2B·BB%BF_I!g "' >2 :2@ > @[B> CD~ +B* *!x!+>)<)+ <=+|G+y3+|Gz)*͘(,Q0|)+DM!>)ڈ+)p+ ڈ+=b+|+x+ʙ+*͘(*'x)*s(| ++DM!>+ +7>{_zW}o|g=+v+|G+|)Ooyg)*' +|5*X(ͧ+g{o)+!6 ~w!7 ~G+N* (Q,/<#Fwx+ A,F+N9(!/ G>w2" !6 $-:/ 2" x,,,4ʗ0P-,>,!+ -G:) ¹,!" Vwz# ž,x‘,%!" X-,x,!* w%:" ,!+ ~++w!# 4#,4ʗ0+6S !0 ->!0 #2:#p#w#6!9 #zҋ3(4-5z 55{(= 5͜1@3p#6!8 #: ~ E3*E3+Y32-+$0ƒ3#2҃3++wy3F3ʃ36%/4ʧ3K6B)3c1+6%)3D(Ė43_x 5 5\55H5-3_y/3/3{_x4 5 54 5yL5O 5GO\54* = 5P63*ѯ54D(7Ė4y/OzWO/U4c4/<* D<^#~#;: ;~<#^^#V#;: DM\'ʈ<  #:;#;+<;: w#_ƕo>Cg9*++"  3C͈G3CC* D:G!^#V#GCT*ͯD2 2 2 w#w#" *+" : ŒC2 2 ! 6#…C7!8(!s8w#w#w2 og" " * : ·C" D* " " : T*++" ##! " w%nAgo" 2 "q " " 2 * |}~D##~:7 */DZ`i+" <@DT" ! " !*}ƒD22>^@@@QB* | * "͋ <2>2! ͨ9! (* D,ͨ9 * DJ( (>2 ͨ9J2  2-# -~/w!" Oyw#-q;-NsY+0-&- W~w+E->-!) B-~w# Z-D(:7 %'͠.qʘ-G,P-x -x-Ð,!) ,-Ð-L} :* A--!0 (c-:) -2) !s(.# !0 (.%,# !0 (>.%.%,!6 6.=-...!* 5%!7 >5=.>!0 N#F#=+.>!7 p+q+=<.:7 ʣ0:* %'44ʗ0͠.!Z qA>,?w.>,:) <=,!# Z-!S X-xe.!* 5e.%y26 +Y ~q+«.(+~ڗ0w%,4×0%2*o%>2, `h)~&ʄ-.+.+2 6B)4=60# 55H560#=5{5#HT56." #H 6,#5(!C6(%,*S6> H5/>,҅5>,p#=|5!# ͥ(ø5~%>A*ͨ(6?H5ͳ(/{_#zW#yO++5G&#ͨ(p#ھ5>56>H5N#F#*' /}o|g 6"' p#=5H5w1_cƤ~@zZrN vH Tʚ;@B''d G"8 կ6))))6y=660:6 666!s(͘(!G6 V2* <=O" `i##N#F#!|<>!@T1> @!  ~#B=G%BM=v0l= l=_zWM=!K=w=>O>?=1ڒ= !? >#=i>>4>?(d>=a>>@QB=~B#=!.>7%B_.>~ >Bܬ>>#~== QB*=~>\B~.>Bͬ>>>\@~%B V> V>V> V>>@7>wB#4>6H=%Bʜ>ʞ> ?ʞ> ʼ>ʼ> ʼ> i>_¼>>_>B+i> ~7\'#~+w#î>y>>@i> o&DM#BwB#>x+>B>x+~B * `i E * DE `i" ~,2D~A[?oC,KEF+2oCD,oC*,jE"|J+2ʯED,ʯEF+2 !NDCEC*  DC" "oC** {_zWÃE}_|W2 " Ĩ9" s ^#V#* D ~#~##Fͥ(: F! ͥ(ā%Ϳ(Ͷ()YF####N#F#^#Vi`: ?F* JF0+:  r+s^#V#2)Ͷ(kF"i`" * ~,2EH~#N#FH^#N#F{zد< #ʓF?O(ͩ6úFͬ6úFc1FHI~#]GN#FFoͽH>]G! w#s#r+"P#~ FFF" /.ʉ/e/E8/2l&/L&/q&/Q7/: Q/>Q/~%ʖ/#ʧ/!ʨ/dQ/Dh/ͱ/2M2V0h/_{_//l/j(!\') h/ܱ/.2!\'!y)h/ͱ/2h/)*-(.=c'-2, *|$2 > ͆$> ͆$!'ͥ( 7)!w%>2, D(xW7"70%yͳ(?7͌*)|") "' 6s(&'8;':* Ҍ7hڞ7͘(͌*Ɓʏ7͊%!77J'͘(:) 7%Í0ͨ(|Yt&wz^Pc|u~r1͘(+ͳ('͘(~#ͥ(='Ͷ(͍%7RO2!&ͥ( 85*D(!u8k8!8ͥ(!u8Ȇw#O Ͷ(':t8<2t8!8O ́%ͳ({YOO6+F6!s84~֫b8w %!8ÿ(w+w+wF85Jʙ9v" GSљ e͘w>ROhFhiuh!9́%:* w"~'͘(͌*͊%)8͍%͍%D(s(͍%s(:) 9> QBz\@@_W@W~#!ʹ@#?&ʴ@ʒ@+>s?+~#.?_ʨ@\Q?j?$?*j?x#ڽ?~$> ?#W!@~#.?#?,@z@W?~#>.j?# !@~##?@T]^###xG#z+A@xA@~-<@A@>Wʝ@CxJzd1DG+27y@2 ;v@, 2~#N#fi_xp?Ø@@@3?QBH@~#@Ê@ý@>@ʝ@:**' AqIGG*' <`@=G> `@@@z>+@+2x,G G+~ G#yF >* "' >2 ( D" ~ #FH͸( @ [BNG* * /O #D{G" # _G* " !* ! * DG4H!o " * " * * DG~###<G5H_öG* ~#fo* G" ##^#V#" öG* DYH~###2 : sS:2ÿR2 2 * DM* " * #* " DUP `i" * |*+ `iQ+2PPc1F*' #^#V °Pr+s+5GG+2P;PD,+2>,@ÍP>"@GG>"@óP*| Q~ Qʹ\}o|g Q>.< !! {w:ẂW!! ~!) ?WU?W~#BW*~ʈ\( ~lW+~#5O ~+~xW~WNW7>*T]% N#F+q#p###6 –W͵W:C͗Z>®W>w+w!(LW7?*' 6#67H~ #^#fk_XN#~:X++@ y@  ! #TX~.2X@X7X#X2-z  > @X9X> YX9XW!< !! w#„XDADSW:!!J!< H~ #N#F OXIXR D,#2͋ D,{ _C|g}o_|_!{ozgC" "" " *C}o|g++!_DGT1!y_DG!DG" QB! "h] Owned by Microsoft Bytes freeBASIC-80 Rev. 5.2 [CP/M Version] Copyright 1977, 78, 79, 80 (C) by Microsoft Created: 14-Jul-80  o *" >2!^"^:^¼^<2^!~"^ʼ^F#~+w##+^+6"^!2ʼ^/_^+6""^#/_^2P^ü^62Sʦ^Mt^F 2D:ʓ^zJ{J2Ø^" +2ʼ^D/d^2D:" Ø^+* +" +:!|]"2<s#r# *  DM=^#"" {ozg-W~HJ#^#VF͎ * sG2D(͋ D,D)FI͎ IIIRI͎ > {FGI* w#aIIIO>~zIx]G#F#fh DMFoͽHHGInI~IJKrI=O~GCH_#~#foFr+2.pD)C2>J͎ JD,:*D,*' D)H\'HG=O>x~#F#fh GN#^#VwJ nJ#YJѯx<#VJkJD(ͨ9:*#^#V* DگJ*DүJF(D,͋ J~KHG!\'y~J>>F* (I>>>HJ<#N#fi2 ( ,QZQQͨ9:*;W_W QQ"QG{,xQPXW7R! Oz"y"R WR "RO{,yĐRW7R "R{ 1R,> 1R1R7R7R͐RWQ"BR jRWjR BR,jR bRWjR jR*( 46! { ~RBF2..ɷw#kRX͚R:2+2RD,DR 22!6"UC:2*""*#|.@ JZ: W:yZ> @@QB!:Z~*6?# ZO!!4¯Z#4¯Z#4y"Z ><+2ZC* DJ! s#r#wZ2g]0Q?0LVGRAPH COMPRES MBASIC LVGRAPH.ASC /M:&H9800 (SAVEGRF HEX[MODE56 PRNiMODE56 ASMjMODE56 HEXkMODE56 COMlDOWORDS DOCmSAVEGRF COMdGMBASIC BAKnT*++" #pSAVEGRF ASCh GMBASIC $$$ SAVEGRF BAK6mn J)KD,͋ D)$KH͈G* * >?@> @IKA›K6YKp22 AKQB!+=:>\2vKHK@+ʊK~@;K+@;K@QB! 2ObK:ʱK>\@2yLwD7 \L L KIKLwDIKKQK@> @>ÃKK>#ÊKL6QB! ;K ;Kx<9L*|>=L! Z"Îyq#@ ;K2 > @AML ;KÛK: LBw! >2 ;2 2" $2L33L " ** L L M" *" ##^#V#~#fo"ͅ(LA3* "!9~#L LN#F`i 5<S**  D\SLWw#S" : ]##" !~26kC:2: 7P:ʪ  VCUCC͚R+2sSSS 2W < *( 4 *|B ͜R+2ʸSD,P\DAß ͕#W]>lV* *DSS~#lVS V:SS=S~,2~#2͋ SůSѯ0Q  ! ~#fo" !"a]| G~,͈ DADSͨ9:*O*a] "a]* D q#s#r:T7ͨ9:*HF~O#^#VT*DT* DTY* * DUy]GH#s#r#^#V#^#VyTGO UU~#T g ! ^#V~,C+2 { +s#r! w#w! ~#fo!DM[Ë[BK>!)`[)#a[))o[ n[#=V[}_}la)J҆[#xJ"a]! "c]!) "e]!}o|gDڵ[bk:g][D[\DM*e]*c]M\"c]PY\}o|g*a]#"a]˜[\DM*c]*e]M\"c]PY[2*a]! ~#foDs#r<\:I\!I\!& èV~# xN\DMͶ\ ͫ\! w!( V6 ʃ\zwʹ\ ͫ\! ~!æ\! ^#V! s#rDMͣ\͝\D2" ͕#\>S]C ** D!u9}o|g!$9}o|g _ & < < < N O - F I L E M E N U > > >  D Open Document File | Y DELETE a file | H Set HELP LEVEL  N Open Non-document File | E RENAME a file | L Change Drive  X EXIT to System @ | O COPY a file | R Run a program  F Directory + | P    -  M Run MailMerge  S Run SpellStar  & < < < N O - F I L E M E N U > > >    D L >2 ͨ9(y)"  B!9 +2" MD(ͨ9s#r#~,]M 2CMD)" >!=M=M=M!9DM!M* * * 2 2 ~§M2 #+2͚R!" +2'ND,,M"" +2'ND,MDADLDL\OD, 2 28$`i"  NT]" DJ\O*+#~#N#^#V"2+N:;NXN2+;N2>N>2 ͨ9ʶNxGͽ;>2 „N~(ŠNN~(Jͨ9z£NxG: WF:zJBK!N N 2 ~(ŠN ͪN+2>N(N2D)>ND,^N* * D2ON##~w#< U>  U$UxFGT2D$D(͋ ~,OU20Q (QD)}JFʉUBpU%BʂUw# bUG* MDW uUO #~~(PY!' ůw͵W:D͗Z = =Uѯý < !% ^#Vr+s?Q:V PY0V!'V`i>}V!' ~U͵W)=VC*+6*^~ Rê !0`2 "" * ^#V"B"B"##^#V")B##^#V"A##^#V"gA 2B!]!!""C!"22 2 2 2!"!" ! " ! "o *" >2!^"^:^¼^<2^!~"^ʼ^F#~+w##+^+6"^!2ʼ^/_^+6""^#/_^2P^ü^62Sʦ^Mt^F 2D:ʓ^zJ{J2Ø^" +2ʼ^D/d^2D:" Ø^+* +" +:!|]"2<s#r# *  DM=^#"" {ozg4h󭭭 | 堠 |  L Changed logged disk drive | a| R Run a program  F File directory + | P  | X EXIT to system  H Set help level  | |  孭 | E RENAME a file |  D Open a document file | O COPY a file | M Run MailMerge  N Open a non-document file | Y DELETE a file | S Run SpellStar  g7o marker  SCROLL: Z=continuous up W=continuous down  DELETE TO END LINE: DEL = left Y = right r FIND, REPLACE: F=Find a string A=find And substitute  REPEAT NEXT COMMAND: Q=repeat until key pressed  '< < < Q U I C K M E N U > > >  | | |  S left side D right side |Y line rt|F Find text in file | (from Main only)  E top) INTO PRINTER GRAPHICS MEMORY 21110 LET LPXYA=&HDC00-(INT((LPY/8)+1)*361)+LPX 21120 LET YBYTE=INT(2^(((LPY/8)-INT(LPY/8))*8)) 21130 LET PO=PEEK(LPXYA) 21140 LET YBYTE=YBYTE OR PO 21150 POKE LPXYA,YBYTE 21160 RETURN 21200 REM SET THE PIXEL SCREEN ADDRESS AND WRITE TO THE SCREEN 21210 PX=INT(LPX*154/361) :PY=INT(LPY*120/360) 21220 GOSUB 20150 21230 RETURN 21500 REM DO A POINT TO POINT INTERPOLATION 21510 GOSUB 21100 : GOSUB 21210: IF LLX>361 OR LLY>360 GOTO 21690 21520 SLPX=LPX :SLPY=LPY :MY=(L  | |  H Display & set help level |S Status line | (from Main only)  B Paragraph reform (CTRL B)|R Ruler line |^J Help ^K Block  F Flags in rightmost column|M Margin & Tab |^Q Quick ^P Print  D Dot commands, print ctrls|P Place markers|^O Onscreen  $|V Moving text |Space Bar returns  |  |you to Main Menu.  (< < < H E L P M E N U > > >    For maximum help (full menu display),  select Help Level 3 by typing ^JH3.  This message will clear when a key is pressed.  TO HYPHENATE, PRESS -. Before pressing -, you may  move cursor: ^S=cursor left, ^D=cursor right.  If *hyphenation not desired, type ^B.  (< < < M A I N M E N U > > >   | | |  ^S char left ^D char right |^G char | ^I Tab ^B ReHb scrn X bottom scrn |DEL lin lf|A Find & Replace |^J Help ^K Block  R top file C end file C |L Find Misspelling |^Q Quick ^P Print  B top block K end block E|Q Repeat command or |^O Onscreen  0-9 marker Z up W down | key until space |Space Bar returns  P previous V last Find or Block | bar or other key |you to Main Menu.  ^K PREFIX (to cancel prefix, press SPACE bar) 9 END EDIT/SAVE: D=Done X=done,eXit S=Save,reedit Q=aSPY-LLY)/(LPX-LLX) :BY=LLY-MY*LLX 21530 STPX=(SLPX-LLX)/ABS(SLPX-LLX) 21540 IF ABS(LPX-LLX) > >      GRAPHICS MEMORY JMP BORDER ;DRAW THE BORDER AROUND THE PICTURE JMP SAVE ;SAVE THE PICTURE TO DISK JMP LOAD ;LOAD A PICTURE FROM DISK VB3ON JMP GRAFON ;INITIALIZE THE VB3 FOR GRAPHICS VB3OFF JMP GRAFOF ;PUT THE VB3 BACK INTO ASCII CHECK: JMP CHK1 ;CHECK THE PIXEL (BLACK OR WHITE) WHITE: JMP WHT1 ;WRITE WHITE PIXEL TO SCREEN BLACK: JMP BLK1 ;WRITE BLACK PIXEL TO SCREEN BDRBYT DS 1 ;BYTE GOVERNING THE BORDER CONFIGURATION PXY: DS 2 ;SCREEN ADDRESS FOR NEXT PIXEL (PXY) ; ;LOAD ZEROS INTO ME POP H POP D POP B RET ZERO: MVI E,00 ;PUT ZEROS INTO THE LEFT MARGIN PUSH B MVI B,60 CLEAR: CALL PRINT DCR B MOV A,B ORA A JNZ CLEAR POP B RET GRFDAT: PUSH B ;DUMP ONE LINE OF GRAPHICS DATA TO THE PRINTER MVI B,0FFH ;FIRST 255 BYTES OF GRAPHICS MEMORY DAT1: MOV E,M CALL PRINT DCR B INX H MOV A,B ORA A JNZ DAT1 MVI B,106 ;THE REST OF THE GRAPHICS DATA IN THE LINE (361 BYTES) DAT2: MOV E,M CALL PRINT DCR B INX H MOV A,B ORA A JNZ DAT2 POP B RET 7MNS PER ROW NEXTCB: MVI A,1 MOV M,A DCX B INX H MOV A,B ORA A JNZ NEXTCB ;GET THE NEXT COLUMN MOV A,C ORA A JNZ NEXTCB RET ;FINISHED, RETURN TO BASIC ; ;DISK SAVE AND LOAD ROUTINES FILE NAME IS LOADED INTO FCB BY THE ;SETFCB ROUTINE AND IS PASSED FROM BASIC VIA THE USR COMMAND. ; SAVE: CALL SETFCB CALL WRFILE JMP CLFILE ; LOAD CALL SETFCB CALL RDFILE JMP CLFILE ; SETFCB: LDAX D ;NO. OF CHARACTERS MOV B,A ;B IS LENGTH COUNTER INX D LDAX D ;ADDRESS OF STRING yB: MVI A,0 ;RE-INITIALIZE THE FCB MOV M,A INX H DCR B MOV A,B ORA A JNZ CLFCB LXI H,(FCB+1) ;SET SPACES INTO FCB FILE NAME SPACE MVI B,8 SPACE: MVI A,20H MOV M,A INX H DCR B MOV A,B ORA A JNZ SPACE LXI H,(FCB+9) ;SET THE FILE TYPE TO " .GRF " MVI A,'G' MOV M,A INX H MVI A,'R' MOV M,A INX H MVI A,'F' MOV M,A RET ;RETURN TO BASIC ; NOFILE: MVI C,9 ;PRINT THE NO FILE ERROR MESSAGE TO THE SCREEN LXI D,EMESS CALL 05 RET ;RETURN TO BASIC ; EMESS: DB 0fMORY FROM 9C00H TO DC00H ; MEZERO: LXI H,9C00H ;DESTINATION LXI B,4000H ;MEMORY BLOCK SIZE MCLEAR: MVI A,00 MOV M,A INX H DCX B MOV A,B ORA A JNZ MCLEAR MOV A,C ORA A JNZ MCLEAR RET ; ;DUMP THE GRAPHICS DATA TO THE PRINTER. THE GRAPHICS FORMAT ;IS X(PIXEL)=0 TO 360, Y(PIXEL)=0 TO 359. THE FIELD IS 6 ;INCHES WIDE CENTERED ON THE PAPER BY 5 INCHES HIGH. START: MVI B,45 ;NUMBER OF 8 DOT ROWS (8*45=360) LXI H,(0DC00H-(361*45)) ;STARTING ADDRESS OF DATA LINE: MVI E,1BH ; CODE: DB 1BH,0FH,1BH,33H,18H DB 1BH,43H,99,1BH,'N',14,1BH,'l',8 ;DATA TABLE FOR RETURNING LENGTH: NOP ;THE LINE PRINTER TO TEXT MODE. ; ;ROUTINE TO DRAW THE BORDER AROUND THE PICTURE. ;EACH SIDE CAN BE CONTROLED INDIVIDUALLY FROM BASIC. ;BDBYTE CONTAINS A NUMBER FROM 1 TO 15 WHICH DETERMINS ;WHAT COMBINATION OF BORDER LINES WILL BE DRAWN. ;1=LEFT,2=RIGHT,4=TOP,8=BOTTOM. ;THE DESIRED COFIGURATION IS THE SUM. ; BORDER: LXI H,BDRBYT PUSH H MOV A,M ;GET ARGUMENT ANI 1 ;IS IT LEFT W MOV L,A ;LOWER BYTE INX D LDAX D ;UPPER BYTE MOV H,A ;STRING ADDRESS IN HL LXI D,(FCB+1) ;DESTINATION OF STRING (FILE NAME) NXTCHR: MOV A,M ;MOVE THE STRING STAX D INX D INX H DCR B MOV A,B ORA A JNZ NXTCHR ; MVI C,26 ;SET THE DMA ADDRESS LXI D,9C00H CALL 05H ;CALL BDOS RET ; WRFILE: MVI C,19 ;UNCONDITIONALLY ERASE THE FILE NAME FROM THE DISK LXI D,FCB ;ADDRESS OF FCB CALL 05 ;BDOS ; MAKE: MVI C,22 ;MAKE (CREATE) FILE LXI D,FCB CALL 05 ; MVI B,80H ;NO. OF^DH,0AH,'FILE NOT FOUND',0DH,0AH,'$' ; FCB: DB 0,20H,20H,20H,20H,20H,20H,20H,20H,'GRF' DB  0,0 DB  0,0 DB 0,0,0,0 ;VB3 GRAPHICS ROUTINE. ;WRITTEN BY MALCOM WRIGHT,2-3-80 ;CONCEPTS FROM CAL OHM'S VB1B ROUTINE. ;GRFON & GRFOF WRITTEN BY B. BAILEY 9-20-82 ;MERGED WITH LGRAPH (FX80 PRINTER GRAPHICS) 10-4-83 ;ENTRY CONDITIONS ; H=VERTICAL COORDINATE x(0 TO 4 TIMES NROW) ; L= HORIZONTAL COORDINATE (0 TO 159) ;EXIT CONDITIONS ; A=USED ; B=PRESEVED ; C=BIT MASK FOR D  SETS THE LINE SPACING TO 8 DOTS CALL PRINT ;SENDS " ESC A 8 "TO THE PRINTER MVI E,'A' CALL PRINT MVI E,8 CALL PRINT MVI E,1BH ;SETS LEFT MARGIN TO ZERO CALL PRINT ;"ESC l 0 " MVI E,'l' CALL PRINT MVI E,0 CALL PRINT MVI E,1BH ;CANCEL THE SKIP-OVER MODE CALL PRINT ;"ESC O" MVI E,'O' CALL PRINT GRAPH: MVI C,05 ;LIST DEVICE MVI E,141 ;CR CALL PRINT MVI E,138 ;LF CALL PRINT MVI E,27 ;ESC CALL PRINT MVI E,'K' ;K CALL PRINT MVI E,165 ; 8 DOT GRAPHICS COMMAND FOR 42 @ JZ RIGHT ;NO, TRY RIGHT LEFT: LXI H,40075 ;STARTING ADDRESS FOR PICTURE (X=0,Y=259) MVI B,45 ;NO. OF LINES NEXTRL: MVI A,0FFH MOV M,A ;LOAD FFH INTO MEMORY LXI D,361 ;NEXT ROW DAD D ;MOVE HL TO NEXT ROW DCR B MOV A,B ORA A JNZ NEXTRL ;LOOP UNTIL B=0 RIGHT: POP H ;GET THE ARGUMENT POINTER PUSH H ;STORE IT BACK MOV A,M ;ARGUMENT ANI 2 ;IS IT RIGHT JZ TOP ;NO, TRY TOP LXI H,40435 ;ADDRESS OF RIGHT BORDER MVI B,45 ;NO. OF ROWS NEXTRR: MVI A,0FFH MOV M,A LXI D,361 ;NEXT ROW  ( RECORDS LXI H,9C00H ;ADDRESS OF FIRST RECORD ; WRSEQ: PUSH B ;WRITE THE PICTURE TO DISK PUSH H MVI C,21 ;WRITE SEQUENTIAL LXI D,FCB CALL 05 ;BDOS POP H POP B MOV A,L ;COMPUTE NEXT RECORD ADDRESS ADI 80H MOV L,A MVI A,0 ADC H MOV H,A PUSH B PUSH H MVI C,26 ;SET THE DMA TO THE NEXT RECORD ADDRESS XCHG CALL 05 ;BDOS POP H POP B DCR B ;TEST FOR END MOV A,B ORA A JNZ WRSEQ RET ; RDFILE: MVI C,15 ;OPEN FILE LXI D,FCB CALL 05 CPI 0FFH ;NO FILE ERROR CO OT ; D&E= MEMORY ADDRESS OF DOT ; H=VERTICAL COORDINATE NORMALIZED ; L=HORIZONTAL COORDINATE NORMALIZED ;LOWER LEFT CORNER: H=0 ,L=0 ;UPPER RIGHT CORNER H=4*NROW ,L=159 ;THERE ARE THREE MAIN ENTRY POINTS CALLED: ; CHECK ; WHITE ; BLACK ;SET UP FOR 80 CHARACTERS ACROSS TIMES 2. ;SET FOR "NROW" OF ROWS DOWN. ;CLEAR CHARATER MEMORY, SET ATTRIBUTE TO GRAPHICS GRAFON PUSH PSW OUT KSTAT ;TURN ON VB3 PUSH D PUSH H LXI H,0C000H LXI D,1000H CLR1 MVI A,00 MOV M,A INX H DCX D MOV A, 1 CALL PRINT MVI E,01 ; 1 (1*256+105+60=421) CALL PRINT CALL ZERO ;INSERT 60 ZEROS INTO THE LEFT MARGIN TO CENTER THE GRAPH CALL GRFDAT ;PRINT ONE LINE OF GRAPHICS DATA DCR B ;GO TO THE NEXT LINE MOV A,B ORA A ;DONE? JNZ GRAPH ;IF NOT, REPEAT TEXT: LXI H,CODE ;DONE, RESET PRINTER TO TEXT MODE MVI B,(LENGTH-CODE) LOOP: MOV E,M CALL PRINT INX H DCR B MOV A,B ORA A JNZ LOOP RET ;RETURN TO PROGRAM PRINT: MVI C,05H ;LIST DEVICE PUSH B PUSH D PUSH H CALL 05H ;BDOS  DAD D ;HL POINTS TO NEXT ADDRESS DCR B MOV A,B ORA A JNZ NEXTRR TOP: POP H PUSH H MOV A,M ANI 4 ;IS IT TOP? JZ BOTTOM ;NO, TRY BOTTOM LXI H,40076 ;YES, PRINT TOP LXI B,359 ;NO. OF COLUMNS NEXTCT: MVI A,128 ;SET THE 8 BIT MOV M,A ;PRINT IT DCX B INX H MOV A,B ORA A JNZ NEXTCT ;GET THE NEXT COLUMN MOV A,C ORA A JNZ NEXTCT ;LOOP IF BC NOT ZERO BOTTOM: POP H MOV A,M ANI 8 ;IS IT BOTTOM RZ ;RETURN IF NOT, DONE LXI H,55960 ;ADDRESS OF BOTTOM ROW LXI B,359 ;COLUDE JZ NOFILE ; MVI B,80H ;NO. OF RECORDS LXI H,9C00H RDSEQ: PUSH B ;READ THE FILE FROM DISK PUSH H MVI C,20 ;READ SEQUENTIAL LXI D,FCB CALL 05 ;BDOS POP H POP B MOV A,L ADI 80H MOV L,A MVI A,0 ADC H MOV H,A ;ADDRESS OF NEXT RECORD IN HL PUSH B PUSH H MVI C,26 ;SET DMA TO ADDRESS OF NEXT RECORD XCHG CALL 05 ;BDOS POP H POP B DCR B MOV A,B ORA A JNZ RDSEQ RET ; CLFILE: MVI C,16 ;CLOSE THE FILE LXI D,FCB CALL 05 ;BDOS LXI H,FCB MVI B,24H CLFCD ORA E JNZ CLR1 LXI H,0D000H ;ADDRESS OF ATTRIBUTE LXI D,1000H CLR2 MVI A,00 ;ATTRIBUTE IN GRAPHICS MODE MOV M,A MVI A,31 ;SET LINE 31 TO THE BOTTOM OF THE SCREEN STA 0FBA5H ;BOTTOM OF SCREEN LOCATION FOR VB3 OUT 0D6H INX H DCX D MOV A,D ORA E JNZ CLR2 POP H POP D OUT KDATA ;TURN VB3 OFF POP PSW RET ;CLEAR CHARACTER MEMORY, SET ATTRIBUTE TO ASCII GRAFOF PUSH PSW OUT KSTAT PUSH D PUSH H LXI H,0C000H LXI D,1000H CLR3 MVI A,20H ;SPACE BAR MOV M,A INX H W TIMES 80 MVI D,0 MOV L,E ;L = QUOTIENT MOV H,D DAD H ;X2 DAD H ;X4 DAD D ;X5 DAD H ;X10 DAD H ;X20 DAD H ;X40 DAD H ;X80 XCHG ;SAVE 80*NROW POP H ;FIND ACTUAL DELTA PUSH H ORA A ;CLEAR CARRY MOV A,L ;X:AXIS RAR ;DIVIDE BY 2 MOV L,A MOV A,C RAL ;UPDATE MASK INDEX MOV C,A ;CREATE ACTUAL MEMORY ADDRESS FOR PIXEL MVI H,0 ;H&L= WIDTH DAD D ;ADD TO HEIGHT FOR OFFSET LXI D,VID ;GET VB3 ADDRESS DAD D ;OFFSET + BASE ADDRESS XCHG ;D&E= ACTUAL MEMORY ADDRESS +100 REM PROGRAM NAME: FFT 110 REM COMPUTES FORWARD OR INVERSE FFT 120 REM 130 REM BY R.F. COBB 1983 140 REM BASED ON A FORTRAN ALGORITHM BY E.O. BRIGHAM 150 REM 160 DIM X(1024),Y(1024) 170 TW=2 : N=0 175 PT=2*ATN(1) : REM PT=Pi/2 180 GOSUB 3730 : PRINT : GOTO 500 : REM START FIRST RUN WITH DATA LOAD 190 GOSUB 3730 : PRINT 200 REM 210 REM 220 REM *MENU 230 REM 240 REM 250 PRINT " (L)OAD DATA" 260 PRINT " (F)ORWARD FFT (T TO F)" 270 PRINT " (I)NVERSE FFT (F TO T)" 280 A: T2=Y(K) 1380 X(K)=X(I) : Y(K)=Y(I) 1390 X(I)=T1 : Y(I)=T2 1400 NEXT K 1410 PRINT CHR$(7), CHR$(7) 1420 IF M$="I" THEN GOSUB 1700 : GOSUB 1760 : PRINT : PRINT 1425 IF M$="F" THEN GOSUB 1800 : PRINT : PRINT 1430 PRINT : PRINT "TRANSFORM COMPLETE " : PRINT 1450 IF M$="I" THEN PRINT "DT=";DT 1460 IF M$="F" THEN PRINT "DF=";DF 1470 PRINT : PRINT : GOTO 200 1500 REM 1510 REM * UNSCRAMBLING ALGORITHM 1520 REM 1530 J1=X : Z=0 1540 FOR Y=1 TO G : J2=INT(J1/2) 1550 Z=2*Z+J1-2*J2 1560 J1=J2 : NEXT ` DCX D MOV A,D ORA E JNZ CLR3 LXI H,0D000H ;ADDRESS OF ATTRIBUTE LXI D,1000H CLR4 MVI A,03 MOV M,A INX H DCX D MOV A,D ORA E JNZ CLR4 POP H POP D OUT KDATA POP PSW RET ;CHECK THE PIXEL FOR BLACK OR WHITE. SET ZERO FLAG. CHK1: CALL CNURT ;ZERO FLAG=1 IF WHITE ;ZERO FLAG=0 IF BLACK ANA C RET ;SET PIXEL TO WHITE AT GIVEN COORDINATE. WHT1: CALL CNURT ;CHANGE TO WHITE ORA C ;ADD DOT STAX D RET ;SET PIXEL TO BLACK AT GIVEN COORDINATE. BLK1: CALL CNURT ;CHANG ;GET BIT MASK MVI B,0 ;B&C= MASK INDEX LXI H,BTBL ;START OF MASK TABLE DAD B ;ADD INDEX MOV A,M ;GET MASK ;RETURN AND GET VB3 BYTE POP H POP B MOV C,A ;C=MASK LDAX D RET ;MASK BIT TABLE (2*4 PIXELS) BTBL: DB 80H DB 8 DB 20H D+B 2 DB 40H DB 4 DB 10H DB 1 END+DAD D ;ADD TO HEIGHT FOR OFFSET LXI D,VID ;GET VB3 ADDRESS DAD D ;OFFSET + BASE ADDRESS XCHG ;D&E= ACTUAL MEMORY ADDRESS PRINT " (P)RINT DATA" 290 PRINT " (S)TORE DATA" 300 PRINT " (E)XIT" : PRINT : INPUT M$ 310 IF M$="L" GOTO 550 320 IF M$="F" THEN DF=1/(N*DT) :GOTO 1000 330 IF M$="I" THEN DT=1/(N*DF) : GOSUB 1700 :GOTO 1000 340 IF M$="P" GOTO 3000 350 IF M$="S" GOTO 2000 360 IF M$="E" GOTO 9000 370 PRINT "NOT A VALID COMMAND" : GOTO 200 500 REM 510 REM 520 REM * LOAD DATA 530 REM 540 REM 550 INPUT "NAME OF INPUT FILE: " ; IN$ 560 OPEN"I",#1,IN$ 580 INPUT "NUMBER OF INPUT DATA POINTS,DF,DT";N,DF,DT 590 FOR: RETURN 1570 PR# 0 : PRINT : DF=1/(N*DF) 1580 IF M$="I" THEN PRINT "DT=";DT 1590 IF M$="F" THEN PRINT "DF=";DF 1600 PRINT : GOTO 200 1690 REM 1700 REM * CONJUGATE SUBROUTINE 1710 REM 1730 FOR I=1 TO N : Y(I)=-Y(I) : NEXT I : RETURN 1740 REM 1750 REM * NORMALIZE INVERSE FFT 1760 REM 1770 REM 1790 FOR I=1 TO N : X(I)=X(I)*DF : Y(I)=Y(I)*DF : NEXT : RETURN 1800 REM 1810 REM 1820 REM * NORMALIZE FORWARD FFT 1830 REM 1840 REM 1860 FOR I=1 TO N : X(I)=X(I)*DT : Y(I)=Y(I)*DT : NEXT : RETURN 2 E TO BLACK ORA C ;ADD DOT XRA C ;MAKE BLACK STAX D RET ;CONVERT H&L AS Y&X POSITIONS INTO ACTUAL MEMORY ADDRESS. CNURT: PUSH B ;SAVE B&C ;GET PXY DATA LHLD PXY ;PXY IS IN H&L ;NORMALIZE X-AXIS MOV A,L CPI 0FFH ;BELOW LIMIT, NEGATIVE. JNZ X1 MVI A,(80*2)-1 ;RESET TO RIGHT SIDE X1: CPI 80*2 ;ABOVE UPPER LIMIT JC X2 XRA A ;RESET TO LEFT SIDE X2: MOV L,A ;NORMALIZE Y-AXIS MOV A,H CPI 0FFH ;BELOW LIMIT, NEGATIVE. JNZ Y1 MVI A,(NROW*4)-1 ;RESET TO TOP Y1: CPI NROW*4 ;ABOVE op typing. Press space bar:  If page break display is OFF (^OP command) or edit  was started with N command, then Status Line shows  FC=nnnn FL=nnnn in place of PAGE n LINE n .   FC=nnnn cursor position in characters (bytes) from  beginning of file  FL=nnnn cursor position in file lines from beginning  of file, including dot command lines   space bar:  ***** FLAG CHARACTERS (rightmost column of screen) *   I=1 TO N : INPUT#1,X(I),Y(I) : NEXT 600 CLOSE#1 610 PP=B*ATN(1)/N : REM THIS IS 2*Pi/N 630 PRINT : PRINT "DATA LOADED" 650 PRINT : GOTO 200 660 REM 1000 REM 1010 REM 1020 REM * FFT ALGORITHM 1030 REM 1040 REM 1042 V$=M$ : REM TIME/FREQUENCY DOMAIN FLAG FOR USE IN PRINTOUT 1045 IF N<1 THEN PRINT :PRINT "NO DATA IN FILE" :PRINT : GOTO 200 1048 PRINT : PRINT N; "POINT TRANSFORM IN PROGRESS" 1050 G=INT(LOG(N)/LOG(2)+.5) 1060 N2=INT(N/2) 1070 G1=G-1 1080 K=0 1090 FOR L=1 TO G 1100 M1=1.5  000 REM 2010 REM 2020 REM * STORE DATA 2030 REM 2040 REM 2050 INPUT "FILE NAME: ";F$ 2060 OPEN"O",#2,F$ 2070 FOR I=1 TO N 2080 PRINT#2,X(I);Y(I); :NEXT 2090 PRINT#2,DF,DT,N 2100 CLOSE #2 2130 PRINT : PRINT "DONE": PRINT : GOTO 200 3000 REM 3010 REM 3020 REM * PRINTOUT 3030 REM 3040 REM 3050 GOSUB 3730 : PRINT: INPUT "(C)RT OR (P)RINTER? ";A$ 3055 PRINT :INPUT "(R)ECTANGULAR OR (P)OLAR? ";RP$ 3060 PRINT : PRINT " START, END, INCREMENT":PRINT 3070 PRINT : INPUT ST,SE,SI 3080 GOSU  UPPER LIMIT JC Y2 XRA A ;RESET TO BOTTOM Y2: MOV H,A ;REVERSE(FLIP-OVER) Y-AXIS PUSH H ;SAVE H&L NORMALIZED MOV C,A MVI A,(NROW*4)-1 SUB C ;FLIP OVER ;FIND ACTUAL DELTA HIGHT MVI C,0 ;CLEAR MASK INDEX ORA A ;CLEAR CARRY RAR ;DIVIDE BY 2 MOV B,A ;SAVE QUOTIENT MOV A,C RAL ;UPDATE INDEX MOV C,A MOV A,B ;GET QUOTIENT ORA A ;CLEAR CARRY RAR ;DIVIDE BY 2 MOV E,A ;SAVE DELTA HEIGHT MOV A,C RAL ;UPDATE INDEX MOV C,A ;SAVE MASK INDEX(REMAINDER) ;COMPUTE VERTICAL RO****  < line ends in "hard" carriage return, entered by user  space this line break arose from word wrap or paragraph  reform, and may moved on subsequent reform  + this line of document continues on next screen line  - next line will overprint this line  ? unrecognized or incomplete dot command  M Merge-Print (optional feature) dot command  P page break  : this screen line is before beginning of document  . 1110 FOR I=1 TO N2 1120 M=INT(K/(2^G1)) 1130 IF M=M1 GOTO 1180 1140 X=M: GOSUB 1510 : P=Z 1150 V=PP*P 1160 C=COS(V) : S=SIN(V) 1170 M1=M 1180 K1=K+1 1190 K2=K1+N2 1200 T1=X(K2)*C+Y(K2)*S 1210 T2=Y(K2)*C-X(K2)*S 1220 X(K2)=X(K1)-T1 1230 Y(K2)=Y(K1)-T2 1240 X(K1)=X(K1)+T1 1250 Y(K1)=Y(K1)+T2 1260 K=K+1 1270 NEXT I 1280 K=K+N2 1290 IF K 50 THEN PRINT CHR$ (140);: GOSUB 3400 3140 IF A$="C" AND QQ > 20 THEN GOSUB 3500 3150 NEXT Type text of item, without using RETURN.  At end of item, press RETURN. Left margin resets.  Press RETURN again if blank line desired.  press space bar:  ***** RULER LINE *****   L----!----!----!----!----!----!----!----!---------R   L Left margin (set with ^OL)  R Right margin (set with ^OR)  ! regular tab stop (set with ^OI, clear with ^ON)  # decimal tab stop (set with ^OI, clear with ^ON)  - other positions between margins  1:!vji+: vi+͈C8Lj͹j1Bj*&vZ~###j6͝_ͯj͝_lj!vw?1Ê͑j:d5vLz>v >͗L>:*#ڤj=w<6Rj6#w#w#wR}))v~wXj~~wXjj͹jj>v&>?1WDM5kʊz2'͈C26k!vjK2'?1!]AM͈Cko L{lk{XkPk|gk!gk 29  DB XP11 AND 0FFH 02D8 23  DB '#' 02D9 86  DB (XP12 SHR 8) +128 02DA 2F  DB XP12 AND 0FFH 02DB 3E  DB '>' 02DC 86  DB (XP13 SHR 8) +128 02DD 35  DB XP13 AND 0FFH 02DE 3D  DB '=' 02DF 86  DB (XP15 SHR 8) +128 02E0 44 5 DB XP15 AND 0FFH 02E1 3C3D DB '<=' 02E3 86  DB (XP14 SHR 8) +128 02E4 3C  DB XP14 AND 0FFH 02E5 3C  DB '<' 02E6 86  DB (XP16 SHR 8) +128 02E7 4A  DB X 3155 IF V$= "I" THEN PRINT "TIME INCREMENT = ";DT 3156 IF V$= "F" THEN PRINT "FREQUENCY INCREMENT = ";DF 3160 PRINT "END.. PRESS TO CONTINUE": 3161 B$=INKEY$ :C$=CHR$(30) 3162 IF B$TABLE 02F9 BE u CMP M ;IF MATCH, TEST NEXT 02FA CAF102 JZ EX1 ;02DAH 02FD 3E7F MVI A,7FH ;ELSE SEE IF BIT 7 02FF 1B ( DCX D ;OF TABLE IS SET, WHICH 0300 BE N CMP M ;IS THE JUMP ADDR. (HI) 0301 DA1503 JC EX5 ;02FEH C:YES MATCHED  -EX2: ;02ED ;NC:NO FIND JUMP ADDR. 0304 23  INX H 0305 BE 1 CMP M 0306 D20403 JNC EX2 ;02EDH 0309 23 * INX H ;BUMP THE NEXT TABLE ITEM 030A D1 n) : RETURN 3700 REM 3710 REM * HOME 3720 REM 3730 FOR CLS = 1 TO 33 :PRINT : NEXT CLS : RETURN 9000 END   3533 B$=CHR$(0) 3535 GOSUB 3730 : PRINT "I"; 3540 IF RP$="P" THEN PRINT TAB(16) "MAG" TAB(30) "PHASE" : GOTO 3560 3550 PRINT TAB(15) "REAL" TAB(28) "IMAGINARY" 3560 QQ=0: RETURN 3600 REM 3610 REM * RECTANGULAR TO POLAR CONVERSION 3620 REM 3630 MA=SQR(X(I+1)*X(I+1)+Y(I+1)*Y(I+1)) 3640 DN=MA+X(I+1) 3650 IF DN=0 THEN PH=PT*(1-SGN (X(I+1))) : RETURN 3660 PH=2*ATN(Y(I+1)/DN source of text for last block move or copy.  press space bar:  IF THIS DISPLAYS YOU ARE USING WRONG VERSION OF WSMSGS.OVR ext for last block move or copy.  press space bar:  IF THIS DISPLAYS YOU ARE USING WRONG VERSION se markers can be moved (^KV), copied  (^KC), deleted (^KY), or written to a file (^KW).   ^QP moves cursor to its position before preceding command.   ^QV moves cursor to start of last find/replace, or to   2C6 544F DB 'TO' 02C8 84  DB (FR1 SHR 8) +128 02C9 EC  DB FR1 AND 0FFH 02CA 8A DB (QWHAT SHR 8) +128 02CB 59  DB QWHAT AND 0FFH  BTAB6: ;02B7 "STEP" IN "FOR" 02CC 53544550 DB 'STEP' 02D0 84  DB (FR2 SHR 8) +128 02D1 F8  DB FR2 AND 0FFH 02D2 84  DB (FR3 SHR 8) +128 02D3 FE  DB FR3 AND 0FFH  FTAB8: ;02BF RELATIONAL OPERATORS 02D4 3E3D DB '>=' 02D6 86  DB (XP11 SHR 8) +128 02D7' X POP D ;RESTORE STRING POINTER 030B C3ED02 JMP EX0 ;02D8H TEST AGIANST NEXT ITEM  ?EX3: ;02F7 030E 3E7F MVI A,7FH ;PARTIAL MATCH, FIND  EX4: ;02F9 0310 23 & INX H ;JUMP ADDR., WHICH IS 0311 BE ; CMP M ;FLAGED BY BIT 7. 0312 D21003 JNC EX4 ;02F9H  EX5: ;02FE 0315 7E ) MOV A,M ;LOAD HL WITH THE JUMP 0316 23 & INX H ;ADDR. FROM THE TABLE 0317 6E - MOV L,M 0318 E67F ANI 7FH ;MASK OFF ћ  ;  & ;THERE ARE 3 MORE ENTRIES IN 'RUN':  E ;'RUNNXL' FINDS THE NEXT LINE, STORES ITS ADDRESS AND EXECUTES IT.  = ;'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT.  2 ;'RUNSML' CONTINUES THE EXECUTION ON SAME LINE.   ;   ;  C ;'GOTO EXPR(CR)' EVALUATES THE EXPRESSION. FIND THE TARGET LINE,  " ;AND JUMP TO 'RUNTSL' TO DO IT.   ;   < PUSH H 0360 CD0604 CALL L03E5 ;03E5H 0363 D5  PUSH D 0364 C5 PUSH B 0365 115C00 LXI D,5CH ;DE=FCB ADDRESS 0368 0E0F MVI C,0FH ;OPEN FILE 036A CD0500 CALL 5 ;CALL BDOS 036D FEFF CPI 0FFH 036F CA6A01 JZ QHOW ;0166H 0372 AF H XRA A 0373 327C00 STA 7CH 0376 11DE0C LXI D,TXTUNF ;09D5H  %DSKRD: ;035E READ THE DISK 0379 D5 R PUSH D 037A 0E1A MVI C,1AH ;SET DMA ADDRESS 037C CD0500 CALL 5 ;CALB2 ORA A 03DB C26A01 JNZ QHOW ;0166H 03DE D1 K POP D 03DF 3ADF0C LDA TXTUNF+1 ;09D6H WRITE TO DISK UNTIL 03E2 BA CMP D ;TXTUNF 03E3 DAF803 JC CLFIL ;03D9H 03E6 C2F003 JNZ DSKLOOP ;03D1H 03E9 3ADE0C LDA TXTUNF ;09D5H 03EC BB , CMP E ; 03ED DAF803 JC CLFIL ;03D9H  6DSKLOOP: ;03D1 03F0 218000 LXI H,80H 03F3 19  DAD D 03F4 EB * XCHG 03F5 C3CC03 JMP DSKWR ;03ADH  CLFIL: ;03D9 03F8 0E޷BIT 7 031A 67  MOV H,A 031B F1 , POP PSW ;CLEAN UP THE GARBAGE AND 031C E9  PCHL ;GO DO IT.   ;   ;  ; ;WHAT FOLLOWS IS THE CODE TO EXECUTE DIRECT AND STATMENT  ; ;COMMANDS. CONTROL IS TRANSFERED TO THESE POINTS VIA THE  < ;COMMAND TABLE LOOKUP CODE OF 'DIRECT' AND 'EXEC' IN LAST  6 ;SECTION. AFTER THE COMMAND IS EXECUTED, CONTROL IS  ( ;TRANSFERED TO OTHER SECTIONS AS FOLLOW NEW: ;0306 +++NEW(CR)+++ 031D CD530A CALL ENDCHK ;07DCH 0320 21E00C LXI H,TXTBGN ;09D7H 0323 22DE0C SHLD TXTUNF ;09D5H  fSTOP: ;030F +++STOP(CR)+++ 0326 CD530A CALL ENDCHK ;07DCH 0329 C38501 JMP RSTART ;0181H  wRUN: ;0315 +++RUN(CR)+++ 032C CD530A CALL ENDCHK ;07DCH 032F 11E00C LXI D,TXTBGN ;09D7H FIRST SAVED LINE  ^RUNNXL: ;031B +++RUNNXL++ 0332 210000 LXI H,0 ;FIND WHATEVER LINE # 0335 CD140B C<L BDOS 037F 0E14 MVI C,14H ;READ SEQUENTIAL 0381 115C00 LXI D,5CH ;DE=FCB ADDRESS 0384 CD0500 CALL 5 ;CALL BDOS 0387 FE01 CPI 1 ;ERROR CODE? 0389 DA9E03 JC NEWFIL ;0381H 038C C26A01 JNZ QHOW ;0166H ERROR 038F 0E10v MVI C,10H ;CLOSE FILE 0391 115C00 LXI D,5CH ;DE=FCB ADDRESS 0394 CD0500 CALL 5 ;CALL BDOS 0397 D1 # POP D ;RESTORE REGISTERS 0398 C1  POP B 0399 D1  POP D 039A E1 ( POP H 039B CD7C0C CALL FINISH "x10 MVI C,10H ;CLOSE FILE 03FA 115C00 LXI D,5CH ;DE=FCB ADDRESS 03FD CD0500 CALL 5 ;CALL BDOS 0400 C1 # POP B ;RESTORE REGISTERS 0401 D1  POP D 0402 E1 & POP H 0403 CD7C0C CALL FINISH  FL03E5: ;03E5 0406 215C00 LXI H,5CH 0409 3600 MVI M,0  8L03EA: ;03EA FILL 64H BYTES WITH SPACES (20H) 040B 23 M INX H 040C 3620 MVI M,' ' ;20H 040E 3E64 MVI A,64H 0410 BD  CMP L 0411 C20B04 JNZ S:   ;   ;  6 ;FOR 'LIST', 'NEW', AND 'STOP', GO BACK TO 'RSTART'  < ;FOR 'RUN', GO EXECUTE THE FIRST STORED LINE IF ANY, ELSE   ;GO BACK TO 'RSTART'.  7 ;FOR 'GOTO' AND 'GOSUB' : GO EXECUTE THE TARGET LINE  ; ;FOR 'RETURN' AND 'NEXT': GO BACK TOO SAVED RETURN LINE.  9 ;FOR ALL OTHERS: IF 'CURRENT' ->0, GO TO 'RSTART',ELSE  / ;GO EXECUTE NEXT COMMAND. (THIS IS DONE IN 'FI pJALL FL1 ;085FH C:PASSED TXTUNF, QUIT. 0338 DA8501 JC RSTART ;0181H  %RUNTSL: ;0324 +++RUNTSL+++ 033B EB J XCHG 033C 228686 SHLD CURRNT ;09C1H SET 'CURRENT'->LINE # 033F EB  XCHG 0340 13 " INX D ;BUMP PASS LINE # 0341 13  INX D  RUNSML: ;032B +++RUNSML+++ 0342 CD8D0C CALL CHKIO ;0985H FIND COMMAND IN TAB2 0345 212102 LXI H,TAB2-1 ;0219H AND EXICUTE IT. 0348 C3ED02 JMP EX0 ;02D8H  GOTO: ;0334 +++G  NEWFIL: ;0381 039E D1 , POP D 039F 218000 LXI H,80H 03A2 19  DAD D 03A3 EB * XCHG 03A4 C37903 JMP DSKRD ;035EH  -SAVE: 03A7 CD740C CALL IGNBLK 03AA E5 5 PUSH H 03AB CD0604 CALL L03E5 ;03E5H 03AE D5  PUSH D 03AF C5 PUSH B 03B0 115C00 LXI D,5CH ;DE=FCB ADDRESS 03B3 0E13 MVI C,13H ;DELETE FILE 03B5 CD0500 CALL 5 ;CALL BDOS 03B8 115C00 LXI D,5CH ;DE=FCB ADDRESS 03BB 0E16 M ;( L03EA ;03EAH FILL LOOP RETURN 0414 23 K INX H ; THE NEXT 3 BYTES "TBI" 0415 3654 MVI M,'T' ;54H 0417 23 1 INX H 0418 3642 MVI M,'B' ;42H 041A 23 ) INX H 041B 3649 MVI M,'I' ;49H  L03FC: ;03FC 041D 23 g INX H ;FILL FROM "TBI" TO 5C6B WITH 00 041E 3600 MVI M,0 0420 3E6B MVI A,6BH 0422 BD G CMP L 0423 C21D04 JNZ L03FC ;03FCH 0426 215D00 LXI H,5DH  L0408: ;0408 0429 1A  LDAX ԟ NISH'.)   ;   ;  / ;+++NEW+++STOP+++RUN (& FRIENDS)+++& GOTO+++   ;  A ;'NEW(CR)' SETS 'TXTUNF' TO POINT TO THE BEGINING OF TEXT AREA   ;  $ ;'STOP(CR)' GOES BACK TO 'RSTART'  @ ;'RUN(CR)' FINDS THE FIRST STORED LINE, STORE ITS ADDRESS (IN  : ;'CURRNT' AND START TO EXECUTE IT. NOTE THAT ONLY THOSE  9 ;COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM. d3OTO EXPR+++ 034B CD640C CALL EXPR ; 034E D5 PUSH D ;SAVE FOR ERROR ROUTINE 034F CD530A CALL ENDCHK ;07DCH MUST FIND A CR 0352 CD0C0B CALL FNDLN ;0857H FIND THE TARGET LINE 0355 C26B01 JNZ AHOW ;0167H NO SUCH LINE # 0358 F1 L POP PSW ;CLEAR THE "PUSH DE" 0359 C33B03 JMP RUNTSL ;0324H GO DO IT   ;  4 ;THE FOLLOWING ROUTINES DO THE DISK COMMUNICATION   ;  .LOAD: 035C CD740C CALL IGNBLK 035F E5 VI C,16H ;MAKE A FILE 03BD CD0500 CALL 5 ;CALL BDOS 03C0 FEFF CPI 0FFH ;ERROR? 03C2 CA6A01 JZ QHOW ;0166H 03C5 AF H XRA A 03C6 327C00 STA 7CH 03C9 11DE0C LXI D,TXTUNF ;09D5H  )DSKWR: ;03AD WRITE TO THE DISK 03CC D5 PUSH D 03CD 0E1A MVI C,1AH ;SET DMA ADDRESS 03CF CD0500 CALL 5 ;CALL BDOS 03D2 0E15 MVI C,15H ;WRITE SEQUENTIAL 03D4 115C00 LXI D,5CH ;DE=FCB ADDRESS 03D7 CD0500 CALL 5 ;CALL BDOS 03DA B7 & D 042A FE0D CPI 0DH 042C C8 RZ 042D FE21 CPI '!' ;21H 042F DA590A JC QWHAT ;07E0H 0432 FE5B CPI 5BH 0434 D2590A JNC QWHAT ;07E0H 0437 77  MOV M,A 0438 23  INX H 0439 13 , INX D 043A 3E65 MVI A,65H 043C BD 3 CMP L 043D C22904 JNZ L0408 ;0408H 0440 C9  RET   ;   ;   ;+++LIST+++& PRINT+++   ;   ;LIST HAS 2 FORMS  LLL PRTLN ;08EDH PRINT THE LINE 0450 CD8D0C CALL CHKIO ;0985H STOP IF ^C 0453 CD140B CALL FL1 ;085FH FIND NEXT LINE 0456 C34A04 JMP LS1 ;0429H AND LOOP BACK  qPRINT: ;0438 0459 0E06 MVI C,6 ;C= # OF SPACES 045B CD520C CALL PG0 ;IF NULL LIST & ";" 045E 3B  DB ';' 045F 06 u DB (PR2-$-1) 0460 CD5A0C CALL CRLF1 ;GIVE (CR-LF) AND 0463 C34203 JMP RUNSML ;032BH CONTINUE SAME LINE  *PR2: ;0443 ; 0466 CD520C CALL PG0 ) SAVED IN 'STKGOS'. THE OLD 'STKGOS' IS  ? ;SAVED IN THE STACK. IF WE ARE IN THE MAIN ROUTINE, 'STKGOS'  > ;IS ZERO (THIS WAS DONE BY THE "MAIN" SECTION OF THE CODE),  < ;BUT WE STILL SAVE IT AS A FLAG FOR NO FURTHER 'RETURN'S.   ;  = ;'RETURN(CR)' UNDOES EVERYTHING THAT 'GOSUB' DID, AND THUS  = ;RETURN THE EXECUTION TO THE COMMAND AFTER THE MOST RECENT  0 ;'GOSUB'. IF 'STDGOS' IS 0, IT INDICATES THAT WG ? ;'FOR VAR=EXP1 TO EXP2 STEP EXP3' AND 'FOR VAR=EXP1 TO EXP2'   ;(WHERE EXP3 ASSUME 1).  = ;TB1 WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE  : ;CURRENT VALUE OF EXP1. IT ALSO EVALUATES EXP2 AND EXP3  7 ;AND SAVE ALL TOGATHER WITH THE TEXT POINTER ETC. IN  > ;THE 'FOR' SAVE AREA. WHICH CONSISTS OF 'LOPVAR', 'LOPINC',  A ;'LOPLMT', 'LOPLN', AND 'LOPPT'. IF THERE IS ALREADY SOMETHING  $ ;'LIST(CR)' LISTS ALL SAVED LINES  * ;'LIST #(CR)' START LIST AT THIS LINE #   ;YOU CAN STOP LIST WITH ^C   ;  6 ;PRINT COMMAND IS 'PRINT ....;' OR 'PRINT ....(CR)'  > ;WHERE "...." IS A LIST OF EXPRESSIONS, FORMATS, BAKARROWS,  5 ;AND STRINGS. THESE ITEMS ARE SEPARATED BY COMMAS.   ;  > ;A FORMAT IS A FOUND SIGN FOLLOWED BY A NUMBER. IT CONTROLS   ;THE NUMBER OF SPACESi;IF NULL, LIST (CR) 0469 0D06 DB 0DH,(PR0-$-1) 046B CD5A0C CALL CRLF1 ;ALSO GIVE CR-LF AND 046E C33203 JMP RUNNXL ;031BH GO TO NEXT LINE  EPR0: ;044C 0471 CD520C CALL PG0 ;ELSE IS IT FORMAT? 0474 23  DB '#' 0475 07 H DB (PR1-$-1) 0476 CD640C CALL EXPR ;YES, EVALUATE EXPR. 0479 4D U MOV C,L ;AND SAVE IT IN C. 047A C38304 JMP PR3 ;045AH LOOK FOR MORE TO PRINT  7PR1: ;0454 047D CD440B CALL OTSTG ;088BH OR IS E  - ;NEVER HAD A 'GOSUB' AND IS THUS AN ERROR.   ;   ;    {GOSUB: ;0470 049F CD010C CALL PUSHA ;0934H SAVE THE CURRENT "FOR" 04A2 CD640C CALL EXPR ;PARAMETERS 04A5 D5 PUSH D ;AND TEXT POINTER 04A6 CD0C0B CALL FNDLN ;0857H FIND THE TARGET LINE 04A9 C26B01 JNZ AHOW ;0167H NOT THERE SAY "HOW?" 04AC 2A8686 LHLD CURRNT ;09C1H FOUND IT, SAVE OLD 04AF E5 PUSH H ;'CURRNT' OLD 'STKGOS' n7 ;IN THE SAVE AREA (THIS IS INDICATED BY A NON-ZERO  ; ;'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK  & ;BEFORE THE NEW ONE OVER WRITES IT.  < ;TB1 WILL THEN DIG IN THE STACK AND FIND OUT IF THIS SAME  = ;VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP.  @ ;IF THAT IS THE CASE, THEN THE OLD 'FOR' LOOP IS DEACTIVATED.   ;(PURGED FROM THE STACK.)   ;   ;'NEXT VAR' SE 9( THE VALUE OF A EXPRESSION IS GOING TO  < ;BE PRINTED. IT STAYS EFFECTIVE FOR THE REST OF THE PRINT  = ;COMMAND UNLESS CHANGED BY ANOTHER FORMAT. IF NO FORMAT IS  ( ;SPECIFIED. 6 POSITIONS WILL BE USED.   ;  8 ;A STRING IS QUOTED IN A PAIR OF SINGLE OR A PAIR OF   ;DOUBLE QUOTES.   ;  3 ;A BACK-ARROW MEANS GENERATE A (CR) WITHOUT (LF)   ;   ;A (CRLF) IS  EIT A STRING? 0480 C39404 JMP PR8 ;0467H IF NOT, MUST BE EXPR.  PR3: ;045A 0483 CD520C CALL PG0 ;IF ",", GO FIND NEXT 0486 2C06 DB ',',(PR6-$-1) 0488 CD400A CALL FIN ;07CDH IN THE LIST 048B C37104 JMP PR0 ;044CH  LPR6: 048E CD5A0C CALL CRLF1 ;LIST ENDS 0491 CD7C0C CALL FINISH  EPR8: ;0467 0494 CD640C CALL EXPR ;EVALUATE THE EXPR 0497 C5 @ PUSH B 0498 CD740B CALL PRTNUM ;08B1H PRINT THE VALUE 0 - 04B0 2A8886 LHLD STKGOS ;09C3H 04B3 E5 c PUSH H 04B4 210000 LXI H,0 ;AND LOAD NEW ONES 04B7 228E86 SHLD LOPVAR ;09C9H 04BA 39 e DAD SP 04BB 228886 SHLD STKGOS ;09C3H 04BE C33B03 JMP RUNTSL ;0324H THEN RUN THAT LINE  RETURN: ;0490 04C1 CD530A CALL ENDCHK ;07DCH THERE MUST BE A CR 04C4 2A8886 LHLD STKGOS ;09C3H OLD STACK POINTER 04C7 7C % MOV A,H ;0 MEANS NOT EXIST 04C8 B5 . ORA L 04C9 CA590A JZ QWHAT ;07E0H SO WE 0RVES AS THE LOGICAL (NOT NECESSARILY PHYSICAL)  ? ;END OF THE 'FOR' LOOP. THE CONTROL VARIABLE VAR. IS CHECKED  < ;WITH THE 'LOPVAR'. IF THEY ARE NOT THE SAME, TB1 DIGS IN  = ;THE STACK TO FIND THE RIGHT ONE AND PURGES ALL THOSE THAT  9 ;DID NOT MATCH EITHER WAY, TB1 THEN ADDS THE 'STEP' TO  < ;THAT VARIABLE AND CHECK THE RESULT WITH THE LIMIT. IF IT  : ;IS WITHIN THE LIMIT, CONTROL LOOPS VACK TO THE COMMAND    *GENERATED AFTER THE ENTIRE LIST HAS BEEN  > ;PRINTED OR IF THE LIST IS A NULL LIST. HOWEVER IF THE LIST  . ;ENDED WITH A COMMA NO (CRLF) IS GENERATED.   ;  LIST: ;0420 TEST IF THERE IS A # 0441 CD4001 CALL TSTNUM ;013EH IF NO # WE GET A 0 0444 CD530A CALL ENDCHK ;07DCH 0447 CD0C0B CALL FNDLN ;0857H FIND THIS OR THE NEXT LINE  TLS1: ;0429 044A DA8501 JC RSTART ;0181H C:PASSED TXTUNF 044D CDB60B CA49B C1 8 POP B 049C C38304 JMP PR3 ;045AH MORE TO PRINT?   ;   ;   ;+++GOSUB+++& RETURN+++   ;  9 ;'GOSUB EXPR;' OR 'GOSUB EXPR (CR)' IS LIKE THE 'GOTO'  A ;COMMAND, EXCEPT THAT THE EXECUTION CAN BE CONTINUED AFTER THE  < ;SUBROUTINE 'RETURN'. IN ORDER THAT 'GOSUB' CAN BE NESTED  8 ;(AND EVEN RECURSIVE), THE SAVE AREA MUST BE STACKED.   ;THE STACK POINTER IS SAY "WHAT?" 04CC F9 " SPHL ;ELSE, RESTORE IT 04CD E1 J POP H 04CE 228886 SHLD STKGOS ;09C3H AND THE OLD 'STKGOS' 04D1 E1 J POP H 04D2 228686 SHLD CURRNT ;09C1H AND THE OLD 'CURRNT' 04D5 D1 POP D ;OLD TEXT POINTER 04D6 CDE50B CALL POPA ;0918H OLD "FOR" PARAMETERS 04D9 CD7C0C CALL FINISH ;AND WE ARE BACK HOME   ;   ;   ;+++FOR+++& NEXT+++   ;   ;'FOR' HAS TWO FORMS: 5C ;FOLLOWING THE 'FOR'. IF OUTSIDE THE LIMIT, THE SAVE AREA  & ;IS PURGED AND EXECUTION CONTINUES.   ;   ;    FOR: ;04A9 04DC CD010C CALL PUSHA ;0934H SAVE THE OLD SAVE AREA 04DF CD270A CALL SETVAL ;07BAH SET THE CONTROL VAR. 04E2 2B DCX H ;HL IS ITS ADDRESS 04E3 228E86 SHLD LOPVAR ;09C9H SAVE THAT 04E6 21C502 LXI H,TAB5-1 ;USE "EXEC" TO LOOK 04E9 C3ED02 JMP EX0 ;02D8H FOR THE WORDi MOV B,H 0531 4D . MOV C,L 0532 210A00 LXI H,0AH 0535 19 H DAD D 0536 CDD60B CALL MVDOWN ;0909H AND PURGE 10 WORDS 0539 F9  SPHL ;IN THE STACK  NFR8: ;0503 053A 2A9686 LHLD LOPPT ;09D1H JOB DONE RESTORE DE 053D EB 3 XCHG 053E CD7C0C CALL FINISH ;AND CONTINUE  NEXT: ;0508 0541 CD840C CALL TSTVAR ;GET ADDRESS OF VAR 0544 DA590A JC QWHAT ;07E0H NO VARIABLE, "WHAT?" 0547 228A86 SHLD VARNXT ;09C5=58D CD7C0C CALL FINISH  _NX2: ;0551 0590 CDE50B CALL POPA ;0918H PURGE THIS LOOP 0593 CD7C0C CALL FINISH   ;   ;  , ;+++REM+++IF+++INPUT+++& LET (& DEFLT)+++   ;  < ;'REM' CAN BE FOLLOWED BY ANYTHING AND IS IGNORED BY TBI.  6 ;TBI TREATS IT LIKE AN 'IF' WITH A FALSE CONDITION.   ;  G ;'IF' IS FOLLOWED BY AN EXPR. AS A CONDITION AND ONE OR MORE N EQUAL SIGN, AND AN EXPR.  ? ;TBI EVALUATES THE EXPR. AND SETS THE VARIABLE TO THAT VALUE  = ;TBI WILL ALSO HANDLE 'LET' COMMAND WITHOUT THE WORD 'LET'   ;THIS IS DONE BY 'DEFLT'   ;   ;        9REM: ;0555 +++REM+++ 0596 210000 LXI H,0 0599 3E DB '>'  ;IFF: ;0559 +++IF+++; 059A CD640C CALL EXPR 059D 7C  MOV A,H ;IS THE E* "TO"  FR1: ;04B9 04EC CD640C CALL EXPR ;EVALUATE THE LIMIT 04EF 229286 SHLD LOPLNT ;09CDH SAVE THAT 04F2 21CB02 LXI H,TAB6-1 ;USE 'EXEC' TO LOOK 04F5 C3ED02 JMP EX0 ;02D8H FOR THE WORD 'STEP'  aFR2: ;04C3 ; 04F8 CD640C CALL EXPR ;FOUND IT, GET STEP 04FB C30105 JMP FR4 ;04CAH  ?FR3: ;04C7 04FE 210100 LXI H,1 ;NOT FOUND, SET TO ONE  DFR4: ;04CA 0501 229086 SHLD LOPINC ;09CBH SAVE THAT TOO H YES SAVE IT  NX0: ;050F 054A D5 $ PUSH D ;SAVE TEXT POINTER 054B EB E XCHG 054C 2A8E86 LHLD LOPVAR ;09C9H GET VAR IN 'FOR' 054F 7C  MOV A,H 0550 B5 ORA L ;0 SAYS NEVER HAD ONE 0551 CA5A0A JZ AWHAT ;07E1H SO WE ASK "WHAT?" 0554 CD6C0C CALL COMP ;ELSE WE CHECK THEM 0557 CA6405 JZ NX3 ;0527H OK, THEY AGREE 055A D1 o POP D ;NO, LETS SEE 055B CDE50B CALL POPA ;0918H PURGE CURRENT LOOP 055E 2A8A86 LHLD VARNXT ;09C5H > ;COMMANDS (INCLUDING OTHER 'IF'S) SEPERATED BY SEMI-COLONS.  < ;NOTE THAT THE WORD 'THEN' IS NOT USED. TBI EVALUATES THE  > ;EXPR. IF IT IS NON-ZERO, EXECUTION CONTINUES. IF THE EXPR.  ? ;IS ZERO, THE COMMANDS THAT FOLLOW ARE IGNORED AND EXECUTION   ;CONTINUES AT THE NEXT LINE.   ;  @ ;'INPUT' COMMAND IS LIKE THE 'PRINT' COMMAND, AND IS FOLLOWED  . ;BY A LIST OF ITEMS. IF THE ITEM IS A STRING GXPR. =0? 059E B5 ORA L 059F C24203 JNZ RUNSML ;032BH NO, CONTINUE 05A2 CD2C0B CALL FNDSKP ;0875H YES, SKIP REST OF LINE 05A5 D23B03 JNC RUNTSL ;0324H 05A8 C38501 JMP RSTART ;0181H  JINPERR: ;0568 +++INPERR+++ 05AB 2A8C86 LHLD STKINP ;09C7H 05AE F9 SPHL ;RESTORE OLD SP 05AF E1 5 POP H 05B0 228686 SHLD CURRNT ;09C1H 05B3 D1 & POP D ;AND OLD TEXT POINTER 05B4 D1  POP D ;REDO INPUT  IP1: ;0572 +++I  t FR5: ;04CD 0504 2A8686 LHLD CURRNT ;09C1H SAVE CURRENT LINE # 0507 229486 SHLD LOPLN ;09CFH 050A EB XCHG ;AND TEXT POINTER 050B 229686 SHLD LOPPT ;09D1H 050E 010A00 LXI B,0AH ;DIG INTO STACK TO 0511 2A8E86 LHLD LOPVAR ;09C9H FIND 'LOPVAR' 0514 EB  XCHG 0515 60  MOV H,B 0516 68  MOV L,B ;HL=0 NOW 0517 39 $ DAD SP ;HERE IS THE STACK 0518 3E DB '>'  FR7: ;04E2 0519 09  DAD B ;EACH LEV uD AND POP ONE LEVEL 0561 C34A05 JMP NX0 ;050FH GO CHECK AGAIN  NX3: ;0527 0564 5E ) MOV E,M ;COME HERE WHEN AGREED 0565 23  INX H ; 0566 56 H MOV D,M ;DE=VALUE OF VAR 0567 2A9086 LHLD LOPINC ;09CBH 056A E5  PUSH H 056B 19  DAD D  NX4: ;052F 056C EB A XCHG 056D 2A8E86 LHLD LOPVAR ;09C9H PUT IT BACK 0570 73  MOV M,E 0571 23  INX H 0572 72 ) MOV M,D 0573 2A9286 LHLD LOPLNT ;0 ѳIN SINGLE OR  @ ;DOUBLE QUOTES, OR IS A BACK-ARROW, IT HAS THE SAME EFFECT AS  ? ;IN 'PRINT'. IF AN ITEM IS A VARIABLE, THIS VARIABLE NAME IS  : ;PRINTED OUT FOLLOWED BY A COLON. THEN TBI WAITS FOR AN  8 ;EXPR. TO BE TYPED IN THE VARIABLE IS THEN SET TO THE  @ ;VALUE OF THIS EXPR. IF THE VARIABLE IS PROCEDED BY A STRING.   ;  ; ;(AGIAN IN SINGLE OR DOUBLE QUOTES), THE STRING WILL BE   ; NPUT+++ 05B5 D5 PUSH D ;SAVE IN CASE OF ERROR 05B6 CD440B CALL OTSTG ;088BH IS NEXTITEM A STRING? 05B9 C3C505 JMP IP2 ;0580H NO 05BC CD840C CALL TSTVAR ;YES, BUT FOLLOWED BY A 05BF DA0306 JC IP4 ;05BAH VARIABLE? NO. 05C2 C3D705 JMP IP3 ;0590H YES INPUT VARIABLE  IP2: ;0580 05C5 D5 PUSH D ;SAVE FOR 'PRTSTG' 05C6 CD840C CALL TSTVAR ;MUST BE VARIABLE NOW 05C9 DA590A JC QWHAT ;07E0H 'WHAT?' IT IS NOT? 05CC 1A  LDAX D ;GET R EL IS 10 DEEP 051A 7E ) MOV A,M ;GET THAT OLD 'LOPVAR' 051B 23  INX H ; 051C B6 H ORA M 051D CA3A05 JZ FR8 ;0503H ZERO SAYS NO MORE IN IT 0520 7E  MOV A,M 0521 2B  DCX H 0522 BA D CMP D ;SAME AS THIS ONE? 0523 C21905 JNZ FR7 ;04E2H 0526 7E # MOV A,M ;THE OTHER HALF? 0527 BB 1 CMP E 0528 C21905 JNZ FR7 ;04E2H 052B EB : XCHG ;YES, FOUND ONE 052C 210000 LXI H,0 052F 39 " DAD SP ;TRY TO MOVE SP 0530 44 9CDH HL=LIMIT 0576 F1  POP PSW ;OLD HL 0577 B7 9 ORA A 0578 F27C05 JP NX1 ;053FH STEP > 0 057B EB  XCHG  NNX1: ;053F 057C CD1D0A CALL CKHLDE ;07B2H COMPARE WITH LIMIT 057F D1 POP D ;RESTORE TEXT POINTER 0580 DA9005 JC NX2 ;0551H OUTSIDE LIMIT 0583 2A9486 LHLD LOPLN ;09CFH WITHIN LIMIT, GO 0586 228686 SHLD CURRNT ;09C1H BACK TO THE SAVED 0589 2A9686 LHLD LOPPT ;09D1H 'CURRNT' AND TEXT 058C EB  XCHG ;POINTER 0=PRINTED FOLLOWED BY A COLON. TBI THEN WAITS FOR INPUT EXPR.   ;  : ;IF THE INPUT EXPR. IS INVALID, TBI WILL PRINT "WHAT?",  @ ;"HOW?" OR "SORRY" AND REPRINT THE PROMPT AND REDO THE INPUT.  @ ;THE EXECUTION WILL NOTT TERMINATE UNLESS YOU TYPE CONTROL-C.  ;THIS IS HANDLED IN 'INPERR'.   ;  < ;'LET' IS FOLLOWED BY A LIST OF ITEMS SEPERATED BY COMMAS  % ;EACH ITEM CONSISTS OF A VARIABLE, AEADY FOR 'PRTSTG' 05CD 4F  MOV C,A 05CE 97  SUB A 05CF 12  STAX D 05D0 D1 L POP D 05D1 CD360B CALL PRTSTG ;087FH PRINT STRING AS PROMPT 05D4 79 MOV A,C ;RESTORE TEXT 05D5 1B  DCX D 05D6 12 STAX D  IP3: ;0590 05D7 D5 $ PUSH D ;SAVE TEXT POINTER 05D8 EB G XCHG 05D9 2A8686 LHLD CURRNT ;09C1H ALSO SAVE 'CURRNT' 05DC E5 L PUSH H ; 05DD 21B505 LXI H,IP1 ;0572H A NEGATIVE NUMBER 05E0 228686  ;+++EXPR+++   ;  8 ;'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS   ;=   ;  < ;WHERE IS ONE OF THE OPERATORS IN TABS AND THE  ; ;RESULT OF THESE OPERATIONS IS 1 IF TRUE AND 0 IF FALSE.  2 ;::=(+ OR -)(+ OR -)(....)  8 ;WHERE <> ARE OPTIONAL AND (....) ARE OPIONAL REPEATS  ;::=H REL. OP. "=" 0647 C0 # RNZ ;FALSE, RETURN HL=0 0648 6F ! MOV L,A ;ELSE SET HL=1 0649 C9  RET  GXP16: ;05F9 064A CD5206 CALL XP18 ;0601H REL. OP. "<" 064D D0 # RNC ;FALSE, RETURN HL=0 064E 6F ! MOV L,A ;ELSE SET HL=1 064F C9  RET  XP17: ;05FF 0650 E1  POP H ;NOT REL. OP. 0651 C9  RET ;RETURN HL=  XP18: ;0601 0652 79 & MOV A,C ;SUBROUTINE FOR ALL 0653 E1   R XP25: 0694 CD520C CALL PG0 ;SUBTRACT? 0697 2D8A DB '-',(XP42-$-1)  XP26: ;0640 0699 E5 PUSH H ;YES, SAVE 1ST 069A CDA306 CALL EXPR3 ;064AH GET 2ND /PR3> 069D CD110A CALL CHGSGN ;07A6H NEGATE 06A0 C38306 JMP XP24 ;062CH AND ADD THEM  DEXPR3: ;064A 06A3 CDFF06 CALL EXPR4 ;06A7H GET 1ST  dXP31: ;064D 06A6 CD520C CALL PG0 ;MULTIPLY? 06A9 2A27 DB '*',(XP34-$-1) 06AB E5 )R SHLD CURRNT ;09C1H AS A FLAG 05E3 210000 LXI H,0 ;SAVE SP TOO 05E6 39 6 DAD SP 05E7 228C86 SHLD STKINP ;09C7H 05EA D5 e PUSH D ;OLD HL 05EB 3E3A MVI A,':' ;3AH 05ED CD8F0A CALL GETLN ;0814H AND GET A LINE  zIP33: ;05A9 05F0 113787 LXI D,BUFFER ;0F37H POINTS TO BUFFER 05F3 CD640C CALL EXPR ;EVALUATE INPUT 05F6 00 % NOP ;CAN BE 'CALL ENDCHK' 05F7 00  NOP 05F8 00  NOP 05F9 D1  POP D ;OK, GET OLD HL (< OR />)(....)   ;::=   ;  ;()  ? ; IS RECURSIVE SO THAT VARIABLE '@' CAN HAVE AN  < ;AS INDEX, FUNCTIONS CAN HAVE AN AS ARGUMENTS, AND  , ; CAN BE AN IN PARENTHESES.   ;  ( ; EXPR CALL EXPR2 THIS IS AT LOC. 18   ; PUSH HL   ;   ;   POP H ;REL. OP.'S 0654 C1 & POP B ;REVERSE TOP OF STACK 0655 E5  PUSH H 0656 C5  PUSH B 0657 4F F MOV C,A 0658 CD6706 CALL EXPR2 ;0616H GET 2ND 065B EB ! XCHG ;VALUE OF DE NOW 065C E3 _ XTHL ;1ST IN HL 065D CD1D0A CALL CKHLDE ;07B2H COMPARE FIRST WITH 2ND 0660 D1 j POP D ;RESTORE TEXT POINTER 0661 210000 LXI H,0 ;SET HL=0 , A=1 0664 3E01 MVI A,1 0666 C9  RET  EXPR2: ;0616 0667 C, PUSH H ;YES, SAVE 1ST 06AC CDFF06 CALL EXPR4 ;06A7H AND GET 2ND 06AF 0600 MVI B,0 ;CLEAR B FOR SIGN 06B1 CD0E0A CALL CHKSGN ;07A3H CHECK SIGN 06B4 EB  XCHG ;1ST IN HL 06B5 E3 F XTHL 06B6 CD0E0A CALL CHKSGN ;07A3H CHECK SIGN OF 1ST 06B9 7C MOV A,H ;IS HL >255 ? 06BA B7 4 ORA A 06BB CAC406 JZ XP32 ;0669H NO 06BE 7A % MOV A,D ;YES, HOW ABOUT DE 06BF B2  ORA D 06C0 EB % XCHG ;PUT SMALLER IN HL 06C1 C26B  05FA EB  XCHG 05FB 73 & MOV M,E ;SAVE VALUE IN VAR. 05FC 23  INX H 05FD 72  MOV M,D 05FE E1 G POP H ;GET OLD 'CURRNT' 05FF 228686 SHLD CURRNT ;09C1H 0602 D1  POP D ;AND OLD TEXT POINTER  IP4: ;05BA 0603 F1 S POP PSW ;PURGE JUNK IN STACK 0604 CD520C CALL PG0 ;IS NEXT CH. ',' 0607 2C  DB ',' 0608 03 @ DB (IP5-$-1) 0609 C3B505 JMP IP1 ;0572H YES, MORE ITEMS  IP5: ;05C1 060C CD7C0C    sEXPR1: ;05D2 0623 21D302 LXI H,TAB8-1 ;02BEH LOOK UP REL. OP. 0626 C3ED02 JMP EX0 ;02D8H GO DO IT  HXP11: ;05D8 0629 CD5206 CALL XP18 ;0601H REL. OP. ">=" 062C D8  RC ;NO, RETURN HL=0 062D 6F # MOV L,A ;YES,RETURN HL=1 062E C9  RET  EXP12: ;05DE REL OF "#" 062F CD5206 CALL XP18 ;0601H 0632 C8 " RZ ;FALSE, RETURN HL=0 0633 6F % MOV L,A ;TRUE, RETURN HL=1 0634 C9  RE D520C CALL PG0 ;NEGATIVE SIGN? 066A 2D06 DB '-',(XP21-$-1) 066C 210000 LXI H,0 ;YES, FAKE '0-' 066F C39906 JMP XP26 ;0640H TREAT LIKE SUBTRACT  eXP21: ;061F 0672 CD520C CALL PG0 ;POSITIVE SIGN? IGNORE 0675 2B00 DB '+',(XP22-$-1)  ?XP22: ;0622 0677 CDA306 CALL EXPR3 ;064AH 1ST  ]XP23: ;0625 067A CD520C CALL PG0 ;ADD? 067D 2B15 DB '+',(XP25-$-1) 067F E5  PUSH H ;YES, SAVE VALUE 0680 .01 JNZ AHOW ;0167H ALSO >, WILL OVERFLOW  XP32: ;0669 06C4 7D H MOV A,L ;THIS IS DUMB 06C5 210000 LXI H,0 ;CLEAR RESULT 06C8 B7 8 ORA A ;ADD AND COUNT 06C9 CAF106 JZ XP35 ;0699H  RXP33: 06CC CDB609 CALL MULTIPLY 06CF C3F106 JMP XP35 ;0699H FINISHED  _XP34: ;067C 06D2 CD520C CALL PG0 ;DIVIDE? 06D5 2F4C DB '/',(XP42-$-1) 06D7 E5 B PUSH H ;YES, SAVE 1ST 06D8 CDFF06 CALL EXPR4 ;06A7H  CALL FINISH  DEFLT: ;05C2 060F 1A x LDAX D ;+++DEFLT+++ 0610 FE0D CPI 0DH ;(CR) EMPTY LINE IS OK 0612 CA2006 JZ LT1 ;05D1H ELSE IT IS 'LET'  LET: ;05C8 0615 CD270A CALL SETVAL ;07BAH +++LET+++ 0618 CD520C CALL PG0 ;SET VALUE TO VAR. 061B 2C03 DB ',',(LT1-$-1) 061D C31506 JMP LET ;05C8H ITEM BY ITEM  :LT1: ;05D1 0620 CD7C0C CALL FINISH ;UNTIL FINISH   ;  ; QT  FXP13: ;05E4 0635 CD5206 CALL XP18 ;0601H REL OP. ">" 0638 C8  RZ ;FALSE 0639 D8  RC ;ALSO FALSE HL=0 063A 6F  MOV L,A ;TRUE HL=1 063B C9  RET  HXP14: ;05EB 063C CD5206 CALL XP18 ;0601H REL. OP. "<=" 063F 6F  MOV L,A ;SET HL=1 0640 C8 ! RZ ;REL. TRUE, RETURN 0641 D8 RC 0642 6C ! MOV L,H ;ELSE SET HL=0 0643 C9  RET  /XP15: ;05F3 0644 CD5206 CALL XP18 ;0601Z/ CDA306 CALL EXPR3 ;064AH GET 2ND  XP24: ;062C 0683 EB  XCHG ;2ND IN DE 0684 E3  XTHL ;1ST IN HL 0685 7C MOV A,H ;COMPARE SIGN 0686 AA  XRA D 0687 7A  MOV A,D 0688 19  DAD D 0689 D1 [ POP D ;RESTORE TEXT POINTER 068A FA7A06 JM XP23 ;0625H 1ST 2ND SIGN DIFFER 068D AC XRA H ;1ST 2ND SIGN EQUAL 068E F27A06 JP XP23 ;0625H SO IS RESULT 0691 C36A01 JMP QHOW ;0166H ELSE WE HAVE OVERFLOW  (} AND GET 2ND ONE 06DB 0600 MVI B,0 ;CLEAR B FOR SIGN 06DD CD0E0A CALL CHKSGN ;07A3H CHECK SIGN OF 2ND 06E0 EB  XCHG ;GET 1ST IN HL 06E1 E3 F XTHL 06E2 CD0E0A CALL CHKSGN ;07A3H CHECK SIGN OF 1ST 06E5 7A " MOV A,D ;DIVIDE BY 0 ? 06E6 B3 < ORA E 06E7 CA6B01 JZ AHOW ;0167H SAY "HOW" 06EA C5 U PUSH B ;ELSE SAVE SIGN 06EB CDC309 CALL DIVIDE ;0786H USE SUBROUTINE 06EE 60 $ MOV H,B ;RESULT IN HL NOW 06EF 69  MOV L,C 06F0  072F B5 ? ORA L ;AND NON-ZERO 0730 CA6A01 JZ QHOW ;0166H 0733 D5  PUSH D ;SAVE BOTH 0734 E5 PUSH H 0735 2A9886 LHLD RANPNT ;09D3H GET MEMORY AS RANDOM 0738 11B80C LXI D,LSTROM ;09B0H NUMBER 073B CD6C0C CALL COMP 073E DA4407 JC RA1 ;06E2H RAP AROUND IF LAST 0741 210001 LXI H,BEGIN ;0100H  RA1: ;06E2 0744 5E  MOV E,M 0745 23  INX H 0746 56 7 MOV D,M 0747 229886 SHLD RANPNT ;09D3H 074A E1  p0F904771 :10082000CD8D077CB7F22B08C36A01D1C1C93E0048 :10083000329F862A9D8646237EB8F245084F3E01A8 :10084000329F867841905F16002100005F3A9C86B7 :1008500006082917D258081905C252080604CD8D7A :1008600007EB219F867EB7C278082A9D867E6F2679 :1008700000197D21A08677C92A9D867E9321A086B6 :1008800077C900060D13191F24292E32363A3D412F :100890004447494C4E505153545556575757585842 :1008A0005757575655545352504E4D4B4947454252 :1008B000403D3A3734312E2B2724201C1915110CBA :1008C0000804000004090E12171B1F23272A2E31CB :1008D0 3E08CD5C0C3E20CD5C0C3E08CD5C11 :100B00000CC3950ACD5A0C3E5EC38F0A7CB7FA6AB5 :100B10000111E00CE52ADE0C2BCD6C0CE1D81A9506 :100B200047131A9CDA2B0B1BB0C913131AFE0DC204 :100B30002B0B13C3140B471A13B8C8CD5C0CFE0D56 :100B4000C2370BC9CD520C220F3E22CD360BFE0D03 :100B5000E1CA3203232323E9CD520C27053E27C3E4 :100B60004B0BCD520C5F0C3E8DCD5C0CCD5C0CE183 :100B7000C3540BC9D5110A00D5420DCD0E0AF2841B :100B80000B062D0DC5CDC30978B1CA950BE32DE534 :100B90006069C3850BC10D79B7FAA40B3E20CD5C0B :100BA0000CC3960B78CD5C0C5D7BF v C1  POP B ;GET SIGN BACK  XP35: ;0699 06F1 D1 " POP D ;AND TEXT POINTER 06F2 7C MOV A,H ;HL MUST BE + 06F3 B7 : ORA A 06F4 FA6A01 JM QHOW ;0166H OVERFLOW 06F7 78  MOV A,B 06F8 B7 w ORA A 06F9 FC110A CM CHGSGN ;07A6H CHANGE SIGN IF NEEDED 06FC C3A606 JMP XP31 ;064DH LOOK FOR MORE TERMS  zEXPR4: ;06A7 FIND FUNCTION IN TAB4 06FF 218602 LXI H,TAB4-1 ;027EH 0702 C3ED02 JMP EX0 ;02D8H AND GO DO IT QPOP H 074B EB  XCHG 074C C5 H PUSH B 074D CDC309 CALL DIVIDE ;0786H RND(N)=MOD(M,N)+1 0750 C1  POP B 0751 D1  POP D 0752 23  INX H 0753 C9  RET  vABS: ;06F2 +++ABS(EXPR) 0754 CD1607 CALL PARN ;06BCH 0757 CD0E0A CALL CHKSGN ;07A3H CHECK SIGN 075A 7C  MOV A,H 075B B4 1 ORA H 075C FA6A01 JM QHOW ;0166H 075F C9  RET   ;LOG2.ASM JUNE 24, 1984   ;CONVERTS 16 B 0035383B3E404346484A4C4E5051525455A1 :1008E0005656575758585857575655545352504EB6 :1008F0004C4A484543403C3936322E2925201B16A8 :10090000110B06002ADE0CD5EB218086CD070AD11B :10091000C9CD640C7D329B86CD520C2C3ECD640C2F :100920007DCDB80CCD520C2C03C31109CD7C0CCD60 :10093000640C7D329A86CD520C2C20CD640CE5CD12 :10094000520C2C09CD640C7DE167C332072600C32D :10095000C30CCD16077D329A862600C3D40CC3592A :100960000ACD640CE5CD520C2C18CD640C7DE177DA :10097000CD520C2C03C36109CD7C0CCD16076E261D :1009800000C9C3590AC5CD5 NE0AD1C8C630B9 :100BB000CD5C0CC3A90B1A6F131A67130E04CD7406 :100BC0000B3E20CD5C0C97CD360BC9CD6C0CC81AF2 :100BD000021303C3CB0B7892C2DE0B7993C81B2B95 :100BE0001A77C3D60BC1E1228E867CB5CAFF0BE112 :100BF000229086E1229286E1229486E1229686C5A1 :100C0000C921AF87CD110AC139D2880A2A8E867CC4 :100C1000B5CA270C2A9686E52A9486E52A9286E5A7 :100C20002A9086E52A8E86E5C5C9C22F0CF1C9F146 :100C3000C5D5E53281865F0E02CD05003A8186FE7C :100C40000DC24B0C1E0A0E02CD05003A8186E1D181 :100C5000C1C9E3CD740CBEC331013E0DF53A8286A5 :1  yXP40: ;06AD 0705 CD840C CALL TSTVAR ;NO, NOT A FUNCTION 0708 DA1007 JC XP41 ;06B6H NOR A VARIABLE 070B 7E  MOV A,M ;VARIABLE 070C 23  INX H 070D 66  MOV H,M ;VALUE IN HL 070E 6F  MOV L,A 070F C9  RET  NXP41: ;06B6 0710 CD4001 CALL TSTNUM ;013EH OR IS IT A NUMBER 0713 78  MOV A,B ;# OF DIGIT 0714 B7  ORA A 0715 C0 RNZ ;OK  -PARN: ;06BC 0716 CD520C CALL PG0 ;NO 1006B00000CD0E0AEBE3CD0E0A7CB7CAC4067AB2AF :1006C000EBC26B017D210000B7CAF106CDB609C3AC :1006D000F106CD520C2F4CE5CDFF060600CD0E0ADB :1006E000EBE3CD0E0A7AB3CA6B01C5CDC3096069CD :1006F000C1D17CB7FA6A0178B7FC110AC3A60621FA :100700008602C3ED02CD840CDA10077E23666FC922 :10071000CD400178B7C0CD520C2809CD640CCD5224 :100720000C2901C9C3590ACD16077CB7FA6A01B56D :10073000CA6A01D5E52A988611B80CCD6C0CDA444A :10074000072100015E2356229886E1EBC5CDC3093F :10075000C1D123C9CD1607CD0E0A7CB4FA6A01C9EE :10076000CD1607CD0 20C2826CD640CCD52DE :100990000C2907D511B009D5E5C9CD520C2C12E5AB :1009A000CD640CCD520C2909C1D511B009D5C5C9EA :1009B000D1C1C9C3590A0E082917D2BE09190DC2DF :1009C000B809C9D5EB060129047ABCD2C709780158 :1009D0000000F57ABCDAF109C2E0097BBDDAF10961 :1009E0007B955F7A9C5779B7174F78174703C3F801 :1009F0000979B7174F7817477CB71F677D1F6FF1CD :100A00003DC2D209EBD1C97D936F7C9A67C97CB78F :100A1000F07C2F677D2F6F2378EE8047C97CAAF288 :100A2000230AEBCD6C0CC9CD840CDA590AE5CD5202 :100A30000C3D0ACD640C444DE1712370C9C3590A *IT NUMBER IN HL TO 1024*LOG(BASE2)OF N0.   ;RETURNS IN HL  ; ;CONVERTS 1024*LOG(BASE2)OF NUMBER TO NUMBER (ANTILOG)   ;RETURNS IN HL  ;  ;  LOG2: ;CONVERTS NO. IN HL TO LOG2 0760 CD1607 CALL PARN ;FIND AND EVALUATE THE PARENTHISIS 0763 CD0E0A CALL CHKSGN ;GET THE ABSOLUTE VALUE OF THE NUMBER  ;  ;  !LOGG: ;LOG CONVERSION 0766 C5  PUSH B DIGIT, MUST BE 0719 28  DB '(' ;28H 071A 09 Y DB (XP43-$-1) 071B CD640C CALL EXPR ;"" 071E CD520C CALL PG0 0721 29  DB ')' 0722 01  DB (XP43-$-1)  XP42: ;06C3 0723 C9  RET  @XP43: ;06C4 0724 C3590A JMP QWHAT ;07E0H ELSE SAY WHAT  IRND: ;06C7 +++RND(EXPR)+++ 0727 CD1607 CALL PARN ;06BCH 072A 7C " MOV A,H ;EXPR MUST BE + 072B B7 ( ORA A 072C FA6A01 JM QHOW ;0166H E0AC5D57CB7C278077DB7C2B6 :1007700078072101D4D1C1C906100529D27A07789A :10078000B7171747C50606CD8D07C399077CB71F56 :10079000677D1F6F05C28D07C9E57DE60F329C8618 :1007A0000604CD8D0711820819229D86CD2E0821C1 :1007B000A0865E1600E1C10E00190911010019D1D1 :1007C000C1C9CD1607C5D57CE6FCC2D407AF676F9B :1007D0002CD1C1C97CE680CAE007AF676FD1C1C91F :1007E0003E3CBCFA6A017CB71FB71F47C57CE603D5 :1007F00067E57DE60F329C860604CD8D0711C308A0 :1008000019229D86CD2E08E13AA0860E00477D90E4 :100810006F7C99C604672929292929C13E C1 :100A4000CD520C3B04F1C34203CD520C0D04F1C353 :100A50003203C9CD740CFE0DC8D511790197CD367E :100A60000BD11AF597122A8686E57E23B6D1CA8560 :100A7000017EB7FAAB05CDB60B1BF1123E3FCD5C44 :100A80000C97CD360BC38501D5117F01C35D0ACD0F :100A90005C0C113787CD8D0C0000CA950AFE7FCA09 :100AA000DC0AFE08CAC80AFE0ACA950AB7CA950A2D :100AB000FE5CCA040B1213FE0DC2C20A3E0ACD5CD4 :100AC0000CC97BFE87C2950A7BFE37CA040B1B3E0E :100AD00020CD5C0C3E08CD5C0CC3950A7BFE37CA6A :100AE000040B1B3E08CD5C0C3E20CD5C0C3E08CDBB :100AF0005C0C!\!;PUSH THE REGISTERS 0767 D5  PUSH D 0768 7C  MOV A,H 0769 B7 - ORA A 076A C27807 JNZ LOGCHR 076D 7D  MOV A,L 076E B7 z ORA A 076F C27807 JNZ LOGCHR 0772 2101D4 LXI H,54273 ;MAKE LOG2(0)=-11263 (LOG2(1/2047)) AND RETURN 0775 D1  POP D 0776 C1  POP B 0777 C9  RET  ;  ;  PLOGCHR: ;NO. IS NOT ZERO 0778 0610 MVI B,16 ;FIND THE CHARACTERISTIC  LSH1: 077!0 MVI D,0 07B5 E1 2 POP H ;RECOVER THE UNCORRECTED MANTISSA 07B6 C1 R POP B ;RECOVER THE UNCORRECTED CHARACTERISTIC 07B7 0E00 MVI C,0 07B9 19  DAD D ;ADD CORRECTOR 07BA 09 > DAD B ;ADD CHARACTERISTIC 07BB 110100 LXI D,1 07BE 19 $ DAD D ;ADD ONE TO THE LOG 07BF D1  POP D 07C0 C1  POP B 07C1 C9 RET ;LOG CONVERSION COMPLETE  ;  ;  ;ALOG2   ;RETURNS THE B!b ; 07F2 7D MOV A,L ;FIND THE INTERPOLATOR 07F3 E60F ANI 15 07F5 329C86 STA INTSCR ;SAVE THE INTERPOLATOR IN THE SCRATCH PAD  ;  ; 07F8 0604 MVI B,4 ;GENERATE THE POINTER 07FA CD8D07 CALL MANTIS ;RIGHT SHIFT THE MANTISSA, 4 BITS 07FD 11C308 LXI D,ALTAB ;ANTILOG TABLE ADDRESS 0800 19 DAD D ;HL> (POINTER) 0801 229D86 SHLD (INTSCR+1) ;STORE THE TABLE POINTER IN THE SCRATCH PAD 0804 CD2E08 CALL INTERP ;CALL THE I!XON POLARITY 083A F24508 JP ABSPON ;I.E. ACENDING OR DECENDING CORRECTORS 083D 4F t MOV C,A ;NEG, SWAP A&B, SET THE SIGN BYTE TO 1 083E 3E01 MVI A,1 0840 329F86 STA (INTSCR+3) 0843 78  MOV A,B 0844 41 MOV B,C  ;  ABSPON: 0845 90 , SUB B ;ABS((POINTER+1)-(POINTER)) 0846 5F MOV E,A  ;  c; 0847 1600 MVI D,0 ;MULTIPLY BY THE INTERPOLATOR 0849 210000 LXI H,0 084C 5F !>A 05  DCR B 077B 29 I DAD H ;SHIFT NO. LEFT 077C D27A07 JNC LSH1 ;UNTIL CARRY 077F 78 9 MOV A,B ;LEFT SHIFT THE CHARACTERISTIC, 2 BITS 0780 B7  ORA A ;CLEAR CARRY 0781 17  RAL 0782 17  RAL 0783 47  MOV B,A 0784 C5 / PUSH B ;SAVE THE CHARACTERISTIC TO THE STACK  ;  {; 0785 0606 MVI B,6 ;POSITION THE UNCORRECTED MANTISSA 0787 CD8D07 CALL MANTIS 078A C39907 JMP LTABAD  ; !ASE 2 ANTILOG  ;  :ALOG2: 07C2 CD1607 CALL PARN ;EVALUATE PARENTHISIS  ;  ALOG: 07C5 C5 ! PUSH B ;PUSH REGISTERS 07C6 D5  PUSH D 07C7 7C b MOV A,H ;IS CHARACTERISTIC ZERO OR MINUS 07C8 E6FC ANI 252 07CA C2D407 JNZ LOGNEG  " ;IF ZERO, RETURN HL=1 07CD AF  XRA A 07CE 67  MOV H,A 07CF 6F  MOV L,A 07D0 2C  INR L ;RETURN 1 07D1 D1  POP D 07D2 !uNTERPOLATOR 0807 E1 R POP H ;RECOVER THE MANTISSA 0808 3AA086 LDA (INTSCR+4) ;GET THE CORRECTOR  ;  %; 080B 0E00 MVI C,0 080D 47 . MOV B,A ;SUBTRACT CORRECTOR FROM HL 080E 7D  MOV A,L 080F 90  SUB B 0810 6F  MOV L,A 0811 7C  MOV A,H 0812 99 @ SBB C 0813 C604 ADI 4 ;ADD BACK THE LEADING 1 0815 67  MOV H,A 0816 29 & DAD H ;SHIFT LEFT HL 5 BITS 0817 29  DAD H 0818 29 ! MOV E,A 084D 3A9C86 LDA INTSCR ;LOAD THE INTERPOLATOR FROM THE SCRATCH PAD 0850 0608 MVI B,8 ;SIZE OF MULTIPLIER  ;  ;  MULT: 0852 29  DAD H 0853 17 * RAL 0854 D25808 JNC CHCNT 0857 19  DAD D ;ADD IF CARRY IS 1  ;  CHCNT: 0858 05 3 DCR B 0859 C25208 JNZ MULT ;LOOP UNTIL B=0  ;  ; DIVIDE BY 16  ; 085C 0604 MVI B,! 2  1MANTIS: ;SHIFT HL B BITS TO THE RIGHT 078D 7C  MOV A,H 078E B7  ORA A 078F 1F  RAR 0790 67  MOV H,A 0791 7D  MOV A,L 0792 1F  RAR 0793 6F  MOV L,A 0794 05 - DCR B 0795 C28D07 JNZ MANTIS 0798 C9  RET  ;  ;  LTABAD: 0799 E5 0 PUSH H ;SAVE THE UNCORRECTED MANTISSA 079A 7D G MOV A,L ;GET THE INTERPOLATOR 079B E60F ANI 15 079D 329C86 ! C1  POP B 07D3 C9  RET  ;  2LOGNEG: ;ANTILOG OF MINUS, RETURN HL=0 07D4 7C F MOV A,H 07D5 E680 ANI 128 07D7 CAE007 JZ MLOG 07DA AF  XRA A 07DB 67  MOV H,A 07DC 6F  MOV L,A ;CLEAR HL 07DD D1  POP D 07DE C1  POP B 07DF C9  RET  ;  QMLOG: ;IS THE CHARACTERISTIC OUT OF RANGE? 07E0 3E3C MVI A,60 07E2 BC % CMP H 07E3 FA6A01 JM QHOW ;YES!  DAD H 0819 29  DAD H 081A 29  DAD H 081B C1 [ POP B ;RECOVER THE CHARACTERISTIC 081C 3E0F MVI A,15 ;JUSTIFY THE NUMBER 081E 90  SUB B 081F 47 h MOV B,A ;B=N0. OF RIGHT SHIFTS NEEDED TO JUSTIFY 0820 CD8D07 CALL MANTIS ;DO THE SHIFTS 0823 7C  MOV A,H 0824 B7 d ORA A 0825 F22B08 JP ALGFIN 0828 C36A01 JMP QHOW ;ANTILOG OUT OF RANGE, ERROR 082B D1 ALGFIN: POP D 082C C1  POP B 082D C9 RET ;ANTILO! {=4 ;RIGHT SHIFT 4 BITS 085E CD8D07 CALL MANTIS 0861 EB % XCHG ;POINTER ADJUSTMENT IS IN DE  <; 0862 219F86 LXI H,(INTSCR+3) ;GET THE SIGN 0865 7E  MOV A,M 0866 B7 e ORA A 0867 C27808 JNZ INTREV ;IS IT + 086A 2A9D86 LHLD (INTSCR+1) ;YES, ADD DE 086D 7E  MOV A,M 086E 6F , MOV L,A 086F 2600 MVI H,0 0871 19  DAD D 0872 7D K MOV A,L 0873 21A086 LXI H,(INTSCR+4) ;STORE IN SCRATCH PAD 0876 77  M! " STA INTSCR ;AND STORE IT IN THE SCRATCH PAD 07A0 0604 MVI B,4 ;SHIFT THE UNCORRECTED MANTISSA RIGHT 4 BITS 07A2 CD8D07 CALL MANTIS ;TO FORM THE CORRECTION TABLE POINTER 07A5 118208 LXI D,LOGTAB;TABLE ADDRESS 07A8 19 DAD D ;ADD IT TO HL 07A9 229D86 SHLD (INTSCR+1) ;STORE THE POINTER IN THE INTERP.SCRATCH PAD 07AC CD2E08 CALL INTERP  .; 07AF 21A086 LXI H,(INTSCR+4) 07B2 5E ? MOV E,M ;RECOVER THE CORRECTOR FROM THE SCRATCH PAD 07B3 160!H , ERROR  ; 07E6 7C  MOV A,H 07E7 B7  ORA A ;CLEAR CARRY 07E8 1F ; RAR ;REPOSITION THE CHARACTERISTIC 2 BITS RIGHT 07E9 B7  ORA A 07EA 1F  RAR 07EB 47 + MOV B,A ;PUT CHARACTERISTIC IN B 07EC C5  PUSH B ;SAVE IT  ;  ; 07ED 7C L MOV A,H ;CLEAR THE CHARACTERISTIC FROM HL 07EE E603 ANI 3 07F0 67  MOV H,A 07F1 E5  PUSH H ;SAVE THE MANTISSA  ;  !G DONE  ;  J;INTERPOLATOR EVALUATES POINTER+((POINTER+1)-(POINTER))*INTERPOLATOR/16)  ;  }INTERP: ;INTERPOLATOR FOR 10 BIT MANTISSA 082E 3E00 MVI A,0 ;CLEAR THE SIGN BYTE 0830 329F86 STA (INTSCR+3)  E; 0833 2A9D86 LHLD (INTSCR+1) ;LOAD THE TABLE POINTER 0836 46 " MOV B,M ;(POINTER) TO B 0837 23  INX H 0838 7E $ MOV A,M ;(POINTER+1) TO A 0839 B8 CMP B ;DETERMIN THE INTERPOLATI""3OV M,A 0877 C9  RET  ;  ; THE SIGN IS -  ;  ;"SETVAL" EXPECTS A VARIABLE, FOLLOWED BY AN EQUAL SIGN AND  < ;THE AN EXPR. IT EVALUATES THE EXPR. AND SET THE VARIABLE   ;TO THAT VALUE.   ;  < ;"FIN" CHECKS THE END OF A COMMAND, IF IT ENDED WITH ";",  < ;EXECUTION CONTINUES. IF IT ENDED WITH A CR, IT FINDS THE  ' ;NEXT LINE AND CONTINUES FROM THERE.   ;   #A) MOV B,H ;VALUE IN BC NOW 0A37 4D  MOV C,L 0A38 E1  POP H ;GET ADDRRESS 0A39 71  MOV M,C ;SAVE VALUE 0A3A 23  INX H 0A3B 70  MOV M,B 0A3C C9  RET  =SV1: ;07CA 0A3D C3590A JMP QWHAT ;07E0H NO "=" SIGN  ]FIN: ;07CD +++FIN+++ 0A40 CD520C CALL PG0 0A43 3B04 DB ';',(FI1-$-1) 0A45 F1 V POP PSW ;";",PURGE RET ADDR. 0A46 C34203 JMP RUNSML ;032BH CONTINUE SAME LINE  FI1: ;07#&P COUNTER IN C. ** SIGN IN B 09B9 17 U RAL ;SHIFT LEFT MULTIPLIER 09BA D2BE09 JNC CHCNTI ;GO ON IF CARRY=0 09BD 19 8 DAD D ;ADD MULTIPLICAND TO PRODUCT IF CARRY=1 09BE 0D GCHCNTI: DCR C ;GO TO THE NEXT BIT 09BF C2B809 JNZ MULTI 09C2 C9  RET ;FINISHED  ;  %DIVIDE: ;0786 +++DIVIDE+++ 09C3 D5 # PUSH D ;SAVE THE DIVISOR 09C4 EB Z XCHG ;DIVISOR IN HL, DIVIDEND IN DE 09C5 0601 MVI B,1 ;CLEAR THE B REGISTER #OV A,H 09F9 B7  ORA A 09FA 1F  RAR 09FB 67  MOV H,A 09FC 7D  MOV A,L 09FD 1F  RAR 09FE 6F  MOV L,A 09FF F1 , POP PSW ;GET THE SHIFT COUNT BACK 0A00 3D S DCR A ;DECREMENT THE COUNT 0A01 C2D209 JNZ DV2 ;GO TO THE NEXT MSB 0A04 EB A XCHG ;QUOTIENT IN BC, REMAINDER IN HL, DIVIDEND IN DE 0A05 D1  POP D 0A06 C9  RET  ;  #SUBDE: ;079C +++SUBDE+++ 0A07 7D  MOV A,L 0A08 93#i; ;"ENDCHK" CHECKS IF A COMMAND IS ENDED WITH CR, THIS IS  @ ;REQUIRED IN CERTIAND COMMANDS, (GOTO, RETURN, AND STOP ETC.)   ;  > ;"ERROR" PRINTS THE STRING POINTED BY DE (AND ENDS WITH CR)  : ;IT THEN PRINTS THE LINE POINTED BY "CURRNT" WITH A "?"  < ;INSERTED AT WHERE THE OLD TEXT POINTER (SHOULD BE ON TOP  7 ;OF THE STACK) POINTS TO. EXECUTION OF TB IS STOPPED  & ;AND TB1 IS RESTARTED. HOWEVER, IF 'C#_D4 0A49 CD520C CALL PG0 ;NOT ";", IS IT CR? 0A4C 0D04 DB 0DH,(FI2-$-1) 0A4E F1 R POP PSW ;YES, PURGE RET ADDR. 0A4F C33203 JMP RUNNXL ;031BH RUN NEXT LINE  FI2: ;07DB 0A52 C9  RET ;ELSE RETURN TO CALLER  mENDCHK: ;07DC +++ENDCHK+++ 0A53 CD740C CALL IGNBLK 0A56 FE0D CPI 0DH ;END WITH CR? 0A58 C8  RZ ;OK, ELSE SAY "WHAT?"  %QWHAT: ;07E0 +++QWHAT+++ 0A59 D5 PUSH D  AWHA# f + DV1: ;LEFT JUSTIFY THE DIVISOR 09C7 29 ( DAD H ;LEFT SHIFT THE DIVISOR 09C8 04 " INR B ;COUNT THE SHIFTS 09C9 7A MOV A,D ;TEST FOR MSB 09CA BC " CMP H 09CB D2C709 JNC DV1  ; 09CE 78 c MOV A,B ;STORE THE SHIFT COUNT ON THE STACK 09CF 010000 LXI B,0 ;CLEAR BC FOR THE QUOTIENT  %DV2: ;DIVISOR > DIVIDEND? 09D2 F5  PUSH PSW 09D3 7A  MOV A,D 09D4 BC % CMP H ;IS IT GREATER 09D5 DAF109 #  " SUB E ;SUBTRACT DE FROM 0A09 6F  MOV L,A ;HL. 0A0A 7C  MOV A,H 0A0B 9A  SBB D ;RESULT IN HL 0A0C 67  MOV H,A 0A0D C9  RET  %CHKSGN: ;07A3 +++CHKSGN+++ 0A0E 7C  MOV A,H 0A0F B7 " ORA A ;CHECK SIGN OF HL 0A10 F0  RP ;IF - ,CHANGE SIGN  %CHGSGN: ;07A6 +++CHGSGN+++ 0A11 7C  MOV A,H 0A12 2F " CMA ;CHANGE SIGN OF HL 0A13 67  MOV H,A 0A14 7D  MOV A,L 0A15 2F # URRNT'->ZERO  = ;(INDICATING A DIRECT COMMAND) , THE DIRECT COMMAND IS NOT  : ;PRINTED, AND IF 'CURRNT'->NEGATIVE # (INDICATING INPUT  < ;COMMAND, THE INPUT LINE IS NOT PRINTED AND EXICUTION IS  - ;NOT TERMINATED BUT CONTINUED AT 'INPEPR'.   ;  ) ;RELATED TO 'ERROR' ARE THE FOLLOWING:  ? ;'QWHAT' SAVES TEXT POINTER IN STACK AND GET MESSAGE "WHAT?"  & ;'AWHAT' JUST GET MESSAGE "WHAT?" AND#  0A64 97 # SUB A ;AND PUT A 0 THERE 0A65 12 I STAX D 0A66 2A8686 LHLD CURRNT ;09C1H GET CURRENT LINE # 0A69 E5  PUSH H 0A6A 7E MOV A,M ;CHECK THE VALUE 0A6B# G JC DV4 ;SKIP IF NOT 09D8 C2E009 JNZ DV3 ;IS IT ZERO? 09DB 7B + MOV A,E ;YES, COMPARE LOWER BYTE 09DC BD 2 CMP L 09DD DAF109 JC DV4 ;SKIP IF GREATER  ;  2DV3: ;SUBTRACT HL FROM DE RESULT IN DE 09E0 7B  MOV A,E 09E1 95  SUB L 09E2 5F  MOV E,A 09E3 7A  MOV A,D 09E4 9C  SBB H 09E5 57 MOV D,A  ; 09E6 79 + MOV A,C ;LEFT SHIFT THE QUOTIENT 09E7 B7  ORA A 09E8 17 # CMA 0A16 6F  MOV L,A 0A17 23  INX H 0A18 78 = MOV A,B ;AND ALSO FLIP B 0A19 EE80 XRI 80H 0A1B 47  MOV B,A 0A1C C9  RET  CKHLDE: ;07B2 0A1D 7C  MOV A,H 0A1E AA I XRA D ;SAME SIGN? 0A1F F2230A JP CK1 ;07B8H YES, COMPARE 0A22 EB $ XCHG ;NO EXCHANGE AND COMPLIMENT  2CK1: ;07B8 0A23 CD6C0C CALL COMP 0A26 C9  RET   ;   ;  ;+++SETVAL# JUMP TO ERROR.  4 ;'QSORRY' AND 'ASORRY' DO THE SAME KIND OF THING.  ; ;'OHOW' AND 'AHOW' IN THE ZERO PAGE SECTION ALSO DO THIS   ;   ;  zSETVAL: ;07BA +++SETVAL+++ 0A27 CD840C CALL TSTVAR 0A2A DA590A JC QWHAT ;07E0H "WHAT?", NO VARIABLE 0A2D E5 PUSH H ;SAVE ADDRESS OF VARIABLE 0A2E CD520C CALL PG0 0A31 3D0A DB '=',(SV1-$-1) ;PASS "=" SIGN 0A33 CD640C CALL EXPR ;EVALUATE EXPR. 0A36 44 $$ 23  INX H 0A6C B6  ORA M 0A6D D1 I POP D 0A6E CA8501 JZ RSTART ;0181H IF ZERO, JUST RESTART 0A71 7E ! MOV A,M ;IF NEGATIVE, 0A72 B7 v ORA A 0A73 FAAB05 JM INPERR ;0568H REDO INPUT 0A76 CDB60B CALL PRTLN ;08EDH ELSE PRINT THE LINE 0A79 1B ! DCX D ;UPTO WHERE 0 IS 0A7A F1 ) POP PSW ;RESTORE THE CHARACTOR 0A7B 12 [ STAX D 0A7C 3E3F MVI A,'?' ;3FH PRINT A "?" 0A7E CD5C0C CALL PRCHR 0A81 97  SUB A ;AND THE $[>'FNDLN' WILL INITIALIZE DE TO THE BEGINNING OF THE TEXT SAVE  8 ;AREA TO START THE SEARCH. SOME OTHER ENTRIES OF THIS  5 ;ROUTINE WILL NOT INITIALIZE DE AND DO THE SEARCH.  : ;'FNDLNP' WILL START WITH DE AND SEARCH FOR THE LINE #.  @ ;'FNDNXT' WILL BUMP DE BY 2, FIND A CR AND THEN START SEARCH.  8 ;'FNDSKP' USE DE TO FIND A CR, AND THEN START SEARCH.   ;   ;  GETLN: ;0814 +++GETLN+++ $)S' ;37H BUFFER AND 0FFH 0ADF CA040B JZ GL4 ;084FH NO REDO WHOLE LINE 0AE2 1B  DCX D ;YES, BACKUP POINTER  -BKSPC: ;BACK SPACE THE CURSER AND DELETE  ;THE CHARACTER FROM THE SCREEN 0AE3 3E08 MVI A,08H ;AND ECHO A BACK SPACE 0AE5 CD5C0C CALL PRCHR 0AE8 3E20 MVI A,20H ;SPACE 0AEA CD5C0C CALL PRCHR 0AED 3E08 MVI A,08H ;BACK SPACE 0AEF CD5C0C CALL PRCHR 0AF2 3 ;'GETLN' READS A INPUT LINE INTO 'BUFFER'. IT FIRST PROMPTS   ;THE CHARACTER IN A (GIVEN BY$U 0A8F CD5C0C CALL PRCHR 0A92 113787 LXI D,BUFFER ;0F37H PROMPT AND INIT.  IGL1: ;0818 0A95 CD8D0C CALL CHKIO ;0985H CHECK KEYBOARD 0A98 00  NOP 0A99 00 NOP 0A9A CA950A JZ GL1 ;0818H NO INPUT, WAIT. 0A9D FE7F CPI 7FH ;DELETE LAST CHARACTER? 0A9F CADC0A JZ GL3 ;0842H YES 0AA2 FE08 CPI 08H ;IS IT A BACKSPACE? 0AA4 CAC80A JZ CONTH ;YES DELETE THE LAST CHARACTER 0AA7 FE0A 5 CPI 0AH ;INPUT, ECHO BACK , IGNORE LF 0AA9 CA$ 0AF7 3E20 MVI A,20H ;SPACE 0AF9 CD5C0C CALL PRCHR 0AFC 3E08 MVI A,08H ;BACK SPACE 0AFE CD5C0C CALL PRCHR 0B01 C3950A JMP GL1 ;0818H GO GET NEXT INPUT  GL4: ;084F ;REDO ENTIRE LINE 0B04 CD5A0C CALL CRLF1 0B07 3E5E MVI A,5EH ;CR, LF, AND UP-ARROW 0B09 C38F0A JMP GETLN ;0814H  $FNDLN: ;0857 +++FNDLN+++ 0B0C 7C  MOV A,H 0B0D B7 N ORA A ;CHECK SIGN OF HL 0B0E FA6A01 JM QHOW ;0166H IT CANNOT BE "-" 0$% 2 ;CALLER). OLD A IS STORED IT B, OLD B IS LOST.   ;  ; ;'OTSTG' LOOKS FOR A BACK-ARROW. SINGLE QUOTE, OR DOUBLE  = ;QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACK-ARROW,  > ;OUTPUT A CR WITHOUT A LF. IF SINGLE OR DOUBLE QUOTE, PRINT  ; ;THE STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE.  @ ;AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED   ;OVER (USUALLY A JUMP INSTRU$ f! THE CALLER), THEN IT FILLS THE  : ;BUFFER AND ECHOS. IT IGNORES LF'S AND NULLS, BUT STILL  : ;ECHOS THEM BACK. RUB-OUT IS USED TO CAUSE IT TO DELETE  @ ;THE LAST CHARACTER (IF THERE IS ONE), AND ALT-MOD IS USED TO  ; ;CAUSE IT TO DELETE THE WHOLE LINE AND START IT ALL OVER  > ;CR SIGNALS THE END OF A LINE, AND CAUSE 'GETLN' TO RETURN.   ;  > ;'FNDLN' FINDS A LINE WITH A GIVEN LINE # (IN HL) IN THE $ !950A JZ GL1 ;0818H 0AAC B7 ORA A ;IGNORE NULL 0AAD CA950A JZ GL1 ;0818H 0AB0 FE5C CPI 5CH ;DELETE THE WHOLE LINE? 0AB2 CA040B JZ GL4 ;084FH YES 0AB5 12 # STAX D ;ELSE, SAVE INPUT 0AB6 13 INX D ;AND BUMP POINTER 0AB7 FE0D CPI 0DH ;WAS IT CR? 0AB9 C2C20A JNZ MORM ;083CH NO, JUMP TO MORM 0ABC 3E0A MVI A,0AH ;YES, END OF LINE 0ABE CD5C0C CALL PRCHR 0AC1 C9  RET  -MORM: ;083C IS E 87H?, IF NOT LOOP 0AC2 7$ 7B11 11E00C LXI D,TXTBGN ;09D7H INIT, TEXT POINTER  "FL1: ;085F +++FNDLP+++ 0B14 E5 Z PUSH H ;SAVE LINE # 0B15 2ADE0C LHLD TXTUNF ;09D5H CHECK IF WE PASSED END 0B18 2B N DCX H ;GET LINE # BACK 0B19 CD6C0C CALL COMP ;C,NZ PASSED END 0B1C E1  POP H 0B1D D8 RC 0B1E 1A ) LDAX D ;WE DID NOT, GET BYTE 1 0B1F 95 # SUB L ;IS THIS THE LINE? 0B20 47 % MOV B,A ;COMPARE LOW ORDER 0B21 13  INX D 0B22 1A LDAX D ;$  CTION).   ;  > ;'PRTNUM' PRINTS THE NUMBER IN HL. LEADING BLANKS ARE ADDED  = ;IF NEEDED TO PAD THE NUMBER OF SPACES TO THE NUMBER IN C.  < ;HOWEVER, IF THE NUMBER OF DIGITS IS LARGER THAN THE # IN  ; ;C, ALL DIGITS ARE PRINTED ANYWAY. NEGATIVE SIGN IS ALSO  0 ;PRINTED AND COUNTED IS. POSTIVE SIGN IS NOT.   ;  9 ;'PRTLN' PRINTS A SAVED TEXT LINE WITH LINE # AND ALL.   ; $  ; ;TEXT SAVE AREA. DE IS USED AS THE TEXT POINTER. IF THE  > ;LINE IS FOUND, DE WILL POINT TO THE BEGINNING OF THAT LINE  < ;(I.E. THE LOW BYTE OF THE LINE #), AND FLAGS ARE NC & Z.  < ;IF THE LINE IS NOT THERE AND A LINE WITH A HIGHER LINE #  : ;IS FOUND, DE POINTS TO THERE AND FLAGS ARE NC & NZ. IF  < ;WE REACHED THE END OF TEXT SAVE AREA AND CANNOT FIND THE   ;LINE, FLAGS ARE C & NZ.   ;$B M MOV A,E 0AC3 FE87 CPI 87H 0AC5 C2950A JNZ GL1 ;0818H 0AC8 7B bCONTH: MOV A,E ;DELETE LAST CHARACTER 0AC9 FE37 CPI '7' 0ACB CA040B JZ GL4 0ACE 1B DCX D ;BACKUP THE POINTER 0ACF 3E20 MVI A,20H ;SPACE 0AD1 CD5C0C CALL PRCHR ;TO THE CONSOLE 0AD4 3E08 MVI A,08H ;BACK SPACE 0AD6 CD5C0C CALL PRCHR 0AD9 C3950A JMP GL1  GL3: ;0842 0ADC 7B ? MOV A,E ;DELETE LAST CHARACTER (NULL) 0ADD FE37 CPI '7$GET BYTE 2 0B23 9C V SBB H ;COMPARE HIGH ORDER 0B24 DA2B0B JC FL2 ;0874H NO, NOT THERE YET 0B27 1B * DCX D ;ELSE WE EITHER FOUND IT, 0B28 B0 $ ORA B ;OR IT IS NOT THERE 0B29 C9  RET ;NC,Z: FOUND, NC,NZ: NO  &FNDNXT: ;0873 +++FNDNXT+++ 0B2A 13  INX D ;FIND NEXT LINE  -FL2: ;0874 JUST PASSED BYTE 1 & 2 0B2B 13  INX D  &FNDSKP: ;0875 +++FNDSKP+++ 0B2C 1A ( LDAX D 0B2D FE0D CPI 0DH ;TRY T%x%v  ;  %PRTSTG: ;087F +++PRTSTG+++ 0B36 47 MOV B,A  PS1: ;0880 0B37 1A " LDAX D ;GET A CHARACTER 0B38 13  INX D ;BKUMP POINTER 0B39 B8 CMP B ;SAME AS OLD A? 0B3A C8 RZ ;YES RETURN 0B3B CD5C0C CALL PRCHR ;ELSE PRINT IT 0B3E FE0D CPI 0DH ;WAS IT CR? 0B40 C2370B JNZ PS1 ;0880H NO, NEXT 0B43 C9  RET ;YES RETURN  =OTSTG: ;088B +++OTSTG+++ 0B44 CD520C CALL PG0 0B47 2%@ 0B85 CDC309 CALL DIVIDE ;0786H DIVIDE HL BY 10 0B88 78  MOV A,B ;RESULT 0? 0B89 B1 B ORA C ; 0B8A CA950B JZ PN3 ;08D2H YES, WE GOT ALL 0B8D E3 $ XTHL ;NO, SAVE REMAINDER 0B8E 2D ! DCR L ;AND COUNT SPACE 0B8F E5 ! PUSH H ;HL IS OLD BC ' 0B90 60 % MOV H,B ;MOVE RESULT TO BC 0B91 69 < MOV L,C 0B92 C3850B JMP PN2 ;08C2H AND DIVIDE BY 10  PN3: ;08D2 0B95 C1  POP B ;WE GOT ALL DIGITS IN  PN4: %;HERE DE-> TO WHERE HL->   ;UNTIL DE = BC   ;  > ;'POPA' RESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE  ;STACK   ;  = ;'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SAVE AREA INTO THE  ;STACK   ;  =MVUP: ;0900 +++MVUP+++ 0BCB CD6C0C CALL COMP 0BCE C8  RZ ;DE = HL, RETURN 0BCF 1A  LDAX D ;GET ONE BYTE 0BD0 02  STAX B ;MOVE IT 0BD1 13%6 LHLD LOPVAR ;09C9H ELSE SAVE LOOP VAR. $ 0C0F 7C & MOV A,H ;BUT IF LOPVAR IS 0 0C10 B5 y ORA L ;THAT WILL BE ALL 0C11 CA270C JZ PU1 ;095AH 0C14 2A9686 LHLD LOPPT ;09D1H ELSE, MORE TO SAVE 0C17 E5 5 PUSH H 0C18 2A9486 LHLD LOPLN ;09CFH 0C1B E5 6 PUSH H 0C1C 2A9286 LHLD LOPLNT ;09CDH 0C1F E5 6 PUSH H 0C20 2A9086 LHLD LOPINC ;09CBH 0C23 E5 . PUSH H 0C24 2A8E86 LHLD LOPVAR ;09C9H  PU1: ;095A 0C27 E5 %I20F DB '"',(OT3-$-1) 0B49 3E22 MVI A,'"' ;22H IT IS A (")  |OT1: ;0890 PRINT UNTIL ANOTHER 0B4B CD360B CALL PRTSTG ;087FH 0B4E FE0D CPI 0DH ;WAS LAST ONE A CR? 0B50 E1 Q POP H ;RETURN ADDRESS 0B51 CA3203 JZ RUNNXL ;031BH WAS CR, RUN NEXT LINE  2OT2: ;0899 SKIP THREE BYTES ON RETURN 0B54 23  INX H 0B55 23  INX H 0B56 23  INX H 0B57 E9  PCHL ;RETURN  OT3: ;089D 0B58 CD520C C%;08D3 0B96 0D  DCR C ;THE STACK 0B97 79 ' MOV A,C ;LOOK AT SPACE COUNT 0B98 B7 ORA A 0B99 FAA40B JM PN5 ;08DFH NO LEADING BLANKS 0B9C 3E20 MVI A,' ' ;20H LEADING BLANKS 0B9E CD5C0C CALL PRCHR ; 0BA1 C3960B JMP PN4 ;08D3H MORE?  PN5: ;08DF PRINT SIGN 0BA4 78 / MOV A,B 0BA5 CD5C0C CALL PRCHR 0BA8 5D  MOV E,L ;LAST REMAINDER IN E  PN6: ;08E2 D 0BA9 7B ) MOV A,E ;CHECK DIGIT IN E 0BAA FE0A % ( INX D ;INCREASE BOTH POINTERS 0BD2 03 5 INX B 0BD3 C3CB0B JMP MVUP ;0900H UNTIL DONE  %MVDOWN: ;0909 +++MVDOWN+++ 0BD6 78  MOV A,B 0BD7 92 N SUB D ;TEST IF DE = BC 0BD8 C2DE0B JNZ MD1 ;0911H NO, GO MOVE 0BDB 79 & MOV A,C ;MAYBE, OTHER BYTE? 0BDC 93  SUB E 0BDD C8  RZ ;YES, RETURN  MD1: ;0911 0BDE 1B " DCX D ;ELSE MOVE A BYTE 0BDF 2B $ DCX H ;BUT FIRST DECREASE 0BE0 1A LDAX D ;%8 PUSH H 0C28 C5 & PUSH B ;BC = RETURN ADDRESS 0C29 C9  RET   ;  1 ;THIS IS THE TERMINAL OUTPUT ROUTINE THE ASCII  1 ;CHARACTER IS IN THE A REG. IF CR, LF IS ADDED   ;  @OC2: ;095D 0C2A C22F0C JNZ OC3 ;0962H IT IS ON 0C2D F1  POP PSW ;IT IS OFF 0C2E C9  RET ;RESTORE AF AND RETURN  OC3: ;0962 0C2F F1 * POP PSW ;COME HERE TO DO OUTPUT 0C30 C5 PUSH B 0C% ALL PG0 ;IS IT A (') ? 0B5B 2705 DB '''',(OT4-$-1) 0B5D 3E27 MVI A,'''' ;27H YES, DO SAME 0B5F C34B0B JMP OT1 ;0890H AS IN (")  OT4: ;08A5 0B62 CD520C CALL PG0 ;IS IT BACK-ARROW? 0B65 5F0C DB '_',(OT5-$-1) ; 0B67 3E8D MVI A,8DH ;YES, CR WITHOUT LF 0B69 CD5C0C CALL PRCHR ;DO IT TWICE TO GIVE 0B6C CD5C0C CALL PRCHR ;TTY ENOUGH TIME (SHOULD WE CA!LL THE RUBOUT ROUTINE?) 0B6F E1 2 POP H ;RETURN ADDDRESS 0B70 C3540B JMP OT2 % d- CPI 0AH ;10 IS FLAG FOR NO MORE 0BAC D1  POP D 0BAD C8 RZ ;IF SO, RETURN 0BAE C630 ADI '0' ;30H ELSE CONVERT TO ASCII 0BB0 CD5C0C CALL PRCHR ;AND PRINT THE DIGIT 0BB3 C3A90B JMP PN6 ;08E2H GO BACK FOR MORE  #PRTLN: ;08ED +++PRTLN+++ 0BB6 1A  LDAX D 0BB7 6F $ MOV L,A ;LOW ORDER LINE # 0BB8 13 # INX D ;HIGH ORDER LINE # 0BB9 1A ' LDAX D ;PRINT 4 DIGIT LINE # 0BBA 67  MOV H,A 0BBB 13  INX D 0BBC 0E0% BOTH POINTERS AND 0BE1 77 D MOV M,A ;THEN DO IT 0BE2 C3D60B JMP MVDOWN ;0909H LOOP BACK  POPA: ;0918 0BE5 C1 % POP B ;BC = RETURN ADDRESS 0BE6 E1 [ POP H ;RESTORE LOPVAR, BUT 0BE7 228E86 SHLD LOPVAR ;09C9H =0 MEANS NO MORE 0BEA 7C  MOV A,H 0BEB B5 ? ORA L 0BEC CAFF0B JZ PP1 ;0932H YEP, GO RETURN 0BEF E1 P POP H ; NOP, RESTORE OTHERS 0BF0 229086 SHLD LOPINC ;09CBH 0BF3 E1 ! POP H 0BF4 229286 SHLD LOP% 131 D5  PUSH D 0C32 E5 S PUSH H 0C33 328186 STA OCSW-1 ;09BFH STORE THE CHARACTER AT OCSW-1 0C36 5F MOV E,A ;MOVE ASCII CHARACTER TO BE OUTPUT FROM A TO E 0C37 0E02 MVI C,2 ;CONSOLE OUTPUT 0C39 CD0500 CALL 5 ;CALL BDOS, PRINT THE CHARACTER ON THE CONSOLE 0C3C 3A8186 LDA OCSW-1 ;09BFH RELOAD THE CHARACTER 0C3F FE0D CPI 0DH ;IS IT CR? 0C41 C24B0C JNZ LDACC ;097EH NO, JUMP LDACC 0C44 1E0A MVI E,0AH ;YES, SEND LF TO THE TERMINAL 0C46 0E02% ;0899H  OT5: ;08B0 0B73 C9  RET ;NONE OF THE ABOVE  %PRTNUM: ;08B1 +++PRTNUM+++ 0B74 D5 / PUSH D ; 0B75 110A00 LXI D,0AH 0B78 D5  PUSH D 0B79 42  MOV B,D 0B7A 0D DCR C 0B7B CD0E0A CALL CHKSGN ;07A3H CHECK SIGN 0B7E F2840B JP PN1 ;08C1H NO SIGN 0B81 062D MVI B,'-' ;2DH B-SIGN 0B83 0D  DCR C ;'-' TAKES SPACE  PN1: ;08C1 0B84 C5  PUSH B ;SAVE  PN2: ;08C2%m4 MVI C,4 0BBE CD740B CALL PRTNUM ;08B1H 0BC1 3E20 MVI A,' ' ;20H FOLLOWED BY A BLANK 0BC3 CD5C0C CALL PRCHR 0BC6 97 H SUB A ;AND THEN THE TEXT 0BC7 CD360B CALL PRTSTG ;087FH 0BCA C9  RET   ;  ( ;+++MVUP+++MVDOWN+++PAPA+++& PUSHA+++   ;  ? ;'MVUP' MOVES A BLOCK UP FROM WHERE DE-> TO WHERE BC-> UNTIL  ;DE = HL   ;  $ ;'MVDOWN' MOVES A BLOCK DOWN FROM W%LNT ;09CDH 0BF7 E1 4 POP H 0BF8 229486 SHLD LOPLN ;09CFH 0BFB E1 , POP H 0BFC 229686 SHLD LOPPT ;09D1H  PP1: ;0932 0BFF C5 & PUSH B ;BC = RETURN ADDRESS 0C00 C9  RET  nPUSHA: ;0934 +++PUSHA+++ 0C01 21AF87 LXI H,STKLMT ;0FAFH 0C04 CD110A CALL CHGSGN ;07A6H 0C07 C1 % POP B ;BC = RETURN ADDRESS 0C08 39 g DAD SP ;IS STACK NEAR THE TOP? 0C09 D2880A JNC QSORRY ;080DH YES, SORRY FOR THAT. 0C0C 2A8E86 &&H MVI C,2 ;OUTPUT TO TERMINAL 0C48 CD0500 CALL 5 ;CALL BDOS  ILDACC: ;097E 0C4B 3A8186 LDA OCSW-1 ;09BFH RELOAD THE CHARACTER  3POPR: ;0981 RESTORE ALL THE REGISTERS 0C4E E1  POP H 0C4F D1  POP D 0C50 C1  POP B 0C51 C9  RET   ;  ( ;THIS IS THE RESTART SUBROUTINE GROUP   ;  5PG0: ;0A50 THIS BLOCK IS MOVED INTO PAGE 0 0C52 E3  XTHL 0C53 CD740C && JMP TV0 ;JUMP TV0 AND CALL PARN   ;  A ;THIS IS CONSOLE STATUS, 00 RETURNED IN A, IF READY FOR INPUT.   ;FF RETURNED IF NO INPUT.   ;  CHKIO: ;0985 0C8D C5 ! PUSH B ;PUSH REGISTERS 0C8E D5  PUSH D 0C8F E5 a PUSH H 0C90 0E0B MVI C,0BH ;CONSOLE STATUS 0C92 CD0500 CALL 5 ;CALL BDOS 0C95 B7 Z ORA A ;READY? 0C96 C29C0C JNZ CONTLO ;0994H YES, GET INPUT CHARACTER 0C99 C34E0C &OMOV C,A 0CC9 ED78 DB 0EDH,78H;Z80 INPUT INSTRUCTION IN A,(C) 0CCB AC 5 XRA H ;EX-OR WITH "K", IF GIVEN IN PROGRAM 0CCC A5 P ANA L ;MASK WITH "J" 0CCD CAC30C JZ WAITCOM ;09B3H LOOP IF ZERO 0CD0 C1 & POP B 0CD1 CD7C0C CALL FINISH   ;  : ;INP COMMAND THE PORT # IS CHANGED BY THE BASIC PROGRAM   ;  INCOMM: 0CD4 C5  PUSH B ;SAVE BC 0CD5 43 1 MOV B,E ;PREVENT 8080 CRASH 0CD6 3A9A86 LD&q00C6000B7C32A0CCD6706E5C32306577CBAC07DFF :100C7000BBC9414E1AFE20C013C3740CF1CD400A0B :100C8000C3590A47CD740CD640D8C30301C5D5E576 :100C90000E0BCD0500B7C29C0CC34E0C0E01CD054A :100CA00000FE0FC2B00C3A82862F328286C38D0CB2 :100CB000FE03C24E0CC38501C5F53A9B864FF1ED8C :100CC00079C1C9C5433A9A864FED78ACA5CAC30C21 :100CD000C1CD7C0CC5433A9A864FED786FC9E00CC4 :100CE0004D7F7F7F4241494C455920524F4D4142F3 :100CF0004C452054494E59204241534943205645C2 :100D0000522E2031300D3EFF3282863E0ACD5C0CE1 :100D10009711E10CCD& CALL IGNBLK 0C56 BE ) CMP M 0C57 C33101 JMP TC1 ;012FH    9CRLF1: ;0A56 +++CRLF+++ 0C5A 3E0D MVI A,0DH ;  $PRCHR: ;PRINT CHARACTERS 0C5C F5 R PUSH PSW ;RST 2 0C5D 3A8286 LDA OCSW ;09C0H PRINT CHARACTERS ONLY 0C60 B7 P ORA A ;IF OCSTW IS ON 0C61 C32A0C JMP OC2 ;095DH REST OF THIS IS AT OC2  >EXPR: 0C64 CD6706 CALL EXPR2 ;0616H +++EXPR+++ 0C67 E5 " PUSH H ;EVALUATE AN EXPRESSION &j6 JMP POPR ;0981H NO, POP THE REGISTERS AND RETURN   ;  : ;THIS IS THE CONSOLE INPUT ROUTINE, ASCII CHARACTER IS   ;RETURNED IN A .   ;  CONTLO: ;0994 0C9C 0E01 MVI C,1 ;CONSOLE INPUT 0C9E CD0500 CALL 5 ;CALL BDOS 0CA1 FE0F CPI 0FH ;IS IT BACK-SPACE (^I)? 0CA3 C2B00C JNZ CI1 ;09A8H NO,SKIP TO CI1 0CA6 3A8286 LDA OCSW ;09C0H YES, RELOAD THE BACK-SPACE 0CA9 2F  CMA ;COMPLEMENT (F0H)&.'A INPORT ;GET THE PORT NUMBER 0CD9 4F P MOV C,A 0CDA ED78 DB 0EDH,78H;Z80 INPUT INSTRUCTION IN A,(C) 0CDC 6F % MOV L,A ;RETURN THE NUMBER 0CDD C9  RET ;IN THE L REG.  ;  fTXTUNF: ;09D5 ->UNFILLED TEXT AREA (END OF PROGRAM TEXT) 0CDE E00C DW TXTBGN ;INITIAL VALUE  .TXTBGN: ;09D7 TEXT SAVE AREA BEGINS 0CE0 4D DB 'M'  ;  ;; SIGN ON MESSAGE (OVER WRITTEN BY THE BASIC PROGRAM) &K!360B218801220101C3850119 :10868200 E8 :0F8692000100D8 :00 ......s*|q: * |  s#r  {w#6"** >2 h!9N#F~#~~+~#~+^#V####|%~#fo!-D Internal Error - No Line Number ~#D at lineu>ͩ<ڎ͢xͩ<ڎ00͢Ҋ}_|W!v1~#fo>D at address|h}h> 0> 0~#*v1~#fo!9",& A0C68 C32306 JMP EXPR1 ;05D2H REST OF IT IS AT EXPR1 0C6B 57 DB 'W'   ;  COMP: 0C6C 7C  MOV A,H ;+++COMP+++ 0C6D BA % CMP D ;COMPARE HL WITH DE 0C6E C0 % RNZ ;RETURN CORRECT C AND 0C6F 7D  MOV A,L ;Z FLAGS 0C70 BB # CMP E ;BUT OLD A IS LOST 0C71 C9 " RET 0C72 414E DB 'AN'  IGNBLK: 0C74 1A L LDAX D ;+++IGNBLK+++ 0C75 FE20 CPI ' ' ;20H IGNORE BLANKS 0C77 C0  RNZ & i 0CAA 328286 STA OCSW ;09C0H STORE BACK 0CAD C38D0C JMP CHKIO ;0985H JUMP TO CONSOLE STATUS  CI1: ;09A8 0CB0 FE03 CPI 3 ;IS IT 03 (^C) 0CB2 C24E0C JNZ POPR ;0981H NO, POP THE REGISTERS AND GO ON 0CB5 C38501 JMP RSTART ;0181H RESTART  ;  LSTROM: 0CB8 C5  PUSH B ;SAVE BE 0CB9 F5 T PUSH A ;SAVE THE DATA 0CBA 3A9B86 LDA OUTPORT ;LOAD THE PORT NUMBER 0CBD 4F * MOV C,A ;PUT THE PORT NUMBER IN C 0CBE &  g MSAG1: ; 0CE1 7F7F7F4241 DB 7FH,7FH,7FH,'BAILEY ROMABLE ' 0CF3 54494E5920 DB 'TINY BASIC VER. '  )MSAG2: ; 0D03 31300D DB '10',0DH   ;MESSAGE READING ROUTINE  SETSTK: ;09FF 0D06 3EFF MVI A,0FFH ;INITIALIZE SWITCH FOR OUTPUT 0D08 328286 STA OCSW ;09C0H 0D0B 3E0A MVI A,0AH 0D0D CD5C0C CALL PRCHR 0D10 97 b SUB A 0D11 11E10C LXI D,MSAG1 ;09D8H 0D14 CD360B CALL PRTSTG ;087FH PRINT THE SIGN ON& ;!*,".!$*.!:ey*r~#^#V#ȷN=GO [=b*{z*?w}|*p#N#F*r~#@ʞ^#V# ~#s#r_Ã6#6#6*r{OzG*tw+ x´#"r##6@#*r}o|g++s#r++"r"p|‡}p+ʿ.¼.`i"!"!"n ,ͦIX*2*2*2*2h@*2h*2*2 ,Zͦ~#wxAh !>Òͦ2Am'ډ ¶¦"G{,xPX'!R Oz"y 9 O{,yx' { ,>& ;IN TEXT (WHERE DE->) 0C78 13 Q INX D ;AND RETURN THE FIRST 0C79 C3740C JMP IGNBLK ;NON-BLANK CHAR. IN A   ;  FINISH: 0C7C F1 POP PSW ;+++FINISH+++ 0C7D CD400A CALL FIN ;07CDH CHECK END OF COMMAND 0C80 C3590A JMP QWHAT ;07E0H PRINT "WHAT?" IF WRONG 0C83 47 DB 'G'  l ; 0C84 CD740C TSTVAR: CALL IGNBLK ;+++TSTV+++ 0C87 D640 SUI '@' ;40H TEST VARIABLES 0C89 D8 % RC ; C:NOT A VARIABLE 0C8A C30301&|F1 ^ POP PSW ;GET THE DATA BACK 0CBF ED79 DB 0EDH,79H;Z-80 CODE FOR OUPUT A,(C) 0CC1 C1  POP B 0CC2 C9  RET  ; ;THIS IS THE WAIT COMMAND. THE INPUT PORT # SPECIFIED IN  : ;THE BASIC PROGRAM IS READ IN A LOOP UNTIL THE "J" MASK  ;RESULTS IN A NON-ZERO VALUE.  WAITCOM: 0CC3 C5  PUSH B ;SAVE BC 0CC4 43 X MOV B,E ;PREVENT 8080 CRASH 0CC5 3A9A86 LDA INPORT ;GET THE PORT NUMBER 0CC8 4F  &Q MESSAGE 0D17 218801 LXI H,ST1 ;LOAD ADDRESS OF THE START ROUTINE 0D1A 220101 SHLD 0101H ;NEW JUMP VECTOR TO PROGRAM START 0D1D C38501 JMP RSTART ;0184H START THE PROGRAM  ;  ;SCRATCH PAD AREA IN RAM 8682  ORG VARBGN+2; 8682 00 >OCSW: NOP ;STORAGE REG. FOR CONSOLE OUTPUT CHARACTER 8683 00  NOP 8684 00 8 NOP ;STORAGE REG. FOR CONSOLE INPUT CHARACTER 8685 00  NOP  "CURRNT: ;09C1 SWITCH FOR OUTPU'j' x'"$ L'L $,L D'L L*( 4:r{,r6!R 2O r+~ f#6!R ɷw#M2!2R*N#"!9""y2*|ʫ*!"A~#*R j1:~ʕP"R *2*2*2*2@*2*2*2*R j1C~#"R ,ʳ •:ʕó~•!"~,"[#"~oo# ^Õ"u#"R x"ʊ ʊ+~ yAD?Redo from Start *s! *:Oò*+~+ +w ++~#fom"!'E7à21:2221:2322#Ä0F0L:2!26+~w>+6=^^#V#^#V#"1^#V#"11^#V#1x 11^# 1^#1&))) G6 G61~#fo3##@>M~+~?~X+#e+ eÐ6M96 1Ù66 1ù6^#V#ͺͺz||m99^#Vâ^#V#m9'=G-1 1080 K=0 1090 FOR L=1 TO G 1100 M1=1.5 1110 FOR I=1 TO N2 1120 M=INT(K/(2^G1)) 1130 IF M=M1 GOTO 1180 1140 X=M: GOSUB 1510 : P=Z 1150 V=PP*P 1160 C=COS(V) : S=SIN(V) 1170 M1=M 1180 K1=K+1 1190 K2=K1+N2 1200 T1=X(K2)*C+Y(K2)*S 1210 T2=Y(K2)*C-X(K2)*S 1220 X(K2)=X(K1)-T1 1230 Y(K2)=Y(K1)-T2 1240 X(K1)=X(K1)+T1 1250 Y(K1)=Y(K1)+T2 1260 K=K+1 1270 NEXT I 1280 K=K+N2 1290 IF K 50 THEN PRINT CHR$ (140);: GOSUB 3400 3140 '5*~2 #~#^#V6++i._:R *|N !R 2Am* ͅ 9* * * ͅ _!* * * BK* * * * * " * * BK* * " " " "= ~w#~wPYd>͆BKl!~@: ~@w+~_q+W: =>Cw+p+q+r+sA! ͔A%Mult. Def. Global ~@*b+"b}p+ʿ.¼.! ~#fo"T ! "V |‡*T }o|g."T *V "V #s#r++s ' 2   " ' " 2 " ͇ "  '} T 8686 00  NOP 8687 00  NOP  ,STKGOS: ;09C3 SAVES SP IN 'GOSUB' 8688 00  NOP 8689 00  NOP  %VARNXT: ;09C5 TEMP STORAGE 868A 00  NOP 868B 00  NOP  ,STKINP: ;09C7 SAVES SP IN 'INPUT' 868C 00  NOP 868D 00  NOP  -LOPVAR: ;09C9 'FOR' LOOP SAVE AREA 868E 00  NOP 868F 00  NOP  "LOPINC: ;09CB INCREMENT 8690 00  NOP 8691 00  NOP ''0 : I=Z+1 1360 IF I<=K GOTO 1400 1370 T1=X(K) : T2=Y(K) 1380 X(K)=X(I) : Y(K)=Y(I) 1390 X(I)=T1 : Y(I)=T2 1400 NEXT K 1410 PRINT CHR$(7), CHR$(7) 1420 IF M$="I" THEN GOSUB 1700 : GOSUB 1760 : PRINT : PRINT 1425 IF M$="F" THEN GOSUB 1800 : PRINT : PRINT 1430 PRINT : PRINT "TRANSFORM COMPLETE " : PRINT 1450 IF M$="I" THEN PRINT "DT=";DT 1460 IF M$="F" THEN PRINT "DF=";DF 1470 PRINT : PRINT : GOTO 200 1500 REM 1510 REM * UNSCRAMBLING ALGORITHM 1520 REM 1530 J1=X : Z=0 1540 FOR Y=1 TO G : J2=I'  ;DISASSEMBLY OF SHERRY BROTHERS VERSION OF PALO ALTO TINY BASIC ;BILL BAILEY JUNE 1 1983 ;MODIFIED STARTING JUNE 25 1983 ;BASE TWO LOGORITHMS ADDED JUNE 24 1984 ;MULTIPLY AND DIVIDE SPEEDED UP JULY 10 1984 ;RESTARTS REMOVED AUGUST 19 1984 ;CONVERT TO ROMABLE CODE DECEMBER 2 1984 ; ; RAM EQU 8000H ;START OF RAM TRAM EQU 8800H ;TOP OF RAM BUFFER EQU (TRAM-100H+37H) ;BUFFER AREA IN RAM STKLMT EQU (TRAM-100H+0AFH) ;LIMIT ADDRESS OF THE STACK VARBGN EQU (TRAM-180H) ;TOP OF VARIABLE AREA IN RAM ;'  ' 2 ͇ 2= 2= "2F H~# > x2: v ͜2<. ~o 70#c  ͜~r 70#y >2: F#~#fox . ; ʵ ~#70é ; i >"70G:x 0*+~< = ###~ *#0!r * *~= /<.  = > 70 >,70W*#^ X R +=R :=R 0z{j {_\ >2|¬ }p+ʋ ¼.`i"++"! "#! "!2 Çå&(.}o|g > 70+| 0!"!"2 !"!"2' B  LOPLNT: ;09CD LIMIT 8692 00  NOP 8693 00  NOP  #LOPLN: ;09CF LINE NUMBER 8694 00  NOP 8695 00  DB 0  5LOPPT: ;09D1 TEXT POINTER 8696 0000 DB 0,0  ?RANPNT: ;09D3 RANDOM NUMBER POINTER 8698 0001 DB 0,1  INPORT: 869A 00  DB 0  OUTPORT: 869B 00  DB 0   ; INTERPOLATION SCRATCH PAD  INTSCR: 869C 00 DB 0 ;INTE' NT(J1/2) 1550 Z=2*Z+J1-2*J2 1560 J1=J2 : NEXT : RETURN 1570 PR# 0 : PRINT : DF=1/(N*DF) 1580 IF M$="I" THEN PRINT "DT=";DT 1590 IF M$="F" THEN PRINT "DF=";DF 1600 PRINT : GOTO 200 1690 REM 1700 REM * CONJUGATE SUBROUTINE 1710 REM 1730 FOR I=1 TO N : Y(I)=-Y(I) : NEXT I : RETURN 1740 REM 1750 REM * NORMALIZE INVERSE FFT 1760 REM 1770 REM 1790 FOR I=1 TO N : X(I)=X(I)*DF : Y(I)=Y(I)*DF : NEXT : RETURN 1800 REM 1810 REM 1820 REM * NORMALIZE FORWARD FFT 1830 REM 1840 REM 1860 FOR I=1 TO N '  ; ORG 100H BEGIN: ;0100 JMP SETSTK TV0: ;0103 JNZ TV1 ;011FH NOT "@" ARRAY INX D ;IT IS THE "@" ARRAY CALL PARN ;06BCH @ SHOULD BE FOLLOWED DAD H ;BY (EXPR) AS ITS INDEX JC QHOW ;0166H IS INDEX TOO BIG PUSH D ;WILL IT OVERRUN XCHG ;RAM? LXI H,(VARBGN-RAM); FIND SIZE OF FREE RAM CALL COMP ;AND CHECK THAT JC ASORRY ;080EH IF SO SAY "SORRY" TV00: ;0117 LXI H,VARBGN ;0F00H IF NOT GET ADDRESS CALL SUBDE ;079CH OF @(EXPR) AND PUT IT POP D ;IN HL RET ;C FLAG IS CLEA'   !~6#w~!& VN  i&Ò *&*&; -A -+͞ *{ 70e |‡}*t ) MOV C,M ;IF NOT =, ADD THE 2ND MVI B,0 ;BYTE THAT FOLLOWS THE DAD B ;RST TO THE OLD PC POP B ;I.E. DO A RELATIVE (ITH THE SAME ;LINE NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE. ;IF THE REST OF THE LINE IS "CR" ONLY, IT IS NOT STORED AND ;AND ANY EXISTING LINE WITH THE SAME NUMBER IS DELETED. ; ;AFTER A LINE IS INSERTED, REPLACED, OR DELETED, THE PROGRAM ;LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILL BE ;TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE NUMBER, ;AND CONTROL IS TRANSFERED TO "DIRECT". ; ;THE MEMORY LOCATION "CURRNT" POINTS TO THE LINE NUMBER ;THAT IS(LEAR THE STACK ADD L ;COMPUTE THE NEW TXTUNF MOV L,A MVI A,0 ADC H MOV H,A ;HL->NEW UNFILLED AREA ST44: ;01E3 LXI D,VARBGN ;0F00H CHECK TO SEE IF THERE CALL COMP ;IS ENOUGH SPACE JNC QSORRY ;080DH SORRY, NO ROOM SHLD TXTUNF ;09D5H OK, UPDATE TXTUNF POP D ;DE->OLD UNFILLED AREA CALL MVDOWN ;0909H POP D ;DE->BEGIN, HL->END POP H CALL MVUP ;0900H MOVE NEW LINE TO SAVE JMP ST3 ;019DH AREA ; +++TABLES+++DIRECT+++& EXEC+++ ; ;THIS SECTION OF THE CODE TESTS A STRING AGI(SUB' DB (GOSUB SHR 8) +128 DB GOSUB AND 0FFH DB 'RETURN' DB (RETURN SHR 8) +128 DB RETURN AND 0FFH DB 'REM' DB (REM SHR 8) +128 DB REM AND 0FFH DB 'FOR' DB (FOR SHR 8) +128 DB FOR AND 0FFH DB 'INPUT' DB (IP1 SHR 8) +128 DB IP1 AND 0FFH DB 'PRINT' DB (PRINT SHR 8) +128 DB PRINT AND 0FFH DB 'STOP' DB (STOP SHR 8) +128 DB STOP AND 0FFH DB (DEFLT SHR 8) +128 DB DEFLT AND 0FFH DB 'YOU CAN ADD MORE' TAB4: ;027F FUNCTIONS DB 'RND' DB (RND SHR 8) +128 DB RND AN( DCX D ;JUMP IF NOT = TC2: ;013A ;IF =,SKIP THOSE BYTES INX D ;AND CONTINUE INX H XTHL RET TSTNUM: ;013E +++TSTNUM+++ LXI H,0 ;TEST IF THE TEXT IS MOV B,H ;A NUMBER CALL IGNBLK ;IF NOT, RETURN 0 IN TN1: ;0143 B AND HL CPI '0' ;30H IF NUMBERS, CONVERT RC ;TO BINARY IN HL AND CPI ':' ;3AH SET A TO # OF DIGITS RNC MVI A,0F0H ANA H ;IF H>255, THERE IS NO JNZ QHOW ;0166H ROOM FOR NEXT DIGIT INR B ;B COUNTS # OF DIGITS PUSH B MOV B,H ;HL=10*HL+ MOV C,L ;WHE(G CURRENTLY BEING INTERPRETED. WHILE WE ARE IN ;THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND ; RSTART: ; LXI SP,TRAM ;STACK POINTER IS AT TOP OF RAM ST1: ; CALL CRLF1 ;+CRLF+ JUMP TO HERE LXI D,OK ;0172H DE->STRING SUB A ;A=0 CALL PRTSTG ;087FH PRINT STRING UNTIL CR LXI H,ST2+1 ;0195H LITERAL 0 SHLD CURRNT ;09C1H CURRNT->LINE # = 0 ST2: ;0194 ; LXI H,0 SHLD LOPVAR ;09C9H SHLD STKGOS ;09C3H ST3: ;019D MVI A,'>' ;3EH PROMPT '>' AND CALL GETLN ;0814H READ A LI(ANST A TABLE ;WHEN A MATCH IS FOUND, CONTROL IS TRANSFERED TO THE SECTION ;OF CODE ACCORDING TO THE TABLE ;AT 'EXEC' DE SHOULD POINT TO THE STRING AND HL SHOULD POINT ;TO THE TABLE-1 AT 'DIRECT' DE SHOULD POINT TO THE STRING ;HL WILL BE SET TO POINT TO TAB1-1, WHICH IS THE TABLE FOR ;ALL DIRECT AND INDIRECT STATEMENT COMMANDS. ; ;A '.' IN THE STRING WILL TERMINATE THE TEST AND THE PARTIAL ;MATCH WILL BE CONSIDERED AS A MATCH E.G. 'P.','PR.','PRIN.' ;ALL MATCH 'PRINT'. ; ;(D 0FFH DB 'INP' DB (INP SHR 8) +128 DB INP AND 0FFH DB 'PEEK' DB (PEEK SHR 8) +128 DB PEEK AND 0FFH DB 'USR' DB (USR SHR 8) +128 DB USR AND 0FFH DB 'ABS' DB (ABS SHR 8) +128 DB ABS AND 0FFH DB 'LOG2' DB (LOG2 SHR 8) +128 DB LOG2 AND 0FFH DB 'ALOG2' DB (ALOG2 SHR 8) +128 DB ALOG2 AND 0FFH DB 'SIZE' DB (SIZE SHR 8) +128 DB SIZE AND 0FFH DB (XP40 SHR 8) +128 DB XP40 AND 0FFH DB 'YOU CAN ADD MORE' TAB5: ;02B1 "TO" IN "FOR" DB 'TO' DB (FR1 SHR 8) +128 DB FR( RE 10+ IS DONE BY DAD H ;SHIFT AND ADD DAD H DAD B DAD H LDAX D ;AND IS FROM INX D ;STRIPPING THE ASCII ANI 0FH ;CODE ADD L MOV L,A MVI A,0 ADC H MOV H,A POP B LDAX D ;DO THIS DIGIT AFTER JP TN1 ;0143H DIGIT. $ SAYS OVERFLOW QHOW: ;0166 +++ERROR "HOW"+++ PUSH D AHOW: ;0167 LXI D,HOW ;016DH JMP ERROR ;07E4H HOW: ;016D DB 'HOW?',0DH OK: ;0172 DB 'OK',0DH WHAT: ;0175 DB 'WHAT?',0DH SORRY: ;017B DB 'SORRY',0DH ;THIS IS THE MAIN LOOP THAT( NE PUSH D ;DE->END OF LINE ST33: ;01A3 LXI D,BUFFER ;0F37H DE->BEGINING OF LINE CALL TSTNUM ;013EH TEST IF IT IS A NUMBER CALL IGNBLK ; MOV A,H ;HL = VALUE OF # OR ORA L ;0 IF NO NUMBER POP B ;BC->END OF LINE JZ DIRECT ;02D5H DCX D ;BACKUP DE AND SAVE MOV A,H ;VALUE OF LINE # THERE STAX D DCX D MOV A,L STAX D PUSH B ;BC,DE->BEGIN. END PUSH D MOV A,C SUB E PUSH PSW ;A=# OF BYTES IN LINE CALL FNDLN ;0857H FIND THIS LINE IN SAVE PUSH D ;AREA DE->SAVE AREA JNZ ST( BTHE TABLE CONSISTS OF A NUMBER OF ITEMS. EACH ITEM ;IS A STRING OF CHARACTERS WITH BIT 7 SET TO 0 AND ;A JUMP ADDRESS HI-LO WITH BIT 7 OF THE HIGH BYTE ;SET TO 1 ; ;END OF TABLE IS AN ITEM WITH A JUMP ADDRESS ONLY. IF THE ;STRING DOES NOT MATCH, THIS IS THE DEFAULT. ; TAB1: ;01F9 DIRECT COMMANDS DB 'LIST' DB (LIST SHR 8) +128 DB LIST AND 0FFH DB 'RUN' DB (RUN SHR 8) +128 DB RUN AND 0FFH DB 'NEW' DB (NEW SHR 8) +128 DB NEW AND 0FFH DB 'LOAD' DB (LOAD SHR( 1 AND 0FFH DB (QWHAT SHR 8) +128 DB QWHAT AND 0FFH TAB6: ;02B7 "STEP" IN "FOR" DB 'STEP' DB (FR2 SHR 8) +128 DB FR2 AND 0FFH DB (FR3 SHR 8) +128 DB FR3 AND 0FFH TAB8: ;02BF RELATIONAL OPERATORS DB '>=' DB (XP11 SHR 8) +128 DB XP11 AND 0FFH DB '#' DB (XP12 SHR 8) +128 DB XP12 AND 0FFH DB '>' DB (XP13 SHR 8) +128 DB XP13 AND 0FFH DB '=' DB (XP15 SHR 8) +128 DB XP15 AND 0FFH DB '<=' DB (XP14 SHR 8) +128 DB XP14 AND 0FFH DB '<' DB (XP16 SHR 8) +128 DB XP16 ( } COLLECTS THE TINY BASIC PROGRAM ;AND STORES IT IN MEMORY. ; ;AT START, IT PRINTS OUT "OK", AND INITIALIZES THE ;STACK AND SOME OTHER INTERNAL VARIABLES. THE STACK, IN THIS ;VERSION IS MODIFIED DURING INITIALIZATION TO REFLECT THE ;SIZE OF MEMORY. ;THEN IT PROMPTS ">" AND READS A LINE. IF THE LINE STARTS ;WITH A NON-ZERO NUMBER, THIS NUMBER IS THE LINE NUMBER. THE ;LINE NUMBER AND THE REST OF THE LINE ; IS STORED IN MEMORY. IF A LINE W(4 ;01D2H NZ: NOT FOUND, INSERT PUSH D ;Z: FOUND DELETE IT CALL FNDNXT ;0873H FIND THE NEXT LINE DE->NEXT LINE POP B ;BC ->LINE TO BE DELETED LHLD TXTUNF ;09D5H HL->UNFILLED SAVE AREA CALL MVUP ;0900H MOVE UP TO DELETE MOV H,B ;TEXTUNF->UNFILLED AREA MOV L,C ; SHLD TXTUNF ;09D5H UPDATE ST4: ;01D2 POP B ;GET READY TO INSERT LHLD TXTUNF ;09D5H BUT FIRST CHECK IF POP PSW ;THE LENGTH OF THE NEW LINE PUSH H ;IS 3 (LINE # AND CR) CPI 3 ;THEN DO NOT INSERT JZ RSTART ;0181H MUST C(D 8) +128 DB LOAD AND 0FFH DB 'SAVE' DB (SAVE SHR 8) +128 DB SAVE AND 0FFH DB 'BYE' DB 80H,0 TAB2: ;021A DIRECT/STATMENT DB 'NEXT' DB (NEXT SHR 8) +128 DB NEXT AND 0FFH DB 'LET' DB (LET SHR 8) +128 DB LET AND 0FFH DB 'OUT' DB (OUT1 SHR 8) +128 DB OUT1 AND 0FFH DB 'POKE' DB (POKE SHR 8) +128 DB POKE AND 0FFH DB 'WAIT' DB (WAIT SHR 8) +128 DB WAIT AND 0FFH DB 'IF' DB (IFF SHR 8) +128 DB IFF AND 0FFH DB 'GOTO' DB (GOTO SHR 8) +128 DB GOTO AND 0FFH DB 'GO))?AND 0FFH DB (XP17 SHR 8) +128 ;NOT A REL OP. DB XP17 AND 0FFH DIRECT: ;02D5 +++DIRECT+++ LXI H,TAB1-1 ;01F8H EX0: ;02D8 CALL IGNBLK ;IGNORE LEADING BLANKS PUSH D ;SAVE POINTER EX1: ;02DA LDAX D ;IF FOUND '.' IN STRING INX D ;BEFORE ANY MISMATCH CPI '.' ;2EH DECLARE A MATCH JZ EX3 ;02F7H INX H ;HL->TABLE CMP M ;IF MATCH, TEST NEXT JZ EX1 ;02DAH MVI A,7FH ;ELSE SEE IF BIT 7 DCX D ;OF TABLE IS SET, WHICH CMP M ;IS THE JUMP ADDR. (HI) JC EX5 ;02FEH C:YES MATCHED EX2:)eTHE NEXT LINE, STORES ITS ADDRESS AND EXECUTES IT. ;'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT. ;'RUNSML' CONTINUES THE EXECUTION ON SAME LINE. ; ; ;'GOTO EXPR(CR)' EVALUATES THE EXPRESSION. FIND THE TARGET LINE, ;AND JUMP TO 'RUNTSL' TO DO IT. ; NEW: ;0306 +++NEW(CR)+++ CALL ENDCHK ;07DCH LXI H,TXTBGN ;09D7H SHLD TXTUNF ;09D5H STOP: ;030F +++STOP(CR)+++ CALL ENDCHK ;07DCH JMP RSTART ;0181H RUN: ;0315 +++RUN(CR)+++ CALL ENDCHK ;07DCH LXI D,TXTBGN ;09D7H FIRS) BDOS CPI 0FFH ;ERROR? JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKWR: ;03AD WRITE TO THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,15H ;WRITE SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS ORA A JNZ QHOW ;0166H POP D LDA TXTUNF+1 ;09D6H WRITE TO DISK UNTIL CMP D ;TXTUNF JC CLFIL ;03D9H JNZ DSKLOOP ;03D1H LDA TXTUNF ;09D5H CMP E ; JC CLFIL ;03D9H DSKLOOP: ;03D1 LXI H,80H DAD D XCHG JMP DSKWR ;03ADH CLFIL: ;03D)bS A NULL LIST. HOWEVER IF THE LIST ;ENDED WITH A COMMA NO (CRLF) IS GENERATED. ; LIST: ;0420 TEST IF THERE IS A # CALL TSTNUM ;013EH IF NO # WE GET A 0 CALL ENDCHK ;07DCH CALL FNDLN ;0857H FIND THIS OR THE NEXT LINE LS1: ;0429 JC RSTART ;0181H C:PASSED TXTUNF CALL PRTLN ;08EDH PRINT THE LINE CALL CHKIO ;0985H STOP IF ^C CALL FL1 ;085FH FIND NEXT LINE JMP LS1 ;0429H AND LOOP BACK PRINT: ;0438 MVI C,6 ;C= # OF SPACES CALL PG0 ;IF NULL LIST & ";" DB ';' DB (PR2-$-1) CAL) ;02ED ;NC:NO FIND JUMP ADDR. INX H CMP M JNC EX2 ;02EDH INX H ;BUMP THE NEXT TABLE ITEM POP D ;RESTORE STRING POINTER JMP EX0 ;02D8H TEST AGIANST NEXT ITEM EX3: ;02F7 MVI A,7FH ;PARTIAL MATCH, FIND EX4: ;02F9 INX H ;JUMP ADDR., WHICH IS CMP M ;FLAGED BY BIT 7. JNC EX4 ;02F9H EX5: ;02FE MOV A,M ;LOAD HL WITH THE JUMP INX H ;ADDR. FROM THE TABLE MOV L,M ANI 7FH ;MASK OFF BIT 7 MOV H,A POP PSW ;CLEAN UP THE GARBAGE AND PCHL ;GO DO IT. ; ; ;WHAT FOLLOWS IS TH)uT SAVED LINE RUNNXL: ;031B +++RUNNXL++ LXI H,0 ;FIND WHATEVER LINE # CALL FL1 ;085FH C:PASSED TXTUNF, QUIT. JC RSTART ;0181H RUNTSL: ;0324 +++RUNTSL+++ XCHG SHLD CURRNT ;09C1H SET 'CURRENT'->LINE # XCHG INX D ;BUMP PASS LINE # INX D RUNSML: ;032B +++RUNSML+++ CALL CHKIO ;0985H FIND COMMAND IN TAB2 LXI H,TAB2-1 ;0219H AND EXICUTE IT. JMP EX0 ;02D8H GOTO: ;0334 +++GOTO EXPR+++ CALL EXPR ; PUSH D ;SAVE FOR ERROR ROUTINE CALL ENDCHK ;07DCH MUST FIND A CR CALL FNDLN ;0857H F)9 MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP B ;RESTORE REGISTERS POP D POP H CALL FINISH L03E5: ;03E5 LXI H,5CH MVI M,0 L03EA: ;03EA FILL 64H BYTES WITH SPACES (20H) INX H MVI M,' ' ;20H MVI A,64H CMP L JNZ L03EA ;03EAH FILL LOOP RETURN INX H ; THE NEXT 3 BYTES "TBI" MVI M,'T' ;54H INX H MVI M,'B' ;42H INX H MVI M,'I' ;49H L03FC: ;03FC INX H ;FILL FROM "TBI" TO 5C6B WITH 00 MVI M,0 MVI A,6BH CMP L JNZ L03FC ;03FCH LXI )@L CRLF1 ;GIVE (CR-LF) AND JMP RUNSML ;032BH CONTINUE SAME LINE PR2: ;0443 ; CALL PG0 ;IF NULL, LIST (CR) DB 0DH,(PR0-$-1) CALL CRLF1 ;ALSO GIVE CR-LF AND JMP RUNNXL ;031BH GO TO NEXT LINE PR0: ;044C CALL PG0 ;ELSE IS IT FORMAT? DB '#' DB (PR1-$-1) CALL EXPR ;YES, EVALUATE EXPR. MOV C,L ;AND SAVE IT IN C. JMP PR3 ;045AH LOOK FOR MORE TO PRINT PR1: ;0454 CALL OTSTG ;088BH OR IS IT A STRING? JMP PR8 ;0467H IF NOT, MUST BE EXPR. PR3: ;045A CALL PG0 ;IF ",", GO FIND NEXT ) ~E CODE TO EXECUTE DIRECT AND STATMENT ;COMMANDS. CONTROL IS TRANSFERED TO THESE POINTS VIA THE ;COMMAND TABLE LOOKUP CODE OF 'DIRECT' AND 'EXEC' IN LAST ;SECTION. AFTER THE COMMAND IS EXECUTED, CONTROL IS ;TRANSFERED TO OTHER SECTIONS AS FOLLOWS: ; ; ;FOR 'LIST', 'NEW', AND 'STOP', GO BACK TO 'RSTART' ;FOR 'RUN', GO EXECUTE THE FIRST STORED LINE IF ANY, ELSE ;GO BACK TO 'RSTART'. ;FOR 'GOTO' AND 'GOSUB' : GO EXECUTE THE TARGET LINE ;FOR 'RETURN' AND 'NEXT': GO BACK TOO SAVED RETURN LIN) JIND THE TARGET LINE JNZ AHOW ;0167H NO SUCH LINE # POP PSW ;CLEAR THE "PUSH DE" JMP RUNTSL ;0324H GO DO IT ; ;THE FOLLOWING ROUTINES DO THE DISK COMMUNICATION ; LOAD: CALL IGNBLK PUSH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,0FH ;OPEN FILE CALL 5 ;CALL BDOS CPI 0FFH JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKRD: ;035E READ THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,14H ;READ SEQUENTIAL LXI D,5CH ;DE=) fH,5DH L0408: ;0408 LDAX D CPI 0DH RZ CPI '!' ;21H JC QWHAT ;07E0H CPI 5BH JNC QWHAT ;07E0H MOV M,A INX H INX D MVI A,65H CMP L JNZ L0408 ;0408H RET ; ; ;+++LIST+++& PRINT+++ ; ;LIST HAS 2 FORMS ;'LIST(CR)' LISTS ALL SAVED LINES ;'LIST #(CR)' START LIST AT THIS LINE # ;YOU CAN STOP LIST WITH ^C ; ;PRINT COMMAND IS 'PRINT ....;' OR 'PRINT ....(CR)' ;WHERE "...." IS A LIST OF EXPRESSIONS, FORMATS, BAKARROWS, ;AND STRINGS. THESE ITEMS ARE SEPARATED BY COMMA)  DB ',',(PR6-$-1) CALL FIN ;07CDH IN THE LIST JMP PR0 ;044CH PR6: CALL CRLF1 ;LIST ENDS CALL FINISH PR8: ;0467 CALL EXPR ;EVALUATE THE EXPR PUSH B CALL PRTNUM ;08B1H PRINT THE VALUE POP B JMP PR3 ;045AH MORE TO PRINT? ; ; ;+++GOSUB+++& RETURN+++ ; ;'GOSUB EXPR;' OR 'GOSUB EXPR (CR)' IS LIKE THE 'GOTO' ;COMMAND, EXCEPT THAT THE EXECUTION CAN BE CONTINUED AFTER THE ;SUBROUTINE 'RETURN'. IN ORDER THAT 'GOSUB' CAN BE NESTED ;(AND EVEN RECURSIVE), THE SAVE AREA MUST BE STAC) E. ;FOR ALL OTHERS: IF 'CURRENT' ->0, GO TO 'RSTART',ELSE ;GO EXECUTE NEXT COMMAND. (THIS IS DONE IN 'FINISH'.) ; ; ;+++NEW+++STOP+++RUN (& FRIENDS)+++& GOTO+++ ; ;'NEW(CR)' SETS 'TXTUNF' TO POINT TO THE BEGINING OF TEXT AREA ; ;'STOP(CR)' GOES BACK TO 'RSTART' ;'RUN(CR)' FINDS THE FIRST STORED LINE, STORE ITS ADDRESS (IN ;'CURRNT' AND START TO EXECUTE IT. NOTE THAT ONLY THOSE ;COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM. ; ;THERE ARE 3 MORE ENTRIES IN 'RUN': ;'RUNNXL' FINDS )FCB ADDRESS CALL 5 ;CALL BDOS CPI 1 ;ERROR CODE? JC NEWFIL ;0381H JNZ QHOW ;0166H ERROR MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP D ;RESTORE REGISTERS POP B POP D POP H CALL FINISH NEWFIL: ;0381 POP D LXI H,80H DAD D XCHG JMP DSKRD ;035EH SAVE: CALL IGNBLK PUSH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,13H ;DELETE FILE CALL 5 ;CALL BDOS LXI D,5CH ;DE=FCB ADDRESS MVI C,16H ;MAKE A FILE CALL 5 ;CALL)LS. ; ;A FORMAT IS A FOUND SIGN FOLLOWED BY A NUMBER. IT CONTROLS ;THE NUMBER OF SPACES THE VALUE OF A EXPRESSION IS GOING TO ;BE PRINTED. IT STAYS EFFECTIVE FOR THE REST OF THE PRINT ;COMMAND UNLESS CHANGED BY ANOTHER FORMAT. IF NO FORMAT IS ;SPECIFIED. 6 POSITIONS WILL BE USED. ; ;A STRING IS QUOTED IN A PAIR OF SINGLE OR A PAIR OF ;DOUBLE QUOTES. ; ;A BACK-ARROW MEANS GENERATE A (CR) WITHOUT (LF) ; ;A (CRLF) IS GENERATED AFTER THE ENTIRE LIST HAS BEEN ;PRINTED OR IF THE LIST I**uKED. ;THE STACK POINTER IS SAVED IN 'STKGOS'. THE OLD 'STKGOS' IS ;SAVED IN THE STACK. IF WE ARE IN THE MAIN ROUTINE, 'STKGOS' ;IS ZERO (THIS WAS DONE BY THE "MAIN" SECTION OF THE CODE), ;BUT WE STILL SAVE IT AS A FLAG FOR NO FURTHER 'RETURN'S. ; ;'RETURN(CR)' UNDOES EVERYTHING THAT 'GOSUB' DID, AND THUS ;RETURN THE EXECUTION TO THE COMMAND AFTER THE MOST RECENT ;'GOSUB'. IF 'STDGOS' IS 0, IT INDICATES THAT WE ;NEVER HAD A 'GOSUB' AND IS THUS AN ERROR. ; ; GOSUB: ;0470 CALL PUSH*w 'FOR' LOOP IS DEACTIVATED. ;(PURGED FROM THE STACK.) ; ;'NEXT VAR' SERVES AS THE LOGICAL (NOT NECESSARILY PHYSICAL) ;END OF THE 'FOR' LOOP. THE CONTROL VARIABLE VAR. IS CHECKED ;WITH THE 'LOPVAR'. IF THEY ARE NOT THE SAME, TB1 DIGS IN ;THE STACK TO FIND THE RIGHT ONE AND PURGES ALL THOSE THAT ;DID NOT MATCH EITHER WAY, TB1 THEN ADDS THE 'STEP' TO ;THAT VARIABLE AND CHECK THE RESULT WITH THE LIMIT. IF IT ;IS WITHIN THE LIMIT, CONTROL LOOPS VACK TO THE COMMAND ;FOLLOWING THE 'FOR'. IF OUT*TER XCHG LHLD LOPVAR ;09C9H GET VAR IN 'FOR' MOV A,H ORA L ;0 SAYS NEVER HAD ONE JZ AWHAT ;07E1H SO WE ASK "WHAT?" CALL COMP ;ELSE WE CHECK THEM JZ NX3 ;0527H OK, THEY AGREE POP D ;NO, LETS SEE CALL POPA ;0918H PURGE CURRENT LOOP LHLD VARNXT ;09C5H AND POP ONE LEVEL JMP NX0 ;050FH GO CHECK AGAIN NX3: ;0527 MOV E,M ;COME HERE WHEN AGREED INX H ; MOV D,M ;DE=VALUE OF VAR LHLD LOPINC ;09CBH PUSH H DAD D NX4: ;052F XCHG LHLD LOPVAR ;09C9H PUT IT BACK MOV M,E INX *I WILL PRINT "WHAT?", ;"HOW?" OR "SORRY" AND REPRINT THE PROMPT AND REDO THE INPUT. ;THE EXECUTION WILL NOTT TERMINATE UNLESS YOU TYPE CONTROL-C. ;THIS IS HANDLED IN 'INPERR'. ; ;'LET' IS FOLLOWED BY A LIST OF ITEMS SEPERATED BY COMMAS ;EACH ITEM CONSISTS OF A VARIABLE, AN EQUAL SIGN, AND AN EXPR. ;TBI EVALUATES THE EXPR. AND SETS THE VARIABLE TO THAT VALUE ;TBI WILL ALSO HANDLE 'LET' COMMAND WITHOUT THE WORD 'LET' ;THIS IS DONE BY 'DEFLT' ; ; REM: ;0555 +++REM+++ LXI H,0 D*A ;0934H SAVE THE CURRENT "FOR" CALL EXPR ;PARAMETERS PUSH D ;AND TEXT POINTER CALL FNDLN ;0857H FIND THE TARGET LINE JNZ AHOW ;0167H NOT THERE SAY "HOW?" LHLD CURRNT ;09C1H FOUND IT, SAVE OLD PUSH H ;'CURRNT' OLD 'STKGOS' LHLD STKGOS ;09C3H PUSH H LXI H,0 ;AND LOAD NEW ONES SHLD LOPVAR ;09C9H DAD SP SHLD STKGOS ;09C3H JMP RUNTSL ;0324H THEN RUN THAT LINE RETURN: ;0490 CALL ENDCHK ;07DCH THERE MUST BE A CR LHLD STKGOS ;09C3H OLD STACK POINTER MOV A,H ;0 MEANS NOT EXIST O*cSIDE THE LIMIT, THE SAVE AREA ;IS PURGED AND EXECUTION CONTINUES. ; ; FOR: ;04A9 CALL PUSHA ;0934H SAVE THE OLD SAVE AREA CALL SETVAL ;07BAH SET THE CONTROL VAR. DCX H ;HL IS ITS ADDRESS SHLD LOPVAR ;09C9H SAVE THAT LXI H,TAB5-1 ;USE "EXEC" TO LOOK JMP EX0 ;02D8H FOR THE WORD "TO" FR1: ;04B9 CALL EXPR ;EVALUATE THE LIMIT SHLD LOPLNT ;09CDH SAVE THAT LXI H,TAB6-1 ;USE 'EXEC' TO LOOK JMP EX0 ;02D8H FOR THE WORD 'STEP' FR2: ;04C3 ; CALL EXPR ;FOUND IT, GET STEP JMP FR4*{H MOV M,D LHLD LOPLNT ;09CDH HL=LIMIT POP PSW ;OLD HL ORA A JP NX1 ;053FH STEP > 0 XCHG NX1: ;053F CALL CKHLDE ;07B2H COMPARE WITH LIMIT POP D ;RESTORE TEXT POINTER JC NX2 ;0551H OUTSIDE LIMIT LHLD LOPLN ;09CFH WITHIN LIMIT, GO SHLD CURRNT ;09C1H BACK TO THE SAVED LHLD LOPPT ;09D1H 'CURRNT' AND TEXT XCHG ;POINTER CALL FINISH NX2: ;0551 CALL POPA ;0918H PURGE THIS LOOP CALL FINISH ; ; ;+++REM+++IF+++INPUT+++& LET (& DEFLT)+++ ; ;'REM' CAN BE FOLLOWED BY ANYTHI*B '>' IFF: ;0559 +++IF+++; CALL EXPR MOV A,H ;IS THE EXPR. =0? ORA L JNZ RUNSML ;032BH NO, CONTINUE CALL FNDSKP ;0875H YES, SKIP REST OF LINE JNC RUNTSL ;0324H JMP RSTART ;0181H INPERR: ;0568 +++INPERR+++ LHLD STKINP ;09C7H SPHL ;RESTORE OLD SP POP H SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER POP D ;REDO INPUT IP1: ;0572 +++INPUT+++ PUSH D ;SAVE IN CASE OF ERROR CALL OTSTG ;088BH IS NEXTITEM A STRING? JMP IP2 ;0580H NO CALL TSTVAR ;YES, BUT FOLLOWED BY A JC IP4* RA L JZ QWHAT ;07E0H SO WE SAY "WHAT?" SPHL ;ELSE, RESTORE IT POP H SHLD STKGOS ;09C3H AND THE OLD 'STKGOS' POP H SHLD CURRNT ;09C1H AND THE OLD 'CURRNT' POP D ;OLD TEXT POINTER CALL POPA ;0918H OLD "FOR" PARAMETERS CALL FINISH ;AND WE ARE BACK HOME ; ; ;+++FOR+++& NEXT+++ ; ;'FOR' HAS TWO FORMS: ;'FOR VAR=EXP1 TO EXP2 STEP EXP3' AND 'FOR VAR=EXP1 TO EXP2' ;(WHERE EXP3 ASSUME 1). ;TB1 WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE ;CURRENT VALUE OF EXP1. IT ALSO E*  ;04CAH FR3: ;04C7 LXI H,1 ;NOT FOUND, SET TO ONE FR4: ;04CA SHLD LOPINC ;09CBH SAVE THAT TOO FR5: ;04CD LHLD CURRNT ;09C1H SAVE CURRENT LINE # SHLD LOPLN ;09CFH XCHG ;AND TEXT POINTER SHLD LOPPT ;09D1H LXI B,0AH ;DIG INTO STACK TO LHLD LOPVAR ;09C9H FIND 'LOPVAR' XCHG MOV H,B MOV L,B ;HL=0 NOW DAD SP ;HERE IS THE STACK DB '>' FR7: ;04E2 DAD B ;EACH LEVEL IS 10 DEEP MOV A,M ;GET THAT OLD 'LOPVAR' INX H ; ORA M JZ FR8 ;0503H ZERO SAYS NO MORE IN IT MOV A,M * NG AND IS IGNORED BY TBI. ;TBI TREATS IT LIKE AN 'IF' WITH A FALSE CONDITION. ; ;'IF' IS FOLLOWED BY AN EXPR. AS A CONDITION AND ONE OR MORE ;COMMANDS (INCLUDING OTHER 'IF'S) SEPERATED BY SEMI-COLONS. ;NOTE THAT THE WORD 'THEN' IS NOT USED. TBI EVALUATES THE ;EXPR. IF IT IS NON-ZERO, EXECUTION CONTINUES. IF THE EXPR. ;IS ZERO, THE COMMANDS THAT FOLLOW ARE IGNORED AND EXECUTION ;CONTINUES AT THE NEXT LINE. ; ;'INPUT' COMMAND IS LIKE THE 'PRINT' COMMAND, AND IS FOLLOWED ;BY A LIST OF ITE* A ;05BAH VARIABLE? NO. JMP IP3 ;0590H YES INPUT VARIABLE IP2: ;0580 PUSH D ;SAVE FOR 'PRTSTG' CALL TSTVAR ;MUST BE VARIABLE NOW JC QWHAT ;07E0H 'WHAT?' IT IS NOT? LDAX D ;GET READY FOR 'PRTSTG' MOV C,A SUB A STAX D POP D CALL PRTSTG ;087FH PRINT STRING AS PROMPT MOV A,C ;RESTORE TEXT DCX D STAX D IP3: ;0590 PUSH D ;SAVE TEXT POINTER XCHG LHLD CURRNT ;09C1H ALSO SAVE 'CURRNT' PUSH H ; LXI H,IP1 ;0572H A NEGATIVE NUMBER SHLD CURRNT ;09C1H AS A FLAG LXI H,0 ;SAVE SP* aVALUATES EXP2 AND EXP3 ;AND SAVE ALL TOGATHER WITH THE TEXT POINTER ETC. IN ;THE 'FOR' SAVE AREA. WHICH CONSISTS OF 'LOPVAR', 'LOPINC', ;'LOPLMT', 'LOPLN', AND 'LOPPT'. IF THERE IS ALREADY SOMETHING ;IN THE SAVE AREA (THIS IS INDICATED BY A NON-ZERO ;'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK ;BEFORE THE NEW ONE OVER WRITES IT. ;TB1 WILL THEN DIG IN THE STACK AND FIND OUT IF THIS SAME ;VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP. ;IF THAT IS THE CASE, THEN THE OLD* DCX H CMP D ;SAME AS THIS ONE? JNZ FR7 ;04E2H MOV A,M ;THE OTHER HALF? CMP E JNZ FR7 ;04E2H XCHG ;YES, FOUND ONE LXI H,0 DAD SP ;TRY TO MOVE SP MOV B,H MOV C,L LXI H,0AH DAD D CALL MVDOWN ;0909H AND PURGE 10 WORDS SPHL ;IN THE STACK FR8: ;0503 LHLD LOPPT ;09D1H JOB DONE RESTORE DE XCHG CALL FINISH ;AND CONTINUE NEXT: ;0508 CALL TSTVAR ;GET ADDRESS OF VAR JC QWHAT ;07E0H NO VARIABLE, "WHAT?" SHLD VARNXT ;09C5H YES SAVE IT NX0: ;050F PUSH D ;SAVE TEXT POIN*MS. IF THE ITEM IS A STRING IN SINGLE OR ;DOUBLE QUOTES, OR IS A BACK-ARROW, IT HAS THE SAME EFFECT AS ;IN 'PRINT'. IF AN ITEM IS A VARIABLE, THIS VARIABLE NAME IS ;PRINTED OUT FOLLOWED BY A COLON. THEN TBI WAITS FOR AN ;EXPR. TO BE TYPED IN THE VARIABLE IS THEN SET TO THE ;VALUE OF THIS EXPR. IF THE VARIABLE IS PROCEDED BY A STRING. ; ;(AGIAN IN SINGLE OR DOUBLE QUOTES), THE STRING WILL BE ;PRINTED FOLLOWED BY A COLON. TBI THEN WAITS FOR INPUT EXPR. ; ;IF THE INPUT EXPR. IS INVALID, TB+++ TOO DAD SP SHLD STKINP ;09C7H PUSH D ;OLD HL MVI A,':' ;3AH CALL GETLN ;0814H AND GET A LINE IP33: ;05A9 LXI D,BUFFER ;0F37H POINTS TO BUFFER CALL EXPR ;EVALUATE INPUT NOP ;CAN BE 'CALL ENDCHK' NOP NOP POP D ;OK, GET OLD HL XCHG MOV M,E ;SAVE VALUE IN VAR. INX H MOV M,D POP H ;GET OLD 'CURRNT' SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER IP4: ;05BA POP PSW ;PURGE JUNK IN STACK CALL PG0 ;IS NEXT CH. ',' DB ',' DB (IP5-$-1) JMP IP1 ;0572H YES, MORE ITEMS+)L XP18 ;0601H REL. OP. "=" RNZ ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP16: ;05F9 CALL XP18 ;0601H REL. OP. "<" RNC ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP17: ;05FF POP H ;NOT REL. OP. RET ;RETURN HL= XP18: ;0601 MOV A,C ;SUBROUTINE FOR ALL POP H ;REL. OP.'S POP B ;REVERSE TOP OF STACK PUSH H PUSH B MOV C,A CALL EXPR2 ;0616H GET 2ND XCHG ;VALUE OF DE NOW XTHL ;1ST IN HL CALL CKHLDE ;07B2H COMPARE FIRST WITH 2ND PO+/P42-$-1) PUSH H ;YES, SAVE 1ST CALL EXPR4 ;06A7H AND GET 2ND ONE MVI B,0 ;CLEAR B FOR SIGN CALL CHKSGN ;07A3H CHECK SIGN OF 2ND XCHG ;GET 1ST IN HL XTHL CALL CHKSGN ;07A3H CHECK SIGN OF 1ST MOV A,D ;DIVIDE BY 0 ? ORA E JZ AHOW ;0167H SAY "HOW" PUSH B ;ELSE SAVE SIGN CALL DIVIDE ;0786H USE SUBROUTINE MOV H,B ;RESULT IN HL NOW MOV L,C POP B ;GET SIGN BACK XP35: ;0699 POP D ;AND TEXT POINTER MOV A,H ;HL MUST BE + ORA A JM QHOW ;0166H OVERFLOW MOV A,B ORA + ;LOG CONVERSION PUSH B ;PUSH THE REGISTERS PUSH D MOV A,H ORA A JNZ LOGCHR MOV A,L ORA A JNZ LOGCHR LXI H,54273 ;MAKE LOG2(0)=-11263 (LOG2(1/2047)) AND RETURN POP D POP B RET ; ; LOGCHR: ;NO. IS NOT ZERO MVI B,16 ;FIND THE CHARACTERISTIC LSH1: DCR B DAD H ;SHIFT NO. LEFT JNC LSH1 ;UNTIL CARRY MOV A,B ;LEFT SHIFT THE CHARACTERISTIC, 2 BITS ORA A ;CLEAR CARRY RAL RAL MOV B,A PUSH B ;SAVE THE CHARACTERISTIC TO THE STACK ; ; MVI B,6 ;POSITION THE UNCORRE+ IP5: ;05C1 CALL FINISH DEFLT: ;05C2 LDAX D ;+++DEFLT+++ CPI 0DH ;(CR) EMPTY LINE IS OK JZ LT1 ;05D1H ELSE IT IS 'LET' LET: ;05C8 CALL SETVAL ;07BAH +++LET+++ CALL PG0 ;SET VALUE TO VAR. DB ',',(LT1-$-1) JMP LET ;05C8H ITEM BY ITEM LT1: ;05D1 CALL FINISH ;UNTIL FINISH ; ; ;+++EXPR+++ ; ;'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS ;= ; ;WHERE IS ONE OF THE OPERATORS IN TABS AND THE ;RESULT OF THESE OPE+NP D ;RESTORE TEXT POINTER LXI H,0 ;SET HL=0 , A=1 MVI A,1 RET EXPR2: ;0616 CALL PG0 ;NEGATIVE SIGN? DB '-',(XP21-$-1) LXI H,0 ;YES, FAKE '0-' JMP XP26 ;0640H TREAT LIKE SUBTRACT XP21: ;061F CALL PG0 ;POSITIVE SIGN? IGNORE DB '+',(XP22-$-1) XP22: ;0622 CALL EXPR3 ;064AH 1ST XP23: ;0625 CALL PG0 ;ADD? DB '+',(XP25-$-1) PUSH H ;YES, SAVE VALUE CALL EXPR3 ;064AH GET 2ND XP24: ;062C XCHG ;2ND IN DE XTHL ;1ST IN HL MOV A,H ;COMPARE SIGN XRA D +MA CM CHGSGN ;07A6H CHANGE SIGN IF NEEDED JMP XP31 ;064DH LOOK FOR MORE TERMS EXPR4: ;06A7 FIND FUNCTION IN TAB4 LXI H,TAB4-1 ;027EH JMP EX0 ;02D8H AND GO DO IT XP40: ;06AD CALL TSTVAR ;NO, NOT A FUNCTION JC XP41 ;06B6H NOR A VARIABLE MOV A,M ;VARIABLE INX H MOV H,M ;VALUE IN HL MOV L,A RET XP41: ;06B6 CALL TSTNUM ;013EH OR IS IT A NUMBER MOV A,B ;# OF DIGIT ORA A RNZ ;OK PARN: ;06BC CALL PG0 ;NO DIGIT, MUST BE DB '(' ;28H DB (XP43-$-1) CALL EXPR ;"" +CTED MANTISSA CALL MANTIS JMP LTABAD ; MANTIS: ;SHIFT HL B BITS TO THE RIGHT MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A DCR B JNZ MANTIS RET ; ; LTABAD: PUSH H ;SAVE THE UNCORRECTED MANTISSA MOV A,L ;GET THE INTERPOLATOR ANI 15 STA INTSCR ;AND STORE IT IN THE SCRATCH PAD MVI B,4 ;SHIFT THE UNCORRECTED MANTISSA RIGHT 4 BITS CALL MANTIS ;TO FORM THE CORRECTION TABLE POINTER LXI D,LOGTAB;TABLE ADDRESS DAD D ;ADD IT TO HL SHLD (INTSCR+1) ;STORE THE POINTER IN+ CRATIONS IS 1 IF TRUE AND 0 IF FALSE. ;::=(+ OR -)(+ OR -)(....) ;WHERE <> ARE OPTIONAL AND (....) ARE OPIONAL REPEATS ;::=(< OR />)(....) ;::= ; ;() ; IS RECURSIVE SO THAT VARIABLE '@' CAN HAVE AN ;AS INDEX, FUNCTIONS CAN HAVE AN AS ARGUMENTS, AND ; CAN BE AN IN PARENTHESES. ; ; EXPR CALL EXPR2 THIS IS AT LOC. 18 ; PUSH HL ; ; EXPR1: ;05D2 LXI H,TAB8-1 ;02BEH L+  MOV A,D DAD D POP D ;RESTORE TEXT POINTER JM XP23 ;0625H 1ST 2ND SIGN DIFFER XRA H ;1ST 2ND SIGN EQUAL JP XP23 ;0625H SO IS RESULT JMP QHOW ;0166H ELSE WE HAVE OVERFLOW XP25: CALL PG0 ;SUBTRACT? DB '-',(XP42-$-1) XP26: ;0640 PUSH H ;YES, SAVE 1ST CALL EXPR3 ;064AH GET 2ND /PR3> CALL CHGSGN ;07A6H NEGATE JMP XP24 ;062CH AND ADD THEM EXPR3: ;064A CALL EXPR4 ;06A7H GET 1ST XP31: ;064D CALL PG0 ;MULTIPLY? DB '*',(XP34-$-1) PUSH H ;YES, SAVE 1ST CALL E+ 2 CALL PG0 DB ')' DB (XP43-$-1) XP42: ;06C3 RET XP43: ;06C4 JMP QWHAT ;07E0H ELSE SAY WHAT RND: ;06C7 +++RND(EXPR)+++ CALL PARN ;06BCH MOV A,H ;EXPR MUST BE + ORA A JM QHOW ;0166H ORA L ;AND NON-ZERO JZ QHOW ;0166H PUSH D ;SAVE BOTH PUSH H LHLD RANPNT ;09D3H GET MEMORY AS RANDOM LXI D,LSTROM ;09B0H NUMBER CALL COMP JC RA1 ;06E2H RAP AROUND IF LAST LXI H,BEGIN ;0100H RA1: ;06E2 MOV E,M INX H MOV D,M SHLD RANPNT ;09D3H POP H XCHG PUSH B CALL DIVIDE + 0 THE INTERP.SCRATCH PAD CALL INTERP ; LXI H,(INTSCR+4) MOV E,M ;RECOVER THE CORRECTOR FROM THE SCRATCH PAD MVI D,0 POP H ;RECOVER THE UNCORRECTED MANTISSA POP B ;RECOVER THE UNCORRECTED CHARACTERISTIC MVI C,0 DAD D ;ADD CORRECTOR DAD B ;ADD CHARACTERISTIC LXI D,1 DAD D ;ADD ONE TO THE LOG POP D POP B RET ;LOG CONVERSION COMPLETE ; ; ;ALOG2 ;RETURNS THE BASE 2 ANTILOG ; ALOG2: CALL PARN ;EVALUATE PARENTHISIS ; ALOG: PUSH B ;PUSH REGISTERS PUSH D MOV A,H ;IS+ OOK UP REL. OP. JMP EX0 ;02D8H GO DO IT XP11: ;05D8 CALL XP18 ;0601H REL. OP. ">=" RC ;NO, RETURN HL=0 MOV L,A ;YES,RETURN HL=1 RET XP12: ;05DE REL OF "#" CALL XP18 ;0601H RZ ;FALSE, RETURN HL=0 MOV L,A ;TRUE, RETURN HL=1 RET XP13: ;05E4 CALL XP18 ;0601H REL OP. ">" RZ ;FALSE RC ;ALSO FALSE HL=0 MOV L,A ;TRUE HL=1 RET XP14: ;05EB CALL XP18 ;0601H REL. OP. "<=" MOV L,A ;SET HL=1 RZ ;REL. TRUE, RETURN RC MOV L,H ;ELSE SET HL=0 RET XP15: ;05F3 CAL+XPR4 ;06A7H AND GET 2ND MVI B,0 ;CLEAR B FOR SIGN CALL CHKSGN ;07A3H CHECK SIGN XCHG ;1ST IN HL XTHL CALL CHKSGN ;07A3H CHECK SIGN OF 1ST MOV A,H ;IS HL >255 ? ORA A JZ XP32 ;0669H NO MOV A,D ;YES, HOW ABOUT DE ORA D XCHG ;PUT SMALLER IN HL JNZ AHOW ;0167H ALSO >, WILL OVERFLOW XP32: ;0669 MOV A,L ;THIS IS DUMB LXI H,0 ;CLEAR RESULT ORA A ;ADD AND COUNT JZ XP35 ;0699H XP33: CALL MULTIPLY JMP XP35 ;0699H FINISHED XP34: ;067C CALL PG0 ;DIVIDE? DB '/',(X+g;0786H RND(N)=MOD(M,N)+1 POP B POP D INX H RET ABS: ;06F2 +++ABS(EXPR) CALL PARN ;06BCH CALL CHKSGN ;07A3H CHECK SIGN MOV A,H ORA H JM QHOW ;0166H RET ;LOG2.ASM JUNE 24, 1984 ;CONVERTS 16 BIT NUMBER IN HL TO 1024*LOG(BASE2)OF N0. ;RETURNS IN HL ;CONVERTS 1024*LOG(BASE2)OF NUMBER TO NUMBER (ANTILOG) ;RETURNS IN HL ; ; LOG2: ;CONVERTS NO. IN HL TO LOG2 CALL PARN ;FIND AND EVALUATE THE PARENTHISIS CALL CHKSGN ;GET THE ABSOLUTE VALUE OF THE NUMBER ; ; LOGG:,,# CHARACTERISTIC ZERO OR MINUS ANI 252 JNZ LOGNEG ;IF ZERO, RETURN HL=1 XRA A MOV H,A MOV L,A INR L ;RETURN 1 POP D POP B RET ; LOGNEG: ;ANTILOG OF MINUS, RETURN HL=0 MOV A,H ANI 128 JZ MLOG XRA A MOV H,A MOV L,A ;CLEAR HL POP D POP B RET ; MLOG: ;IS THE CHARACTERISTIC OUT OF RANGE? MVI A,60 CMP H JM QHOW ;YES, ERROR ; MOV A,H ORA A ;CLEAR CARRY RAR ;REPOSITION THE CHARACTERISTIC 2 BITS RIGHT ORA A RAR MOV B,A ;PUT CHARACTERISTIC IN B PUSH,$ D,0 ;MULTIPLY BY THE INTERPOLATOR LXI H,0 MOV E,A LDA INTSCR ;LOAD THE INTERPOLATOR FROM THE SCRATCH PAD MVI B,8 ;SIZE OF MULTIPLIER ; ; MULT: DAD H RAL JNC CHCNT DAD D ;ADD IF CARRY IS 1 ; CHCNT: DCR B JNZ MULT ;LOOP UNTIL B=0 ; ; DIVIDE BY 16 ; MVI B,4 ;RIGHT SHIFT 4 BITS CALL MANTIS XCHG ;POINTER ADJUSTMENT IS IN DE ; LXI H,(INTSCR+3) ;GET THE SIGN MOV A,M ORA A JNZ INTREV ;IS IT + LHLD (INTSCR+1) ;YES, ADD DE MOV A,M MOV L,A MVI H,0 DAD D MOV A,L ,8TXTUNF' SIZE1: ;0703 'VARBGN' LXI H,VARBGN ;0F00H CALL SUBDE ;079CH POP D RET OUT1: ;070B CALL EXPR MOV A,L STA OUTPORT ;09B1H CALL PG0 DB 2CH DB (OU1-$-1) CALL EXPR MOV A,L CALL LSTROM ;09B0H CALL PG0 DB 2CH DB (OU2-$-1) JMP OUT1 ;070BH OU2: CALL FINISH WAIT: CALL EXPR MOV A,L STA INPORT ;09B4H CALL PG0 DB 2CH DB (OU1-$-1) CALL EXPR PUSH H CALL PG0 DB 2CH DB (WA1-$-1) CALL EXPR MOV A,L POP H MOV H,A FUNJP: ;0730 DB 0C3H,32H,07H,IGN IN B RAL ;SHIFT LEFT MULTIPLIER JNC CHCNTI ;GO ON IF CARRY=0 DAD D ;ADD MULTIPLICAND TO PRODUCT IF CARRY=1 CHCNTI: DCR C ;GO TO THE NEXT BIT JNZ MULTI RET ;FINISHED ; DIVIDE: ;0786 +++DIVIDE+++ PUSH D ;SAVE THE DIVISOR XCHG ;DIVISOR IN HL, DIVIDEND IN DE MVI B,1 ;CLEAR THE B REGISTER DV1: ;LEFT JUSTIFY THE DIVISOR DAD H ;LEFT SHIFT THE DIVISOR INR B ;COUNT THE SHIFTS MOV A,D ;TEST FOR MSB CMP H JNC DV1 ; MOV A,B ;STORE THE SHIFT COUNT ON THE STACK LXI B,0 ;CLEAR , B ;SAVE IT ; ; MOV A,H ;CLEAR THE CHARACTERISTIC FROM HL ANI 3 MOV H,A PUSH H ;SAVE THE MANTISSA ; ; MOV A,L ;FIND THE INTERPOLATOR ANI 15 STA INTSCR ;SAVE THE INTERPOLATOR IN THE SCRATCH PAD ; ; MVI B,4 ;GENERATE THE POINTER CALL MANTIS ;RIGHT SHIFT THE MANTISSA, 4 BITS LXI D,ALTAB ;ANTILOG TABLE ADDRESS DAD D ;HL> (POINTER) SHLD (INTSCR+1) ;STORE THE TABLE POINTER IN THE SCRATCH PAD CALL INTERP ;CALL THE INTERPOLATOR POP H ;RECOVER THE MANTISSA LDA (INTSCR+4) ;GET THE , LXI H,(INTSCR+4) ;STORE IN SCRATCH PAD MOV M,A RET ; ; THE SIGN IS - ; INTREV: LHLD (INTSCR+1) ;POINTER MOV A,M SUB E LXI H,(INTSCR+4) ;STORE THE CORRECTOR IN THE SCRATCH PAD MOV M,A RET ; ; ; ; ; CORRECTOR TABLE FOR LOG2 WITH 10 BIT MANTISSA ; LOGTAB: ;LOG CORRECTORS DB 0 DB 6 DB 13 DB 19 DB 25 DB 31 DB 36 DB 41 DB 46 DB 50 DB 54 DB 58 DB 61 DB 65 DB 68 DB 71 DB 73 DB 76 DB 78 DB 80 DB 81 DB 83 DB 84 DB 85 DB 86 DB 87 DB 8,i ;I DON'T KNOW WHAT THIS MEANS (MISTAKE?) WA1: MVI H,0 JMP WAITCOM ;09B3H INP: CALL PARN ;06BCH MOV A,L STA INPORT ;09BCH MVI H,0 OU1: JMP INCOMM ;09BBH JMP QWHAT ;07E0H POKE: ;0747 CALL EXPR PUSH H CALL PG0 DB 2CH DB (PO1-$-1) CALL EXPR MOV A,L POP H MOV M,A CALL PG0 DB 2CH DB (PO2-$-1) JMP POKE ;0747H PO2: CALL FINISH PEEK: CALL PARN ;06BCH MOV L,M MVI H,0 RET PO1: JMP QWHAT ;07E0H USR: PUSH B CALL PG0 DB '(' ;28H DB (POPB-$-1) CALL,sBC FOR THE QUOTIENT DV2: ;DIVISOR > DIVIDEND? PUSH PSW MOV A,D CMP H ;IS IT GREATER JC DV4 ;SKIP IF NOT JNZ DV3 ;IS IT ZERO? MOV A,E ;YES, COMPARE LOWER BYTE CMP L JC DV4 ;SKIP IF GREATER ; DV3: ;SUBTRACT HL FROM DE RESULT IN DE MOV A,E SUB L MOV E,A MOV A,D SBB H MOV D,A ; MOV A,C ;LEFT SHIFT THE QUOTIENT ORA A RAL MOV C,A MOV A,B RAL MOV B,A INX B ;ADD ONE TO THE QUOTIENT JMP DV5 ; DV4: MOV A,C ;LEFT SHIFT THE QUOTIENT ORA A RAL MOV C,A MOV, CORRECTOR ; ; MVI C,0 MOV B,A ;SUBTRACT CORRECTOR FROM HL MOV A,L SUB B MOV L,A MOV A,H SBB C ADI 4 ;ADD BACK THE LEADING 1 MOV H,A DAD H ;SHIFT LEFT HL 5 BITS DAD H DAD H DAD H DAD H POP B ;RECOVER THE CHARACTERISTIC MVI A,15 ;JUSTIFY THE NUMBER SUB B MOV B,A ;B=N0. OF RIGHT SHIFTS NEEDED TO JUSTIFY CALL MANTIS ;DO THE SHIFTS MOV A,H ORA A JP ALGFIN JMP QHOW ;ANTILOG OUT OF RANGE, ERROR ALGFIN: POP D POP B RET ;ANTILOG DONE ; ;INTERPOLATOR EVALUATES P, R7 DB 87 DB 88 DB 88 DB 87 DB 87 DB 87 DB 86 DB 85 DB 84 DB 83 DB 82 DB 80 DB 78 DB 77 DB 75 DB 73 DB 71 DB 69 DB 66 DB 64 DB 61 DB 58 DB 55 DB 52 DB 49 DB 46 DB 43 DB 39 DB 36 DB 32 DB 28 DB 25 DB 21 DB 17 DB 12 DB 8 DB 4 DB 0 ; ; ; TABLE FOR ANTILOG CORRECTIONS WITH 10 BIT MANTISSA ; ALTAB: DB 0 DB 4 DB 9 DB 14 DB 18 DB 23 DB 27 DB 31 DB 35 DB 39 DB 42 DB 46 DB 49 DB 53 DB 56 DB 59 DB 62 DB ,  EXPR CALL PG0 DB ')' DB (US1-$-1) PUSH D LXI D,POPDEHL ;0780H PUSH D PUSH H RET US1: CALL PG0 DB 2CH DB (POPB-$-1) PUSH H CALL EXPR CALL PG0 DB ')' DB (POPB-$-1) POP B PUSH D LXI D,POPDEHL ;0780H PUSH D PUSH B RET POPDEHL: ;0780 POP D POPB: POP B RET JMP QWHAT ;07E0H ; ; ;+++MULTIPLY+++DIVIDE+++SUBDE+++CHKSGN+++& CKHLDE+++ ; ;'MULTIPLY' MULTIPLIES A BY DE. RESULT IN HL ; ;'DIVIDE' DIVIDES HL BY DE. RESULT IN BC. REMAINDER IN HL. ; ;,  A,B RAL MOV B,A ; DV5: ;RIGHT SHIFT THE DIVISOR MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A POP PSW ;GET THE SHIFT COUNT BACK DCR A ;DECREMENT THE COUNT JNZ DV2 ;GO TO THE NEXT MSB XCHG ;QUOTIENT IN BC, REMAINDER IN HL, DIVIDEND IN DE POP D RET ; SUBDE: ;079C +++SUBDE+++ MOV A,L SUB E ;SUBTRACT DE FROM MOV L,A ;HL. MOV A,H SBB D ;RESULT IN HL MOV H,A RET CHKSGN: ;07A3 +++CHKSGN+++ MOV A,H ORA A ;CHECK SIGN OF HL RP ;IF - ,CHANGE SIGN CHGSGN: , ;OINTER+((POINTER+1)-(POINTER))*INTERPOLATOR/16) ; INTERP: ;INTERPOLATOR FOR 10 BIT MANTISSA MVI A,0 ;CLEAR THE SIGN BYTE STA (INTSCR+3) ; LHLD (INTSCR+1) ;LOAD THE TABLE POINTER MOV B,M ;(POINTER) TO B INX H MOV A,M ;(POINTER+1) TO A CMP B ;DETERMIN THE INTERPOLATION POLARITY JP ABSPON ;I.E. ACENDING OR DECENDING CORRECTORS MOV C,A ;NEG, SWAP A&B, SET THE SIGN BYTE TO 1 MVI A,1 STA (INTSCR+3) MOV A,B MOV B,C ; ABSPON: SUB B ;ABS((POINTER+1)-(POINTER)) MOV E,A ; ; MVI,64 DB 67 DB 70 DB 72 DB 74 DB 76 DB 78 DB 80 DB 81 DB 82 DB 84 DB 85 DB 86 DB 86 DB 87 DB 87 DB 88 DB 88 DB 88 DB 87 DB 87 DB 86 DB 85 DB 84 DB 83 DB 82 DB 80 DB 78 DB 76 DB 74 DB 72 DB 69 DB 67 DB 64 DB 60 DB 57 DB 54 DB 50 DB 46 DB 41 DB 37 DB 32 DB 27 DB 22 DB 17 DB 11 DB 6 DB 0 ; ; END OF ANTILOG TABLE ; SIZE: ;06FE +++SIZE+++ LHLD TXTUNF ;09D5H PUSH D ;GET THE NUMBER OF FREE XCHG ;BYTES BETWEEN ','SUBDE' SUBTRACTS DE FROM HL. ; ;'CHKSGN' CHECKS SIGN OF HL. IF +, NO CHANGE. IF -, CHANGE ;SIGN AND FLIP SIGN OF B. ; ;'CHGSGN' CHANGES THE SIGN OF HL AND B UNCONDITIONALLY. ; ;'CKHLDE' CHECKS THE SIGN OF HL AND DE, IF DIFFERENT, HL AND DE ;ARE INTERCHANGED. IF SAME SIGN, NOT INTERCHANGED. EITHER ;CASE, HL DE ARE THEN COMPARED TO SET THE FLAGES. ; ; ; MULTIPLY: MVI C,8 ;MULTIPLIER IN A, MULTIPLICAND IN DE, PRODUCT IN HL MULTI: DAD H ;SHIFT LEFT PRODUCT. ** LOOP COUNTER IN C. ** S-0- ;07A6 +++CHGSGN+++ MOV A,H CMA ;CHANGE SIGN OF HL MOV H,A MOV A,L CMA MOV L,A INX H MOV A,B ;AND ALSO FLIP B XRI 80H MOV B,A RET CKHLDE: ;07B2 MOV A,H XRA D ;SAME SIGN? JP CK1 ;07B8H YES, COMPARE XCHG ;NO EXCHANGE AND COMPLIMENT CK1: ;07B8 CALL COMP RET ; ; ;+++SETVAL+++FIN+++ENDCHK+++& ERROR (& FRIENDS)+++ ; ;"SETVAL" EXPECTS A VARIABLE, FOLLOWED BY AN EQUAL SIGN AND ;THE AN EXPR. IT EVALUATES THE EXPR. AND SET THE VARIABLE ;TO THAT VALUE. ; ;"FIN-:E FI1: ;07D4 CALL PG0 ;NOT ";", IS IT CR? DB 0DH,(FI2-$-1) POP PSW ;YES, PURGE RET ADDR. JMP RUNNXL ;031BH RUN NEXT LINE FI2: ;07DB RET ;ELSE RETURN TO CALLER ENDCHK: ;07DC +++ENDCHK+++ CALL IGNBLK CPI 0DH ;END WITH CR? RZ ;OK, ELSE SAY "WHAT?" QWHAT: ;07E0 +++QWHAT+++ PUSH D AWHAT: ;07E1 +++AWHAT+++ LXI D,WHAT ;0175H ERROR: ;07E4 +++ERROR+++ SUB A CALL PRTSTG ;087FH PRINT 'WHAT?', 'HOW?', OR 'SORRY'. POP D LDAX D ;SAVE THE CHARACTER PUSH PSW ;AT WHERE OLD-GINNING OF THE TEXT SAVE ;AREA TO START THE SEARCH. SOME OTHER ENTRIES OF THIS ;ROUTINE WILL NOT INITIALIZE DE AND DO THE SEARCH. ;'FNDLNP' WILL START WITH DE AND SEARCH FOR THE LINE #. ;'FNDNXT' WILL BUMP DE BY 2, FIND A CR AND THEN START SEARCH. ;'FNDSKP' USE DE TO FIND A CR, AND THEN START SEARCH. ; ; GETLN: ;0814 +++GETLN+++ CALL PRCHR LXI D,BUFFER ;0F37H PROMPT AND INIT. GL1: ;0818 CALL CHKIO ;0985H CHECK KEYBOARD NOP NOP JZ GL1 ;0818H NO INPUT, WAIT. CPI 7FH ;DELETE L-mEND POP H RC LDAX D ;WE DID NOT, GET BYTE 1 SUB L ;IS THIS THE LINE? MOV B,A ;COMPARE LOW ORDER INX D LDAX D ;GET BYTE 2 SBB H ;COMPARE HIGH ORDER JC FL2 ;0874H NO, NOT THERE YET DCX D ;ELSE WE EITHER FOUND IT, ORA B ;OR IT IS NOT THERE RET ;NC,Z: FOUND, NC,NZ: NO FNDNXT: ;0873 +++FNDNXT+++ INX D ;FIND NEXT LINE FL2: ;0874 JUST PASSED BYTE 1 & 2 INX D FNDSKP: ;0875 +++FNDSKP+++ LDAX D CPI 0DH ;TRY TO FIND CR JNZ FL2 ;0874H KEEP LOOKING INX D ;FOUND CR, SKIP OVER-7" CHECKS THE END OF A COMMAND, IF IT ENDED WITH ";", ;EXECUTION CONTINUES. IF IT ENDED WITH A CR, IT FINDS THE ;NEXT LINE AND CONTINUES FROM THERE. ; ;"ENDCHK" CHECKS IF A COMMAND IS ENDED WITH CR, THIS IS ;REQUIRED IN CERTIAND COMMANDS, (GOTO, RETURN, AND STOP ETC.) ; ;"ERROR" PRINTS THE STRING POINTED BY DE (AND ENDS WITH CR) ;IT THEN PRINTS THE LINE POINTED BY "CURRNT" WITH A "?" ;INSERTED AT WHERE THE OLD TEXT POINTER (SHOULD BE ON TOP ;OF THE STACK) POINTS TO. EXECUTION OF TB IS STO- DE-> SUB A ;AND PUT A 0 THERE STAX D LHLD CURRNT ;09C1H GET CURRENT LINE # PUSH H MOV A,M ;CHECK THE VALUE INX H ORA M POP D JZ RSTART ;0181H IF ZERO, JUST RESTART MOV A,M ;IF NEGATIVE, ORA A JM INPERR ;0568H REDO INPUT CALL PRTLN ;08EDH ELSE PRINT THE LINE DCX D ;UPTO WHERE 0 IS POP PSW ;RESTORE THE CHARACTOR STAX D MVI A,'?' ;3FH PRINT A "?" CALL PRCHR SUB A ;AND THE REST OF THE CALL PRTSTG ;087FH JMP RSTART ;0181H QSORRY: ;080D +++QSORRY+++ PUSH D ASORRY-AST CHARACTER? JZ GL3 ;0842H YES CPI 08H ;IS IT A BACKSPACE? JZ CONTH ;YES DELETE THE LAST CHARACTER CPI 0AH ;INPUT, ECHO BACK , IGNORE LF JZ GL1 ;0818H ORA A ;IGNORE NULL JZ GL1 ;0818H CPI 5CH ;DELETE THE WHOLE LINE? JZ GL4 ;084FH YES STAX D ;ELSE, SAVE INPUT INX D ;AND BUMP POINTER CPI 0DH ;WAS IT CR? JNZ MORM ;083CH NO, JUMP TO MORM MVI A,0AH ;YES, END OF LINE CALL PRCHR RET MORM: ;083C IS E 87H?, IF NOT LOOP MOV A,E CPI 87H JNZ GL1 ;0818H CONTH: MOV A,E ;DELETE- JMP FL1 ;085FH CHECK IF END OF TEXT ; ; ;+++PRTSTG+++OTSTG+++PRTNUM+++& PRTLN+++ ; ;'PRTSTG' PRINTS A STRING POINTED TO BY DE. IT STOPS PRINTING ;AND RETURNS TO CALLER WHEN EITHER A CR IS PRINTED OR WHEN ;THE NEXT BYTE IS THE SAME AS WHAT WAS IN A (GIVEN BY THE ;CALLER). OLD A IS STORED IT B, OLD B IS LOST. ; ;'OTSTG' LOOKS FOR A BACK-ARROW. SINGLE QUOTE, OR DOUBLE ;QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACK-ARROW, ;OUTPUT A CR WITHOUT A LF. IF SINGLE OR DOUBLE QUOTE, PRI- PPED ;AND TB1 IS RESTARTED. HOWEVER, IF 'CURRNT'->ZERO ;(INDICATING A DIRECT COMMAND) , THE DIRECT COMMAND IS NOT ;PRINTED, AND IF 'CURRNT'->NEGATIVE # (INDICATING INPUT ;COMMAND, THE INPUT LINE IS NOT PRINTED AND EXICUTION IS ;NOT TERMINATED BUT CONTINUED AT 'INPEPR'. ; ;RELATED TO 'ERROR' ARE THE FOLLOWING: ;'QWHAT' SAVES TEXT POINTER IN STACK AND GET MESSAGE "WHAT?" ;'AWHAT' JUST GET MESSAGE "WHAT?" AND JUMP TO ERROR. ;'QSORRY' AND 'ASORRY' DO THE SAME KIND OF THING. ;'OHOW' AND 'A- s: ;080E +++ASORRY+++ LXI D,SORRY ;017BH JMP ERROR ;07E4H ; ; ;+++GETLN+++FNDLN (& FRIENDS)+++ ; ;'GETLN' READS A INPUT LINE INTO 'BUFFER'. IT FIRST PROMPTS ;THE CHARACTER IN A (GIVEN BY THE CALLER), THEN IT FILLS THE ;BUFFER AND ECHOS. IT IGNORES LF'S AND NULLS, BUT STILL ;ECHOS THEM BACK. RUB-OUT IS USED TO CAUSE IT TO DELETE ;THE LAST CHARACTER (IF THERE IS ONE), AND ALT-MOD IS USED TO ;CAUSE IT TO DELETE THE WHOLE LINE AND START IT ALL OVER ;CR SIGNALS THE END OF A LINE, AND - l LAST CHARACTER CPI '7' JZ GL4 DCX D ;BACKUP THE POINTER MVI A,20H ;SPACE CALL PRCHR ;TO THE CONSOLE MVI A,08H ;BACK SPACE CALL PRCHR JMP GL1 GL3: ;0842 MOV A,E ;DELETE LAST CHARACTER (NULL) CPI '7' ;37H BUFFER AND 0FFH JZ GL4 ;084FH NO REDO WHOLE LINE DCX D ;YES, BACKUP POINTER BKSPC: ;BACK SPACE THE CURSER AND DELETE ;THE CHARACTER FROM THE SCREEN MVI A,08H ;AND ECHO A BACK SPACE CALL PRCHR MVI A,20H ;SPACE CALL PRCHR MVI A,08H ;BACK SPACE CALL PRCHR MVI A,- NT ;THE STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE. ;AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED ;OVER (USUALLY A JUMP INSTRUCTION). ; ;'PRTNUM' PRINTS THE NUMBER IN HL. LEADING BLANKS ARE ADDED ;IF NEEDED TO PAD THE NUMBER OF SPACES TO THE NUMBER IN C. ;HOWEVER, IF THE NUMBER OF DIGITS IS LARGER THAN THE # IN ;C, ALL DIGITS ARE PRINTED ANYWAY. NEGATIVE SIGN IS ALSO ;PRINTED AND COUNTED IS. POSTIVE SIGN IS NOT. ; ;'PRTLN' PRINTS A SAVED TEXT LINE WITH LINE # AN- _HOW' IN THE ZERO PAGE SECTION ALSO DO THIS ; ; SETVAL: ;07BA +++SETVAL+++ CALL TSTVAR JC QWHAT ;07E0H "WHAT?", NO VARIABLE PUSH H ;SAVE ADDRESS OF VARIABLE CALL PG0 DB '=',(SV1-$-1) ;PASS "=" SIGN CALL EXPR ;EVALUATE EXPR. MOV B,H ;VALUE IN BC NOW MOV C,L POP H ;GET ADDRRESS MOV M,C ;SAVE VALUE INX H MOV M,B RET SV1: ;07CA JMP QWHAT ;07E0H NO "=" SIGN FIN: ;07CD +++FIN+++ CALL PG0 DB ';',(FI1-$-1) POP PSW ;";",PURGE RET ADDR. JMP RUNSML ;032BH CONTINUE SAME LIN-CAUSE 'GETLN' TO RETURN. ; ;'FNDLN' FINDS A LINE WITH A GIVEN LINE # (IN HL) IN THE ;TEXT SAVE AREA. DE IS USED AS THE TEXT POINTER. IF THE ;LINE IS FOUND, DE WILL POINT TO THE BEGINNING OF THAT LINE ;(I.E. THE LOW BYTE OF THE LINE #), AND FLAGS ARE NC & Z. ;IF THE LINE IS NOT THERE AND A LINE WITH A HIGHER LINE # ;IS FOUND, DE POINTS TO THERE AND FLAGS ARE NC & NZ. IF ;WE REACHED THE END OF TEXT SAVE AREA AND CANNOT FIND THE ;LINE, FLAGS ARE C & NZ. ;'FNDLN' WILL INITIALIZE DE TO THE BE-\08H ;BACK SPACE CALL PRCHR MVI A,20H ;SPACE CALL PRCHR MVI A,08H ;BACK SPACE CALL PRCHR JMP GL1 ;0818H GO GET NEXT INPUT GL4: ;084F ;REDO ENTIRE LINE CALL CRLF1 MVI A,5EH ;CR, LF, AND UP-ARROW JMP GETLN ;0814H FNDLN: ;0857 +++FNDLN+++ MOV A,H ORA A ;CHECK SIGN OF HL JM QHOW ;0166H IT CANNOT BE "-" LXI D,TXTBGN ;09D7H INIT, TEXT POINTER FL1: ;085F +++FNDLP+++ PUSH H ;SAVE LINE # LHLD TXTUNF ;09D5H CHECK IF WE PASSED END DCX H ;GET LINE # BACK CALL COMP ;C,NZ PASSED ..jD ALL. ; ; PRTSTG: ;087F +++PRTSTG+++ MOV B,A PS1: ;0880 LDAX D ;GET A CHARACTER INX D ;BKUMP POINTER CMP B ;SAME AS OLD A? RZ ;YES RETURN CALL PRCHR ;ELSE PRINT IT CPI 0DH ;WAS IT CR? JNZ PS1 ;0880H NO, NEXT RET ;YES RETURN OTSTG: ;088B +++OTSTG+++ CALL PG0 DB '"',(OT3-$-1) MVI A,'"' ;22H IT IS A (") OT1: ;0890 PRINT UNTIL ANOTHER CALL PRTSTG ;087FH CPI 0DH ;WAS LAST ONE A CR? POP H ;RETURN ADDRESS JZ RUNNXL ;031BH WAS CR, RUN NEXT LINE OT2: ;0899 SKIP THR.s"*fw: QԖQcQ1Q{P!XuP;S͖Q4QlM:h2h:iҾ"Q:iUQZQ`Q|/g}/otQ!":i}QQ"f>2u͍PajsQs"Qw;PQx]P!eFN*fQ|UOs"wQ!"b"d>>yQs"wGOW_;P]PgQ>UN|(NANz< s"OROROs">RwgQ!i~:f~Q6{yM!i~bRO+~+NR!aRtQøQy;P]P+6+qR:hO!h>ͽTuT2a)T!b~5#ʕR!xʺR>)w)ҶR w=¨R|G͆SyR|GzsQͬQ P͠SW|tQzSDM!>)!S.H SHLD LOPPT ;09D1H PP1: ;0932 PUSH B ;BC = RETURN ADDRESS RET PUSHA: ;0934 +++PUSHA+++ LXI H,STKLMT ;0FAFH CALL O RETURN POP H ; NOP, RESTORE OTHERS SHLD LOPINC ;09CBH POP H SHLD LOPLNT ;09CDH POP H SHLD LOPLN ;09CFH POP ;BC = RETURN ADDRESS POP H ;RESTORE LOPVAR, BUT SHLD LOPVAR ;09C9H =0 MEANS NO MORE MOV A,H ORA L JZ PP1 ;0932H YEP, GCX H ;BUT FIRST DECREASE LDAX D ;BOTH POINTERS AND MOV M,A ;THEN DO IT JMP MVDOWN ;0909H LOOP BACK POPA: ;0918 POP B .w 0 0 2.41255 0 3.56321 0 2.92036 0 .986245 0 -1.00321 0 -1.80571 0 -.900875 0 1.20709 0 3.28904 0 4.11663 0 3.18802 0 1.02746 0 -1.11754 0 -2.00465 0 -1.12429 0 .999966 0 3.11461 0 3.96622 0 3.03148 0 .820373 0 -1.42413 0 -2.45369 0 -1.74306 0 .207057 0 2.16962 0 2.91686 0 1.94606 0 -.220807 0 -2.33975 0 -3.17303 0 -2.21657 0 -7.02201E-05 0 2.21647 0 3.17303 0 2.33985 0 .220952 . EE BYTES ON RETURN INX H INX H INX H PCHL ;RETURN OT3: ;089D CALL PG0 ;IS IT A (') ? DB '''',(OT4-$-1) MVI A,'''' ;27H YES, DO SAME JMP OT1 ;0890H AS IN (") OT4: ;08A5 CALL PG0 ;IS IT BACK-ARROW? DB '_',(OT5-$-1) ; MVI A,8DH ;YES, CR WITHOUT LF CALL PRCHR ;DO IT TWICE TO GIVE CALL PRCHR ;TTY ENOUGH TIME (SHOULD WE CALL THE RUBOUT ROUTINE?) POP H ;RETURN ADDDRESS JMP OT2 ;0899H OT5: ;08B0 RET ;NONE OF THE ABOVE PRTNUM: ;08B1 +++PRTNUM+++ PUSH D ; LXI D,0AH .H ; PRCHR: ;PRINT CHARACTERS PUSH PSW ;RST 2 LDA OCSW ;09C0H PRINT CHARACTERS ONLY ORA A ;IF OCSTW IS ON JMP OC2 ;095: ;0A50 THIS BLOCK IS MOVED INTO PAGE 0 XTHL CALL IGNBLK CMP M JMP TC1 ;012FH CRLF1: ;0A56 +++CRLF+++ MVI A,0DER POPR: ;0981 RESTORE ALL THE REGISTERS POP H POP D POP B RET ; ;THIS IS THE RESTART SUBROUTINE GROUP ; PG0SEND LF TO THE TERMINAL MVI C,2 ;OUTPUT TO TERMINAL CALL 5 ;CALL BDOS LDACC: ;097E LDA OCSW-1 ;09BFH RELOAD THE CHARACT.[ JNZ MD1 ;0911H NO, GO MOVE MOV A,C ;MAYBE, OTHER BYTE? SUB E RZ ;YES, RETURN MD1: ;0911 DCX D ;ELSE MOVE A BYTE DD ;INCREASE BOTH POINTERS INX B JMP MVUP ;0900H UNTIL DONE MVDOWN: ;0909 +++MVDOWN+++ MOV A,B SUB D ;TEST IF DE = BC NTO THE ;STACK ; MVUP: ;0900 +++MVUP+++ CALL COMP RZ ;DE = HL, RETURN LDAX D ;GET ONE BYTE STAX B ;MOVE IT INX ;'POPA' RESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE ;STACK ; ;'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SAVE AREA I.)0 -1.94595 0 -2.91685 0 -2.16971 0 -.20719 0 1.74298 0 2.4537 0 1.42424 0 -.820223 0 -3.03138 0 -3.96622 0 -3.1147 0 -1.00011 0 1.12419 0 2.00465 0 1.11764 0 -1.02731 0 -3.18792 0 -4.11663 0 -3.28913 0 -1.20723 0 .900774 0 1.80571 0 1.0033 0 -.986111 0 -2.92028 0 -3.56322 0 -2.41267 0  -3. -.220807 0 -2.33975 0 -3.17303 0 -2.21657 0 -7.02201E-05 0 2.21647 0 3.17303 0 2.33985 0 .220952 .  PUSH D MOV B,D DCR C CALL CHKSGN ;07A3H CHECK SIGN JP PN1 ;08C1H NO SIGN MVI B,'-' ;2DH B-SIGN DCR C ;'-' TAKES SPACE PN1: ;08C1 PUSH B ;SAVE PN2: ;08C2 CALL DIVIDE ;0786H DIVIDE HL BY 10 MOV A,B ;RESULT 0? ORA C ; JZ PN3 ;08D2H YES, WE GOT ALL XTHL ;NO, SAVE REMAINDER DCR L ;AND COUNT SPACE PUSH H ;HL IS OLD BC ' MOV H,B ;MOVE RESULT TO BC MOV L,C JMP PN2 ;08C2H AND DIVIDE BY 10 PN3: ;08D2 POP B ;WE GOT ALL DIGITS IN PN4: ;08D3 DCR C ;THE STACK MOV A,C . lN THE CONSOLE LDA OCSW-1 ;09BFH RELOAD THE CHARACTER CPI 0DH ;IS IT CR? JNZ LDACC ;097EH NO, JUMP LDACC MVI E,0AH ;YES, -1 MOV E,A ;MOVE ASCII CHARACTER TO BE OUTPUT FROM A TO E MVI C,2 ;CONSOLE OUTPUT CALL 5 ;CALL BDOS, PRINT THE CHARACTER OETURN OC3: ;0962 POP PSW ;COME HERE TO DO OUTPUT PUSH B PUSH D PUSH H STA OCSW-1 ;09BFH STORE THE CHARACTER AT OCSWER IS IN THE A REG. IF CR, LF IS ADDED ; OC2: ;095D JNZ OC3 ;0962H IT IS ON POP PSW ;IT IS OFF RET ;RESTORE AF AND R. TWHERE DE-> TO WHERE BC-> UNTIL ;DE = HL ; ;'MVDOWN' MOVES A BLOCK DOWN FROM WHERE DE-> TO WHERE HL-> ;UNTIL DE = BC ; A ;AND THEN THE TEXT CALL PRTSTG ;087FH RET ; ;+++MVUP+++MVDOWN+++PAPA+++& PUSHA+++ ; ;'MVUP' MOVES A BLOCK UP FROM ;PRINT 4 DIGIT LINE # MOV H,A INX D MVI C,4 CALL PRTNUM ;08B1H MVI A,' ' ;20H FOLLOWED BY A BLANK CALL PRCHR SUB PN6 ;08E2H GO BACK FOR MORE PRTLN: ;08ED +++PRTLN+++ LDAX D MOV L,A ;LOW ORDER LINE # INX D ;HIGH ORDER LINE # LDAX D. 88B +++OTSTG+++ CALL PG0 DB '"',(OT3-$-1) MVI A,'"' ;22H IT IS A (") OT1: ;0890 PRINT UNTIL ANOTHER CALL PRTSTG ;087FH A? RZ ;YES RETURN CALL PRCHR ;ELSE PRINT IT CPI 0DH ;WAS IT CR? JNZ PS1 ;0880H NO, NEXT RET ;YES RETURN OTSTG: ;0; ; PRTSTG: ;087F +++PRTSTG+++ MOV B,A PS1: ;0880 LDAX D ;GET A CHARACTER INX D ;BKUMP POINTER CMP B ;SAME AS OLDIVE SIGN IS ALSO ;PRINTED AND COUNTED IS. POSTIVE SIGN IS NOT. ; ;'PRTLN' PRINTS A SAVED TEXT LINE WITH LINE # AND ALL. . ;LOOK AT SPACE COUNT ORA A JM PN5 ;08DFH NO LEADING BLANKS MVI A,' ' ;20H LEADING BLANKS CALL PRCHR ; JMP PN4 ;08D3H MORE? PN5: ;08DF PRINT SIGN MOV A,B CALL PRCHR MOV E,L ;LAST REMAINDER IN E PN6: ;08E2 D MOV A,E ;CHECK DIGIT IN E CPI 0AH ;10 IS FLAG FOR NO MORE POP D RZ ;IF SO, RETURN ADI '0' ;30H ELSE CONVERT TO ASCII CALL PRCHR ;AND PRINT THE DIGIT JMP PN6 ;08E2H GO BACK FOR MORE PRTLN: ;08ED +++PRTLN+++ LDAX D MOV L,A ;LOW ORDER LINE # INX D ;HIGH ORDER LINE #.09C9H PU1: ;095A PUSH H PUSH B ;BC = RETURN ADDRESS RET ; ;THIS IS THE TERMINAL OUTPUT ROUTINE THE ASCII ;CHARACT, MORE TO SAVE PUSH H LHLD LOPLN ;09CFH PUSH H LHLD LOPLNT ;09CDH PUSH H LHLD LOPINC ;09CBH PUSH H LHLD LOPVAR ;AR ;09C9H ELSE SAVE LOOP VAR. $ MOV A,H ;BUT IF LOPVAR IS 0 ORA L ;THAT WILL BE ALL JZ PU1 ;095AH LHLD LOPPT ;09D1H ELSECHGSGN ;07A6H POP B ;BC = RETURN ADDRESS DAD SP ;IS STACK NEAR THE TOP? JNC QSORRY ;080DH YES, SORRY FOR THAT. LHLD LOPV.10 IS FLAG FOR NO MORE POP D RZ ;IF SO, RETURN ADI '0' ;30H ELSE CONVERT TO ASCII CALL PRCHR ;AND PRINT THE DIGIT JMP: ;08DF PRINT SIGN MOV A,B CALL PRCHR MOV E,L ;LAST REMAINDER IN E PN6: ;08E2 D MOV A,E ;CHECK DIGIT IN E CPI 0AH ;SPACE COUNT ORA A JM PN5 ;08DFH NO LEADING BLANKS MVI A,' ' ;20H LEADING BLANKS CALL PRCHR ; JMP PN4 ;08D3H MORE? PN5JMP PN2 ;08C2H AND DIVIDE BY 10 PN3: ;08D2 POP B ;WE GOT ALL DIGITS IN PN4: ;08D3 DCR C ;THE STACK MOV A,C ;LOOK AT /"/vPACES TO THE NUMBER IN C. ;HOWEVER, IF THE NUMBER OF DIGITS IS LARGER THAN THE # IN ;C, ALL DIGITS ARE PRINTED ANYWAY. NEGATUALLY A JUMP INSTRUCTION). ; ;'PRTNUM' PRINTS THE NUMBER IN HL. LEADING BLANKS ARE ADDED ;IF NEEDED TO PAD THE NUMBER OF S STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE. ;AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED ;OVER (US ;QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACK-ARROW, ;OUTPUT A CR WITHOUT A LF. IF SINGLE OR DOUBLE QUOTE, PRINT ;THE/aO WHOLE LINE DCX D ;YES, BACKUP POINTER BKSPC: ;BACK SPACE THE CURSER AND DELETE ;THE CHARACTER FROM THE SCREEN MVI CALL PRCHR JMP GL1 GL3: ;0842 MOV A,E ;DELETE LAST CHARACTER (NULL) CPI '7' ;37H BUFFER AND 0FFH JZ GL4 ;084FH NO REDRACTER CPI '7' JZ GL4 DCX D ;BACKUP THE POINTER MVI A,20H ;SPACE CALL PRCHR ;TO THE CONSOLE MVI A,08H ;BACK SPACE E CALL PRCHR RET MORM: ;083C IS E 87H?, IF NOT LOOP MOV A,E CPI 87H JNZ GL1 ;0818H CONTH: MOV A,E ;DELETE LAST CHA/=G-1 1080 K=0 1090 FOR L=1 TO G 1100 M1=1.5 1110 FOR I=1 TO N2 1120 M=INT(K/(2^G1)) 1130 IF M=M1 GOTO 1180 1140 X=M: GOSUB 1510 : P=Z 1150 V=PP*P 1160 C=COS(V) : S=SIN(V) 1170 M1=M 1180 K1=K+1 1190 K2=K1+N2 1200 T1=X(K2)*C+Y(K2)*S 1210 T2=Y(K2)*C-X(K2)*S 1220 X(K2)=X(K1)-T1 1230 Y(K2)=Y(K1)-T2 1240 X(K1)=X(K1)+T1 1250 Y(K1)=Y(K1)+T2 1260 K=K+1 1270 NEXT I 1280 K=K+N2 1290 IF K 50 THEN PRINT CHR$ (140);: GOSUB 3400 3140 /(GIVEN BY THE ;CALLER). OLD A IS STORED IT B, OLD B IS LOST. ; ;'OTSTG' LOOKS FOR A BACK-ARROW. SINGLE QUOTE, OR DOUBLE E. IT STOPS PRINTING ;AND RETURNS TO CALLER WHEN EITHER A CR IS PRINTED OR WHEN ;THE NEXT BYTE IS THE SAME AS WHAT WAS IN A 1 ;085FH CHECK IF END OF TEXT ; ; ;+++PRTSTG+++OTSTG+++PRTNUM+++& PRTLN+++ ; ;'PRTSTG' PRINTS A STRING POINTED TO BY DSKP: ;0875 +++FNDSKP+++ LDAX D CPI 0DH ;TRY TO FIND CR JNZ FL2 ;0874H KEEP LOOKING INX D ;FOUND CR, SKIP OVER JMP FL/100 REM PROGRAM NAME: FFT 110 REM COMPUTES FORWARD OR INVERSE FFT 120 REM 130 REM BY R.F. COBB 1983 140 REM BASED ON A FORTRAN ALGORITHM BY E.O. BRIGHAM 150 REM 160 DIM X(512),Y(512) 170 TW=2 : N=0 175 PT=2*ATN(1) : REM PT=Pi/2 180 GOSUB 3730 : PRINT : GOTO 500 : REM START FIRST RUN WITH DATA LOAD 190 GOSUB 3730 : PRINT 200 REM 210 REM 220 REM *MENU 230 REM 240 REM 250 PRINT " (L)OAD DATA" 260 PRINT " (F)ORWARD FFT (T TO F)" 270 PRINT " (I)NVERSE FFT (F TO T)" 280 PR/'0 : I=Z+1 1360 IF I<=K GOTO 1400 1370 T1=X(K) : T2=Y(K) 1380 X(K)=X(I) : Y(K)=Y(I) 1390 X(I)=T1 : Y(I)=T2 1400 NEXT K 1410 PRINT CHR$(7), CHR$(7) 1420 IF M$="I" THEN GOSUB 1700 : GOSUB 1760 : PRINT : PRINT 1425 IF M$="F" THEN GOSUB 1800 : PRINT : PRINT 1430 PRINT : PRINT "TRANSFORM COMPLETE " : PRINT 1450 IF M$="I" THEN PRINT "DT=";DT 1460 IF M$="F" THEN PRINT "DF=";DF 1470 PRINT : PRINT : GOTO 200 1500 REM 1510 REM * UNSCRAMBLING ALGORITHM 1520 REM 1530 J1=X : Z=0 1540 FOR Y=1 TO G : J2=I/IF A$="C" AND QQ > 20 THEN GOSUB 3500 3150 NEXT 3155 IF V$= "I" THEN PRINT "TIME INCREMENT = ";DT 3156 IF V$= "F" THEN PRINT "FREQUENCY INCREMENT = ";DF 3160 PRINT "END.. PRESS TO CONTINUE": 3161 B$=INKEY$ :C$=CHR$(30) 3162 IF B$361 OR LLY>360 GOTO 21690 21520 SLPX=LPX :SLPY=LPY :MY=(LPY-LLY)/(LPX-LLX) :BY=LLY-MY*LLX 21530 STPX=(SLPX-LLX)/ABS(SLPX-LLX) 21540 IF ABS(LPX-LLX) (POINTER) SHLD (INTSCR+1) ;STORE THE THE INTERPOLATOR ANI 15 STA INTSCR ;SAVE THE INTERPOLATOR IN THE SCRATCH PAD ; ; MVI B,4 ;GENERATE THE POINTER CALL MAN;SAVE IT ; ; MOV A,H ;CLEAR THE CHARACTERISTIC FROM HL ANI 3 MOV H,A PUSH H ;SAVE THE MANTISSA ; ; MOV A,L ;FIND TORA A ;CLEAR CARRY RAR ;REPOSITION THE CHARACTERISTIC 2 BITS RIGHT ORA A RAR MOV B,A ;PUT CHARACTERISTIC IN B PUSH B 0 INTER 20070 DEF USR6=&H9803 'ZERO PRINTER GRAPHICS MEMORY 20080 DEF USR7=&H9806 'PRINT PICTURE BORDER 20090 DEF USR8=&H9809 'SAVE THE PICTURE TO DISK (ARGUMENT=FILENAME STRING 1-8CH) 20100 DEF USR9=&H980C 'LOAD THE PICTURE FROM DISK " 20110 BORDER=&H981E 'BORDER CONFIGURATION BYTE 20120 'BORDER IS ADDRESS OF CONFIGURATION BYTE TO BE POKED 20130 'ARGUMENT IS A NO. 1-15 (LEFT=1,RIGHT=2,TOP=4,BOTTOM=8,POKE THE SUM) 20140 GOTO 21000 20150 'SEND PX AND PY TO THE GRAPHICS PROG RAM 20160  10 REM WAVEFORM GENERATOR " WAVE.ASC " 15 TP=2*3.14159 20 INPUT "FILE NAME ";F$ 30 OPEN"O",#1,F$ 40 FOR I=0 TO 63 50 X=SIN(TP/64*I)+.5*SIN(TP/32*I)+.25*SIN(TP/16*I)+3*SIN(TP/8*I) :Y=0 60 PRINT#1,X;Y :NEXT 70 PRINT "DONE" 80 END 0 TO 63 50 X=SIN(0  DIVIDE BY 16 ; MVI B,4 ;RIGHT SHIFT 4 BITS CALL MANTIS XCHG ;POINTER ADJUSTMENT IS IN DE ; LXI H,(INTSCR+3) ;GET THEMULTIPLIER ; ; MULT: DAD H RAL JNC CHCNT DAD D ;ADD IF CARRY IS 1 ; CHCNT: DCR B JNZ MULT ;LOOP UNTIL B=0 ; ;0 ;MULTIPLY BY THE INTERPOLATOR LXI H,0 MOV E,A LDA INTSCR ;LOAD THE INTERPOLATOR FROM THE SCRATCH PAD MVI B,8 ;SIZE OF YTE TO 1 MVI A,1 STA (INTSCR+3) MOV A,B MOV B,C ; ABSPON: SUB B ;ABS((POINTER+1)-(POINTER)) MOV E,A ; ; MVI D,0 `100 REM PROGRAM NAME: FFT 160 DIM X(4096),Y(4096) 170 TW=2 : N=0 175 PT=2*ATN(1) : REM PT=Pi/2 180 GOSUB 3730 : PRINT : GOTO 500 190 GOSUB 3730 : PRINT 250 PRINT " (L)OAD DATA" 260 PRINT " (F)ORWARD FFT (T TO F)" 270 PRINT " (I)NVERSE FFT (F TO T)" 290 PRINT " (S)TORE DATA" 305 PRINT : INPUT M$ 310 IF M$="L" GOTO 550 320 IF M$="F" THEN DF=1/(N*DT) :GOTO 1000 330 IF M$="I" THEN DT=1/(N*DF) : GOSUB 1700 :GOTO 1000 350 IF M$="S" GOTO 2000 370 PRINT "NOT A VALID COMMAND" : GOTO 200 550 0 POKE &H981F,PX 20170 POKA &H9820,PY 20180 OUT &HE0,0 20190 H=USR3 (0) 20200 OUT &HE1,0 20210 RETURN 21000 REM INITIALIZE THE PRINTER GRAPHICS MEMORY 21010 LET M=USR6 (0) 21020 RETURN 21100 REM LOAD LPX,LPY (X,Y PIXEL) INTO PRINTER GRAPHICS MEMORY 21110 LET LPXYA=&HDC00-(INT((LPY/8)+1)*361)+LPX 21120 LET YBYTE=INT(2^(((LPY/8)-INT(LPY/8))*8)) 21130 LET PO=PEEK(LPXYA) 21140 LET YBYTE=YBYTE OR PO 21150 POKE LPXYA,YBYTE 21160 RETURN 21200 REM SET THE PIXEL SCREEN ADDRESS AND WRITE TO THE SCREEN0= DB 64 DB 60 DB 57 DB 54 DB 50 DB 46 DB 41 DB 37 DB 32 DB 27 DB 22 DB 17 DB 11 DB 6 DB 0 ; ; END DB 88 DB 88 DB 87 DB 87 DB 86 DB 85 DB 84 DB 83 DB 82 DB 80 DB 78 DB 76 DB 74 DB 72 DB 69 DB 67 DB 67 DB 70 DB 72 DB 74 DB 76 DB 78 DB 80 DB 81 DB 82 DB 84 DB 85 DB 86 DB 86 DB 87 DB 87 DB 88 DB 9 DB 14 DB 18 DB 23 DB 27 DB 31 DB 35 DB 39 DB 42 DB 46 DB 49 DB 53 DB 56 DB 59 DB 62 DB 64 0|;DETERMIN THE INTERPOLATION POLARITY JP ABSPON ;I.E. ACENDING OR DECENDING CORRECTORS MOV C,A ;NEG, SWAP A&B, SET THE SIGN BA (INTSCR+3) ; LHLD (INTSCR+1) ;LOAD THE TABLE POINTER MOV B,M ;(POINTER) TO B INX H MOV A,M ;(POINTER+1) TO A CMP B TER+((POINTER+1)-(POINTER))*INTERPOLATOR/16) ; INTERP: ;INTERPOLATOR FOR 10 BIT MANTISSA MVI A,0 ;CLEAR THE SIGN BYTE ST JP ALGFIN JMP QHOW ;ANTILOG OUT OF RANGE, ERROR ALGFIN: POP D POP B RET ;ANTILOG DONE ; ;INTERPOLATOR EVALUATES POIN1[10 INPUT "NAME OF INPUT FILE: " ; IN$ 560 OPEN"I",#1,IN$ 580 INPUT "N,DF,DT";N,DF,DT 590 FOR I=1 TO N : INPUT#1,X(I),Y(I) : NEXT 600 CLOSE#1 610 PP=B*ATN(1)/N : REM THIS IS 2*Pi/N 630 PRINT : PRINT "DATA LOADED" 650 PRINT : GOTO 200 660 REM 1042 V$=M$ 1045 IF N<1 THEN PRINT :PRINT "NO DATA IN FILE" :PRINT : GOTO 200 1048 PRINT : PRINT N; "POINT TRANSFORM IN PROGRESS" 1050 G=INT(LOG(N)/LOG(2)+.5) 1060 N2=INT(N/2) 1070 G1=G-1 1080 K=0 1090 FOR L=1 TO G 1100 M1=1.5 1110 FOR I=1 TO N2 1120 1OTH PUSH H LHLD RANPNT ;09D3H GET MEMORY AS RANDOM LXI D,LSTROM ;09B0H NUMBER CALL COMP JC RA1 ;06E2H RAP AROUND IF LA++ CALL PARN ;06BCH MOV A,H ;EXPR MUST BE + ORA A JM QHOW ;0166H ORA L ;AND NON-ZERO JZ QHOW ;0166H PUSH D ;SAVE BLL PG0 DB ')' DB (XP43-$-1) XP42: ;06C3 RET XP43: ;06C4 JMP QWHAT ;07E0H ELSE SAY WHAT RND: ;06C7 +++RND(EXPR)+F DIGIT ORA A RNZ ;OK PARN: ;06BC CALL PG0 ;NO DIGIT, MUST BE DB '(' ;28H DB (XP43-$-1) CALL EXPR ;"" CA1"#"*{ozg"*"> ͎E**y**{ozgEE**#{z*!+"!""*+}ʝ ʁ*> b##"*+"k*^#V#" >  ^#~))))!o&:/o*"*#" >k*+}P" k2*&&&>002(x0J:*>0:2*2 *  *  *#ڑW+}ʢzŒÈi`:ʱ)=¬   : Total of $k in $ files with $k space remaining.$>:> _1SO THAT VARIABLE '@' CAN HAVE AN ;AS INDEX, FUNCTIONS CAN HAVE AN AS ARGUMENTS, AND ; CAN BE AN NAL REPEATS ;::=(< OR />)(....) ;::= ; ;() ; IS RECURSIVE IONS IS 1 IF TRUE AND 0 IF FALSE. ;::=(+ OR -)(+ OR -)(....) ;WHERE <> ARE OPTIONAL AND (....) ARE OPIOPR1>= ; ;WHERE IS ONE OF THE OPERATORS IN TABS AND THE ;RESULT OF THESE OPERAT1vM=INT(K/(2^G1)) 1130 IF M=M1 GOTO 1180 1140 X=M: GOSUB 1510 : P=Z 1150 V=PP*P 1160 C=COS(V) : S=SIN(V) 1170 M1=M 1180 K1=K+1 1190 K2=K1+N2 1200 T1=X(K2)*C+Y(K2)*S 1210 T2=Y(K2)*C-X(K2)*S 1220 X(K2)=X(K1)-T1 1230 Y(K2)=Y(K1)-T2 1240 X(K1)=X(K1)+T1 1250 Y(K1)=Y(K1)+T2 1260 K=K+1 1270 NEXT I 1280 K=K+N2 1290 IF K >  (Strike any key to continue)$^#V#N#F_ #wl)) ) Nq#Nq)) ) N#F^#V_ #   2{*" k2*&&&>002(x0J:*>0:2*2 *  *  *#ڑW+}ʢzŒÈi`:ʱ)=¬   : Total of $k in $ files with $k space remaining.$>:> _1T1: ;05D1 CALL FINISH ;UNTIL FINISH ; ; ;+++EXPR+++ ; ;'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS ; CALL EXPR4 ;06A7H AND GET 2ND ONE MVI B,0 ;CLEAR B FOR SIGN CALL CHKSGN ;07A3H CHECKD AND COUNT JZ XP35 ;0699H XP33: CALL MULTIPLY JMP XP35 ;0699H FINISHED XP34: ;067C CALL PG0 ;DIVIDE? DB '/',(XP421 r ;0601 MOV A,C ;SUBROUTINE FOR ALL POP H ;REL. OP.'S POP B ;REVERSE TOP OF STACK PUSH H PUSH B MOV C,A CALL EXPR RNC ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP17: ;05FF POP H ;NOT REL. OP. RET ;RETURN HL= XP18:P18 ;0601H REL. OP. "=" RNZ ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP16: ;05F9 CALL XP18 ;0601H REL. OP. "<"18 ;0601H REL. OP. "<=" MOV L,A ;SET HL=1 RZ ;REL. TRUE, RETURN RC MOV L,H ;ELSE SET HL=0 RET XP15: ;05F3 CALL X1  MOV M,E ;SAVE VALUE IN VAR. INX H MOV M,D POP H ;GET OLD 'CURRNT' SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER IP4ER ;0F37H POINTS TO BUFFER CALL EXPR ;EVALUATE INPUT NOP ;CAN BE 'CALL ENDCHK' NOP NOP POP D ;OK, GET OLD HL XCHG O DAD SP SHLD STKINP ;09C7H PUSH D ;OLD HL MVI A,':' ;3AH CALL GETLN ;0814H AND GET A LINE IP33: ;05A9 LXI D,BUFFT ;09C1H ALSO SAVE 'CURRNT' PUSH H ; LXI H,IP1 ;0572H A NEGATIVE NUMBER SHLD CURRNT ;09C1H AS A FLAG LXI H,0 ;SAVE SP TO1 590 IF M$="F" THEN PRINT "DF=";DF 1600 PRINT : GOTO 200 1730 FOR I=1 TO N : Y(I)=-Y(I) : NEXT I : RETURN 1790 FOR I=1 TO N : X(I)=X(I)*DF : Y(I)=Y(I)*DF : NEXT : RETURN 1860 FOR I=1 TO N : X(I)=X(I)*DT : Y(I)=Y(I)*DT : NEXT : RETURN 2050 INPUT "FILE NAME: ";F$ 2060 OPEN"O",#2,F$ 2070 FOR I=1 TO N 2080 PRINT#2,X(I);Y(I); :NEXT 2090 PRINT#2,DF,DT,N 2100 CLOSE #2 2130 PRINT : PRINT "DONE": PRINT : GOTO 200 3730 FOR CLS = 1 TO 33 :PRINT : NEXT CLS : RETURN 3740 END DT,N 2100 CLOSE #2 2130 P1!9""1":m2$2%2 "(}a 2%:)a/ :% O>1:% 0C >2!\~r<2\@2!]~ ‰ 6?#‚>?2h:\=_2\:(##~2#~2##^#V"#^#V"*.;^#~2#~2#^""#)+""*{zҫ\" RZ ;FALSE RC ;ALSO FALSE HL=0 MOV L,A ;TRUE HL=1 RET XP14: ;05EB CALL XPETURN HL=1 RET XP12: ;05DE REL OF "#" CALL XP18 ;0601H RZ ;FALSE, RETURN HL=0 MOV L,A ;TRUE, RETURN HL=1 RET XP13 UP REL. OP. JMP EX0 ;02D8H GO DO IT XP11: ;05D8 CALL XP18 ;0601H REL. OP. ">=" RC ;NO, RETURN HL=0 MOV L,A ;YES,RIN PARENTHESES. ; ; EXPR CALL EXPR2 THIS IS AT LOC. 18 ; PUSH HL ; ; EXPR1: ;05D2 LXI H,TAB8-1 ;02BEH LOOK22=COPYRIGHT (C) 1980, DIGITAL RESEARCH DDT VERS 2.2$10 !~=W!xe ~#Xbxʇ {z~#o}o҃i.2_!fp+q*e2_2_!hp+q*g!jp+q*i!lp+q*k!np+q*m2_!pp+q*oÃO$*sy͏ , $  ͌ 9!z6 # L!zw͌j# X:z 0 ͘=N#Fy}80*z{¯#z+++ ¥ z#½# · 9!`͠ y9!rͷ2͓ !" >- Ͷ Aګ ҫ _!7^#V~  \p Z z ů2[\͓͢ ҫ ͐ =« f " ͓ ҫ ͐ ʻf " =ʻf "=« ý> 2͐ f "]=f =« *]}o"_  *]"a. ~ #E }"]*a 6 *]}#|#*]E ͐ « f f f {zA|« W}d ͐ f f f DMʡڏ"=ʡͲ=ʡYPͲ1**!O~4#~#F#x~#s#r#w>͐ « f f  . ᯕo>g.2|)*)þ))>+><7"9.Yͯ * M^2U :2:2ͳ:_³ͯ !6! @!!BH @@ABH B! "BHI$$BI$BI $ HI f D$HD$$ H B!$D$"$B$DA!ABI$H B$I $HI$H$! $I u$I$$A !A@$I$"!$H$I$I "! $A$  HHAA"I @BB $A"2&BACK HOME ; ; ;+++FOR+++& NEXT+++ ; ;'FOR' HAS TWO FORMS: ;'FOR VAR=EXP1 TO EXP2 STEP EXP3' AND 'FOR VAR=EXP1 TO EXP CURRNT ;09C1H AND THE OLD 'CURRNT' POP D ;OLD TEXT POINTER CALL POPA ;0918H OLD "FOR" PARAMETERS CALL FINISH ;AND WE ARE UATES EXP2 AND EXP3 ;AND SAVE ALL TOGATHER WITH THE TEXT POINTER ETC. IN ;THE 'FOR' SAVE AREA. WHICH CONSISTS OF 'LOPVAR', '2' ;(WHERE EXP3 ASSUME 1). ;TB1 WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE ;CURRENT VALUE OF EXP1. IT ALSO EVAL2 y=!z{w# % w!P͠ y͓}*w#"͌ @.@<!Eͷ~P !ͷ’P͌Q!ͷªP}QxQ!ͷ͓G@Q! ͷ y͓Gþ!ͷ ͓Q!ͷ͓Q͌Q!.ͷ6y#G͙Qà!2ͷQ͓͌Q!>ͷq eg͙Q:zJEËC–EQyQxQRQ** {zҷ*~#" <AOGƐ'@'OxƐ'@'ON# 2& 2|2\  !]w# ʫ .&  0 6 #& .K !e K w# ʫ : U 6 #K 6AW w#] !e~H#~E#~X*}|́ "!́ ͐ !ʬ =« f kʫ j \͢F w# ͋ t ʫ : W& _& & O { `i"F & & w# & ͋ « t Y t Y GтWx ͢!o ~Z #N  *. *.  NEXT PC͐ =« f  . ~ Ͷ ʻ .͓ =« f |« }w#Ä >2L͐ ! =« f }ʫ +"MD Å D  !  #2$$$I$$H!!! BH" !I B  $$!BD! $!BI D@"!$I$$H"!I$I$I$UUU$$A$ /fD$HD$$ H B!$D$"$B$DA!ABI$H B$I $HI$H$! $I u$I$$A !A@$I$"!$H$I$I "! $A$  HHAA"I @BB $A"2 ;SIZE OF MEMORY. ;THEN IT PROMPTS ">" AND READS A LINE. IF THE LINE STARTS ;WITH A NON-ZERO NUMBER, THIS NUMBER IS THE LINE NUMBER. THE ;LINE NUMBER AND THE REST OF THE LINE ; IS STORED IN MEMORY. IF A LINE WITH THE SAME ;LINE NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE. ;IF THE REST OF THE LINE IS "CR" ONLY, IT IS NOT STORED AND ;AND ANY EXISTING LINE WITH THE SAME NUMBER IS DELETED. ; ;AFTER A LINE IS INSERTED, REPLACED, OR DELETED2 ^z8O!B N#N ¾SP.* |} !9":q!"S Ag}S S i |« }!w s#r:[ʔ _!~ʦ ![4ç \͢¦ 2[ 7 >?  e͢!g"c> _͢a_!f~> 5*c~#"c 0 7   > >  ͢| } @ >. *_}o| , 0 ë ^#V#!Y ))))o P q s#r#!V4 !V6# ,® >2Vñ m ͅ m ͅ m ͅ « Vʫ ! XN!~  2  TO FIND THE RIGHT ONE AND PURGES ALL THOSE THAT ;DID NOT MATCH EITHER WAY, TB1 THEN ADDS THE 'STEP' TO ;THAT VARIABLE AND CHF THE 'FOR' LOOP. THE CONTROL VARIABLE VAR. IS CHECKED ;WITH THE 'LOPVAR'. IF THEY ARE NOT THE SAME, TB1 DIGS IN ;THE STACK OR' LOOP IS DEACTIVATED. ;(PURGED FROM THE STACK.) ; ;'NEXT VAR' SERVES AS THE LOGICAL (NOT NECESSARILY PHYSICAL) ;END OK AND FIND OUT IF THIS SAME ;VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP. ;IF THAT IS THE CASE, THEN THE OLD 'F2 Y, THE PROGRAM ;LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILL BE ;TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE NUMBER, ;AND CONTROL IS TRANSFERED TO "DIRECT". ; ;THE MEMORY LOCATION "CURRNT" PIONTS TO THE LINE NUMBER ;THAT IS CURRENTLY BEING INTERPRETED. WHILE WE ARE IN ;THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND ; RSTART: ;0181 LXI SP,2000H ;THIS POINTER IS MODIFIED TO EQUAL TOP OF AVAILABLE ST1: ;0184 MEMORY CALL CRLF ;+CRLF+ JUMP TO HERE LXI D2 IO!b q!vz͒q.?*!9"8"͉Z*" +*'/7?v"*2:EI SPHLDI XCHGPCHLXTHLRET HLT CMC STC CMA DAA RAR RAL RRC RLC NOP CPI ORI XRI ANI SBI IN SUI OUT ACI ADI CALLJMP LDA STA LHLDSHLDMOV ADD ADC SUB SBB ANA XRA ORA CMP INR DCR MVI LXI STAXINX DAD LDAXDCX RST PSW POP PUSHNZZ NCC POPEP M B C D E H L M A B D H SP PSW ??= M!Eâê ö  - Ð f  "J*"!"!"2O!" "]""!1!++""M>28!"9:] !í 12! _^! ^#V~ x+ >= = !~  . !   #x f L L ͓ͅ ҆ *" !6ï +"_*~ #E گ ʫ ^#V. ï ~ CZMEIABDHSP!"M"+"!91*~!O~6=G#^#V#~x (#"!N#FW( *J>7Å*M|N+"M N:LHͅÅD Å >* *͓ b" . *"] !/~##ʁtZ*F#n!Is!^#V&&##&))::^#V#*^#V>+)x-8_2N ;'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK ;BEFORE THE NEW ONE OVER WRITES IT. ;TB1 WILL THEN DIG IN THE STACLOPINC', ;'LOPLMT', 'LOPLN', AND 'LOPPT'. IF THERE IS ALREADY SOMETHING ;IN THE SAVE AREA (THIS IS INDICATED BY A NON-ZERO UATES EXP2 AND EXP3 ;AND SAVE ALL TOGATHER WITH THE TEXT POINTER ETC. IN ;THE 'FOR' SAVE AREA. WHICH CONSISTS OF 'LOPVAR', '2' ;(WHERE EXP3 ASSUME 1). ;TB1 WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE ;CURRENT VALUE OF EXP1. IT ALSO EVAL3I3,OK ;0172H DE->STRING SUB A ;A=0 CALL PRTSTG ;087FH PRINT STRING UNTIL CR LXI H,ST2+1 ;0195H LITERAL 0 SHLD CURRNT ;09C1H CURRNT->LINE # = 0 ST2: ;0194 ; LXI H,0 SHLD LOPVAR ;09C9H SHLD STKGOS ;09C3H ST3: ;019D MVI A,'>' ;3EH PROMPT '>' AND CALL GETLN ;0814H READ A LINE PUSH D ;DE->END OF LINE ST33: ;01A3 LXI D,BUFFER ;0F37H DE->BEGINING OF LINE CALL TSTNUM ;013EH TEST IF IT IS A NUMBER RST 5 ; MOV A,H ;HL = VALUE OF # OR ORA L ;0 IF NO NUMBER POP B ;BC->END OF LINE 3LHLD LOPVAR ;09C9H ELSE SAVE LOOP VAR. $ MOV A,H ;BUT IF LOPVAR IS 0 ORA L ;THAT WILL BE ALL JZ PU1 ;095AH LHLD LOPPT ;09D1H ELSE, MORE TO SAVE PUSH H LHLD LOPLN ;09CFH PUSH H LHLD LOPLNT ;09CDH PUSH H LHLD LOPINC ;09CBH PUSH H LHLD LOPVAR ;09C9H PU1: ;095A PUSH H PUSH B ;BC = RETURN ADDRESS RET ; ;THIS IS THE TERMINAL OUTPUT ROUTINE THE ASCII ;CHARACTER IS IN THE A REG. IF CR, LF IS ADDED ; OC2: ;095D JNZ OC3 ;0962H IT IS ON POP PSW ;IT IS OFF RET ;RESTORE3' ;40H TEST VARIABLES RC ; C:NOT A VARIABLE JMP TV0 ;JUMP TV0 AND CALL PARN ; ;THIS IS CONSOLE STATUS, 00 RETURNED IN A, IF READY FOR INPUT. ;FF RETURNED IF NO INPUT. ; CHKIO: ;0985 PUSH B ;PUSH REGISTERS PUSH D PUSH H MVI C,0BH ;CONSOLE STATUS CALL 5 ;CALL BDOS ORA A ;READY? JNZ CONTLO ;0994H YES, GET INPUT CHARACTER JMP POPR ;0981H NO, POP THE REGISTERS AND RETURN ; ;THIS IS THE CONSOLE INPUT ROUTINE, ASCII CHARACTER IS ;RETURNED IN A . ; CONTLO: ;0994 MVI C,130',0DH ;MESSAGE READING ROUTINE SETSTK: ;09FF MVI A,0FFH ;INITIALIZE SWITCH FOR OUTPUT STA OCSW ;09C0H MVI A,0AH CALL PRCHR SUB A LXI D,MSAG1 ;09D8H CALL PRTSTG ;087FH PRINT THE SIGN ON MESSAGE LXI H,ST1 ;LOAD ADDRESS OF THE START ROUTINE SHLD 0101H ;NEW JUMP VECTOR TO PROGRAM START JMP RSTART ;0184H START THE PROGRAM ; ;SCRATCH PAD AREA IN RAM ORG VARBGN+2; OCSW: NOP ;STORAGE REG. FOR CONSOLE OUTPUT CHARACTER NOP NOP ;STORAGE REG. FOR CONSOLE INPUT CHARACTER NOP CURRNT3V LDAX D ;PRINT 4 DIGIT LINE # MOV H,A INX D MVI C,4 CALL PRTNUM ;08B1H MVI A,' ' ;20H FOLLOWED BY A BLANK CALL PRCHR SUB A ;AND THEN THE TEXT CALL PRTSTG ;087FH RET ; ;+++MVUP+++MVDOWN+++PAPA+++& PUSHA+++ ; ;'MVUP' MOVES A BLOCK UP FROM WHERE DE-> TO WHERE BC-> UNTIL ;DE = HL ; ;'MVDOWN' MOVES A BLOCK DOWN FROM WHERE DE-> TO WHERE HL-> ;UNTIL DE = BC ; ;'POPA' RESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE ;STACK ; ;'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SA3 AF AND RETURN OC3: ;0962 POP PSW ;COME HERE TO DO OUTPUT PUSH B PUSH D PUSH H STA OCSW-1 ;09BFH STORE THE CHARACTER AT OCSW-1 MOV E,A ;MOVE ASCII CHARACTER TO BE OUTPUT FROM A TO E MVI C,2 ;CONSOLE OUTPUT CALL 5 ;CALL BDOS, PRINT THE CHARACTER ON THE CONSOLE LDA OCSW-1 ;09BFH RELOAD THE CHARACTER CPI 0DH ;IS IT CR? JNZ LDACC ;097EH NO, JUMP LDACC MVI E,0AH ;YES, SEND LF TO THE TERMINAL MVI C,2 ;OUTPUT TO TERMINAL CALL 5 ;CALL BDOS LDACC: ;097E LDA OCSW-1 ;09BFH RELOAD TH3  ;CONSOLE INPUT CALL 5 ;CALL BDOS CPI 0FH ;IS IT BACK-SPACE (^I)? JNZ CI1 ;09A8H NO,SKIP TO CI1 LDA OCSW ;09C0H YES, RELOAD THE BACK-SPACE CMA ;COMPLEMENT (F0H) STA OCSW ;09C0H STORE BACK JMP CHKIO ;0985H JUMP TO CONSOLE STATUS CI1: ;09A8 CPI 3 ;IS IT 03 (^C) JNZ POPR ;0981H NO, POP THE REGISTERS AND GO ON JMP RSTART ;0181H RESTART ; LSTROM: PUSH B ;SAVE BE PUSH A ;SAVE THE DATA LDA OUTPORT ;LOAD THE PORT NUMBER MOV C,A ;PUT THE PORT NUMBER IN C POP PSW ;GET THE DATA BAC3S: ;09C1 SWITCH FOR OUTPUT NOP NOP STKGOS: ;09C3 SAVES SP IN 'GOSUB' NOP NOP VARNXT: ;09C5 TEMP STORAGE NOP NOP STKINP: ;09C7 SAVES SP IN 'INPUT' NOP NOP LOPVAR: ;09C9 'FOR' LOOP SAVE AREA NOP NOP LOPINC: ;09CB INCREMENT NOP NOP LOPLNT: ;09CD LIMIT NOP NOP LOPLN: ;09CF LINE NUMBER NOP DB 0 LOPPT: ;09D1 TEXT POINTER DB 0,0 RANPNT: ;09D3 RANDOM NUMBER POINTER DB 0,1 INPORT: DB 0 OUTPORT: DB 0 ; INTERPOLATION SCRATCH PAD INTSCR: DB 0 ;INTERPOL3 !VE AREA INTO THE ;STACK ; MVUP: ;0900 +++MVUP+++ CALL COMP RZ ;DE = HL, RETURN LDAX D ;GET ONE BYTE STAX B ;MOVE IT INX D ;INCREASE BOTH POINTERS INX B JMP MVUP ;0900H UNTIL DONE MVDOWN: ;0909 +++MVDOWN+++ MOV A,B SUB D ;TEST IF DE = BC JNZ MD1 ;0911H NO, GO MOVE MOV A,C ;MAYBE, OTHER BYTE? SUB E RZ ;YES, RETURN MD1: ;0911 DCX D ;ELSE MOVE A BYTE DCX H ;BUT FIRST DECREASE LDAX D ;BOTH POINTERS AND MOV M,A ;THEN DO IT JMP MVDOWN ;0909H LOOP BACK POPA: ;0918 3 E CHARACTER POPR: ;0981 RESTORE ALL THE REGISTERS POP H POP D POP B RET ; ;THIS IS THE RESTART SUBROUTINE GROUP ; PG0: ;0A50 THIS BLOCK IS MOVED INTO PAGE 0 XTHL CALL IGNBLK CMP M JMP TC1 ;012FH CRLF1: ;0A56 +++CRLF+++ MVI A,0DH ; PRCHR: ;PRINT CHARACTERS PUSH PSW ;RST 2 LDA OCSW ;09C0H PRINT CHARACTERS ONLY ORA A ;IF OCSTW IS ON JMP OC2 ;095DH REST OF THIS IS AT OC2 EXPR: CALL EXPR2 ;0616H +++EXPR+++ PUSH H ;EVALUATE AN EXPRESSION JMP EXPR1 ;05D2H RES3 K DB 0EDH,79H;Z-80 CODE FOR OUPUT A,(C) POP B RET ;THIS IS THE WAIT COMMAND. THE INPUT PORT # SPECIFIED IN ;THE BASIC PROGRAM IS READ IN A LOOP UNTIL THE "J" MASK ;RESULTS IN A NON-ZERO VALUE. WAITCOM: PUSH B ;SAVE BC MOV B,E ;PREVENT 8080 CRASH LDA INPORT ;GET THE PORT NUMBER MOV C,A DB 0EDH,78H;Z80 INPUT INSTRUCTION IN A,(C) XRA H ;EX-OR WITH "K", IF GIVEN IN PROGRAM ANA L ;MASK WITH "J" JZ WAITCOM ;09B3H LOOP IF ZERO POP B CALL FINISH ; ;INP COMMAND THE PORT # IS CH3 rATOR DB 0 ;POINTER L (+1) DB 0 ;POINTER H (+2) DB 0 ;SIGN OF ABOVE (+3) DB 0 ;CORRECTOR (+4) END OP STKINP: ;09C7 SAVES SP IN 'INPUT' NOP NOP LOPVAR: ;09C9 'FOR' LOOP SAVE AREA NOP NOP LOPINC: ;09CB INCREMENT NOP NOP LOPLNT: ;09CD LIMIT NOP NOP LOPLN: ;09CF LINE NUMBER NOP DB 0 LOPPT: ;09D1 TEXT POINTER DB 0,0 RANPNT: ;09D3 RANDOM NUMBER POINTER DB 0,1 INPORT: DB 0 OUTPORT: DB 0 ; INTERPOLATION SCRATCH PAD INTSCR: DB 0 ;INTERPOL3   "3xH:>xff`@O`@a>F@x>rNFgF@xqO?>@`xB>BA>@@a@@yO@yGB O>`>`A>`C@O?????>B@>`@a>@N`NFgF@HBqprO@ONFgF@FBpfO@ONFgF@FCpbO@ONFgF@gO ?Osrq?>`C>xff``Ny ?NyFIO@F@bxbOpxFGpN``CyO@srq?>`C>xff`fxgH>xpA>B`x>Na>@BBq@ fO>`>@ >b@>Nx3/T OF IT IS AT EXPR1 DB 'W' ; COMP: MOV A,H ;+++COMP+++ CMP D ;COMPARE HL WITH DE RNZ ;RETURN CORRECT C AND MOV A,L ;Z FLAGS CMP E ;BUT OLD A IS LOST RET DB 'AN' IGNBLK: LDAX D ;+++IGNBLK+++ CPI ' ' ;20H IGNORE BLANKS RNZ ;IN TEXT (WHERE DE->) INX D ;AND RETURN THE FIRST JMP IGNBLK ;NON-BLANK CHAR. IN A ; FINISH: POP PSW ;+++FINISH+++ CALL FIN ;07CDH CHECK END OF COMMAND JMP QWHAT ;07E0H PRINT "WHAT?" IF WRONG DB 'G' ; TSTVAR: CALL IGNBLK ;+++TSTV+++ SUI '@3UANGED BY THE BASIC PROGRAM ; INCOMM: PUSH B ;SAVE BC MOV B,E ;PREVENT 8080 CRASH LDA INPORT ;GET THE PORT NUMBER MOV C,A DB 0EDH,78H;Z80 INPUT INSTRUCTION IN A,(C) MOV L,A ;RETURN THE NUMBER RET ;IN THE L REG. ; TXTUNF: ;09D5 ->UNFILLED TEXT AREA (END OF PROGRAM TEXT) DW TXTBGN ;INITIAL VALUE TXTBGN: ;09D7 TEXT SAVE AREA BEGINS DB 'M' ; ; SIGN ON MESSAGE (OVER WRITTEN BY THE BASIC PROGRAM) MSAG1: ; DB 7FH,7FH,7FH,'BAILEY ROMABLE ' DB 'TINY BASIC VER. ' MSAG2: ; DB '144SAVE POINTER EX1: ;02DA LDAX D ;IF FOUND '.' IN STRING INX D ;BEFORE ANY MISMATCH CPI '.' ;2EH DECLARE A MATCH JZ EX3 ;02F7H INX H ;HL->TABLE CMP M ;IF MATCH, TEST NEXT JZ EX1 ;02DAH MVI A,7FH ;ELSE SEE IF BIT 7 DCX D ;OF TABLE IS SET, WHICH CMP M ;IS THE JUMP ADDR. (HI) JC EX5 ;02FEH C:YES MATCHED EX2: ;02ED ;NC:NO FIND JUMP ADDR. INX H CMP M JNC EX2 ;02EDH INX H ;BUMP THE NEXT TABLE ITEM POP D ;RESTORE STRING POINTER JMP EX0 ;02D8H TEST AGIANST NEXT ITEM EX3: ;04tXPR(CR)' EVALUATES THE EXPRESSION. FIND THE TARGET LINE, ;AND JUMP TO 'RUNTSL' TO DO IT. ; NEW: ;0306 +++NEW(CR)+++ CALL ENDCHK ;07DCH LXI H,TXTBGN ;09D7H SHLD TXTUNF ;09D5H STOP: ;030F +++STOP(CR)+++ CALL ENDCHK ;07DCH JMP RSTART ;0181H RUN: ;0315 +++RUN(CR)+++ CALL ENDCHK ;07DCH LXI D,TXTBGN ;09D7H FIRST SAVED LINE RUNNXL: ;031B +++RUNNXL++ LXI H,0 ;FIND WHATEVER LINE # CALL FL1 ;085FH C:PASSED TXTUNF, QUIT. JC RSTART ;0181H RUNTSL: ;0324 +++RUNTSL+++ XCHG SHLD CURR4@DE=FCB ADDRESS CALL 5 ;CALL BDOS ORA A JNZ QHOW ;0166H POP D LDA L09D6 ;09D6H CMP D JC CLFIL ;03D9H JNZ L03D1 ;03D1H LDA TXTUNF ;09D5H CMP E JC CLFIL ;03D9H L03D1: ;03D1 LXI H,80H DAD D XCHG JMP DSKWR ;03ADH CLFIL: ;03D9 MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP B ;RESTORE REGISTERS POP D POP H RST 6 L03E5: ;03E5 LXI H,5CH MVI M,0 L03EA: ;03EA INX H MVI M,' ' ;20H MVI A,64H CMP L JNZ L03EA ;03EAH INX H MVI 4° *+*e xR ++ NO MEMORY FOR COPY BUFFER ++)i`"!"% *%~@͜:ʉ ڄ >1͜0͜: #~͜#’>.͜~͜#¢~2#"% : :u6ͼ  B66Cʼ DʝFzJLMʊ Pʫ R;SeT`UJVQ Wʴ X͸*%"%]:<2>2u2M*%~*6 ~*%~*6*>2M2~2>͜(#(*I"!"I:o*k/o::M*x"x*x}o|g"x͛> 2Lwk:*x͛:LG> ͜42F7 MVI A,7FH ;PARTIAL MATCH, FIND EX4: ;02F9 INX H ;JUMP ADDR., WHICH IS CMP M ;FLAGED BY BIT 7. JNC EX4 ;02F9H EX5: ;02FE MOV A,M ;LOAD HL WITH THE JUMP INX H ;ADDR. FROM THE TABLE MOV L,M ANI 7FH ;MASK OFF BIT 7 MOV H,A POP PSW ;CLEAN UP THE GARBAGE AND PCHL ;GO DO IT. ; ; ;WHAT FOLLOWS IS THE CODE TO EXECUTE DIRECT AND STATMENT ;COMMANDS. CONTROL IS TRANSFERED TO THESE POINTS VIA THE ;COMMAND TABLE LOOKUP CODE OF 'DIRECT' AND 'EXEC' IN LAST ;SECTION. AFTER THE C4!NT ;09C1H SET 'CURRENT'->LINE # XCHG INX D ;BUMP PASS LINE # INX D RUNSML: ;032B +++RUNSML+++ CALL CHKIO ;0985H FIND COMMAND IN TAB2 LXI H,TAB2-1 ;0219H AND EXICUTE IT. JMP EX0 ;02D8H GOTO: ;0334 +++GOTO EXPR+++ RST 3 ; PUSH D ;SAVE FOR ERROR ROUTINE CALL ENDCHK ;07DCH MUST FIND A CR CALL FNDLN ;0857H FIND THE TARGET LINE JNZ AHOW ;0167H NO SUCH LINE # POP PSW ;CLEAR THE "PUSH DE" JMP RUNTSL ;0324H GO DO IT ; ;THE FOLLOWING ROUTINES DO THE DISK COMMUNICATION ; RST 5 P4M,'T' ;54H INX H MVI M,'B' ;42H INX H MVI M,'I' ;49H L03FC: ;03FC INX H MVI M,0 MVI A,6BH CMP L JNZ L03FC ;03FCH LXI H,5DH L0408: ;0408 LDAX D CPI 0DH RZ CPI '!' ;21H JC QWHAT ;07E0H CPI 5BH JNC QWHAT ;07E0H MOV M,A INX H INX D MVI A,65H CMP L JNZ L0408 ;0408H RET ; ; ;+++LIST+++& PRINT+++ ; ;LIST HAS 2 FORMS ;'LIST(CR)' LISTS ALL SAVED LINES ;'LIST #(CR)' START LIST AT THIS LINE # ;YOU CAN STOP LIST WITH ^C ; ;PRINT COMMAND IS 'PRINT4$>(͜wk)2u2*%*#e]͕!"%]*% eO͕*# "% <- *%"%ftorage remaining on drive: I ͸:Y)(elete? (Y/N): ͼY)(< ++ NO FILE FOUND ++)*%"%*#e 4"#e*%e2 ++ List Empty ++ú*% 4ename file to: z !6# !{N#i&6 ڼ .ʯw#‰ .Ÿ!  .w#´!?! G>w# :2( !)4!4?(4 CCOMPRES MBASIC /M:&HD000 2TYP62 COM&_`USQ COM@>?SLOCK COMeSQ COMj*+,fUN COM"gsWS COM|rtuvFIND COM@DECHEX BAKADECHEX ASCB MBASIC $$$ XDIR COM L!TAPELIB MAC'MNOPQRSTUV4 USH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,0FH ;OPEN FILE CALL 5 ;CALL BDOS CPI 0FFH JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKRD: ;035E READ THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,14H ;READ SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS CPI 1 ;ERROR CODE? JC NEWFIL ;0381H JNZ QHOW ;0166H ERROR MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP D ;RESTORE REGISTERS 4  ;C Copyright (c) 1983 by Frank Gaude' All Rights Reserved!9"1`22:\a=2Y͸:] :e !j] 42h2|/2\<_2 ++ NO FILE FOUND ++ --> Command (l or x): ͼXLog-in drive/user: :'2_I> 2]2e!"x a!|z 2':}:}0}:ҙ0k:~:i0i6ҙ&2'}>G:~:y0ҙx2': cancels, turns up one line, other keys page screen. >22N>ú 2N>ú 2N>2(!4?(< ++ UNABLE TO OPEN FILE ++)2H()!~)_:O:N=  )# { :<2د2 [more...]    >2ʼʼ! "%>*#"%ʸ *%*#eʭ *%Ð 2v/2wW2w!"(!4?2H !)4(<  ++ UNABLE TO OPEN SOU4  EW(CR)' SES 'TXTUNF' TO POINT TO THE BEGINING OF TEXT AREA ; ;'STOP(CR)' GOES BACK TO 'RSTART' ;'RUN(CR)' FINDS THE FIRST STORED LINE, STORE ITS ADDRESS (IN ;'CURRNT' AND START TO EXECUTE IT. NOTE THAT ONLY THOSE ;COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM. ; ;THERE ARE 3 MORE ENTRIES IN 'RUN': ;'RUNNXL' FINDS THE NEXT LINE, STORES ITS ADDRESS AND EXECUTES IT. ;'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT. ;'RUNSML' CONTINUES THE EXECUTION ON SAME LINE. ; ; ;'GOTO E4POP B POP D POP H RST 6 NEWFIL: ;0381 POP D LXI H,80H DAD D XCHG JMP DSKRD ;035EH RST 5 PUSH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,13H ;DELETE FILE CALL 5 ;CALL BDOS LXI D,5CH ;DE=FCB ADDRESS MVI C,16H ;MAKE A FILE CALL 5 ;CALL BDOS CPI 0FFH ;ERROR? JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKWR: ;03AD WRITE TO THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,15H ;WRITE SEQUENTIAL LXI D,5CH ;4h-- File Manipulation Program -- 07/28/83 C - Copy file | D - Delete file | F - File size | J - Jump 22 files L - Log-in | M - Mass copy | P - Print text | R - Rename file S - Stat drive | T - Tag file | U - Untag file | V - View text file W - Write punch | X - Exit to CP/M | advances cursor -- B backs up !"%=ƀo&:\w*% 46 #"%\ Copy exists, erase? (Y/N): ͼY :_<  ++ Destination Directory Full ++)!D 44:v> ̜ͫ ---> Copying file . 2:_!"*"*(ʢ =  ++ SOURCE READ ERROR ++)*~ #§ *"*#"*eh >2:'_*"*|3 +"*"5.mIxB@ @..Y[]{}AEIOU.:+-JP dccdxdBjKjPjVj0j1j2j3j4j5j6j7j8j9jk5~2y;#^#V## 2;~2y;+~2};##{l"z;R|";"z;O:Z;!<=O G q#s#r#ww#Gw!o;~#m #~ͪ*C6|/!N >2D6êo ͪ*C6|/ͧ ê*E;!9"E;Ê:B6C M ";ͧ 2 :C; x~>2 x:;*;";";ͼ*;͎. o ;2 "; ͧ !;w[wÎR R *@;W{k z!!4ʮ zy > W_ !Q;zV#>2@;{ ȯ2@;͌ x~ #à !9"G;! ]% >*G;:B6 "C:B6%C LH7 SRI UJ BPPL5X  F#~# :gG3h*> DM!91m>0{3 z3444E02;d!!:@O 7 o4!D~͖#{͎Ɛ'@'_{x :H4:C:I12A v ʳ*O>y0?  ؀GO xGy#~#ͅ~ ͖# CCS DISK FORMATTER PROGRAM V2.0 WHICH DRIVE (A-D)? IS IT A MINI (Y/N)? SINGLE OR DOUBLE DENSITY (S/D)? SECTOR SIZE (0-3)? TRACK NUMBER (0-4C OR *)? IS THE DISKETTE MOUNTED (Y/N)? SINGLE OR DOUBLE SIDED (0 OR 1)? B5   ++ COPY DISK FULL ++2v):V g>!o r$s%# *O! ~W$^":_**e[ ---> Copy CRC verified :w/2vÚ  ++ Error on CRC compare ++~͜#~€E> ͜> _> ͜> ͜´a{_!{Fxʼ#~w6 #  ʼ59k  e>@ddvgggggBDDF-hCenk<Ie uh fie  Bj Kj 0!j 1"j 2#j 3$j 4%j 5&j 6'j 7(j 8)j 9*j     2 0.         i)       "$6& (I*,.08:H4       +(C))00n  !AB IB  IB5pQ MT] MBc HMi FMo CWu PC PO} PA CP PN OP HE FO !Z;>-w n!v;>< ![;-9 !_;T !g;T !c;T !k;T c >< !r;-\ !t;-Ғ \ -> V>2A;ͧ%ڼ ͑"K;uâ *; *;>oGw#%  % w#- 6> ͧ% !> ONOF͗%]% 4}ͧ% g%MCg ͆| !4sx:Ê͌>2B;!Q;~6͌ڥ:4!B;6>[:4!_; !;͵*;!|;͵!y;õ*<;*K;zĎ>2C;>*M;_:Z;<=*w;͎:45KAD TRACK OR SECTOR SIZE/DENSITY SELECTION: NUMBER OF TRACKS (23, 28, OR 46)?  ! |0MMPN 2N N 6N# #NNNNNN NSEEKINIT < ERROR: DRIVE ; SIDE ; TRACK ; SECTOR ; STATUS- ;,!Ù!;qz8O! !;,z;qyO! ͣͣW_͕qyO! ͣ͒qy5   [! #7*,:;<=>?*%( ~#46#A2 :__ z{|g}ok ځ |w{0͜ ecee<2\@2a##~2#~2##^#V" }0:\=_.!~w+ *E*#$W+}5zi`:E)=@wk bytes free on drive : ??????????? ~͜#~€E> ͜> _> ͜> ͜´a{_!{Fxʼ#~w6 #  ʼ5   -_*_777{7w nw?VWx2z7W:Goocc56    /RCDTTVV2CCTTBT2STTICBTTTTVUUUVUUVVSSVUfVVTVVTUVVgVVUTVTVUTTTTTTSTTRRTRfTTTTSSSTTfTTTTVTVU   6NIQYdXfjly%27?QXivYN @@@@ on () off () INTERNAL ERRORFATAL NAME OF  TO FILEMERGE-5 ͆|*w;͋!g; )!y;͵3!|;͵> :7*;#~+:A;͑:o;G!t;z*K;|f} > :Ͷ42o;u"I;!Y; :+ <*I;"I;!R;~ :# <›Ì:i> :> ;#~+͑:o;G~4#~i\#~i.# *K;Ͷ .:K;#~i  +:!o:2;}X>:2;:o;c >!o;w:2;~q>n>[c o>^#~4> [Á*M;:3;ʠR|:Z;e͎:Q;Ì:3;N#{ ʘ> :> [> :+|#>Ø!".g|,-5 5,0 ;SAVE SP TOO DAD SP SHLD STKINP ;09C7H PUSH D ;OLD HL MVI A,':' ;3AH CALL GETLN ;0814H AND GET A LINE IP33: ;05A9 LXI D,BUFFER ;0F37H POINTS TO BUFFER RST 3 ;EVALUATE INPUT NOP ;CAN BE 'CALL ENDCHK' NOP NOP POP D ;OK, GET OLD HL XCHG MOV M,E ;SAVE VALUEIN VAR. INX H MOV M,D POP H ;GET OLD 'CURRNT' SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER IP4: ;05BA POP PSW ;PURGE JUNK IN STACK RST 1 ;IS NEXT CH. ',' DB ',' DB 3 JMP IP1 ;0572H YES, MORE ITEMS IP55 -,ó -  COPYRIGHT (C) 1981 MicroPro International Corporation  MicroPro WordStar release 3.00 serial # WD5846S5  Televideo 912/920 terminal  Backspacing TTY-like printer  No communications protocol  CP/!M List Output driver (LST:)  ">$2P P=  )(qwC,# @ 5)Print a file РԠ Š *** FATAL ERR F25: NOT ENUF MEMORY $ File  not found. Menus &  messages will display as @@@@ only.  WAIT  PRINT\PAUSED merge-printing\ \editing\no\file\ d ׽ *** Press ESCAPE Key *** INTERRUPTED***  E*** I***   F: mG! e~x7*`;:Z;e*h;*\;R| !͎ "w;!"~;";#"|;51m> >0G@G42H12I! {!Dͥ_2A**2@!ͥ0BB2!mͥ_DhU<2A!{k2Bx!ͥ0}}2C!Xͥ_2GYµ!.{ڠ2Kx:G Y!Q 0N>M2K:A=x@2gGhy2=^#V#">^#V:C<#=~<w:Kw:B<,=,3:=12%>2L#m>20#:%:L:0:C:CO:?G~ x™:G:Lʺ>>4:B<*:=X:%<,2C2B<2A:Gõ!{U0402;!V66: ;05C1 RST 6 DEFLT: ;05C2 LDAX D ;+++DEFLT+++ CPI 0DH ;(CR) EMPTY LINE IS OK JZ LT1 ;05D1H ELSE IT IS 'LET' LET: ;05C8 CALL SETVAL ;07BAH +++LET+++ RST 1 ;SET VALUE TO VAR. DB ',',3 JMP LET ;05C8H ITEM BY ITEM LT1: ;05D1 RST 6 ;UNTIL FINISH ; ; ;+++EXPR+++ ; ;'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS ;= ; ;WHERE IS ONE OF THE OPERATORS IN TABS AND THE ;RESULT OF THESE OPERATIONS IS 1 IF TRUE AND 0 I6:4[}> [G!P;~6!4x!r;^Gz4x!0GO!P> W>~a>- S }!O;~<> STk ‹!"O;F F*Z;&*M;"M;*\;͎*M;|͑!"M;*K;#"K;2Q;u*Z;>*v;> :4*M;|:3;*\;‹͑> [*M;|ñ TW͔ J.S!O;~-5R;!G̞#~^T@!O;4!͌ڈ:4<:4/!4!D;6> ̜͜:C;7*K;*:;Î'ͪÜNħ >2D6ç ['ͧ ͪ¾Ņ ͪħ :4ͪ<:46687<>|&*7"787ͼ):7_71*`5!~! 8~!:7!7~6_7''<>|&Ð!eɷ v&do>!#{ |<ʎs#rɯ7Ê>G!"{}O)|! !!~6w<x7z! q#~w['^#V#o 6 *7~G:7w26 "7:[5>!:!*`5#!6~\!5*7~w27*`5ͫ":6o&{!͔!*`5͎ī"ͪ*6:6o*`5}ͧ!o!6:!<=:!g=!÷!÷!:c5~<=#~ͳ !!0:H=!:I"=O3#:c5T"~ &"# "ye +~ ," ~!!m~Į!S"A> ͳ J" 6 # Z"!!!~x"!ͮ!ͥ" *`5"~"!ͮ!ͧ*H-&"`53#!"7:[5{" ":Ͷ!:d#*^\:]"!J#!S#!X6F FALSE. ;::=(+ OR -)(+ OR -)(....) ;WHERE <> ARE OPTIONAL AND (....) ARE OPIONAL REPEATS ;::=(< OR />)(....) ;::= ; ;() ; IS RECURSIVE SO THAT VARIABLE '@' CAN HAVE AN ;AS INDEX, FUNCTIONS CAN HAVE AN AS ARGUMENTS, AND ; CAN BE AN IN PARENTHESES. ; ; EXPR CALL EXPR2 THIS IS AT LOC. 18 ; PUSH HL ; ; EXPR1: ;05D2 LXI H,TAB8-1 ;02BEH LOOK UP REL. OP. JMP EX0 ;06>'Ng:;;!"B6"D6<=G:E67J*;~7Jp#~d_x2::;*:*:::g" ;yHG*:::g":::o&{2:y: ;ey_! ;*6;R:: ‚> ڲ!e::~œ=<<*6;-ʰҮ<>d lx_gQy2;:; !;4!;4x*;::e";͵";!6/s^#V+ѷs~o #:7277>27!74!77!_8ͪͪ*7*͎l!7"J6:77͎?9͎({%}):7=!9=z27!97o >e!9e:͎ç!` .:7*7+##+6!.}1~6/ % ~6 %!!< nU6#~!͜>ͳ 1*5~*5~w#~<!5"5:c5/!6z!!:`G{ʳ  i#d*7*7[*7Ro&U\*7:IOD# C#*+a#}!+y)>26*`5"6 ]$ ]$]$2'!t#ʜ#ʜ#«#*6!ͫ"o#!####U$## #*`5%~!_! #$$#!#$$- $!#45 $>!w)#ʣ)#ʪ)!oy^>Iy <26+q#$:Y5:H$<26262626$_!>ä$o$â$%_!>!`5ͧ!01:6!6$~:`5!6!"6"6262626 2D8H GO DO IT XP11: ;05D8 CALL XP18 ;0601H REL. OP. ">=" RC ;NO, RETURN HL=0 MOV L,A ;YES,RETURN HL=1 RET XP12: ;05DE REL OF "#" CALL XP18 ;0601H RZ ;FALSE, RETURN HL=0 MOV L,A ;TRUE, RETURN HL=1 RET XP13: ;05E4 CALL XP18 ;0601H REL OP. ">" RZ ;FALSE RC ;ALSO FALSE HL=0 MOV L,A ;TRUE HL=1 RET XP14: ;05EB CALL XP18 ;0601H REL. OP. "<=" MOV L,A ;SET HL=1 RZ ;REL. TRUE, RETURN RC MOV L,H ;ELSE SET HL=0 RET XP15: ;05F3 CALL XP18 ;0601H REL. OP. "=" 6 ;4::#4!;4x!::*;e";!;x *;*#;"#;*;*;͵";!";";";!;~6py_!";";͵";!;4~!!;4!;~::5*;"#;:;!;2;*;";*;|:#;*;)::G$%==xxy2&;>2'; :6;=|g}o|*#;&*6;**;R"*;";:ī͗ͻ͗͢Cs\ͫ -\ͫs\͢s\*;"0;:;UͫcͲ*;".;*;)*!;T]:: ڈ:ʐ*;Î*#;&*;*$;,;ͻͻ*!;(;*;&;*;R|";:6;w#~w+͎  ~# 6 :ͳ *7+wF*|#6!26:?ͺÊ>X:VͽÊ>!*ey!5w+~#wz.!5"5"5P. G:a5Oxͱ:I x  yON#F ܔ ͱp+q ͔!o *7:IO&:H=! D3#:c5N%# H +9 .`ͫ" ? !!!!a5 È*`5>+,&í":`5 *`5-í">o͜:+A ]!6 626r!$261$r!:1%:1%:1%:1%:GOͪO%:C6I% y̔ x4%ê!%2S%%_:S%W~ʑ%#ʂ%###r%~|%#^#VÓ%g% ʗ% ʗ%!͗%%%0% %T])))_%%%0% ڽ%|7%%x 7 7 77?}81U8W8Y8[8]8_8a8c8q8}8e8g8i8k8m8}8}8}8{8}8s8}8u8w8y8}88}88888888}888}8}8}8888}8}8!Ø&?'ͥ"K'oG-!?'?1͉-:626o!$K'>c31̓͹$26:626!&26%×-!6~66  RNZ ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP16: ;05F9 CALL XP18 ;0601H REL. OP. "<" RNC ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP17: ;05FF POP H ;NOT REL. OP. RET ;RETURN HL= XP18: ;0601 MOV A,C ;SUBROUTINE FOR ALL POP H ;REL. OP.'S POP B ;REVERSE TOP OF STACK PUSH H PUSH B MOV C,A CALL EXPR2 ;0616H GET 2ND XCHG ;VALUE OF DE NOW XTHL ;1ST IN HL CALL CKHLDE ;07B2H COMPARE FIRST WITH 2ND POP D ;RESTORE TEXT POINTER 6N͎O>G  %+~ !!x 6#.$%%$o>gAARDMxɅo|gg}o|g^#V#~#fo# ‚Gz—{xɾ~~/w~ͼ#ä   :.,;?!0?:ɷ @[A?a{['N#w@w#6:#6+Y T6.#Z6 dw# Ys0 {{:|sͥ_:§ {2b5_ͥ=!¼sü):OͥGHGxy"6~͙܀ > :a5   >^@ :c5 ̎ !45 ͳ !a5 P H 4*7w#!6*7B +4:H=q :I*7e"7*7eB 5*7 *I&*7[gg> -¤ !!O: y#*`50> XO !X5 ws"g":[5!77U*5~̓!66:7!'!!à&͏G!6~6̀1ͪ:6'o&)&^#Vo&Di:7/!F6ˆ'5:6͎ *`5! ~!~! Î *6|!F6£'o 02F6*7"6':D6ʽ'(:7':C6'V(:B6'((!5((ć`:IO>(!:6*6^(*6^(:6c(>>(:626*7"6'O'G:IPx=(V(*7*6R@(> c(}c(| s(>^c(@!d5\‚(> Ç( ʈ(#*7++*6w͎ڞ(#"6:D6¼(:)ʹ(:f5!6V(0(^#V#(~#c((:&!+!7(26.)!6N61q!6F7~!"%/=r!8Í'>260\/ ͑!~!:7Z/!/v~Z/.%Z/6`]͑! ~!)(:7v/1=!60:7]͍'o :6!6͚o:7š/:6o:6/!6ڱ/!6ڽ/o&͔!o !<Ý/Q):6!606}:7G:Y5O*J6|!6/6:6!6ᠡ/6o ‡0($:D6!8:G6!8:610268I0x/I0͖0F0͜!"6o͢$:626:6f0!6~6!8*J6|!"J6͢$:626‡0>26!G6~6ȯ26:IPڣ0!7:E4 ~"8126×-:7O!60w:70:6=0w~=!6)!61)7Ea7T WAS IN A (GIVEN BY THE ;CALLER). OLD A IS STORED IT B, OLD B IS LOST. ; ;'OTSTG' LOOKS FOR A BACK-ARROW. SINGLE QUOTE, OR DOUBLE ;QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACK-ARROW, ;OUTPUT A CR WITHOUT A LF. IF SINGLE OR DOUBLE QUOTE, PRINT ;THE STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE. ;AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED ;OVER (USUALLY A JUMP INSTRUCTION). ; ;'PRTNUM' PRINTS THE NUMBER IN HL. LEADING BLANKS ARE ADDED ;IF NEEDED TO PAD THE 7wO1):6.):&><)26!6.)2626/262654>G1:k5!H4O)~o :7a:61Êͼ):+/y)>!+Fw>2626ó))26 :6Ÿ)26:6<ð):6=26!"626ó)g:7O/ G:+:6)o#}!6Ěx:+ʉ)o *:6=1Ê)!6͚G:6 *!6):6̐):6W:6)_:6!6<*:6´* + @+:6/<_y!6q*U*qy!6ڣ*<26͟,z<26o !6:7ʣ*:6ң*z26ñ*z±*!6U*26*7"6:6O:6G/!((ͥ*6+"6gx/+!(y+*>͡(:I>(:67 1 ` 1`:7133:6!6͚!6͚!6͚*7"7"7>26: /!6ɯ2L62r6~#26~26#"6Ñ1}26|26"6Ñ1~#26~#26"6:6=>$ԕ&ͽ11i`)2^#V*6 *6)))2N!6 :66i`)2^#V#^#V#͇2~#fo)DM!"q#p#N#F2 ~>)v& 2x2x2 2~>'v&#:6>,v&6 >*v&w!6Y2>+v&# N2^#V>(v&!6:6w>&v&͓2!$~v&><Cpy-M67-M6M6 M6M63M6M6#M6M6mM6t77 COPYRIGHT(C) 1980 MICROPRO INTERNATIONAL, SAN RAFAEL, CALIFORNIA, USA. ALL RIGHTS RESERVED. WordStar 3.00 Message Texts "Rm )L hge!!"#$2.()<)&''n)*%+-../////>0l00001,/W00RmRmA$Rms"w$%"&23C33=3344444445Rm425555.6N6Rm$";QJN'igW]VURm1QRm8-Z6-C.+0Rm...6Rm6P666Rm67Rmg7q7777'8m8Q9l99Rm99Rm:1:\::::::::;2Rm;5;Rmb;Rm;$Rm7 Wß,!6452626*7"6:6=+2626͒ͅ,+:626Ħ,Ê:IO *76 #=M+#m+ x GV+:6G*6+F+N <ʙ+"6gʹ++F+N 26Êʹ++++DM>26>.!m,### ʡ+#~¸+  +m,ʴ+26*7"6*76+r+s ͎,:6,,+~w͊,+*6 !i, ~d,#-, :,~Z,\,6.#w#w#> *6<BAINuHEvREwCOxOVy$$z26͌"6g>26j*7ó,#p+qg+F+N <,#Vp+^qBK,+V+^ oʬ,,, ,,,!91C47 M6M6{s6M6'M6-M6dM6!M6gM6|M6  w3Ô3>e A:)2323:>!+}ˆ3::> AU857  >V<<2E4!9"C4ͨ<=:l2J:] @:4-:5-*C4͢=!~!!S!Ϳ7 _ & < < < N O - F I L E M E N U > > >  D Open Document File | Y DELETE a file | H Set HELP LEVEL  N Open Non-document File | E RENAME a file | L Change Drive  X EXIT to System @ | O COPY a file | R Run a program  F Directory + | P    -  M Run MailMerge  S Run SpellStar  & < < < N O - F I L E M E N U > > >   7n55(???!ͱ6!Sͱ6ͩ6You are trying to run an uninstalled WORDSTAR.Please run INSTALL first.-ͩ6 ʹ6͢6~̢6 #ô67Y!%=#%=#%=#%=:`2Y5:c2+ͥ2b5~f!B6.:2c5K=~"=:b5é*͂="7:Il++"7"7="7+"7:Il++"7"7"7*:c5£=*HL&bj –=R+#"7"7*H-3#"7"7Q"7R"7:c5*HͿ-=|!]=>o&))))>=goR>.>O->26:H26=26=26S>:7*7>|& 7!!Y5~P>(P>6!"J6O-:H|>y|>6u>:I@|>|>~!8"J6>|&w- A4:c5:ª>®>:ʰ>>2d52e5>:2[5ͤ!ͮ!~"!N6 ! t6!q66.!66/:26ɛ884h󭭭 | 堠 |  L Changed logged disk drive | a| R Run a program  F File directory + | P  | X EXIT to system  H Set help level  | |  孭 | E RENAME a file |  D Open a document file | O COPY a file | M Run MailMerge  N Open a non-document file | Y DELETE a file | S Run SpellStar  8g7o marker  SCROLL: Z=continuous up W=continuous down  DELETE TO END LINE: DEL = left Y = right r FIND, REPLACE: F=Find a string A=find And substitute  REPEAT NEXT COMMAND: Q=repeat until key pressed  '< < < Q U I C K M E N U > > >  | | |  S left side D right side |Y line rt|F Find text in file | (from Main only)  E top8Jin File  V=subscript T=superscript Y=ribbon color change  S=underScore B=Boldface D=Double strike  A=alternate pitch N=standard pitch X=strikeout begin/end  O=non-break space F=phantom space G=phantom rubout  C=pause H=overprinUt char RETURN=overprint line  Q,W,E,R=user printer controls SPACE=cancel prefix  '< < < P R I N T M E N U > > > J 젠󠭭 | 砠 | 8  | |  H Display & set help level |S Status line | (from Main only)  B Paragraph reform (CTRL B)|R Ruler line |^J Help ^K Block  F Flags in rightmost column|M Margin & Tab |^Q Quick ^P Print  D Dot commands, print ctrls|P Place markers|^O Onscreen  $|V Moving text |Space Bar returns  |  |you to Main Menu.  (< < < H E L P M E N U > > >   8 For maximum help (full menu display),  select Help Level 3 by typing ^JH3.  This message will clear when a key is pressed.  TO HYPHENATE, PRESS -. Before pressing -, you may  move cursor: ^S=cursor left, ^D=cursor right.  If *hyphenation not desired, type ^B.  (< < < M A I N M E N U > > >   | | |  ^S char left ^D char right |^G char | ^I Tab ^B Re8Hb scrn X bottom scrn |DEL lin lf|A Find & Replace |^J Help ^K Block  R top file C end file C |L Find Misspelling |^Q Quick ^P Print  B top block K end block E|Q Repeat command or |^O Onscreen  0-9 marker Z up W down | key until space |Space Bar returns  P previous V last Find or Block | bar or other key |you to Main Menu.  ^K PREFIX (to cancel prefix, press SPACE bar) 9 END EDIT/SAVE: D=Done X=done,eXit S=Save,reedit Q=a8]  (begin and end) | (one time each) | A Alternate pitch | (from Main only)  B Bold D Double | H Overprint char | N Standard pitch |^J Help ^K Block  S Underscore | O Non-break space | C Printing pause |^Q Quick ^P Print  X Strikeout | F Phantom space | Y Other ribbon color|^O Onscreen  V Subscript | G Phantom rubout | 󭭠 |Space Bar returns  T Superscript | RET Overprint line | Q(1) W(2) E(3) R(4) |you to Main Menu. ^O PREFIX: on-screen f8  | |  H Display & set the help level | S Status line | (from Main only)  B Paragraph reform (CONTROL-B) | R Ruler line | ^J Help ^K Block  F Flags in right-most column | M Margins & Tabs | ^Q Quick ^P Print D D Dot commands, print controls | P Place markers | ^O Onscreen  +| V Moving text | Space Bar returns  |  8 form | (from Main only)  ^A word left ^F word right |DEL chr lf| ^V INSERT ON/OFF |^J Help ^K Block  ^E line up ^X line down |^T word rt|^L Find/Replce again|^Q Quick ^P Print  筭 |^Y line |RETURN End paragraph|^O Onscre'en  ^Z line up ^W line down | | ^N Insert a RETURN |  ^C screen up ^R screen down| | ^U Stop a command | 7 CURSOR: ^A=left word ^S=left char ^D=right char   ^F=right word ^E8 Xbandon  MARK BLOCK: B=Block start K=blocK end H=Hide/display  BLOCK OPERATIONS: V=moVe block C=Copy block Y=delete block  ADDITIONAL FILES R=Read file W=Write block J=delete file  & PRINTING: O=cOpy file E=rEname P=  DISK & DIiRECTORY: L=Log disk F=File directory + MISC: 0-9 = set/hide place markers N=columN move * (< < < B L O C K M E N U > > >  J  砠 | | 堠 | 8 ormatting commands  S=line Spacing C=Center cursor line F=margins/tabs from line  L=Left margin X=margin release E=soft Entry #  R=Right margin W=Word wrap   D=, ctrl dspy%  I=set tab stop J=Justify ! P=Page display (  N=clear tab V=Var tabs " TH=ruler display&  G=para tab H=Hyphn-Help$ SPACE=cancel prefix  ( < < < O N S C R E E N M E N U > > > M  󠦠 | 堠 | 󭭠 | 8  | you to Main Menu. 1 ^S=delete character ^Y=delete entry ^F=File directory  ^D=restore character ^R=Restore entry ^U=cancel command  TYPE ^KP TO CONTINUE PRINT  TO RETURN CURSOR TO POSITION BEFORE SAVE,  TYPE ^QP BEFORE TYPING ANYTHING ELSE.  TYPE 1-9 TO VARY SPEED, SPACE TO STOP *** WARNING:  WRONG VERSION OF WSMSGS.OVR --  SOME MESSAGES MAY BE INCORRECT. *** *** WAR8 =up line ^X=down line  SCROLL: ^Z=up line ^W=down ^C=up screen ^R=down  DELETE: DEL=char left ^G=right ^T=word ^Y=line  OTHER: ^V=insert off/on ^I=tab RETURN=end para ^U=stop  ^N=insert a RETURN ^B=reform ^L=find/reCplace again  PREFIX KEYS ^Q ^J ^K ^O ^P display additional menus 7  ^Q PREFIX (to cancel prefix, press SPACE bar) A CURSOR: S=left Side E=top X=bottom D=right enD line  ,R=beginning file C=end file 0-9,B,K,V,P=t8'  S Save & resume | B Begin K End | R Read P Print | (from Main only)  D Save--done | H Hide / Display | O Copy E Rename | ^J Help ^K Block  X Save & exit | C Copy Y Delete| J Delete | ^Q Quick ^P Print  Q Abandon file | V Move W Write | 렠 | ^O Onscreen  | N Column *|L Change logged disk| Space Bar returns  0-9 set/hide 0-9| H|F Directory+| you to Main Menu. ^P PREFIX: Put Control Character 8a  L Set left margin |C Center text |J Justify !| (from Main only)  R Set right margin|S Set line spacing |V Vari-Tabs"|^J Help ^K Block  X Release margins | |H Hyph-help$|^Q Quick ^P Print  I Set N Clear tab| 󭭭 |E Soft hyph#|^O Onscreen  G Paragraph tab |W Wrd wrap |D Prnt disp%|Space Bar returns  F Ruler from line |T Rlr line&|P Pge break(|you to Main Menu.  (< < < H E L P M E N U > > >     99NING  SCREENS OVER 48 LINES HIGH OR 120 COLUMNS WIDE  HAVE NOT BEEN TESTED AND DEBUGGED. PROCEED WITH  CAUTION; REDUCE WIDTH IF BUGS ENCOUNTERED. *** WARNING: DISK FULL,  DELETING OLD .BAK FILE TO MAKE SPACE  (NORMALLY, THE PREVIOUS BACKUP FILE IS DELETED  ONLY AFTER EDIT IS SUCCESSFULLY COMPLETED).  CAN'T DISPLAY PAGE BREAKS IN A NON-DOCUMENT FILE *** WARNING: WORD TOO LONG TO FIT MARGINS  PUT AT FILE BEGINNING FOR CORRECT PAGE BREAK DISPLAY  Normally press RETURN only, o9tion of an existing document file.  A file name is 1-8 letters/digits, a period,  and an optional 0-3 character type.  File name may be preceded by disk drive letter A-D  and colon, otherwise current logged disk is used.  WARNING: You are editing the same file as you are printing.  WordStar will not allow you to save the edited version  until the print has completed or has been abandoned.  ALLOW PRINT TO FINISH BEFORE EDITING A FILE.  YOUR SYSTEM DOES NOT HAVE ENOUGH MEMOR9ETBLOCK BEGINNING NOT MARKED  (OR MARKER IS UNDISPLAYED)BLOCK END NOT MARKED  (OR MARKER IS UNDISPLAYED)BLOCK END MARKER BEFORE BEGINNING MARKERBLOCK TOO LONG -  MOVE OR DELETE IN TWO SMALLER BLOCKSCURSOR NOT IN RANGE FOR COLUMN MOVE/COPYCOLUMN READ / WRITE NOT ALLOWED THAT FILE EXISTS ON DESTINATION DISK.  DELETE EXISTING FILE FIRST,  OR USE A DIFFERENT DISKETTE.DISK FULLINVALID COPY LENGTHADDRESS IN "HOLE" (TSTADR)MEMORY FULL (MAK256)MEMORY S9M file then press RETURN: *** No .DF before .RV: *** WARNING: Overlong data value truncated *** Invalid variable name in .RV command ignored *** WARNING: Data exhausted, null value(s) used  ***** Print Directives *****  PRINT CONTROL CHARACTERS may be entered anywhere in a line  to invoke underlining, boldface, subscripts, pauses, etc.  They are entered by typing ^P and a letter. A directory  of most print cont*rols is given on the ^P PREFIX MENU;  9r enter one or more of:  number=repeat count, B=search Backwards, W=whole Words only, U=ignore case, N=replace w/o asking, G=replace in entire file. To search for misspelled words, enter one of the following - RETURN=search forward, B=searc2h backward, G=from start of file:  F - Fix word D - Add to dictionary N  B - Bypass word S - Add to supplemental dictionary I - Ignore word .  HELP LEVELS  3 all menus 9Y TO  PERMIT SIMULTANEOUS EDITING AND PRINTING.  CAN'T EDIT A FILE WHILE MERGE-PRINTING --  FINISH OR ABANDON MERGE-PRINT BEFORE EDITING  FINISHING PRINT BEFORE EXIT  (type ^U to cancel exit command) ... FINISHING PRINT OF SAME FILE BEFORE SAVING  (Type ^U to cancel Save command) ...  FINISHING PRINT OF .BAK FILE BEFORE SAVING  (Type ^U to cancel Save command) ...  ABANDONING UNCHANGED  ABANDON EDITED VERSION OF INVALID  NAME:    NOT FOUND 9HORTAGE (MKSP)POINTER > 64K FROM CURSOR (PPTOAD)NOT ENOUGH MEMORY  OR YOUR OPERATING SYSTEM IS NOT  RELOCATED TO MAKE ALL RAM AVAILABLE DISKETTE DIRECTORY FULL CLOSE FAILURE -  SYSTEM FAILURE, OR YOU CHANGED DISKETTES RENAME FAILURE -  SYSTEM FAILURE, OR YOU CHANGED DISKETTES INVALID SCREEN HEIGHT OR WIDTH  MESSAGE  Can't edit a file of type .BAK or .$$$  -- rEname or cOpy before editing BAD OVLY #BAD OVERLAY FILE, OR  WRONG VERSION OVERLAY FILE Overlay file  Not Fou9| see manual for more.  DOT COMMANDS are special lines beginning with a period and  a two-letter code. They control page breaks, headings,  page numbering, page layout, etc. Dot commands are  typed in like other text.  Space bar for DOT COMMAND SUMMARY, ^U to return to editing:  ***** Dot Commands *****  PUT EACH DOT COMMAND ON SEPARATE LINE, WITH . IN COL 1  .PA new PAge  .CP n new page if less than n lines left on this pa9 and explanations displayed  2 main editing menu (1-control-char commands) suppressed  1 prefix menus (2-character commands) also suppressed  0 command explanations (including this) also suppressed  CURRENT HELP LEVEL IS  ENTER Space OR NEW HELP LEVEL (0, 1, 2, OR 3):  The LOGGED DISK (or Current Disk or Default Disk) is the  disk drive used for files except those files for which  you enter a disk drive name as part of the file name.  WordStar displays the File Dire9 M Now printing file  "Y" TO ABANDON PRINT, "N" TO RESUME, ^U TO HOLD: PRINT?  For default press RETURN for each question: START AT PAGE NUMBER (RETURN for beginning)?  STOP AFTER PAGE NUMBER (RETURN for end)?  NUMBER OF COPIES (RETURN for 1)?  DISK  OUTPUT (Y/N):  OUTPUT  NAME?  USE FORM FEEDS (Y/N):  SUPPRESS PAGE FORMATTING (Y/N):  PAUSE FOR PAPER CHANGE BETWEEN PAGES (Y/N):  Ready printer, press RETURN: WARNI9  nd FILE  NOT FOUND  (The seperately sold file   is required for use of chosen function.) NOT FOUNDPROGRAM IS AN EMPTY FILE!?PROGRAM TOO BIG FOR  MEMORY AVAILABLE UNDER WordStar LET PRINT COMPLETE BEFORE RUNNING A PROGRAM  NOT ENOUGH MEMORY TO USE "RUN PROGRAM" COMMAND  File  Not Found --  Can't Run a program unless  is available.  For spelling check, enter name of file to be checked.  (^R for last file edited) $  For dictionary maintenance, ente9 ge  .OP Omit Page numbers when printing, starting this page  .PN print Page Numbers, starting this page (default)  .PN n set Page Number to n, print page numbers  .PC n Page number Column (default 33 (30 if 64-col screen))  .PO n Page Offset: extra indent when printed (default 8)  .. text comment, not printed  press space bar for next frame:  .HE text HEading used until next .HE (default blank)  .FO text FOooting (replaces page number) (blank)9 _ctory of the Logged Disk.  THE LOGGED DISK DRIVE IS NOW  NEW LOGGED DISK DRIVE (letter, colon, RETURN)?  Use this command to create and alter program source files  and other non-documents. Word wrap defaults off;  tabbing defaults to fixed (TAB chars in file; 8-col stops);  page breaks not shown; hi bit flags not used in file.  For normal word processing uses, use the "D" command instead.  Use this command to create a new document file,  or to initiate altera9NG: You are printing the same file as you are editing.  The last saved version will be printed, not reflecting un-  saved changes. Furthermore, WordStar will not allow you to  save the file being edited while the print is in progress.  END EDIT (^KD) BEFORE STARTING PRINT.  YOUR SYSTEM DOES NOT HAVE ENOUGH MEMORY TO  PERMIT SIMULTANEOUS EDITING AND PRINTING.  TOO LITTLE MEMORY FOR MERGE-PRINT  *** PRINT OUTPUT DISK IS FULL. PRINT PAUSED. *** THAT PLACE MARKER NOT S9r name of file  containing words to add to or delete from dictionary.  FILE  ALREADY EXISTS  FILE  NOT ON SAME DRIVE  TOO LITTLE MEMORY TO COPY WHILE  EDITING OR MERGE-PRINTING  FILE  EXISTS -- OVERWRITE? (Y/N): FILE  IN USE BY WordStar   P=   Press space bar after reading screen: *** Invalid Dot Command Ignored: *** File Not Found *** But found, and will use, *** Cannot change disk in drive , request ignored Insert diskette with::  .PL n Paper Length: total number of lines (default 66)  .MT n Margin at Top: # lines, top paper to text (3)  .MB n Margin at Bottom: # lines, end text to end paper (8)  # lines text on page is PL - MT - MB (defaults to 55)  .HM n Heading Margin: blank lines between head and text (2)  .FM n Footing Margin: blank lines, text to footing (2)  FOR PAGE BREAKS TO DISPLAY AS THEY WILL PRINT, USE  .PL,.MT,.MB, AND .LH (next frame) AT FILE BEGINNING ONLY.  Depress space b:4lue. variable names are letter then 0-39 letters, digits, -'s. .FI filename Insert document File  .DM message Display Message  See manual for details and additional commands. Merge-Print  is an optional feature, operational only if MAILMRGE.OVR is  on your diskette. Press any key to return to editing:  ***** STATUS LINE (top line of screen) *****  ^JS at left end of line is command now executing  A:NAME.TYP is name of file you are now editing  P: after end of document press space bar:  COMMANDS TO -- ARE --  move cursor on main and ^Q menus  scroll file up or down on main menu; also find (^QF)  delete text on main and ^Q menus; also ^KY  move or copy text on ^K menu  end edit / save file ^KD; see ^K menu  print (while editing) ^KP  set tabs and margins on ^O menu  reformat text ^B; ^JB gives info  find a string; replace ^QF; ^QA; ^L repeats last :sired justification (^OJ) & line spacing  (^OS), place cursor at paragraph beginning, and type ^B.  To obtain WordStar's help in hyphenating long words, place  cursor at beginning of paragraph and type ^B.  press space bar for more:  ^B reforms lines to end of paragraph as indicated by "hard"  carriage return (< in rightmost column).  Thus, it is important not to use RETURN between lines  within a paragraph when entering text.  ^B may be used to form h:har for next frame:  THE FOLLOWING WORK ONLY WITH INCREMENTAL PRINTERS:  .LH n Line Height in 48ths of an inch (default 8)  .CW n Character Width in 120ths of an inch, for standard or  alternate pitch, whichever is in use (see ^P menu).  (default 12 for standard, 10 for alternate)  .SR n Subscript / Superscript Roll in 48ths of an inch (3)  .UJ OFF/ON "MicroJustification" off/on (default ON)  Use insure that printed column alignment exactly  matches screen:GAGE n is page number of cursor (disregards .PN's)  LINE n is printout line on page of cursor position  COL n is printout column on line of cursor position  INSERT ON shows if character insertion is on (^V command)  MAR REL shows if margins are released (^OX command)  decimal shows during decimal tabbing  LINE SPACING n shows if line spacing is not 1 (^OS command)  PRINT PAUSE shows if printer is stopped (^KP to resume)  when WAIT appears, st:  press space bar for "entering text":  ***** ENTERING TEXT *****  To enter text at cursor position, just type the text.  Use RETURN key for paragraph end or other fixed line break;  let word wrap form lines within paragraph.  Type ^V to turn insertion off (to overtype) or back on.  ^N may be used to create blank lines ahead of cursor,  as before inserting a paragraph.  Use ^B to realign margins after corrections.  ^JM shows info o:anging indents, change margins in  mid-paragraph, etc. The exact rule is:  "^B starts on the cursor line, at the left margin col-  umn, or at the cursor position, whichever is farther  left, and proceeds to the next 'hard' carriage return".  press space bar:  ***** Hyphen-Help *****  ^B will occasionally stop before the end of the paragraph  and ask you whether you wish a word hyphenated.  Following the instructions that appear on the screen, mov: , e.g. for tabular material:  Put .UJ OFF before table, put .UJ ON after table.  Space for next frame, ^U to return to editing:  SPECIAL CHARACTERS in HEADINGS (.HE) and FOOTINGS (.FO):  # prints as current page number  \ do not interpret next character as a special character  ^K do not print following spaces if on even-numbered page  PAGE NUMBER POSITIONING: If a footing text is specified (.FO  dot command), the default bottom center page number is not  pr: op typing. Press space bar:  If page break display is OFF (^OP command) or edit  was started with N command, then Status Line shows  FC=nnnn FL=nnnn in place of PAGE n LINE n .   FC=nnnn cursor position in characters (bytes) from  beginning of file  FL=nnnn cursor position in file lines from beginning  of file, including dot command lines   space bar:  ***** FLAG CHARACTERS (rightmost column of screen) *: n margins, tabs, table entry, outline entry. press space bar after reading:  ***** TO MOVE A BLOCK OF TEXT *****  1. Put cursor on first character, type ^KB to mark start.  2. Put cursor after last character, type ^KK to mark end  (for end line, use start next line to include RETURN).  3. Put cursor at destination, type ^KV to move the text,  or ^KC to make a duplicate copy.  To undisplay markers afterwards, use ^KH.  ^KB and ^KK may be entered: e  the cursor if desired to adjust the hyphen position,  then press "-" to hyphenate, or ^B to not hyphenate.  To turn off "hyphen-help", type ^OH.  press space bar:  ***** MARGINS *****  To set left margin: Type ^OL. WordStar will asks for column.  Type desired column number 1-240 and press RETURN.  Or, to use column of cursor in file, just press ESCAPE.  To set right margin: type ^OR, proceed as above.  To set both margins to match text : Binted. Use a # in heading or footing to position page  number where desired. ^K followed by spaces followed by #  may be used to produce alternating left/right page numbers.  Space for next frame, ^U to return to editing:  ***** Merge-Print Dot Commands *****  .DF filename specify Data File for .RV  .RV name,name,name,... Read Variable values from data file  .AV "prompt",name Ask operator for Variable value  &name& anywhere in doc't prints as variable va:****  < line ends in "hard" carriage return, entered by user  space this line break arose from word wrap or paragraph  reform, and may moved on subsequent reform  + this line of document continues on next screen line  - next line will overprint this line  ? unrecognized or incomplete dot command  M Merge-Print (optional feature) dot command  P page break  : this screen line is before beginning of document  . : in either order, with or without  other intervening commands.  All above commands are on ^K menu. press space bar:  ***** PARAGRAPH REFORM (^B) *****  To realign margins of a paragraph after corrections, place  cursor at beginning of paragraph and type ^B.  To change margins of paragraph already entered, set margins  (^OL, ^OR), place cursor at paragraph beginning, type ^B. To change between justified and ragged right, or change line  spacing, set de;;_in a line already entered:  place cursor in that line, type ^OF.  To temporarily set left margin to next tab stop: type ^OG.  Margins apply to text subsequently entered. To remarginate  text already entered: set margins and use ^B.  press space bar after reading:  ***** LINE SPACING AND JUSTIFICATION *****   To set line spacing: type ^OS. WordStar will ask for line  spacing. Enter a digit 1 thru 9.  To turn justification off (; Type text of item, without using RETURN.  At end of item, press RETURN. Left margin resets.  Press RETURN again if blank line desired.  press space bar:  ***** RULER LINE *****   L----!----!----!----!----!----!----!----!---------R   L Left margin (set with ^OL)  R Right margin (set with ^OR)  ! regular tab stop (set with ^OI, clear with ^ON)  # decimal tab stop (set with ^OI, clear with ^ON)  - other positions between margins  ;]I 0FFH JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKRD: ;035E READ THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,14H ;READ SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS CPI 1 ;ERROR CODE? JC NEWFIL ;0381H JNZ QHOW ;0166H ERROR MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP D ;RESTORE REGISTERS POP B POP D POP H RST 6 NEWFIL: ;0381 POP D LXI H,80H DAD D XCHG JMP DSKRD ;035EH SAVE: RST 5 P;BZBZBZB*;#";o*:&K>A~1APYÞ*A*:&:;HAK*:":*:":!*:REAK*:":*:*9<|R":::_jA*:|*9 –B>!,<*:-,=AҵBAÙB!";0 ;for ragged right format),  or to turn justification back on: type ^OJ.  Line spacing and justification settings apply to text  subsequently entered; they may be applied to previously  entered text with the paragraph reform command (^B).  press space bar for "Tab Stops":  ***** TAB STOPS *****   To set a tab: type ^OI. WordStar will ask for column number.  Type column number and press RETURN. Or, to use cursor  column, press the ESC;'  press space bar after reading:  ***** PLACE MARKERS *****   Up to 10 place markers, identified by numbers (n) 0-9,  may be set in a file while the file is being edited.  To set place marker n at the cursor position: type ^Kn.  will display to indicate the marker position.  To return the cursor to place marker n: type ^Qn any  time during the same edit.  To remove the from the display: type ^Kn when the  cursor is already at the; COPYRIGHT (C) 1981, MICROPRO INTERNATIONAL, SAN RAFAEL, CALIFORNIA, USA. ALL RIGHTS RESERVED. WordStar release 3.00 overlay file number 1. overlays for no-file commands and editing  NOSEY, AREN'T YOU?   Bý<>AE>x ʡ</{/ C:<><26;!:: *;<6#";=Ao͍ͩs{é7!4k$%Ñq!p~Žq4w#…qp~#͹$O*+*`5"6?1"6*6~!͔E$a#͟$~^ry:7ĥGrrrrr8y=qͩ$8îqyr̈́r; APE key. To set a decimal tab stop,  type "#" before typing column number or pressing ESCAPE.  To clear a tab stop or all tab stops: type ^ON.  To tab: type ^I, or press TAB key if present. Tabbing  inserts spaces to next tab stop if insertion (^V) is on.  Tabbing advances cursor over text if insertion is off.  press space bar:  ENTERING A COLUMNAR TABLE -- We Suggest:   Set a tab stop for each column of table.  Clear all other tab stop; [ marker position.  press space bar:  ***** OTHER MARKER & RELATED COMMANDS *****   The block beginning marker, ¾, and the block end marker,  ˾, are set and moved to in a similar manner; the  text between these markers can be moved (^KV), copied  (^KC), deleted (^KY), or written to a file (^KW).   ^QP moves cursor to its position before preceding command.   ^QV moves cursor to start of last find/replace, or to  ; YA A A AL>@ !> :=%>:=A6#J= J=~*:::O ~!:ͥ>!":*;ͮ>========!=F6#>=J=~6# Ox͡?ç=":!::!;".2;::?Y>͡2:2:AWo x4>!:~6)>::ͪA2E6W>2:2;:;!:’>*:*:R*:>*:>͎Ғ>2;?T?ͪo:J= > +~<>*;++~:>>>>>ġ?#; qy(r!7r8îq(r8îqy\r̈́r®q\r8͹$2'!Ur#~®q͔$}!+y)8ͩ$8îq!M6r:7ʦr!:r!vr!87r:C6ʾr!;r:4!;r# ͂8þrկ rMss.r#s sͤ71s&s s1ss>  's~2pGOy*77sx!:ͥ>*:ͮ>9?F#>.?J=~ O#x͡?{?> ͡?":";{2:!:::;2;!2>!:ͥ>*:\A*:::_>G{ʛ?H>G>y”?ʕ? O>xF͡?w?*:\A2 ;WG ҙ@ʙ@ʙ@?2;:?:?:?q>2;@@@>@A?::=$@<<=͖B@9@¢2:>3@N@?::)>@!:1A#yHͿ@::x :=*6;>AͿ@î@Q::@:::=@@z@z ::: @::: ! Z<<s`t!͎tt!8"J67:77Z1tt!75t!7#͎+Mẗ́twt2G6pvtLp::2J:v2:Z1$24: 7«p#8rs(%÷p%8xss2'vpp6sp87p2726:+2_5:^5y)[-'Cq:6 q\!<Sv:6v> v&:>(r293r26p(%v!p :50q:+2^5:_5y)͉):C6Ărdr!8"J6:Y5=*J6!a!Z5r5!8"J6;!: ͂7?ɛ4u pcptp:*/Wͳṗp!vjvLzWvLPj!7I*7:*r̳G31!vPjnpͳpnp,p!vj͇p:*ʤp:Gv2Hvnp&q͆rv2'5k:*ƒqCÐpnp!vj!vj&q7p*7*7Rp!U*v͎> v&31AMG2'o ixg"6!7G*<*`5!5 .>2525:59q~!p!5 L#rqo?q(:5Rq:5kk*5"5>r2'!vͨjͤq{q*5|!p!pà&:5q*5|ʎq+"5:5[qg:5JÔJ?1 ͎rxͨsڼq͎rq͈C2'͗qҭq:5kk7!!:5:55r:5.rĨrr:5:5*7eÈCMh:5*7eC*7!5mrͮG:5:55ro /*7lÈC!n5x:5Srmrermr>+wy<<+w#y25~ʈrr>  > # pr+q#:5:5 r8LãrK?ÈC! p"60͍''/r@Yr>N!d5 7*7~ % *6~!%r͑!~!r2'<.1TJUMNF TAB AT COL CLEAR./; A for all)? ͱ$Bp1< 2)!6~6tq61)!5DpͶq2i52g5<<<2k5===!g5w!i5w̓s1)=xq*"v|}q>q<>!  r!!Þ!"Þ!#Þ!$Þ!%͞?1!&1)Þ:'!(r!I8"J6!*rHp!5͈s͹q_z#?rhrhr1)y!I4.ÊrJp!5A͊sDr͹q_{q!I4eڃr)))){/w!4+ʢr~ʑr¢r{2H41)tksr+C!vͭj@s*v*i5R*k5*v|r7_}r!vj> kD-r!vjtks<4~6"qqv!Cë:!2p ë:'C!7:72:qv!7ëhq2'́qhqFq!7I*7yTJvM!7xVKJqJy£JqJ!"6!7xH*7͈C͟IҖqqJp:C6G-$ͱ$!8.͔ 2':D6:C6G-ôq8q8>25G*B6|!8s:C6s$:Y5r!8͔$:626n$:!4$r,p2JZ1%͹$*+?1*`5"6"6*6~!͔$a#+w#͟$~ʂrͨrږryrsږrGͤ–rxG8x͔$}!+y)8ͩ$8@rկ ®rsr.r#r rͤ7rr rrr>  r~<7*7w# q"7z̈CCp!"6Uq!vj:v>qnp>v&:*|t!Hv:Gv6q:*nq*"v|> v&}> v&:v>v&:v>v&͉qÐp*hv*7͎ҥr:u®qïq͎ҥrtWr|¦qqtqqq:IvLr={rڦqqLræq{ræq!Dv:Iv7ȷ:Iv=4rLr;r:Gvo&A> trr1ru(r;r>2IvxeÏq{rA%rQr*7#"7u>2Iv͈C>t:Iv={rLrnræqgo2Dv2Iv#C>2Dv>2Dv2Iv*Gv&"hv|2u͔ xr+!Dvf:Ivo=Lr{r}2Iv|2Dv"hv>2u*Gv|g*Gv͹R8L͉V*Gv"Gv2Av"Ev`i"Bv2?v<<ͤr͡sys#?"sͩ$ 87B,s-2s>25G@s>2525NJs25WUs>25U`s>25> c"p$p͹$7~͡s#bk))ܝs0_ܝs"5|s!0?::5s!7s*7sÈC!7s*7ltüsIGyOxG7tt  t#s+at#ss#Ltt #0ttattѷt Btat# t~͡s>Ҳt~>ɛ<s+͈C=s:v́q:v=͛q1)rK*sv"v͒kͭ7ͣks *v"svK*sv"v:sv_͒kͭͣkSsKs!:r#?r-frKsÊs%͔$L#Gy¸sͤ#ʶs!¸sW#ͤ7ssͤ{ŒsҌs~:0#bk))es*u(q5tSPELSTAROVR #1 COMMAND? WHAT???   NOT FOUND  Enter name of program you wish to Run,  optionally followed by appropriate arguments.  Example (shows disk space): STAT CHECK / ADD TO DICTIONARY? < -s#.:*? пͤ#~+:1s~1s@##ͥ7$:C6 tKsͱ$8Zs:C6tmsͱ$8.͔ 2':C6]sͱ$.pxs.0p!4:4̎sù$~ʤs ʤs.#ʧsÑs6.#7 ʹsw# ¬s+~.s#6Ê*ps!s#~͹$2'*7*7R!)͎?!=8""J6!_7t!:; ͂7?o< 2Iv2DvLs:&vogss&"GvDsnrtst=s͈tt$s"EvLs*EvDs*Gv&[tvuʨutsTsvu[t}uqs33"Ev!sKât͚tځuŠsnr͚tڛuʕu*Gv"+v:&vg$o"Gv2Dv2Ivt*+v"Gv7t|Ҙs˜s:&vs+Lrs[t:Gvg:HvGu|sDM vuums"Ev:Gv&oA:HvtyGeu>2DvmsmsTs͈C8LyG;rQ8LQt;LNt͈Cs͈tt |t |t͈tGx*Bv}”t7+"BvẍCKt!Avtʾt t6 6Út6Gͭt>xɯx t#t+:Dv2IvGux <  qpppp(p:pÈpÙpqKK7p+pCf+L;LMp@p#D*Pv:6O~`opyL`opop Zp~~wyL`…pDM2v6P[jKKDhËp:pv*g5iڳp*k5+++͓lڶp*i5"g52pv!vͭj1)*6"6!6Þ!dp!d"6>26!"6:6*v:vpv< 24:C6:q!8"J6w-~͎!86q26̀1!|!. !!86q!~8!"|~2|!>"|:4=t!*pt%$p͔$!,uML#Ϳͤy6sq&p×q!y6C#6O#6Mq(p×qyͺr#yͺr23y4y~# qy͔$:42|!+~w26.wͅ"͗*y ?w-! !A4!~yR++R.!yyRR!yy[!Y|y[ͫst!~Y|[! Dկ r͎sr.r#r rͤ7 ss* s < 9r JpQpWp4EDBACKUP$$$BAKNEW FILE:/25bp͒p͡pOqZ1:4:b2f5>0q:2i52g5:I!ڈp~<2k5>24!vi.>2vC!p ̀ʾp!p ̀p!8"J6×-!v.!6.292F2I2[[-*7"v"7p*7*7R|<2 72 7|D!"7>2 7%q)"7,q2 7!5wȷ!  .>2%!:C6!4̗!:~ͣwv:Jtqw::ʀq>26_7 !p ~87!p  :4=q!CS!7v!4:8:6q6 #:v+!4v8!5~8:4=r!SC<Gu #|t͝r+t:Dv1u||t:Gv)u|t>2Dv7=|t>2Dv:Hv|t|t)u> t`ueu}JuWu# }eu Gx*EvóGóG͈C>kD> kD!Þu͈C8L͈C:&vus  ¶u vu:Hvu|s8uo|uu%uEuͳoÊeu8t çpôp2vþp>2v25Ok$%p͹$!n5L#25yp>,cp͹$!5L#25>)c͔$<iK2q!vj*vK2qqf!vv͉d>267ɯ2v{͹qq6q{͹q*q7?Cqͧq{xq͹qͶqʆqͧq>2v͹qͶqsqE7:v7͹qSʝqD q͹q-7+vM"v#{ʿq2'K? ܔ ڿq7*qɾ#45q s6RqhqwqÑq&rSrqqqqrrërrqq r9s{IQ0 ENTER space OR NEW LINE SPACING (1-9): LEFT MARGIN COLUMN NUMBERumn)? (ESCAPE for cursor col RIGHT For decimal tab stop enter "#" and decimal point column  SE=7=r ss>?ss> s s~+s#.: пկ  ps~ͅs#*?+sͤ#~+:¦s~Ҧs@##ͥ7~#fo"t#R"tstsottg*ts#zw+|s~w#+|s*tF#"txG s8$:Y5͢$:626n$%ͩ$"p>24,q$y!p \t>/v&!8t%!4,u%,p͔$:!,uL#Ϳͤy6sҠt&pqt±t(pqt#yͺrryͺr23y*** xm6lm6f161am=Hy^C Cannot return to WordStar. Replace system disk (if removed), Hit any key to return to Operating System:  WS.COM Hit any key to return to Operating System: s(pp:7:C6s6͇2>up:C6up!D6~6Cp:B6Z1 >2:$:7]p)8!5+8q>2:2D6/2:2B6:7ěsB!:.4!$;!5r'8:7Ēqp+~!8¼p"J649p~#p!5~pZ1!9"sͩ$-8:6<26 r:6r!͟$=r=PAF% E> ͧE*v#"v% F>ͧEFEͧ%F% F*v*v#͎%FFͧ%FF%g}2 vÑF! vxF!vxF!vͧ%FF%ҊW{͘FͰF| FO: v> !f v*v*v* vR|F`h: v/<_F Fi`"vÊ 2vx%G  GG FJG`GF:'GJG`G3GF:vOqG*v+"v:XGJG>2v!v454T%*v+"v*v+"v͙E{"v*7RA|#O ʋG wGxMG:v1G*7NJ*7qG͋G0OG HGGºG ͐D  *7*7͎!7!7IxŠͣHz{=6~6N/ cN:6*6*67_N2626qN&* 3.GNy*N!ex *N*6"6"6"6y26x26:6!6nN26-vLvLíj:Y5ڸN͍'"%:6> 0026o $͖0o͢$:626ɯ2626:Y5o!ͩ$M88L K͈CKNNN!% O ܔ %7N!6~6ʦOʹPAO`i+~+++1O6! ^#V{rOV`?G1G:6[O>`Ox=e`ͣRckL7>~.`P͙QҲO*Rv~ʔO@_PÂOb` ʲOh_͍QÔOʹPAO͔QPPAO$PvP{;q r38!4:̧q58#ͧq#:4/78̧qw98͹$2'!:; ͂7?$qqN!q#+qAxq#~xpÿ*sqq>;!q#~͹$72'?:62626:626n$>(r>%͹$O*+?1*`5"6*6~!͔$a#+w#͟$~|rͪrڐrrG8y=ʢrx͔$}!+y)8ͩ$8Frͩ$8Frկ °rsr.r#r rͤ7rr rrr>  r~=XHIG>͕&>2 7!7jH*v*6͎-H"6!7jHYHR*7͎GH"7*7͎UH"7Ê*Z7*\RI`i)\wH!7#͎+ڐHHͺHH!7͎ҊH++++ÓH!7I ͺHҫH####7͎I++ws#r+##s#rÊ++Iw#r+s+r+sÊ!7w[?II>ܘIڊI: 7GO IvIڊBI!64F! 7ZI=O: 7=G͟IsI hIÉ*7+:Vv7!Wv~‹I6!v̭j͈C*7#zI*6*7R*7͎*v*6͎vIdIM*6#"6"7*7JI:\7WlzTJI*6=M5kĈCj2g5:lv͔QòOL :6e``i"PvL͉V:%v26*&v" v""v:(v2v:6VP̀1 o :vL`o:Wv!vj2WvbP2$v!6~6/o ’P͑! ~!:6=ʡPͭPڨP7ԭP1)!65lԉl͹RͅR7ȷ$^PʹP:vL`P!6^͍QP>P:6e`2&w:vW!C?Q! 45QͯRP=6++++!CQEQ! ~QͯR!C?Q#Q#QbPLiUڂQ͉V͗LuQ_\_͏RPQzbg 整͏RͣRzWL_L:6=ÖQ>e`! ʬQ~wýQ ʷQ~½QQQͣRͅRQbPLͅR͉V ͣRͅRRzOR R R͗LiQ_= 1|*"|*"||͕{9|͘{y{ʊz|ʊzڊz!\!y͘{!4y͘{d{{:|{>1|*|"*|"!!|͐{!|͐{|{z!|ͣ{{! }ͣ{{-||9|3|$:|9|*|:|?|:| {!|ͣ{{! }ͣ{Gx{>2|1|ݏzyʈz 8{*|>2|2{2|͜|F{:|F{1|! }ͣ{Èz!y"*!a{͐{!!{͐{!|"Õ{H{:|x~# Ø{^#V+~#ʹ{{ê{!~ͪ{ê{O> {2|>*_y{{N#!{= ʷ s#.:*? пͤ#~+:3s~3s@##ͥ7$*`5&~!bk͔$L#ͤvsͤjs68LʲCڵC*7["7`iͰLzL͚D*7[F*7"7"7zL͏GïC*7"7RDͼL D = *7͎J*7YH͎&J:kKJ*7YH͎87>JdKJM*7+"7J"7:G+~# `J> iJÊJͣH?IPK*7!7CKãJJqJ!7)K*7ͼJJڲJ2\7"7 ¦JsIg77797~J#J7>>:9!777:v7qJI!7,K*7gvsI"7 KsI?I*7ͣH͎UK*7)$$VKNKO>͕&xHͣH͎eK)|Lɯ2 v8M:WvK͈CŽK*72 v/2 v*7ژK*7[:WvʾK:v¾K*v|KPY͎ڽKDMɯ2WvI*72 vKxK~# ! v~6K2 v*7*7[x= n /R͉V͗L)RK^͏RͣRiQͅRR R͏RQ ~R͗LDRR0^iQ/R_ _RR jR WLͣRͅR_RRLQ:6!vvLzWL:v<2v_:v=ëRbP*C!&w####PS~RR###~R+++RzL`S~RS+~G+++ SxPS~PS~PS~4Sz!CPS++++~PSPSDMz!CPS!CPS2v26bP7`S>2?v T ƒS> ]ShX:hvoSŸS:%-T͕SXS:!e5ªS͕S]S͔ SSҾS:%S>^XSSS@XSdV*hv#"hv*Ev+"Ev*hv+"hvS@]SS!= q5x>4!|B|!}B|!}B|!}!}ͣ{ͣ{! }ͣ{{n1&r *;Gw#6*;w#62::Z;2::2:2v;*":!"K;:2A;>2@;Z;!fG#:IODrN +y=!7#͎+ir͠r͓rXr!7͎Ҋ;r++++lr!8d Hit any key to return to WordStar: Replace diskette with file , hit any key: *** file  still not found *** *** file  bad (too big ??!@&*) *** *** file  bad (too short) *** ***  found is bad or incompatible version *** =  bDC HïC|ïC*7["7F`iDͼL W W OD WD ͋LbD;D͏GD G*7w#"7+ͰD`iDͰL8D͚DÃD*7"7ôD2vx0:*7R:'/̼ED|E E E#D*7+ [!"v"v"v͠Fx0 T%uEEx0  oE AE Ex0  Efg*v#"v*v#"v:'bE*v͎jE> ͧEE>ͧEEE:EE*v͙Es#r!"v*v#"v*v&)*vg:'2lv|bk+Ó_:v*v*v:'FͼE!EE!E]% FFLHTFPLiFMToFMBuFCP0F=vMtJmKx7*7ɯ2 v8M*7%L*7[>2 v*7"L+LxEL+~ ! v~6cL=2 v!7w[xvMJLx7LͰLͼL͊LL    7L?®L ®L ɯo>g>_v:~CW o g _ Wz}|{ L*7͎*7͎>͕&MLL1M*7!M*7}o|g_Pg!\*MLAM{yM>ĕ&zʘM*7*7R#͎+nM͔JSM*7>áM<>ĕ&*7*7R͎ҘMJM*7z7>2 vg:H!CڵM~=26=26M~26=26h``i"Rv "Tv͠F>27×-N*6<͎#N:6#N!>> T-T> gT>~!kvU: v7T: v7Tɯ2 v:Wvz2%v*hv:?vPT+"&v:kv2(v>2=v:>v•T:2VvL;LԒU2VvM+LͨUxU+~  •U#xU+~ # +ëU>;L#:hvG:?v!:vUS#~bV*0v}CV#6{=(V=2>v>lT|\!"8vK"3v+"3v#*\Ê o  }!_vзG\z!avد2_vz2`v:/:]vF*0v}:^vT%vL;L? :'!(:'!D9"nvJ*7#~+T%ʸ\!(]]%\\Կ\*nvÊͧ%\*nv>?]͙X\`i{= ]~ ]#]w#\!kv!d5:ÙX\:':(7ĭ]8\LH]PL]MT]MB]HM\FM\PC\PO\SR\UJ\BP\CW\PA\CP\PN\OP\HE\FO\IG\PF ]OJ ]IJ ]LM ]LS ]RM ]CS ]DM ]SV ]AV ]RP ]DF ]RV ]FI ]!vL;LT%ʼ];Lw\]b`o ] ]ͣR!6]bP0]bP>ͭ+KͶd+Kd+2d:6!6did~‰dÌi*Pv~‰d͌iqd]ddid"PvKP>d*Pv####:6=L`1h``iÌi*RvÌi!"6:6/!+£)b` ‰dqd2d!65^:t!c5d>L`:6e` ]:+!6ª)*Rv++++~‰d:6!6>d$^e:{!c5b`]*Rv~1h_͔Q͉de!v~6.en1 K+!f5Þ:g5:v=f+g*7++͈C>2v2g5ڊe(͂N/*`52626(~! ҕef͡eMh!mv626-e!645enk!#45e>f!"45e#e:-fn ~:6/!mv!6qN<26á>kD 7> ęԜkOG1!"vy͉lͮk>2mv2rv͟ltllͯ_tl*~v*k5R"v+|hlo:!nͯ_f"nͯ_>lg͈C26*"v*g5Ól*k5*"vÓlzʜl7?{tkK*sv͂lKͭ7l+́nl~w#ͣkål͈C*sv*g5"svRE̓oKgv>M!uv. ?ml> 2}v:yv:|vm!O8"J6?m!}v5 m*zv"~v*v"v*v"v|n͓n Qm3e7ͭ7_m>+w#_ͦmW*svͣk*k5*svm#͓lҟm:zvŸm"zv+v>M:zv{nʽmzn>m{m2|vz>Gg!uv~p#wzxmO#~q#wz2v*svm#"~v!yv4+x>:2;v!kv:22v[bV:=v2;v8VW*-vp#"-vw#>2@v[bV#54+U:ivbV*0v*hv͎UGxG"0v26=2/v*+v ÉV!"hv9"+v!Wv~ʠV6>2VvvLz2]v>2\v:22v!:v#:* 2jvW:Dv\L͉V *v1_^h__@_1c^ `y`!6p_L`1^p__y`C_!6`^_c^W:c5}^:{…^`͛^͛^T"!{j&~!x":6W0# *7[*7[!!W_:c5_:t_>^`:+^:6!6^:6^26ͳ)1)ͥ"> ͜ `'_'_!tÏ^:6W0#w 7_||g}o&wPY!x[!p0`i&wy_&wr_PY!x[!X_h_=‰_Mæ_DML_`0͹R`é_*w:CW __͗L___7 _::6h``>efkGfxԙMhf!v͜xkD Mh!65͌flMhhf26Khf Mhf:f5Mh~ MhC*Pv~###ʁf~fw+w+w###x͎kf f!vͭj!vj8L ·f;Lڷf#ͼʾf!qv4fD*"v+""vj*v-f!ļ!"pv"6:pv:f57:v=ȷffg͉lg!6~61)!65:)=#g=g!f545;gMh> kD> kDhfKK]gTg+ Hē_w#>gÈC͈Cͯ_.g:i5!g5w1)( Ͷg@_=gPe͉i1( Ͷg͇_͔Qb` ʌg@_P͉dágV`g?<:vf8L~cDg*Pv~~wJhK3eOGh!v~yg4 :p>v>M=n: vL;Lw2 vgvL;LW4n6iK2|nSn͓nW:nͭ7+͈C:)=_g>kD> kD[n2'*g5"svE̓oK:rvMv͗L7Kʣnʣn+͈CKKnʪn̯_n3eên+nCKͼ zn+6 -:vvG:v!v64n!xv owOo!v4o<552vx!xv2vviKgKqo.og!vv5po:vSo!xv5bo!v5bo!v5bo=<.otoK.o:v͈C!vo~G~wogxړo>OxGͳGÆooÆo 7:$/!rv:vv!!vZ1 toK.o^tPC!vo~G> @ X )WX*hv*0v#R|}&X>=,XOyFX FXFX 3XxgðWWxGX'X*hv|}/<7:EvpX=sZ:Av:*2Ev.[:ͮXY:͙XY:;vʦX:2v 2jv͙X:\v2\v#́\X:͙X:"Y:͙XÝ\> )W]SͱX X:X:͙XKY YÝ\YY#:ͮX@+:@v[> O2?v:]v-TXv:\vMwO\GY͋\:*UY:AvzY:kvG_Yw#]Y:jvwo 2VvXvL:CvUY:2CvSZhX:Ev=W:kvGScYw#¸YpXïY:`v<2av=YYY*hvZ[j74ZM>  ~&w!C)`:Ch`!C/8`W:C&w_H` :`G1Ox1!6/<12vog))Bw DM!BwA 4_}:)ʑ`>!f5FO:6ʟ` *6|ʪ`:D6!6O!: #~ ` ½`:I'`V(!4(́\`͡(C*v#a(C*v#a(a͡(C:v_*vͰL aͲa(C*v#Ͳa(C*"v#$%>aA>-c(a:$vc(*6|ja>+0((*7*6Re."6:f5!6V(~ʁa>͡( C:pvʏa>͡($Cʛa>%͡("C:)a>0͡((C0c(;aHa+|axa`i;ac(iÎ :6:6W?> ^v!qv~ h5!vͭj!vj> kDͭj:vjK8LͶKcdfC[j*Pv:!vah: v ih~~w++++~~w>2mvf͠h:pv!"v$"v+L;Lښhͼh#vMiҶh!""vgz:f5hK*"v͓l҈CKh+h#!"vh͈Cͯ_> k:"> f*"v͓lhf> kDi*"v:"'i{_Iiz=iig 7 i{/ikii2pvG1fi*k5͓l/i*i5͓li 7ȷ{!I4e~io&" v*Pv~ʛi++++Îi~ld›i"PvDM#^#V###N#fiR>2VviKi2Wv2VvÈC!")v* v|i{K+zj#!)v#> [rpq|r!! ͎8p:71p̀1p!;8"J6!7Qr*7";";";";";";";";6#";";.6#";";";";"E; s#r":2;:4q::p>24;=/p22;23;>q:>q:>q/25;/!7̗q:4.q/2E6>':4! Wq:4;! 2C6:B6ʔ Z1 n1&r *;Gw#6*;w#62::> ZWO$%Z.}Z.Ey=!Gv2Zx/Zw:*1y#RZ!CvGZRZw!v45!e~[>>NU:Fv:Bv4ZZ2`v2Fv=2Ev=2_v:]vZv !\zZ!_v4:*![ZZ:vZ>2kvÊ:]vv̗LfX?vԗL[[:*[:Gv<[:Hv<[2Avɯ:`v=ZZZ:Iv/!v!vZ*hvM|D!Gv~¯[][=2Dv>2kv:Cvh[ڞ[:Hvګ[ʣ[O:`vŠ[:_v=ګ[ʫ[y!Bvp!Ev2BvÊŠGy/)O*7:I=G:&b:+:e5\b:1vWb:0v0bIbrb{!g5zAb!e5w# Wbb6+db> ^bw#\b6 ͟,z26>26{!i5ڙbb1:!vji+: vi+͈C8Lj͹j1Bj*&vZ~###j6͝_ͯj͝_lj!vw?1Ê͑j:d5vLz>v >͗L>:*#ڤj=w<6Rj6#w#w#wR}))v~wXj~~wXjj͹jj>v&>?1WDM5kʊz2'͈C26k!vjK2'?1!]AM͈Cko L{lk{XkPk|gk!gk?%?Z;2::2:2v;*":!"K;:2A;>2@;Z;!fG#:IODrN +y=!7#͎+ir͠r͓rXr!7͎Ҋ;r++++lr!7r ͓r҄r####7͎r++ws#r+##s#rÊ++rw#r+s+r+sÊw[ɛ uàpàpqïtqÛt&5>Rd ???Action(F/B/I/D/S)?Spelling Check Completed Add to Dictionary:  Add to Supplement: (Y/N)? >2vqr2525~!Q8͹$!5 L#pګpqͤp#Bp>25Gp>25> c#p?=::O ~*;":#>2:2:B~5I= BWo xq=!:~6i=::B2E6W2::;G:;W*::5;==!}>>x=!:y=!:zU=2:)>}>>| >x= >y=z!:5 >z=I=|xOzO>2:2:K>:;?>ɷH>::33ɯ2:d>:;?>::2:z>C>:;z>:;!:4><2:͚>::::!:ڃ>!:.?ͪo:4;!:!; .:>; ͵< > :>?o:ͨ< .> +~*;++~:>V>>V>>>#*:A! D>!:>*: >ʔ>F##>‰>͛{u>> >":";{2:!:::;2;!2D>!:>*:A*:::_7>G{>H7>G#>y>> O7>xF>>*:A2 ;WG ???!?2;:9?:9?:A?q>2;a?a?a?j?A;?PAz?;?::Ç=?!:7A#<€?x$AAA!::APY+:A@ 8::AÛ=yH?::x :=*6;aA??Q::@:::=?r:4!;r# ͂8rկ 2r͝rcr.Jr#cr _rͤ7́rvr cŕror>  wr~͌r#.:*? пͤ#~+:µr~ҵr@##ͥ7r!vj:vrr>v&:*r!Hv:Gvr:v>v&:v>v&!vj:*> v&x?%p͹$7>24>2v(r:Y51qS8͹$!"tPt:5Jq:5kk2'!vͨj͋qgq͛t!+p!)pà&26:5ĢrIrMh!!:5q!7q*7rÈC!7q*7lrqIGyOxr#*r r r# rr7 2r+ /r/r7͜r*7#C*7o /!'p"6͍'*6"ror!d5 *7~ % *r~!%‘r͑!~!or2'8LÈCKÈCg:5JÔJx ~#õr:Y52Y5k$2Y5%!~!tqܨr3ss-sPr26FsB"s2?D?>?>?~>?>i?#::E=2:! >!:ͽ>*:>Y?F#>N?͌WG +@+@+@:”?qBBBB¿?C>i=%@!:ʰB#z=:4;<̉B::!:A@ ::O::U@W@>!:`@ H::̔@:4;::@x :=CB͔@|@@ ::=Q::@:4;::@:=CB@ë@¾@ ::=::zA: O::@: O::@ɷ@z @ :4;@A:?0@?z@z ::: @::: ! úA::!:=@GW@z@!";o:oh@͠@W@:=(=LX:Ox 3 O[:%=7=Rd*;#Q@:=@͎@@!8;@6@6:8;͠@ê@@!9;4:=>29;͠@@~@5>E@͎@!8;~4:=:9;?A!@Ê*:&KaA~7APYÞ0A*:&!:0A A<=,@UA:;kAK*:":*:":!*:RhAK*:":::_ÍA >2:2:PAAPAADA ,@AA 82:!::|A,B!:~6B͜B͂?? tIsDsSsr͗s-sr͛t*7tͮG7>26*7tG2t+#tWs_>ʐs2t?s}s}s'Hs ʅs ʅs ʅs ʅsÐs2t?s:t2t?sx2t*t~!:tD­s-p÷sSs/p͹$:tc1p3p*`5"ror*t"`5͹$Yt!By! %A+A *A*A!:4x!:4::ͳA!:=AG]ÀA!";o:onAͩA]A:=(=LX:Ox 3 O[[:%=7=Rd*;#WA::=2:> ;AóA:=A͗AA!8;A6A6:8;ͩAAB!9;4:=>29;ͩAB~B5>KA͗A!8;~4:=:9;?8B!AÊ:4;BÊ:4;CB!:~5N*:!:+#{ 2:yhB!:{Bw::!:5*:!:::+ʞBҕB#<2:w":~ʰBPY͞J 6ͩBBͩB:5;=#B<=/AB? B**:͵B":!:yw:ĩB!xhBB**:ͲB":!:~LBLBNPB!,B͜B!:~6pB!:x!mBPA!:xpx!hBʗBʗB,@PA!:yw:OPAy,@:O|8͎B!BRyKByOB#zxAɛ <<<"<5<ɯWV<<2E4!9"C4ͨ<=:l2J:] @:4-:5-*C4͢=!~!!S!Ϳ!%=#%=#%=#%=:`2Y5:c2+ͥ2b5~f!B6.:2c5K=~"=:b5é*͂="7:Il++"7"7="7+"7:Il++"7"7"7*:c5£=*HL&bj –=R+#"7"7*H-3#"7"7Q"7R"7:c5*HͿ-=|!]=>o&))))>=goR? )  ADD !"<2:oz=*;S<<6#";!&<26;!:: !8!:>!":*; >N=N=N=N=N=N=N=N=!N=F6##>G=ͨ<~6# Ox>=":!::!;".2;::;?ͷ=͡2:2:AWo x’=!:~6=::ͱA2E6W>2:2;:;!:=*:*:R*:>*:>͎=2;^>į>ͪ?9?s ÉpÿpXpB READ? WRITE MARKED TEXT ON?  1:v!v}pj!vj>v&>v&!vj!vjsqp!vPj2'7!:ڹpJO:ͳGڙp!vjrsqpͺr2'!AMv!͗Lp*778͈Cp*7:vTJ7Mr7!4~#k$%͹$O*+?1*`5"6"6*6~!͔$a#͟$~ʦq,rںqºq8y=qy¤qq.>O->26:H26=26=26S>:7*7>|& 7!!Y5~P>(P>6!"J6O-:H|>y|>6u>:I@|>|>~!8"J6>|&w- A4:c5:ª>®>:ʰ>>2d52e5>:2[5ͤ!ͮ!~"!N6 ! t6!q66.!66/:26ɛ!%=#%=#%=#%=:`2Y5:c2+ͥ2b5~f!B6.:2c5K=~"=:b5é*͂="7:Il++"7"7="7+"7:Il++"7"7"7*:c5£=*HL&bj –=R+#"7"7*H-3#"7"7Q"7R"7:c5*HͿ-=|!]=>o&))))>=goR@l DECREASE LDAX D ;BOTH POINTERS AND MOV M,A ;THEN DO IT JMP MVDOWN ;0909H LOOP BACK POPA: ;0918 POP B ;BC = RETURN ADDRESS POP H ;RESTORE LOPVAR, BUT SHLD LOPVAR ;09C9H =0 MEANS NO MORE MOV A,H ORA L JZ PP1 ;0932H YEP, GO RETURN POP H ; NOP, RESTORE OTHERS SHLD LOPINC ;09CBH POP H SHLD LOPLNT ;09CDH POP H SHLD LOPLN ;09CFH POP H SHLD LOPPT ;09D1H PP1: ;0932 PUSH B ;BC = RETURN ADDRESS RET PUSHA: ;0934 +++PUSHA+++ LXI H,STKLMT ;0FAFH CALL CHGSGN ;07A6H @B 21500 Draw a line between LPX,LPY and the previous point LPX,LPY If LLX and LLY are set to >361 then the first call to this routine is the initial point on the line automatically generates PX and PY for the video display 10. GOSUB 2100 Clear printer graphics memory 11. SAV = USR8(0) Save the printer graphics memory to disk File name is a string 1-8 chrs 12. LOD = USR9(0) Load the printer graphics memory from disk File name is a string 1-8 chrs 13. PR = USR5 Dump the graphics @W ;0183H LOAD TOP OF AVAILABLE RAM INTO SP DCR A ;LOAD SP-100H INTO THE FOLLOWING ROUTINES STA TV00+2 ;0119H : STA TV11+2 ;0126H : STA ST33+2 ;01A5H : STA ST44+2 ;01E5H : STA IP33+2 ;05ABH : STA SIZE1+2 ;0705H : STA GETLN+3 ;0817H : STA PUSHA+2 ;0936H : LXI H,ST1 ;0184H LOAD ADDRESS OF ST1 (FIRST START ROUTINE) SHLD 0101H ;STORE THIS ADDRESS AT 101 (NEW JUMP VECTOR AFTER ;THE BLOCK MOVE TO PAGE 0). JMP ST1 ;0184H START THE PROGRAM PG0: ;0A50 THIS BLOCK IS MOVED INTO @OV L,C JMP PN2 ;08C2H AND DIVIDE BY 10 PN3: ;08D2 POP B ;WE GOT ALL DIGITS IN PN4: ;08D3 DCR C ;THE STACK MOV A,C ;LOOK AT SPACE COUNT ORA A JM PN5 ;08DFH NO LEADING BLANKS MVI A,' ' ;20H LEADING BLANKS RST 2 ; JMP PN4 ;08D3H MORE? PN5: ;08DF PRINT SIGN MOV A,B RST 2 MOV E,L ;LAST REMAINDER IN E PN6: ;08E2 D MOV A,E ;CHECK DIGIT IN E CPI 0AH ;10 IS FLAG FOR NO MORE POP D RZ ;IF SO, RETURN ADI '0' ;30H ELSE CONVERT TO ASCII RST 2 ;AND PRINT THE DIGIT JMP PN6 ;@ POP B ;BC = RETURN ADDRESS DAD SP ;IS STACK NEAR THE TOP? JNC QSORRY ;080DH YES, SORRY FOR THAT. LHLD LOPVAR ;09C9H ELSE SAVE LOOP VAR. $ MOV A,H ;BUT IF LOPVAR IS 0 ORA L ;THAT WILL BE ALL JZ PU1 ;095AH LHLD LOPPT ;09D1H ELSE, MORE TO SAVE PUSH H LHLD LOPLN ;09CFH PUSH H LHLD LOPLNT ;09CDH PUSH H LHLD LOPINC ;09CBH PUSH H LHLD LOPVAR ;09C9H PU1: ;095A PUSH H PUSH B ;BC = RETURN ADDRESS RET ; ;THIS IS THE TERMINAL OUTPUT ROUTINE THE ASCII ;CHARACTER IS IN THE A @Zmemory to the printer 14. ASCI = USR1(0) Change the video screen back to ascii mode s routine is the initial point on the line automatically generates PX and PY for the video display 10. GOSUB 2100 Clear printer graphics memory 11. SAV = USR8(0) Save the printer graphics memory to disk File name is a string 1-8 chrs 12. LOD = USR9(0) Load the printer graphics memory from disk File name is a string 1-8 chrs 13. PR = USR5 Dump the graphics @PAGE 0 XTHL ;RST 1 RST 5 CMP M JMP TC1 ;012FH CRLF1: ;0A56 +++CRLF+++ MVI A,0DH ; PUSH PSW ;RST 2 LDA OCSW ;09C0H PRINT CHARACTERS ONLY ORA A ;IF OCSTW IS ON JMP OC2 ;095DH REST OF THIS IS AT OC2 CALL EXPR2 ;0616H +++EXPR+++ RST 3 PUSH H ;EVALUATE AN EXPRESSION JMP EXPR1 ;05D2H REST OF IT IS AT EXPR1 DB 'W' MOV A,H ;+++COMP+++ RST 4 CMP D ;COMPARE HL WITH DE RNZ ;RETURN CORRECT C AND MOV A,L ;Z FLAGS CMP E ;BUT OLD A IS LOST RET DB 'AN' LDAX D ;+++IGNBLK+++ @ h08E2H GO BACK FOR MORE PRTLN: ;08ED +++PRTLN+++ LDAX D MOV L,A ;LOW ORDER LINE # INX D ;HIGH ORDER LINE # LDAX D ;PRINT 4 DIGIT LINE # MOV H,A INX D MVI C,4 CALL PRTNUM ;08B1H MVI A,' ' ;20H FOLLOWED BY A BLANK RST 2 SUB A ;AND THEN THE TEXT CALL PRTSTG ;087FH RET ; ;+++MVUP+++MVDOWN+++PAPA+++& PUSHA+++ ; ;'MVUP' MOVES A BLOCK UP FROM WHERE DE-> TO WHERE BC-> UNTIL ;DE = HL ; ;'MVDOWN' MOVES A BLOCK DOWN FROM WHERE DE-> TO WHERE HL-> ;UNTIL DE = BC ; ;'POPA' R@  , USING THE PRINTER AND VIDEO GRAPHICS DRIVER 1. GOSUB 20000 Sets the USR definitions Clears graphics memory 2. LLX = 1000 : LLY = 1000 If LLX and LLY are initially set outside of the 360 by 361 pixel range then the first data point used in the line draw Subroutine assumes its self as the previous data point 3. VON = USR0(0) Sets the video screen to the graphics mode 4. POKE BORDER, B Sets the printer graph border configuration 1 = left border 2 = right border @ L REG. NOP ;STORAGE REG. FOR CONSOLE OUTPUT CHARACTER OCSW: ;09C0 RST 7 ;STORAGE REG. FOR CONSOLE INPUT CHARACTER CURRNT: ;09C1 SWITCH FOR OUTPUT NOP NOP STKGOS: ;09C3 SAVES SP IN 'GOSUB' NOP NOP VARNXT: ;09C5 TEMP STORAGE NOP NOP STKINP: ;09C7 SAVES SP IN 'INPUT' NOP NOP LOPVAR: ;09C9 'FOR' LOOP SAVE AREA NOP NOP LOPINC: ;09CB INCREMENT NOP NOP LOPLNT: ;09CD LIMIT NOP NOP LOPLN: ;09CF LINE NUMBER NOP DB 0 LOPPT: ;09D1 TEXT POINTER DB 0,0 R@ F0MBASIC LVGRAPH.ASC /M:&H9800$H.ASC /M:&H9800 (0COMPRES$GRAPH.ASC /M:&H9800$H.ASC /M:&H9800 (0LVGRAPH$GRAPH.ASC /M:&H9800$H.ASC /M:&H9800 (LOG2 ASCZ2TINBAS06ASMf[]^_`abcdefgALOG2 ASC\ LOGBAS07PRN @ ESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE ;STACK ; ;'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SAVE AREA INTO THE ;STACK ; MVUP: ;0900 +++MVUP+++ RST 4 RZ ;DE = HL, RETURN LDAX D ;GET ONE BYTE STAX B ;MOVE IT INX D ;INCREASE BOTH POINTERS INX B JMP MVUP ;0900H UNTIL DONE MVDOWN: ;0909 +++MVDOWN+++ MOV A,B SUB D ;TEST IF DE = BC JNZ MD1 ;0911H NO, GO MOVE MOV A,C ;MAYBE, OTHER BYTE? SUB E RZ ;YES, RETURN MD1: ;0911 DCX D ;ELSE MOVE A BYTE DCX H ;BUT FIRST@ 4 = top border 8 = bottom border make "B" equal to the sum of the codes for the desired border components 5. BDR = USR7(0) Draws the border onto the printer graphics memory 6. LPX = , LPY = The X pixel and the Y pixel are generated by the application program range is X = 0 to 359, Y = 0 to 360 0,0 represents the upper left corner of the graph 7. GOSUB 21100 Sets pixel LPX,LPY into printer graphics memory 8. GOSUB 21200 Sets pixel LPX,LPY into video graphics memory 9. GOSU@{ANPNT: ;09D3 RANDOM NUMBER POINTER DB 0,1 TXTUNF: ;09D5 ->UNFILLED TEXT AREA (END OF PROGRAM TEXT) DW TXTBGN ;INITIAL VALUE TXTBGN: ;09D7 TEXT SAVE AREA BEGINS DB 'M' MSAG1: ;09D8 DB 7FH,7FH,7FH,'SHERRY BROTHERS ' DB 'TINY BASIC VER. ' MSAG2: ;09FB DB '3.1',0DH ;STACK POINTER SETUP ROUTINE SETSTK: ;09FF MVI A,0FFH ;INITIALIZE SWITCH FOR OUTPUT STA OCSW ;09C0H MVI A,0CH RST 2 SUB A LXI D,MSAG1 ;09D8H CALL PRTSTG ;087FH PRINT THE SIGN ON MESSAGE LDA 7 STA RSTART+2A`A 4 = top border 8 = bottom border make "B" equal to the sum of the codes for the desired border components 5. BDR = USR7(0) Draws the border onto the printer graphics memory 6. LPX = , LPY = The X pixel and the Y pixel are generated by the application program range is X = 0 to 359, Y = 0 to 360 0,0 represents the upper left corner of the graph 7. GOSUB 21100 Sets pixel LPX,LPY into printer graphics memory 8. GOSUB 21200 Sets pixel LPX,LPY into video graphics memory 9. GOSUA&3.1',0DH ;STACK POINTER SETUP ROUTINE SETSTK: ;09FF MVI A,0FFH ;INITIALIZE SWITCH FOR OUTPUT STA OCSW ;09C0H MVI A,0CH RST 2 SUB A LXI D,MSAG1 ;09D8H CALL PRTSTG ;087FH PRINT THE SIGN ON MESSAGE LDA 7 STA RSTART+2 ;0183H LOAD TOP OF AVAILABLE RAM INTO SP DCR A ;LOAD SP-100H INTO THE FOLLOWING ROUTINES STA TV00+2 ;0119H : STA TV11+2 ;0126H : STA ST33+2 ;01A5H : STA ST44+2 ;01E5H : STA IP33+2 ;05ABH : STA SIZE1+2 ;0705H : STA GETLN+3 ;0817H : STA PUSHA+2 ;0936HA0ST 4 ;AND CHECK THAT JC ASORRY ;080EH IF SO SAY "SORRY" TV00: ;0117 LXI H,VARBGN ;0F00H IF NOT GET ADDRESS CALL SUBDE ;079CH OF @(EXPR) AND PUT IT POP D ;IN HL RET ;C FLAG IS CLEARED TV1: ;011F CPI 1BH ;NOT @ IS IT A 2? CMC ;IF NOT RETURN C FLAG RC INX D ;IF A THROUGH Z TV11: ;0124 LXI H,VARBGN ;0F00H COMPUTE ADDRESS OF RLC ;THAT VARIABLE ADD L ;AND RETURN IT IN HL MOV L,A ;WITH C FLAG CLEARED MVI A,0 ADC H MOV H,A RET TC1: ;012F INX H ;COMPARE THE BYTE THAAjNE STARTS ;WITH A NON-ZERO NUMBER, THIS NUMBER IS THE LINE NUMBER. THE ;LINE NUMBER AND THE REST OF THE LINE ; IS STORED IN MEMORY. IF A LINE WITH THE SAME ;LINE NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE. ;IF THE REST OF THE LINE IS "CR" ONLY, IT IS NOT STORED AND ;AND ANY EXISTING LINE WITH THE SAME NUMBER IS DELETED. ; ;AFTER A LINE IS INSERTED, REPLACED, OR DELETED, THE PROGRAM ;LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILLAB 21500 Draw a line between LPX,LPY and the previous point LPX,LPY If LLX and LLY are set to >361 then the first call to this routine is the initial point on the line 10. GOSUB 2100 Clear printer graphics memory 11. SAV = USR8(0) Save the printer graphics memory to disk File name is a string 1-8 chrs 12. LOD = USR9(0) Load the printer graphics memory from disk File name is a string 1-8 chrs0A : LXI H,ST1 ;0184H LOAD ADDRESS OF ST1 (FIRST START ROUTINE) SHLD 0101H ;STORE THIS ADDRESS AT 101 (NEW JUMP VECTOR AFTER ;THE BLOCK MOVE TO PAGE 0). JMP ST1 ;0184H START THE PROGRAM PG0: ;0A50 THIS BLOCK IS MOVED INTO PAGE 0 XTHL ;RST 1 RST 5 CMP M JMP TC1 ;012FH CRLF1: ;0A56 +++CRLF+++ MVI A,0DH ; PUSH PSW ;RST 2 LDA OCSW ;09C0H PRINT CHARACTERS ONLY ORA A ;IF OCSTW IS ON JMP OC2 ;095DH REST OF THIS IS AT OC2 CALL EXPR2 ;0616H +++EXPR+++ RST 3 PUSH H ;EVALUATE ANAqT JZ TC2 ;013AH FOLLOWS THE RST INST. PUSH B ;WITH THE TEXT (DE->) MOV C,M ;IF NOT =, ADD THE 2ND MVI B,0 ;BYTE THAT FOLLOWS THE DAD B ;RST TO THE OLD PC POP B ;I.E. DO A RELATIVE DCX D ;JUMP IF NOT = TC2: ;013A ;IF =,SKIP THOSE BYTES INX D ;AND CONTINUE INX H XTHL RET TSTNUM: ;013E +++TSTNUM+++ LXI H,0 ;TEST IF THE TEXT IS MOV B,H ;A NUMBER RST 5 ;IF NOT, RETURN 0 IN TN1: ;0143 B AND HL CPI '0' ;30H IF NUMBERS, CONVERT RC ;TO BINARY IN HL AND CPI ':' ;3AH SET A TA) BE ;TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE NUMBER, ;AND CONTROL IS TRANSFERED TO "DIRECT". ; ;THE MEMORY LOCATION "CURRNT" PIONTS TO THE LINE NUMBER ;THAT IS CURRENTLY BEING INTERPRETED. WHILE WE ARE IN ;THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND ; RSTART: ;0181 LXI SP,2000H ;THIS POINTER IS MODIFIED TO EQUAL TOP OF AVAILABLE ST1: ;0184 MEMORY CALL CRLF ;+CRLF+ JUMP TO HERE LXI D,OK ;0172H DE->STRING SUB A ;A=0 CALL PRTSTG ;087FH PRINT STRING UA GIVEN IN PROGRAM ANA L ;MASK WITH "J" JZ WAITCOM ;09B3H LOOP IF ZERO RST 6 ; ;INP COMMAND THE PORT # IS CHANGED BY THE BASIC PROGRAM ; INCOMM: ;09BB IN 0FFH ;INPUT PORT # (X) MOV L,A ;RETURN THE NUMBER RET ;IN THE L REG. NOP ;STORAGE REG. FOR CONSOLE OUTPUT CHARACTER OCSW: ;09C0 RST 7 ;STORAGE REG. FOR CONSOLE INPUT CHARACTER CURRNT: ;09C1 SWITCH FOR OUTPUT NOP NOP STKGOS: ;09C3 SAVES SP IN 'GOSUB' NOP NOP VARNXT: ;09C5 TEMP STORAGE NOP NOP STKINP: ;0A  EXPRESSION JMP EXPR1 ;05D2H REST OF IT IS AT EXPR1 DB 'W' MOV A,H ;+++COMP+++ RST 4 CMP D ;COMPARE HL WITH DE RNZ ;RETURN CORRECT C AND MOV A,L ;Z FLAGS CMP E ;BUT OLD A IS LOST RET DB 'AN' LDAX D ;+++IGNBLK+++ RST 5 CPI ' ' ;20H IGNORE BLANKS RNZ ;IN TEXT (WHERE DE->) INX D ;AND RETURN THE FIRST JMP 28H ;NON-BLANK CHAR. IN A POP PSW ;+++FINISH+++ RST 6 CALL FIN ;07CDH CHECK END OF COMMAND JMP QWHAT ;07E0H PRINT "WHAT?" IF WRONG DB 'G' RST 5 ;+++TSTV+++ RST 7 SUA @O # OF DIGITS RNC MVI A,0F0H ANA H ;IF H>255, THERE IS NO JNZ QHOW ;0166H ROOM FOR NEXT DIGIT INR B ;B COUNTS # OF DIGITS PUSH B MOV B,H ;HL=10*HL+ MOV C,L ;WHERE 10+ IS DONE BY DAD H ;SHIFT AND ADD DAD H DAD B DAD H LDAX D ;AND IS FROM INX D ;STRIPPING THE ASCII ANI 0FH ;CODE ADD L MOV L,A MVI A,0 ADC H MOV H,A POP B LDAX D ;DO THIS DIGIT AFTER JP TN1 ;0143H DIGIT. $ SAYS OVERFLOW QHOW: ;0166 +++ERROR "HOW"+++ PUSH D AHOW: ;0167 LA NTIL CR LXI H,ST2+1 ;0195H LITERAL 0 SHLD CURRNT ;09C1H CURRNT->LINE # = 0 ST2: ;0194 ; LXI H,0 SHLD LOPVAR ;09C9H SHLD STKGOS ;09C3H ST3: ;019D MVI A,'>' ;3EH PROMPT '>' AND CALL GETLN ;0814H READ A LINE PUSH D ;DE->END OF LINE ST33: ;01A3 LXI D,BUFFER ;0F37H DE->BEGINING OF LINE CALL TSTNUM ;013EH TEST IF IT IS A NUMBER RST 5 ; MOV A,H ;HL = VALUE OF # OR ORA L ;0 IF NO NUMBER POP B ;BC->END OF LINE JZ DIRECT ;02D5H DCX D ;BACKUP DE AND SAVE MOV A,H ;VALUE OF LIA 9C7 SAVES SP IN 'INPUT' NOP NOP LOPVAR: ;09C9 'FOR' LOOP SAVE AREA NOP NOP LOPINC: ;09CB INCREMENT NOP NOP LOPLNT: ;09CD LIMIT NOP NOP LOPLN: ;09CF LINE NUMBER NOP DB 0 LOPPT: ;09D1 TEXT POINTER DB 0,0 RANPNT: ;09D3 RANDOM NUMBER POINTER DB 0,1 TXTUNF: ;09D5 ->UNFILLED TEXT AREA (END OF PROGRAM TEXT) DW TXTBGN ;INITIAL VALUE TXTBGN: ;09D7 TEXT SAVE AREA BEGINS DB 'M' MSAG1: ;09D8 DB 7FH,7FH,7FH,'SHERRY BROTHERS ' DB 'TINY BASIC VER. ' MSAG2: ;09FB DB 'Acw!Z~# x R?[?I??$?(?z~#o}o҃i.2_!fp+q*e2_2_!hp+q*g!jp+q*i!lp+q*k!np+q*m2_!ppJ̴DS5-1/4 HEXCCSYSGENCOM  SS5-1/4 COM WS COM|CLS COMSS5-1/4 BAK7SS5-1/4 PRNSS5-1/4 HEXA XI D,HOW ;016DH JMP ERROR ;07E4H HOW: ;016D DB 'HOW?',0DH OK: ;0172 DB 'OK',0DH WHAT: ;0175 DB 'WHAT?',0DH SORRY: ;017B DB 'SORRY',0DH ;THIS IS THE MAIN LOOP THAT COLLECTS THE TINY BASIC PROGRAM ;AND STORES IT IN MEMORY. ; ;AT START, IT PRINTS OUT "OK", AND INITIALIZES THE ;STACK AND SOME OTHER INTERNAL VARIABLES. THE STACK, IN THIS ;VERSION IS MODIFIED DURING INITIALIZATION TO REFLECT THE ;SIZE OF MEMORY. ;THEN IT PROMPTS ">" AND READS A LINE. IF THE LIBB1. ͠x2y2Fz22A2/>020͠z2x2G:VD  :A>M2@@2E:Y>>@2E>#2R 0 G2GàÛ2 Y g::@!!   " :Q!<)="2D2C  >>2B!6#61!."Lx"L~!B4:DA:4* ^#V" .(͑:DO>2B* ͑:A:C:B:Q͑:G> ©§͑:B<2B z/G{/O.(*  $-%͜!>2B!."LV!"L!B#TAB1: ;01F9 DIRECT COMMANDS DB 'LIST' DB (LIST SHR 8) +128 DB LIST AND 0FFH DB 'RUN' DB (RUN SHR 8) +128 DB RUN AND 0FFH DB 'NEW' DB (NEW SHR 8) +128 DB NEW AND 0FFH DB 'LOAD' DB (LOAD SHR 8) +128 DB LOAD AND 0FFH DB 'SAVE' DB (SAVE SHR 8) +128 DB SAVE AND 0FFH DB 'BYE' DB 80H,0 TAB2: ;021A DIRECT/STATMENT DB 'NEXT' DB (NEXT SHR 8) +128 DB NEXT AND 0FFH DB 'LET' DB (LET SHR 8) +128 DB LET AND 0FFH DB 'OUT' DB (OUT1 SHR 8) +128 DB OUT1 AND 0FFH DB 'POB , USING THE PRINTER AND VIDEO GRAPHICS DRIVER 1. GOSUB 20000 Sets the USR definitions Clears graphics memory 2. LLX = 1000 : LLY = 1000 If LLX and LLY are initially set outside of the 360 by 361 pixel range then the first data point used in the line draw Subroutine assumes its self as the previous data point 3. VON = USR0(0) Sets the video screen to the graphics mode 4. POKE BORDER, B Sets the printer graph border configuration 1 = left border 2 = right border BST STORED LINE, STORE ITS ADDRESS (IN ;'CURRNT' AND START TO EXECUTE IT. NOTE THAT ONLY THOSE ;COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM. ; ;THERE ARE 3 MORE ENTRIES IN 'RUN': ;'RUNNXL' FINDS THE NEXT LINE, STORES ITS ADDRESS AND EXECUTES IT. ;'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT. ;'RUNSML' CONTINUES THE EXECUTION ON SAME LINE. ; ; ;'GOTO EXPR(CR)' EVALUATES THE EXPRESSION. FIND THE TARGET LINE, ;AND JUMP TO 'RUNTSL' TO DO IT. ; NEW: ;0306 +++NEW(CR)+++ BB4:D:ED:CD<2C>*@, Y !0́:G:A:60+604#N#~ •‘# 2ADãG7 G4>>:W>G_   :2@:A1:G:B2:4*L>2H03w#3w#3w#3w#6 :2@:A1:G:B2:4*L>2H0~3#~3#~3#~3#~c :2@:4* DM!.(>2H0~3#~3#~3#~3# »»¤:F2H0402G:@2BKE' DB (POKE SHR 8) +128 DB POKE AND 0FFH DB 'WAIT' DB (WAIT SHR 8) +128 DB WAIT AND 0FFH DB 'IF' DB (IFF SHR 8) +128 DB IFF AND 0FFH DB 'GOTO' DB (GOTO SHR 8) +128 DB GOTO AND 0FFH DB 'GOSUB' DB (GOSUB SHR 8) +128 DB GOSUB AND 0FFH DB 'RETURN' DB (RETURN SHR 8) +128 DB RETURN AND 0FFH DB 'REM' DB (REM SHR 8) +128 DB REM AND 0FFH DB 'FOR' DB (FOR SHR 8) +128 DB FOR AND 0FFH DB 'INPUT' DB (IP1 SHR 8) +128 DB IP1 AND 0FFH DB 'PRINT' DB (PRINT SHR 8) +128B 4 = top border 8 = bottom border make "B" equal to the sum of the codes for the desired border components 5. BDR = USR7(0) Draws the border onto the printer graphics memory 6. LPX = , LPY = The X pixel and the Y pixel are generated by the application program range is X = 0 to 359, Y = 0 to 360 0,0 represents the upper left corner of the graph 7. GOSUB 21100 Sets pixel LPX,LPY into printer graphics memory 8. GOSUB 21200 Sets pixel LPX,LPY into video graphics memory 9. GOSUBCALL ENDCHK ;07DCH LXI H,TXTBGN ;09D7H SHLD TXTUNF ;09D5H STOP: ;030F +++STOP(CR)+++ CALL ENDCHK ;07DCH JMP RSTART ;0181H RUN: ;0315 +++RUN(CR)+++ CALL ENDCHK ;07DCH LXI D,TXTBGN ;09D7H FIRST SAVED LINE RUNNXL: ;031B +++RUNNXL++ LXI H,0 ;FIND WHATEVER LINE # CALL FL1 ;085FH C:PASSED TXTUNF, QUIT. JC RSTART ;0181H RUNTSL: ;0324 +++RUNTSL+++ XCHG SHLD CURRNT ;09C1H SET 'CURRENT'->LINE # XCHG INX D ;BUMP PASS LINE # INX D RUNSML: ;032B +++RUNSML+++ CALL CHKIO ;0985H FINDB  :4:2@>!N>2H03w#3w#3w#7 e:@2:@2J 0*PN 2N N NH   NNNNN N N0 CCS DISK COPY PROGRAM VERS 1.0$SOURCE$DESTINATION$ DRIVE (OR CONTROL C TO ABORT) $INVALID DRIVE$MINI DRIVES WILL DEFAULT TO 35 TRACKS. IF THIS IS O.K., TYPE A CARRIAGE RETURN. OTHERWISE, ENTER THE NUMBER OF TRACKS: $WRITE ERROR- IGNORE? $DRIVE IS WRITE PROTECTED- TB  DB PRINT AND 0FFH DB 'STOP' DB (STOP SHR 8) +128 DB STOP AND 0FFH DB (DEFLT SHR 8) +128 DB DEFLT AND 0FFH DB 'YOU CAN ADD MORE' TAB4: ;027F FUNCTIONS DB 'RND' DB (RND SHR 8) +128 DB RND AND 0FFH DB 'INP' DB (INP SHR 8) +128 DB INP AND 0FFH DB 'PEEK' DB (PEEK SHR 8) +128 DB PEEK AND 0FFH DB 'USR' DB (USR SHR 8) +128 DB USR AND 0FFH DB 'ABS' DB (ABS SHR 8) +128 DB ABS AND 0FFH DB 'LOG2' DB (LOG2 SHR 8) +128 DB LOG2 AND 0FFH DB 'ALOG2' DB (ALOG2 SHR 8) B B 21500 Draw a line between LPX,LPY and the previous point LPX,LPY If LLX and LLY are set to >361 then the first call to this routine is the initial point on the line automatically generates PX and PY for the video display 10. GOSUB 2100 Clear printer graphics memory 11. SAV = USR8(0) Save the printer graphics memory to disk File name is a string 1-8 chrs 12. LOD = USR9(0) Load the printer graphics memory from disk File name is a string 1-8 chrs 13. PR = USR5 Dump the graphics B ^ COMMAND IN TAB2 LXI H,TAB2-1 ;0219H AND EXICUTE IT. JMP EX0 ;02D8H GOTO: ;0334 +++GOTO EXPR+++ RST 3 ; PUSH D ;SAVE FOR ERROR ROUTINE CALL ENDCHK ;07DCH MUST FIND A CR CALL FNDLN ;0857H FIND THE TARGET LINE JNZ AHOW ;0167H NO SUCH LINE # POP PSW ;CLEAR THE "PUSH DE" JMP RUNTSL ;0324H GO DO IT ; ;THE FOLLOWING ROUTINES DO THE DISK COMMUNICATION ; LOAD: RST 5 PUSH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,0FH ;OPEN FILE CALL 5 ;CALL BDOS CPB YPE CR TO CONTINUE$ COMBINATION$ COPYING TRACK 00$WARNING - CONTENTS OF DESTINATION DISKETTE WILL BE LOST. DO YOU WISH TO CONTINUE? $DRIVE NOT READY$ $IS IT DOUBLE-SIDED? $BAD NUMBER- TRY AGAIN: $CANNOT READ SOURCE$BAD SOURCE SECTOR 00- IGNORE? $>S IS O.K., TYPE A CARRIAGE RETURN. OTHERWISE, ENTER THE NUMBER OF TRACKS: $WRITE ERROR- IGNORE? $DRIVE IS WRITE PROTECTED- TB+128 DB ALOG2 AND 0FFH DB 'SIZE' DB (SIZE SHR 8) +128 DB SIZE AND 0FFH DB (XP40 SHR 8) +128 DB XP40 AND 0FFH DB 'YOU CAN ADD MORE' TAB5: ;02B1 "TO" IN "FOR" DB 'TO' DB (FR1 SHR 8) +128 DB FR1 AND 0FFH DB (QWHAT SHR 8) +128 DB QWHAT AND 0FFH TAB6: ;02B7 "STEP" IN "FOR" DB 'STEP' DB (FR2 SHR 8) +128 DB FR2 AND 0FFH DB (FR3 SHR 8) +128 DB FR3 AND 0FFH TAB8: ;02BF RELATIONAL OPERATORS DB '>=' DB (XP11 SHR 8) +128 DB XP11 AND 0FFH DB '#' DB (XP12 SHR 8) +128 DBZmemory to the printer 14. ASCI = USR1(0) Change the video screen back to ascii mode s routine is the initial point on the line automatically generates PX and PY for the video display 10. GOSUB 2100 Clear printer graphics memory 11. SAV = USR8(0) Save the printer graphics memory to disk File name is a string 1-8 chrs 12. LOD = USR9(0) Load the printer graphics memory from disk File name is a string 1-8 chrs 13. PR = USR5 Dump the graphics CrC]I 0FFH JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKRD: ;035E READ THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,14H ;READ SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS CPI 1 ;ERROR CODE? JC NEWFIL ;0381H JNZ QHOW ;0166H ERROR MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP D ;RESTORE REGISTERS POP B POP D POP H RST 6 NEWFIL: ;0381 POP D LXI H,80H DAD D XCHG JMP DSKRD ;035EH SAVE: RST 5 PCWITH ^C ; ;PRINT COMMAND IS 'PRINT ....;' OR 'PRINT ....(CR)' ;WHERE "...." IS A LIST OF EXPRESSIONS, FORMATS, BAKARROWS, ;AND STRINGS. THESE ITEMS ARE SEPARATED BY COMMAS. ; ;A FORMAT IS A FOUND SIGN FOLLOWED BY A NUMBER. IT CONTROLS ;THE NUMBER OF SPACES THE VALUE OF A EXPRESSION IS GOING TO ;BE PRINTED. IT STAYS EFFECTIVE FOR THE REST OF THE PRINT ;COMMAND UNLESS CHANGED BY ANOTHER FORMAT. IF NO FORMAT IS ;SPECIFIED. 6 POSITIONS WILL BE USED. ; ;A STRING IS QUOTED IN A PAIR OF SINCIKE THE 'GOTO' ;COMMAND, EXCEPT THAT THE EXECUTION CAN BE CONTINUED AFTER THE ;SUBROUTINE 'RETURN'. IN ORDER THAT 'GOSUB' CAN BE NESTED ;(AND EVEN RECURSIVE), THE SAVE AREA MUST BE STACKED. ;THE STACK POINTER IS SAVED IN 'STKGOS'. THE OLD 'STKGOS' IS ;SAVED IN THE STACK. IF WE ARE IN THE MAIN ROUTINE, 'STKGOS' ;IS ZERO (THIS WAS DONE BY THE "MAIN" SECTION OF THE CODE), ;BUT WE STILL SAVE IT AS A FLAG FOR NO FURTHER 'RETURN'S. ; ;'RETURN(CR)' UNDOES EVERYTHING THAT 'GOSUB' DID, AND THUS ;C2NEW ONE OVER WRITES IT. ;TB1 WILL THEN DIG IN THE STACK AND FIND OUT IF THIS SAME ;VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP. ;IF THAT IS THE CASE, THEN THE OLD 'FOR' LOOP IS DEACTIVATED. ;(PURGED FROM THE STACK.) ; ;'NEXT VAR' SERVES AS THE LOGICAL (NOT NECESSARILY PHYSICAL) ;END OF THE 'FOR' LOOP. THE CONTROL VARIABLE VAR. IS CHECKED ;WITH THE 'LOPVAR'. IF THEY ARE NOT THE SAME, TB1 DIGS IN ;THE STACK TO FIND THE RIGHT ONE AND PURGES ALL THOSE THAT ;DID NOT MATCH EITHER CrUSH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,13H ;DELETE FILE CALL 5 ;CALL BDOS LXI D,5CH ;DE=FCB ADDRESS MVI C,16H ;MAKE A FILE CALL 5 ;CALL BDOS CPI 0FFH ;ERROR? JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKWR: ;03AD WRITE TO THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,15H ;WRITE SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS ORA A JNZ QHOW ;0166H POP D LDA TXTUNF+1 ;09D6H WRITE TO DISK UNTIL CGLE OR A PAIR OF ;DOUBLE QUOTES. ; ;A BACK-ARROW MEANS GENERATE A (CR) WITHOUT (LF) ; ;A (CRLF) IS GENERATED AFTER THE ENTIRE LIST HAS BEEN ;PRINTED OR IF THE LIST IS A NULL LIST. HOWEVER IF THE LIST ;ENDED WITH A COMMA NO (CRLF) IS GENERATED. ; LIST: ;0420 TEST IF THERE IS A # CALL TSTNUM ;013EH IF NO # WE GET A 0 CALL ENDCHK ;07DCH CALL FNDLN ;0857H FIND THIS OR THE NEXT LINE LS1: ;0429 JC RSTART ;0181H C:PASSED TXTUNF CALL PRTLN ;08EDH PRINT THE LINE CALL CHKIO ;0985HCRETURN THE EXECUTION TO THE COMMAND AFTER THE MOST RECENT ;'GOSUB'. IF 'STDGOS' IS 0, IT INDICATES THAT WE ;NEVER HAD A 'GOSUB' AND IS THUS AN ERROR. ; ; GOSUB: ;0470 CALL PUSHA ;0934H SAVE THE CURRENT "FOR" RST 3 ;PARAMETERS PUSH D ;AND TEXT POINTER CALL FNDLN ;0857H FIND THE TARGET LINE JNZ AHOW ;0167H NOT THERE SAY "HOW?" LHLD CURRNT ;09C1H FOUND IT, SAVE OLD PUSH H ;'CURRNT' OLD 'STKGOS' LHLD STKGOS ;09C3H PUSH H LXI H,0 ;AND LOAD NEW ONES SHLD LOPVAR ;09C9H DAD SP CRWAY, TB1 THEN ADDS THE 'STEP' TO ;THAT VARIABLE AND CHECK THE RESULT WITH THE LIMIT. IF IT ;IS WITHIN THE LIMIT, CONTROL LOOPS VACK TO THE COMMAND ;FOLLOWING THE 'FOR'. IF OUTSIDE THE LIMIT, THE SAVE AREA ;IS PURGED AND EXECUTION CONTINUES. ; ; FOR: ;04A9 CALL PUSHA ;0934H SAVE THE OLD SAVE AREA CALL SETVAL ;07BAH SET THE CONTROL VAR. DCX H ;HL IS ITS ADDRESS SHLD LOPVAR ;09C9H SAVE THAT LXI H,TAB5-1 ;USE "EXEC" TO LOOK JMP EX0 ;02D8H FOR THE WORD "TO" FR1: ;04B9 RST 3 ;EVC  CMP D ;TXTUNF JC CLFIL ;03D9H JNZ DSKLOOP ;03D1H LDA TXTUNF ;09D5H CMP E ; JC CLFIL ;03D9H DSKLOOP: ;03D1 LXI H,80H DAD D XCHG JMP DSKWR ;03ADH CLFIL: ;03D9 MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP B ;RESTORE REGISTERS POP D POP H RST 6 L03E5: ;03E5 LXI H,5CH MVI M,0 L03EA: ;03EA FILL 64H BYTES WITH SPACES (20H) INX H MVI M,' ' ;20H MVI A,64H CMP L JNZ L03EA ;03EAH FILL LOOP RETURN INX H ; THE NEXT 3 BYTES "TBI" C  STOP IF ^C CALL FL1 ;085FH FIND NEXT LINE JMP LS1 ;0429H AND LOOP BACK PRINT: ;0438 MVI C,6 ;C= # OF SPACES RST1: RST 1 ;IF NULL LIST & ";" DB ';' DB (RSTO1-RST1) CALL CRLF ;GIVE (CR-LF) AND RSTO1: JMP RUNSML ;032BH CONTINUE SAME LINE PR2: ;0443 ; RST 1 ;IF NULL, LIST (CR) DB 0DH,(RSTO2-PR2) CALL CRLF ;ALSO GIVE CR-LF AND RSTO2: JMP RUNNXL ;031BH GO TO NEXT LINE PR0: ;044C RST 1 ;ELSE IS IT FORMAT? DB '#' DB (RSTO3-PR0) RST 3 ;YES, EVALUATE EXPR. MOV C,L ;AND SC  SHLD STKGOS ;09C3H JMP RUNTSL ;0324H THEN RUN THAT LINE RETURN: ;0490 CALL ENDCHK ;07DCH THERE MUST BE A CR LHLD STKGOS ;09C3H OLD STACK POINTER MOV A,H ;0 MEANS NOT EXIST ORA L JZ QWHAT ;07E0H SO WE SAY "WHAT?" SPHL ;ELSE, RESTORE IT POP H SHLD STKGOS ;09C3H AND THE OLD 'STKGOS' POP H SHLD CURRNT ;09C1H AND THE OLD 'CURRNT' POP D ;OLD TEXT POINTER CALL POPA ;0918H OLD "FOR" PARAMETERS RST 6 ;AND WE ARE BACK HOME ; ; ;+++FOR+++& NEXT+++ ; ;'FOR' HAS TWO FORMS: ;'C fALUATE THE LIMIT SHLD LOPLNT ;09CDH SAVE THAT LXI H,TAB6-1 ;USE 'EXEC' TO LOOK JMP EX0 ;02D8H FOR THE WORD 'STEP' FR2: ;04C3 ; RST 3 ;FOUND IT, GET STEP JMP FR4 ;04CAH FR3: ;04C7 LXI H,1 ;NOT FOUND, SET TO ONE FR4: ;04CA SHLD LOPINC ;09CBH SAVE THAT TOO FR5: ;04CD LHLD CURRNT ;09C1H SAVE CURRENT LINE # SHLD LOPLN ;09CFH XCHG ;AND TEXT POINTER SHLD LOPPT ;09D1H LXI B,0AH ;DIG INTO STACK TO LHLD LOPVAR ;09C9H FIND 'LOPVAR' XCHG MOV H,B MOV L,B ;HL=0 NOW DAD SP ;HC E MVI M,'T' ;54H INX H MVI M,'B' ;42H INX H MVI M,'I' ;49H L03FC: ;03FC INX H ;FILL FROM "TBI" TO 5C6B WITH 00 MVI M,0 MVI A,6BH CMP L JNZ L03FC ;03FCH LXI H,5DH L0408: ;0408 LDAX D CPI 0DH RZ CPI '!' ;21H JC QWHAT ;07E0H CPI 5BH JNC QWHAT ;07E0H MOV M,A INX H INX D MVI A,65H CMP L JNZ L0408 ;0408H RET ; ; ;+++LIST+++& PRINT+++ ; ;LIST HAS 2 FORMS ;'LIST(CR)' LISTS ALL SAVED LINES ;'LIST #(CR)' START LIST AT THIS LINE # ;YOU CAN STOP LIST CAVE IT IN C. RSTO3: JMP PR3 ;045AH LOOK FOR MORE TO PRINT PR1: ;0454 CALL OTSTG ;088BH OR IS IT A STRING? JMP PR8 ;0467H IF NOT, MUST BE EXPR. PR3: ;045A RST 1 ;IF ",", GO FIND NEXT DB ',',(RSTO4-PR3) CALL FIN ;07CDH IN THE LIST RSTO4: JMP PR0 ;044CH CALL CRLF ;LIST ENDS RST 6 PR8: ;0467 RST 3 ;EVALUATE THE EXPR PUSH B CALL PRTNUM ;08B1H PRINT THE VALUE POP B JMP PR3 ;045AH MORE TO PRINT? ; ; ;+++GOSUB+++& RETURN+++ ; ;'GOSUB EXPR;' OR 'GOSUB EXPR (CR)' IS LCJFOR VAR=EXP1 TO EXP2 STEP EXP3' AND 'FOR VAR=EXP1 TO EXP2' ;(WHERE EXP3 ASSUME 1). ;TB1 WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE ;CURRENT VALUE OF EXP1. IT ALSO EVALUATES EXP2 AND EXP3 ;AND SAVE ALL TOGATHER WITH THE TEXT POINTER ETC. IN ;THE 'FOR' SAVE AREA. WHICH CONSISTS OF 'LOPVAR', 'LOPINC', ;'LOPLMT', 'LOPLN', AND 'LOPPT'. IF THERE IS ALREADY SOMETHING ;IN THE SAVE AREA (THIS IS INDICATED BY A NON-ZERO ;'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK ;BEFORE THE DDSERE IS THE STACK DB '>' FR7: ;04E2 DAD B ;EACH LEVEL IS 10 DEEP MOV A,M ;GET THAT OLD 'LOPVAR' INX H ; ORA M JZ FR8 ;0503H ZERO SAYS NO MORE IN IT MOV A,M DCX H CMP D ;SAME AS THIS ONE? JNZ FR7 ;04E2H MOV A,M ;THE OTHER HALF? CMP E JNZ FR7 ;04E2H XCHG ;YES, FOUND ONE LXI H,0 DAD SP ;TRY TO MOVE SP MOV B,H MOV C,L LXI H,0AH DAD D CALL MVDOWN ;0909H AND PURGE 10 WORDS SPHL ;IN THE STACK FR8: ;0503 LHLD LOPPT ;09D1H JOB DONE RESTORE DE XCHG RST 6 ;AND CD IS LIKE THE 'PRINT' COMMAND, AND IS FOLLOWED ;BY A LIST OF ITEMS. IF THE ITEM IS A STRING IN SINGLE OR ;DOUBLE QUOTES, OR IS A BACK-ARROW, IT HAS THE SAME EFFECT AS ;IN 'PRINT'. IF AN ITEM IS A VARIABLE, THIS VARIABLE NAME IS ;PRINTED OUT FOLLOWED BY A COLON. THEN TBI WAITS FOR AN ;EXPR. TO BE TYPED IN THE VARIABLE IS THEN SET TO THE ;VALUE OF THIS EXPR. IF THE VARIABLE IS PROCEDED BY A STRING. ; ;(AGIAN IN SINGLE OR DOUBLE QUOTES), THE STRING WILL BE ;PRINTED FOLLOWED BY A COLON. TBI THD SHLD CURRNT ;09C1H AS A FLAG LXI H,0 ;SAVE SP TOO DAD SP SHLD STKINP ;09C7H PUSH D ;OLD HL MVI A,':' ;3AH CALL GETLN ;0814H AND GET A LINE IP33: ;05A9 LXI D,BUFFER ;0F37H POINTS TO BUFFER RST 3 ;EVALUATE INPUT NOP ;CAN BE 'CALL ENDCHK' NOP NOP POP D ;OK, GET OLD HL XCHG MOV M,E ;SAVE VALUE IN VAR. INX H MOV M,D POP H ;GET OLD 'CURRNT' SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER IP4: ;05BA POP PSW ;PURGE JUNK IN STACK RST 1 ;IS NEXT CH. ',' DB ',' DB D ARE IGNORED AND EXECUTION ;CONTINUES AT THE NEXT LINE. ; ;'INPUT' COMMAND IS LIKE THE 'PRINT' COMMAND, AND IS FOLLOWED ;BY A LIST OF ITEMS. IF THE ITEM IS A STRING IN SINGLE OR ;DOUBLE QUOTES, OR IS A BACK-ARROW, IT HAS THE SAME EFFECT AS ;IN 'PRINT'. IF AN ITEM IS A VARIABLE, THIS VARIABLE NAME IS ;PRINTED OUT FOLLOWED BY A COLON. THEN TBI WAITS FOR AN ;EXPR. TO BE TYPED IN THE VARIABLE IS THEN SET TO THE ;VALUE OF THIS EXPR. IF THE VARIABLE IS PROCEDED BY A STRING. ; ;(AGIAN IN SINGDONTINUE NEXT: ;0508 RST 7 ;GET ADDRESS OF VAR JC QWHAT ;07E0H NO VARIABLE, "WHAT?" SHLD VARNXT ;09C5H YES SAVE IT NX0: ;050F PUSH D ;SAVE TEXT POINTER XCHG LHLD LOPVAR ;09C9H GET VAR IN 'FOR' MOV A,H ORA L ;0 SAYS NEVER HAD ONE JZ AWHAT ;07E1H SO WE ASK "WHAT?" RST 4 ;ELSE WE CHECK THEM JZ NX3 ;0527H OK, THEY AGREE POP D ;NO, LETS SEE CALL POPA ;0918H PURGE CURRENT LOOP LHLD VARNXT ;09C5H AND POP ONE LEVEL JMP NX0 ;050FH GO CHECK AGAIN NX3: ;0527 MOV E,M ;COME HERE WD_EN WAITS FOR INPUT EXPR. ; ;IF THE INPUT EXPR. IS INVALID, TBI WILL PRINT "WHAT?", ;"HOW?" OR "SORRY" AND REPRINT THE PROMPT AND REDO THE INPUT. ;THE EXECUTION WILL NOTT TERMINATE UNLESS YOU TYPE CONTROL-C. ;THIS IS HANDLED IN 'INPERR'. ; ;'LET' IS FOLLOWED BY A LIST OF ITEMS SEPERATED BY COMMAS ;EACH ITEM CONSISTS OF A VARIABLE, AN EQUAL SIGN, AND AN EXPR. ;TBI EVALUATES THE EXPR. AND SETS THE VARIABLE TO THAT VALUE ;TBI WILL ALSO HANDLE 'LET' COMMAND WITHOUT THE WORD 'LET' ;THIS IS DD3 JMP IP1 ;0572H YES, MORE ITEMS IP5: ;05C1 RST 6 DEFLT: ;05C2 LDAX D ;+++DEFLT+++ CPI 0DH ;(CR) EMPTY LINE IS OK JZ LT1 ;05D1H ELSE IT IS 'LET' LET: ;05C8 CALL SETVAL ;07BAH +++LET+++ RST 1 ;SET VALUE TO VAR. DB ',',3 JMP LET ;05C8H ITEM BY ITEM LT1: ;05D1 RST 6 ;UNTIL FINISH ; ; ;+++EXPR+++ ; ;'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS ;= ; ;WHERE IS ONE OF THE OPERATORS IN TABS AND THE ;RESULT ODLE OR DOUBLE QUOTES), THE STRING WILL BE ;PRINTED FOLLOWED BY A COLON. TBI THEN WAITS FOR INPUT EXPR. ; ;IF THE INPUT EXPR. IS INVALID, TBI WILL PRINT "WHAT?", ;"HOW?" OR "SORRY" AND REPRINT THE PROMPT AND REDO THE INPUT. ;THE EXECUTION WILL NOTT TERMINATE UNLESS YOU TYPE CONTROL-C. ;THIS IS HANDLED IN 'INPERR'. ; ;'LET' IS FOLLOWED BY A LIST OF ITEMS SEPERATED BY COMMAS ;EACH ITEM CONSISTS OF A VARIABLE, AN EQUAL SIGN, AND AN EXPR. ;TBI EVALUATES THE EXPR. AND SETS THE VARIABLE TO THATD UDIVIDE: ;0786 +++DIVIDE+++ PUSH H MOV L,H ;DIVIDE H BY DE MVI H,0 CALL DV1 ;0791H MOV B,C ;SAVE RESULTS IN B MOV A,L ;(REMAINDER+L)/DE POP H MOV H,A DV1: ;0791 MVI C,0FFH ;RESULT IN C DV2: ;0793 INR C ;DUMB ROUTINE CALL SUBDFE ;079CH DIVIDE BY SUBTRACT JNC DV2 ;0793H AND COUNT DAD D RET @D xONE BY 'DEFLT' ; ; REM: ;0555 +++REM+++ LXI H,0 DB '>' IFF: ;0559 +++IF+++; RST 3 MOV A,H ;IS THE EXPR. =0? ORA L JNZ RUNSML ;032BH NO, CONTINUE CALL FNDSKP ;0875H YES, SKIP REST OF LINE JNC RUNTSL ;0324H JMP RSTART ;0181H INPERR: ;0568 +++INPERR+++ LHLD STKINP ;09C7H SPHL ;RESTORE OLD SP POP H SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER POP D ;REDO INPUT IP1: ;0572 +++INPUT+++ PUSH D ;SAVE IN CASE OF ERROR CALL OTSTG ;088BH IS NEXTITEM A STRING? JMPD HEN AGREED INX H ; MOV D,M ;DE=VALUE OF VAR LHLD LOPINC ;09CBH PUSH H DAD D NX4: ;052F XCHG LHLD LOPVAR ;09C9H PUT IT BACK MOV M,E INX H MOV M,D LHLD LOPLNT ;09CDH HL=LIMIT POP PSW ;OLD HL ORA A JP NX1 ;053FH STEP > 0 XCHG NX1: ;053F CALL CKHLDE ;07B2H COMPARE WITH LIMIT POP D ;RESTORE TEXT POINTER JC NX2 ;0551H OUTSIDE LIMIT LHLD LOPLN ;09CFH WITHIN LIMIT, GO SHLD CURRNT ;09C1H BACK TO THE SAVED LHLD LOPPT ;09D1H 'CURRNT' AND TEXT XCHG ;POINTER RST 6 ND  VALUE ;TBI WILL ALSO HANDLE 'LET' COMMAND WITHOUT THE WORD 'LET' ;THIS IS DONE BY 'DEFLT' ; ; REM: ;0555 +++REM+++ LXI H,0 DB '>' IFF: ;0559 +++IF+++; RST 3 MOV A,H ;IS THE EXPR. =0? ORA L JNZ RUNSML ;032BH NO, CONTINUE CALL FNDSKP ;0875H YES, SKIP REST OF LINE JNC RUNTSL ;0324H JMP RSTART ;0181H INPERR: ;0568 +++INPERR+++ LHLD STKINP ;09C7H SPHL ;RESTORE OLD SP POP H SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER POP D ;REDO INPUT IP1: ;0572 +++INPUT+++D INPUT+++& LET (& DEFLT)+++ ; ;'REM' CAN BE FOLLOWED BY ANYTHING AND IS IGNORED BY TBI. ;TBI TREATS IT LIKE AN 'IF' WITH A FALSE CONDITION. ; ;'IF' IS FOLLOWED BY AN EXPR. AS A CONDITION AND ONE OR MORE ;COMMANDS (INCLUDING OTHER 'IF'S) SEPERATED BY SEMI-COLONS. ;NOTE THAT THE WORD 'THEN' IS NOT USED. TBI EVALUATES THE ;EXPR. IF IT IS NON-ZERO, EXECUTION CONTINUES. IF THE EXPR. ;IS ZERO, THE COMMANDS THAT FOLLOW ARE IGNORED AND EXECUTION ;CONTINUES AT THE NEXT LINE. ; ;'INPUT' COMMANDD IP2 ;0580H NO RST 7 ;YES, BUT FOLLOWED BY A JC IP4 ;05BAH VARIABLE? NO. JMP IP3 ;0590H YES INPUT VARIABLE IP2: ;0580 PUSH D ;SAVE FOR 'PRTSTG' RST 7 ;MUST BE VARIABLE NOW JC QWHAT ;07E0H 'WHAT?' IT IS NOT? LDAX D ;GET READY FOR 'PRTSTG' MOV C,A SUB A STAX D POP D CALL PRTSTG ;087FH PRINT STRING AS PROMPT MOV A,C ;RESTORE TEXT DCX D STAX D IP3: ;0590 PUSH D ;SAVE TEXT POINTER XCHG LHLD CURRNT ;09C1H ALSO SAVE 'CURRNT' PUSH H ; LXI H,IP1 ;0572H A NEGATIVE NUMBER DX2: ;0551 CALL POPA ;0918H PURGE THIS LOOP RST 6 ; ; ;+++REM+++IF+++INPUT+++& LET (& DEFLT)+++ ; ;'REM' CAN BE FOLLOWED BY ANYTHING AND IS IGNORED BY TBI. ;TBI TREATS IT LIKE AN 'IF' WITH A FALSE CONDITION. ; ;'IF' IS FOLLOWED BY AN EXPR. AS A CONDITION AND ONE OR MORE ;COMMANDS (INCLUDING OTHER 'IF'S) SEPERATED BY SEMI-COLONS. ;NOTE THAT THE WORD 'THEN' IS NOT USED. TBI EVALUATES THE ;EXPR. IF IT IS NON-ZERO, EXECUTION CONTINUES. IF THE EXPR. ;IS ZERO, THE COMMANDS THAT FOLLOWEDE; PUSH D ;SAVE IN CASE OF ERROR CALL OTSTG ;088BH IS NEXTITEM A STRING? JMP IP2 ;0580H NO RST 7 ;YES, BUT FOLLOWED BY A JC IP4 ;05BAH VARIABLE? NO. JMP IP3 ;0590H YES INPUT VARIABLE IP2: ;0580 PUSH D ;SAVE FOR 'PRTSTG' RST 7 ;MUST BE VARIABLE NOW JC QWHAT ;07E0H 'WHAT?' IT IS NOT? LDAX D ;GET READY FOR 'PRTSTG' MOV C,A SUB A STAX D POP D CALL PRTSTG ;087FH PRINT STRING AS PROMPT MOV A,C ;RESTORE TEXT DCX D STAX D IP3: ;0590 PUSH D ;SAVE TEXT POINTER XCHG LHLD CE+ CAN BE AN IN PARENTHESES. ; ; EXPR CALL EXPR2 THIS IS AT LOC. 18 ; PUSH HL ; ; EXPR1: ;05D2 LXI H,TAB8-1 ;02BEH LOOK UP REL. OP. JMP EX0 ;02D8H GO DO IT XP11: ;05D8 CALL XP18 ;0601H REL. OP. ">=" RC ;NO, RETURN HL=0 MOV L,A ;YES,RETURN HL=1 RET XP12: ;05DE REL OF "#" CALL XP18 ;0601H RZ ;FALSE, RETURN HL=0 MOV L,A ;TRUE, RETURN HL=1 RET XP13: ;05E4 CALL XP18 ;0601H REL OP. ">" RZ ;FALSE RC ;ALSO FALSE HL=0 MOV L,A ;TRUE HL=1 RET XP14:ED THEM EXPR3: ;064A CALL EXPR4 ;06A7H GET 1ST XP31: ;064D RST 1 ;MULTIPLY? DB '*',(RSTO11-XP31) PUSH H ;YES, SAVE 1ST CALL EXPR4 ;06A7H AND GET 2ND MVI B,0 ;CLEAR B FOR SIGN CALL CHKSGN ;07A3H CHECK SIGN XCHG ;1ST IN HL XTHL CALL CHKSGN ;07A3H CHECK SIGN OF 1ST MOV A,H ;IS HL >255 ? ORA A JZ XP32 ;0669H NO MOV A,D ;YES, HOW ABOUT DE ORA D XCHG ;PUT SMALLER IN HL JNZ AHOW ;0167H ALSO >, WILL OVERFLOW XP32: ;0669 MOV A,L ;THIS IS DUMB LXI H,0 ;CE 4 JC RA1 ;06E2H RAP AROUND IF LAST LXI H,BEGIN ;0100H RA1: ;06E2 MOV E,M INX H MOV D,M SHLD RANPNT ;09D3H POP H XCHG PUSH B CALL DIVIDE ;0786H RND(N)=MOD(M,N)+1 POP B POP D INX H RET ABS: ;06F2 +++ABS(EXPR) CALL PARN ;06BCH CALL CHKSGN ;07A3H CHECK SIGN MOV A,H ORA H JM QHOW ;0166H RET ;LOG2.ASM JUNE 24, 1984 ;CONVERTS 16 BIT NUMBER IN HL TO 1024*LOG(BASE2)OF N0. ;RETURNS IN HL ;CONVERTS 1024*LOG(BASE2)OF NUMBER TO NUMBER (ANTILOG) ;RETURNS E"URRNT ;09C1H ALSO SAVE 'CURRNT' PUSH H ; LXI H,IP1 ;0572H A NEGATIVE NUMBER SHLD CURRNT ;09C1H AS A FLAG LXI H,0 ;SAVE SP TOO DAD SP SHLD STKINP ;09C7H PUSH D ;OLD HL MVI A,':' ;3AH CALL GETLN ;0814H AND GET A LINE IP33: ;05A9 LXI D,BUFFER ;0F37H POINTS TO BUFFER RST 3 ;EVALUATE INPUT NOP ;CAN BE 'CALL ENDCHK' NOP NOP POP D ;OK, GET OLD HL XCHG MOV M,E ;SAVE VALUE IN VAR. INX H MOV M,D POP H ;GET OLD 'CURRNT' SHLD CURRNT ;09C1H POP D ;AND OLD TEXT POINTER IP4EJ ;05EB CALL XP18 ;0601H REL. OP. "<=" MOV L,A ;SET HL=1 RZ ;REL. TRUE, RETURN RC MOV L,H ;ELSE SET HL=0 RET XP15: ;05F3 CALL XP18 ;0601H REL. OP. "=" RNZ ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP16: ;05F9 CALL XP18 ;0601H REL. OP. "<" RNC ;FALSE, RETURN HL=0 MOV L,A ;ELSE SET HL=1 RET XP17: ;05FF POP H ;NOT REL. OP. RET ;RETURN HL= XP18: ;0601 MOV A,C ;SUBROUTINE FOR ALL POP H ;REL. OP.'S POP B ;REVERSE TOP OF STACK PUSH H PUSH B MELEAR RESULT ORA A ;ADD AND COUNT JZ XP25 ;0699H XP33: CALL MULTIPLY JNZ XP33 RSTO11: JMP XP25 ;0699H FINISHED XP34: ;067C RST 1 ;DIVIDE? DB '/',(RSTO10-XP34) PUSH H ;YES, SAVE 1ST CALL EXPR4 ;06A7H AND GET 2ND ONE MVI B,0 ;CLEAR B FOR SIGN CALL CHKSGN ;07A3H CHECK SIGN OF 2ND XCHG ;GET 1ST IN HL XTHL CALL CHKSGN ;07A3H CHECK SIGN OF 1ST MOV A,D ;DIVIDE BY 0 ? ORA E JZ AHOW ;0167H SAY "HOW" PUSH B ;ELSE SAVE SIGN CALL DIVIDE ;0786H USE SUBROUTINE MOV H,EIN HL ; ; LOG2: ;CONVERTS NO. IN HL TO LOG2 CALL PARN ;FIND AND EVALUATE THE PARENTHISIS CALL CHKSGN ;GET THE ABLOLUTE VALUE OF THE NUMBER ; ; LOGG: ;LOG CONVERSION PUSH B ;PUSH THE REGISTERS PUSH D MOV A,H ORA A JNZ LOGCHR MOV A,L ORA A JNZ LOGCHR LXI H,54273 ;MAKE LOG2(0)=-11263 (LOG2(1/2047)) AND RETURN POP D POP B RET ; ; LOGCHR: ;NO. IS NOT ZERO MVI B,16 ;FIND THE CHARACTERISTIC LSH1: DCR B DAD H ;SHIFT NO. LEFT JNC LSH1 ;UNTIL CARRY MOV A,B ;LEFT E : ;05BA POP PSW ;PURGE JUNK IN STACK RST5: RST 1 ;IS NEXT CH. ',' DB ',' DB (RSTO5-RST5) RSTO5: JMP IP1 ;0572H YES, MORE ITEMS IP5: ;05C1 RST 6 DEFLT: ;05C2 LDAX D ;+++DEFLT+++ CPI 0DH ;(CR) EMPTY LINE IS OK JZ LT1 ;05D1H ELSE IT IS 'LET' LET: ;05C8 CALL SETVAL ;07BAH +++LET+++ RST6: RST 1 ;SET VALUE TO VAR. DB ',',(RSTO6-RST6) RSTO6: JMP LET ;05C8H ITEM BY ITEM LT1: ;05D1 RST 6 ;UNTIL FINISH ; ; ;+++EXPR+++ ; ;'EXPR' EVALUATES ARITHMETICAL OR LOGICAL E qOV C,A CALL EXPR2 ;0616H GET 2ND XCHG ;VALUE OF DE NOW XTHL ;1ST IN HL CALL CKHLDE ;07B2H COMPARE FIRST WITH 2ND POP D ;RESTORE TEXT POINTER LXI H,0 ;SET HL=0 , A=1 MVI A,1 RET EXPR2: ;0616 RST 1 ;NEGATIVE SIGN? DB '-',(RSTO7-EXPR2) LXI H,0 ;YES, FAKE '0-' RSTO7: JMP XP26 ;0640H TREAT LIKE SUBTRACT XP21: ;061F RST 1 ;POSITIVE SIGN? IGNORE DB '+',0 XP22: ;0622 CALL EXPR3 ;064AH 1ST XP23: ;0625 RST 1 ;ADD? DB '+',(RSTO9-XP23) PUSH H ;E B ;RESULT IN HL NOW MOV L,C POP B ;GET SIGN BACK XP25: ;0699 POP D ;AND TEXT POINTER MOV A,H ;HL MUST BE + ORA A JM QHOW ;0166H OVERFLOW MOV A,B ORA A CM CHGSGN ;07A6H CHANGE SIGN IF NEEDED JMP XP31 ;064DH LOOK FOR MORE TERMS EXPR4: ;06A7 FIND FUNCTION IN TAB4 LXI H,TAB4-1 ;027EH JMP EX0 ;02D8H AND GO DO IT XP40: ;06AD RST 7 ;NO, NOT A FUNCTION JC XP41 ;06B6H NOR A VARIABLE MOV A,M ;VARIABLE INX H MOV H,M ;VALUE IN HL MOV L,A RET XP41: ;06B6 CALL TSTNUM ;0E SHIFT THE CHARACTERISTIC, 2 BITS ORA A ;CLEAR CARRY RAL RAL MOV B,A PUSH B ;SAVE THE CHARACTERISTIC TO THE STACK ; ; MVI B,6 ;POSITION THE UNCORRECTED MANTISSA CALL MANTIS JMP LTABAD ; MANTIS: ;SHIFT HL B BITS TO THE RIGHT MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A DCR B JNZ MANTIS RET ; ; LTABAD: PUSH H ;SAVE THE UNCORRECTED MANTISSA MOV A,L ;GET THE INTERPOLATOR ANI 15 STA INTSCR ;AND STORE IT IN THE SCRATCH PAD MVI B,4 ;SHIFT THE UNCORRECTED MANTE EXPRESSIONS ;= ; ;WHERE IS ONE OF THE OPERATORS IN TABS AND THE ;RESULT OF THESE OPERATIONS IS 1 IF TRUE AND 0 IF FALSE. ;::=(+ OR -)(+ OR -)(....) ;WHERE <> ARE OPTIONAL AND (....) ARE OPIONAL REPEATS ;::=(< OR />)(....) ;::= ; ;() ; IS RECURSIVE SO THAT VARIABLE '@' CAN HAVE AN ;AS INDEX, FUNCTIONS CAN HAVE AN AS ARGUMENTS, AND ;EYES, SAVE VALUE CALL EXPR3 ;064AH GET 2ND XP24: ;062C XCHG ;2ND IN DE XTHL ;1ST IN HL MOV A,H ;COMPARE SIGN XRA D MOV A,D DAD D POP D ;RESTORE TEXT POINTER JM XP23 ;0625H 1ST 2ND SIGN DIFFER XRA H ;1ST 2ND SIGN EQUAL JP XP23 ;0625H SO IS RESULT RSTO9: JMP QHOW ;0166H ELSE WE HAVE OVERFLOW RST10: RST 1 ;SUBTRACT? DB '-',(RSTO10-RST10) XP26: ;0640 PUSH H ;YES, SAVE 1ST CALL EXPR3 ;064AH GET 2ND /PR3> CALL CHGSGN ;07A6H NEGATE JMP XP24 ;062CH AND ADER13EH OR IS IT A NUMBER MOV A,B ;# OF DIGIT ORA A RNZ ;OK PARN: ;06BC RST 1 ;NO DIGIT, MUST BE DB '(' ;28H DB (RSTO13-PARN) RST 3 ;"" RSTO10: RST 1 RSTO13: DB ')' DB 1 XP42: ;06C3 RET XP43: ;06C4 JMP QWHAT ;07E0H ELSE SAY WHAT RND: ;06C7 +++RND(EXPR)+++ CALL PARN ;06BCH MOV A,H ;EXPR MUST BE + ORA A JM QHOW ;0166H ORA L ;AND NON-ZERO JZ QHOW ;0166H PUSH D ;SAVE BOTH PUSH H LHLD RANPNT ;09D3H GET MEMORY AS RANDOM LXI D,LSTROM ;09B0H NUMBER RSTFFISSA RIGHT 4 BITS CALL MANTIS ;TO FORM THE CORRECTION TABLE POINTER LXI D,LOGTAB;TABLE ADDRESS DAD D ;ADD IT TO HL SHLD (INTSCR+1) ;STORE THE POINTER IN THE INTERP.SCRATCH PAD CALL INTERP ; LXI H,(INTSCR+4) MOV E,M ;RECOVER THE CORRECTOR FROM THE SCRATCH PAD MVI D,0 POP H ;RECOVER THE UNCORRECTED MANTISSA POP B ;RECOVER THE UNCORRECTED CHARACTERISTIC MVI C,0 DAD D ;ADD CORRECTOR DAD B ;ADD CHARACTERISTIC LXI D,1 DAD D ;ADD ONE TO THE LOG POP D POP B RET ;LOG CONVERSION FS ;DO THE SHIFTS MOV A,H ORA A JP ALGFIN JMP QHOW ;ANTILOG OUT OF RANGE, ERROR ALGFIN: POP D POP B RET ;ANTILOG DONE ; ;INTERPOLATOR EVALUATES POINTER+((POINTER+1)-(POINTER))*INTERPOLATOR/16) ; INTERP: ;INTERPOLATOR FOR 10 BIT MANTISSA MVI A,0 ;CLEAR THE SIGN BYTE STA (INTSCR+3) ; LHLD (INTSCR+1) ;LOAD THE TABLE POINTER MOV B,M ;(POINTER) TO B INX H MOV A,M ;(POINTER+1) TO A CMP B ;DETERMIN THE INTERPOLATION POLARITY JP ABSPON ;I.E. ACENDING OR DECENDING CORRECTORS MOVF DB 52 DB 49 DB 46 DB 43 DB 39 DB 36 DB 32 DB 28 DB 25 DB 21 DB 17 DB 12 DB 8 DB 4 DB 0 ; ; ; TABLE FOR ANTILOG CORRECTIONS WITH 10 BIT MANTISSA ; ALTAB: DB 0 DB 4 DB 9 DB 14 DB 18 DB 23 DB 27 DB 31 DB 35 DB 39 DB 42 DB 46 DB 49 DB 53 DB 56 DB 59 DB 62 DB 64 DB 67 DB 70 DB 72 DB 74 DB 76 DB 78 DB 80 DB 81 DB 82 DB 84 DB 85 DB 86 DB 86 DB 87 DB 87 DB 88 DB 88 DB 88 DB 87 DB 87 DB 86 DB 85 DB 84FT22) PUSH H RST 3 RST23: RST 1 DB ')' DB (RSTO20-RST23) POP B PUSH D LXI D,POPDEHL ;0780H PUSH D RSTO20: PUSH B RET POPDEHL: ;0780 POP D POP B RET JMP QWHAT ;07E0H ; ; ;+++MULTIPLY+++DIVIDE+++SUBDE+++CHKSGN+++& CKHLDE+++ ; ;'MULTIPLY' MULTIPLIES A BY DE. RESULT IN HL ; ;'DIVIDE' DIVIDES HL BY DE. RESULT IN BC. REMAINDER IN HL. ; ;'SUBDE' SUBTRACTS DE FROM HL. ; ;'CHKSGN' CHECKS SIGN OF HL. IF +, NO CHANGE. IF -, CHANGE ;SIGN AND FLIP SIGN OF B. ; FCOMPLETE ; ; ;ALOG2 ;RETURNS THE BASE 2 ANTILOG ; ALOG2: CALL PARN ;EVALUATE PARENTHISIS ; ALOG: PUSH B ;PUSH REGISTERS PUSH D MOV A,H ;IS CHARACTERISTIC ZERO OR MINUS ANI 252 JNZ LOGNEG ;IF ZERO, RETURN HL=1 XRA A MOV H,A MOV L,A INR L ;RETURN 1 POP D POP B RET ; LOGNEG: ;ANTILOG OF MINUS, RETURN HL=0 MOV A,H ANI 128 JZ MLOG XRA A MOV H,A MOV L,A ;CLEAR HL POP D POP B RET ; MLOG: ;IS THE CHARACTERISTIC OUT OF RANGE? MVI A,60 CMP H F C,A ;NEG, SWAP A&B, SET THE SIGN BYTE TO 1 MVI A,1 STA (INTSCR+3) MOV A,B MOV B,C ; ABSPON: SUB B ;ABS((POINTER+1)-(POINTER)) MOV E,A ; ; MVI D,0 ;MULTIPLY BY THE INTERPOLATOR LXI H,0 MOV E,A LDA INTSCR ;LOAD THE INTERPOLATOR FROM THE SCRATCH PAD MVI B,8 ;SIZE OF MULTIPLIER ; ; MULT: DAD H RAL JNC CHCNT DAD D ;ADD IF CARRY IS 1 ; CHCNT: DCR B JNZ MULT ;LOOP UNTIL B=0 ; ; DIVIDE BY 16 ; MVI B,4 ;RIGHT SHIFT 4 BITS CALL MANTIS XCHG ;POINTER ADJUSTMENT IS IF( DB 83 DB 82 DB 80 DB 78 DB 76 DB 74 DB 72 DB 69 DB 67 DB 64 DB 60 DB 57 DB 54 DB 50 DB 46 DB 41 DB 37 DB 32 DB 27 DB 22 DB 17 DB 11 DB 6 DB 0 ; ; END OF ANTILOG TABLE ; SIZE: ;06FE +++SIZE+++ LHLD TXTUNF ;09D5H PUSH D ;GET THE NUMBER OF FREE XCHG ;BYTES BETWEEN 'TXTUNF' SIZE1: ;0703 'VARBGN' LXI H,VARBGN ;0F00H CALL SUBDE ;079CH POP D RET OUT1: ;070B RST 3 MOV A,L STA LSTROM+1 ;09B1H RST14: RST 1 DB 2CH DB (RSTO14-RSTF) ;'CHGSGN' CHANGES THE SIGN OF HL AND B UNCONDITIONALLY. ; ;'CKHLDE' CHECKS THE SIGN OF HL AND DE, IF DIFFERENT, HL AND DE ;ARE INTERCHANGED. IF SAME SIGN, NOT INTERCHANGED. EITHER ;CASE, HL DE ARE THEN COMPARED TO SET THE FLAGES. ; ; ; MULTIPLY: MVI C,8 ;MULTIPLIER IN A, MULTIPLICAND IN DE, PRODUCT IN HL MULTI: DAD H ;SHIFT LEFT PRODUCT. ** LOOP COUNTER IN C. ** SIGN IN B RAL ;SHIFT LEFT MULTIPLIER JNC CHCNTI ;GO ON IF CARRY=0 DAD D ;ADD MULTIPLICAND TO PRODUCT IF CARRY=1 CHCNTI: F CJM QHOW ;YES, ERROR ; MOV A,H ORA A ;CLEAR CARRY RAR ;REPOSITION THE CHARACTERISTIC 2 BITS RIGHT ORA A RAR MOV B,A ;PUT CHARACTERISTIC IN B PUSH B ;SAVE IT ; ; MOV A,H ;CLEAR THE CHARACTERISTIC FROM HL ANI 3 MOV H,A PUSH H ;SAVE THE MANTISSA ; ; MOV A,L ;FIND THE INTERPOLATOR ANI 15 STA INTSCR ;SAVE THE INTERPOLATOR IN THE SCRATCH PAD ; ; MVI B,4 ;GENERATE THE POINTER CALL MANTIS ;RIGHT SHIFT THE MANTISSA, 4 BITS LXI D,ALTAB ;ANTILOG TABLE ADDRESS DAD D ;HL> (POINF N DE ; LXI H,(INTSCR+3) ;GET THE SIGN MOV A,M ORA A JNZ INTREV ;IS IT + LHLD (INTSCR+1) ;YES, ADD DE MOV A,M MOV L,A MVI H,0 DAD D MOV A,L LXI H,(INTSCR+4) ;STORE IN SCRATCH PAD MOV M,A RET ; ; THE SIGN IS - ; INTREV: LHLD (INTSCR+1) ;POINTER MOV A,M SUB E LXI H,(INTSCR+4) ;STORE THE CORRECTOR IN THE SCRATCH PAD MOV M,A RET ; ; ; INTERPOLATION SCRATCH PAD INTSCR: DB 0 ;INTERPOLATOR DB 0 ;POINTER L (+1) DB 0 ;POINTER H (+2) DB 0 ;SIGN OF ABOVE (F 14) RST 3 MOV A,L CALL LSTROM ;09B0H RST15: RST 1 DB 2CH DB (RSTO15-RST15) RSTO15: JMP OUT1 ;070BH RST 6 WAIT: RST 3 MOV A,L STA WAITCOM+1 ;09B4H RST16: RST 1 DB 2CH DB (RSTO14-RST16) RST 3 PUSH H RST17: RST 1 DB 2CH DB (FUNJP-RST17) RST 3 MOV A,L POP H MOV H,A ;FUNJP IS NOT UNDERSTOOD ; FUNJP: ;0730 JMP FUNJP+2 ;0732H MVI H,0 JMP WAITCOM ;09B3H INP: CALL PARN ;06BCH MOV A,L STA INCOMM+1 ;09BCH RSTO14: MVI H,0 JMP INCOMM ;09BBH JF `DCR C ;GO TO THE NEXT BIT JNZ MULTI RET ;FINISHED ; DIVIDE: ;0786 +++DIVIDE+++ PUSH D ;SAVE THE DIVISOR XCHG ;DIVISOR IN HL, DIVIDEND IN DE MVI B,1 ;CLEAR THE B REGISTER DV1: ;LEFT JUSTIFY THE DIVISOR DAD H ;LEFT SHIFT THE DIVISOR INR B ;COUNT THE SHIFTS MOV A,H ;TEST FOR MSB ORA A JP DV1 ; MOV A,B ;STORE THE SHIFT COUNT ON THE STACK LXI B,0 ;CLEAR BC FOR THE QUOTIENT DV2: ;DIVISOR > DIVIDEND? PUSH PSW MOV A,D CMP H ;IS IT GREATER JC DV4 ;SKIP IF NOT JNZ DV3 ;ISF TER) SHLD (INTSCR+1) ;STORE THE TABLE POINTER IN THE SCRATCH PAD CALL INTERP ;CALL THE INTERPOLATOR POP H ;RECOVER THE MANTISSA LDA (INTSCR+4) ;GET THE CORRECTOR ; ; MVI C,0 MOV B,A ;SUBTRACT CORRECTOR FROM HL MOV A,L SUB B MOV L,A MOV A,H SBB C ADI 4 ;ADD BACK THE LEADING 1 MOV H,A DAD H ;SHIFT LEFT HL 5 BITS DAD H DAD H DAD H DAD H POP B ;RECOVER THE CHARACTERISTIC MVI A,15 ;JUSTIFY THE NUMBER SUB B MOV B,A ;B=N0. OF RIGHT SHIFTS NEEDED TO JUSTIFY CALL MANTIF+3) DB 0 ;CORRECTOR (+4) ; ; ; CORRECTOR TABLE FOR LOG2 WITH 10 BIT MANTISSA ; LOGTAB: ;LOG CORRECTORS DB 0 DB 6 DB 13 DB 19 DB 25 DB 31 DB 36 DB 41 DB 46 DB 50 DB 54 DB 58 DB 61 DB 65 DB 68 DB 71 DB 73 DB 76 DB 78 DB 80 DB 81 DB 83 DB 84 DB 85 DB 86 DB 87 DB 87 DB 87 DB 88 DB 88 DB 87 DB 87 DB 87 DB 86 DB 85 DB 84 DB 83 DB 82 DB 80 DB 78 DB 77 DB 75 DB 73 DB 71 DB 69 DB 66 DB 64 DB 61 DB 58 DB 55 FMP QWHAT ;07E0H POKE: ;0747 RST 3 PUSH H RST18: RST 1 DB 2CH DB (RSTO18-RST18) RST 3 MOV A,L POP H MOV M,A RST19: RST 1 DB 2CH DB (RSTO19-RST19) RSTO19: JMP POKE ;0747H RST 6 PEEK: CALL PARN ;06BCH MOV L,M RSTO18: MVI H,0 RET JMP QWHAT ;07E0H USR: PUSH B RST20: RST 1 DB '(' ;28H DB (RSTO20-RST20) RST 3 RST21: RST 1 DB ')' DB (RSTO21-RST21) PUSH D LXI D,POPDEHL ;0780H RSTO21: PUSH D PUSH H RET RST22: RST 1 DB 2CH DB (RSTO20-RSGVG IT ZERO? MOV A,E ;YES, COMPARE LOWER BYTE CMP L JC DV4 ;SKIP IF GREATER ; DV3: ;SUBTRACT HL FROM DE RESULT IN DE MOV A,E SUB L MOV E,A MOV A,D SBB H MOV D,A ; MOV A,C ;LEFT SHIFT THE QUOTIENT ORA A RAL MOV C,A MOV A,B RAL MOV B,A INX B ;ADD ONE TO THE QUOTIENT JMP DV5 ; DV4: MOV A,C ;LEFT SHIFT THE QUOTIENT ORA A RAL MOV C,A MOV A,B RAL MOV B,A ; DV5: ;RIGHT SHIFT THE DIVISOR MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A POP PSW ;G>NEGATIVE # (INDICATING INPUT ;COMMAND, THE INPUT LINE IS NOT PRINTED AND EXICUTION IS ;NOT TERMINATED BUT CONTINUED AT 'INPEPR'. ; ;RELATED TO 'ERROR' ARE THE FOLLOWING: ;'QWHAT' SAVES TEXT POINTER IN STACK AND GET MESSAGE "WHAT?" ;'AWHAT' JUST GET MESSAGE "WHAT?" AND JUMP TO ERROR. ;'QSORRY' AND 'ASORRY' DO THE SAME KIND OF THING. ;'OHOW' AND 'AHOW' IN THE ZERO PAGE SECTION ALSO DO THIS ; ; SETVAL: ;07BA +++SETVAL+++ RST 7 JC QWHAT ;07E0H "WHAT?", NO VARIABLE PUSH H ;SAVE ADDRG)INPUT LINE INTO 'BUFFER'. IT FIRST PROMPTS ;THE CHARACTER IN A (GIVEN BY THE CALLER), THEN IT FILLS THE ;BUFFER AND ECHOS. IT IGNORES LF'S AND NULLS, BUT STILL ;ECHOS THEM BACK. RUB-OUT IS USED TO CAUSE IT TO DELETE ;THE LAST CHARACTER (IF THERE IS ONE), AND ALT-MOD IS USED TO ;CAUSE IT TO DELETE THE WHOLE LINE AND START IT ALL OVER ;CR SIGNALS THE END OF A LINE, AND CAUSE 'GETLN' TO RETURN. ; ;'FNDLN' FINDS A LINE WITH A GIVEN LINE # (IN HL) IN THE ;TEXT SAVE AREA. DE IS USED AS THE TEXT GJ ;0842 MOV A,E ;DELETE LAST CHARACTER (NULL) CPI '7' ;37H BUFFER AND 0FFH JZ GL4 ;084FH NO REDO WHOLE LINE DCX D ;YES, BACKUP POINTER BKSPC: ;BACK SPACE THE CURSER AND DELETE ;THE CHARACTER FROM THE SCREEN MVI A,08H ;AND ECHO A BACK SPACE RST 2 MVI A,20H ;SPACE RST 2 MVI A,08H ;BACK SPACE RST 2 MVI A,08H ;BACK SPACE RST 2 MVI A,20H ;SPACE RST 2 MVI A,08H ;BACK SPACE RST 2 JMP GL1 ;0818H GO GET NEXT INPUT GL4: ;084F ;REDO ENTIRE LINE CALL CRLF MVI A,5EH ;CR,GGET THE SHIFT COUNT BACK DCR A ;DECREMENT THE COUNT JNZ DV2 ;GO TO THE NEXT MSB XCHG ;QUOTIENT IN BC, REMAINDER IN HL, DIVIDEND IN DE POP D RET ; SUBDE: ;079C +++SUBDE+++ MOV A,L SUB E ;SUBTRACT DE FROM MOV L,A ;HL. MOV A,H SBB D MOV H,A RET CHKSGN: ;07A3 +++CHKSGN+++ MOV A,H ORA A ;CHECK SIGN OF HL RP ;IF - ,CHANGE SIGN CHGSGN: ;07A6 +++CHGSGN+++ MOV A,H CMA ;CHANGE SIGN OF HL MOV H,A MOV A,L CMA MOV L,A INX H MOV A,B ;AND ALSO FLIP B XRI 80H MOV GKESS OF VARIABLE RST24: RST 1 DB '=',(RSTO24-RST24) ;PASS "=" SIGN RST 3 ;EVALUATE EXPR. MOV B,H ;VALUE IN BC NOW MOV C,L POP H ;GET ADDRRESS MOV M,C ;SAVE VALUE RSTO24: INX H MOV M,B RET SV1: ;07CA JMP QWHAT ;07E0H NO "=" SIGN FIN: ;07CD +++FIN+++ RST 1 DB ';',(RSTO25-FIN) POP PSW ;";",PURGE RET ADDR. RSTO25: JMP RUNSML ;032BH CONTINUE SAME LINE FI1: ;07D4 RST 1 ;NOT ";", IS IT CR? DB 0DH,(RSTO26-FI1) POP PSW ;YES, PURGE RET ADDR. RSTO26: JMP RUNNXL ;031BH RGPOINTER. IF THE ;LINE IS FOUND, DE WILL POINT TO THE BEGINNING OF THAT LINE ;(I.E. THE LOW BYTE OF THE LINE #), AND FLAGS ARE NC & Z. ;IF THE LINE IS NOT THERE AND A LINE WITH A HIGHER LINE # ;IS FOUND, DE POINTS TO THERE AND FLAGS ARE NC & NZ. IF ;WE REACHED THE END OF TEXT SAVE AREA AND CANNOT FIND THE ;LINE, FLAGS ARE C & NZ. ;'FNDLN' WILL INITIALIZE DE TO THE BEGINNING OF THE TEXT SAVE ;AREA TO START THE SEARCH. SOME OTHER ENTRIES OF THIS ;ROUTINE WILL NOT INITIALIZE DE AND DO THE SEARG LF, AND UP-ARROW JMP GETLN ;0814H FNDLN: ;0857 +++FNDLN+++ MOV A,H ORA A ;CHECK SIGN OF HL JM QHOW ;0166H IT CANNOT BE "-" LXI D,TXTBGN ;09D7H INIT, TEXT POINTER FL1: ;085F +++FNDLP+++ PUSH H ;SAVE LINE # LHLD TXTUNF ;09D5H CHECK IF WE PASSED END DCX H ;GET LINE # BACK RST 4 ;C,NZ PASSED END POP H RC LDAX D ;WE DID NOT, GET BYTE 1 SUB L ;IS THIS THE LINE? MOV B,A ;COMPARE LOW ORDER INX D LDAX D ;GET BYTE 2 SBB H ;COMPARE HIGH ORDER JC FL2 ;0874H NO, NOT THERE YET G B,A RET CKHLDE: ;07B2 MOV A,H XRA D ;SAME SIGN? JP CK1 ;07B8H YES, COMPARE XCHG ;NO EXCHANGE AND COMPLIMENT CK1: ;07B8 RST 4 RET ; ; ;+++SETVAL+++FIN+++ENDCHK+++& ERROR (& FRIENDS)+++ ; ;"SETVAL" EXPECTS A VARIABLE, FOLLOWED BY AN EQUAL SIGN AND ;THE AN EXPR. IT EVALUATES THE EXPR. AND SET THE VARIABLE ;TO THAT VALUE. ; ;"FIN" CHECKS THE END OF A COMMAND, IF IT ENDED WITH ";", ;EXECUTION CONTINUES. IF IT ENDED WITH A CR, IT FINDS THE ;NEXT LINE AND CONTINUES FROM TG ;UN NEXT LINE FI2: ;07DB RET ;ELSE RETURN TO CALLER ENDCHK: ;07DC +++ENDCHK+++ RST 5 CPI 0DH ;END WITH CR? RZ ;OK, ELSE SAY "WHAT?" QWHAT: ;07E0 +++QWHAT+++ PUSH D AWHAT: ;07E1 +++AWHAT+++ LXI D,WHAT ;0175H ERROR: ;07E4 +++ERROR+++ SUB A CALL PRTSTG ;087FH PRINT 'WHAT?', 'HOW?', OR 'SORRY'. POP D LDAX D ;SAVE THE CHARACTER PUSH PSW ;AT WHERE OLD DE-> SUB A ;AND PUT A 0 THERE STAX D LHLD CURRNT ;09C1H GET CURRENT LINE # PUSH H MOV A,M ;CHECK THE VALUE INX HG CH. ;'FNDLNP' WILL START WITH DE AND SEARCH FOR THE LINE #. ;'FNDNXT' WILL BUMP DE BY 2, FIND A CR AND THEN START SEARCH. ;'FNDSKP' USE DE TO FIND A CR, AND THEN START SEARCH. ; ; GETLN: ;0814 +++GETLN+++ RST 2 LXI D,BUFFER ;0F37H PROMPT AND INIT. GL1: ;0818 CALL CHKIO ;0985H CHECK KEYBOARD JZ GL1 ;0818H NO INPUT, WAIT. CPI 7FH ;DELETE LAST CHARACTER? JZ GL3 ;0842H YES CPI 08H ;IS IT A BACKSPACE? JZ CONTH ;YES DELETE THE LAST CHARACTER CPI 0AH ;INPUT, ECHO BACK , IGNORE LF G  DCX D ;ELSE WE EITHER FOUND IT, ORA B ;OR IT IS NOT THERE RET ;NC,Z: FOUND, NC,NZ: NO FNDNXT: ;0873 +++FNDNXT+++ INX D ;FIND NEXT LINE FL2: ;0874 JUST PASSED BYTE 1 & 2 INX D FNDSKP: ;0875 +++FNDSKP+++ LDAX D CPI 0DH ;TRY TO FIND CR JNZ FL2 ;0874H KEEP LOOKING INX D ;FOUND CR, SKIP OVER JMP FL1 ;085FH CHECK IF END OF TEXT ; ; ;+++PRTSTG+++OTSTG+++PRTNUM+++& PRTLN+++ ; ;'PRTSTG' PRINTS A STRING POINTED TO BY DE. IT STOPS PRINTING ;AND RETURNS TO CALLER WHEN EITHER A CG HERE. ; ;"ENDCHK" CHECKS IF A COMMAND IS ENDED WITH CR, THIS IS ;REQUIRED IN CERTIAND COMMANDS, (GOTO, RETURN, AND STOP ETC.) ; ;"ERROR" PRINTS THE STRING POINTED BY DE (AND ENDS WITH CR) ;IT THEN PRINTS THE LINE POINTED BY "CURRNT" WITH A "?" ;INSERTED AT WHERE THE OLD TEXT POINTER (SHOULD BE ON TOP ;OF THE STACK) POINTS TO. EXECUTION OF TB IS STOPPED ;AND TB1 IS RESTARTED. HOWEVER, IF 'CURRNT'->ZERO ;(INDICATING A DIRECT COMMAND) , THE DIRECT COMMAND IS NOT ;PRINTED, AND IF 'CURRNT'-G/ ORA M POP D JZ RSTART ;0181H IF ZERO, JUST RESTART MOV A,M ;IF NEGATIVE, ORA A JM INPERR ;0568H REDO INPUT CALL PRTLN ;08EDH ELSE PRINT THE LINE DCX D ;UPTO WHERE 0 IS POP PSW ;RESTORE THE CHARACTOR STAX D MVI A,'?' ;3FH PRINT A "?" RST 2 SUB A ;AND THE REST OF THE CALL PRTSTG ;087FH JMP RSTART ;0181H QSORRY: ;080D +++QSORRY+++ PUSH D ASORRY: ;080E +++ASORRY+++ LXI D,SORRY ;017BH JMP ERROR ;07E4H ; ; ;+++GETLN+++FNDLN (& FRIENDS)+++ ; ;'GETLN' READS A G JZ GL1 ;0818H ORA A ;IGNORE NULL JZ GL1 ;0818H CPI 5CH ;DELETE THE WHOLE LINE? JZ GL4 ;084FH YES STAX D ;ELSE, SAVE INPUT INX D ;AND BUMP POINTER CPI 0DH ;WAS IT CR? JNZ MORM ;083CH NO, JUMP TO MORM MVI A,0AH ;YES, END OF LINE RST 2 RET MORM: ;083C IS E 87H?, IF NOT LOOP MOV A,E CPI 87H JNZ GL1 ;0818H CONTH: MOV A,E ;DELETE LAST CHARACTER CPI '7' JZ GL4 DCX D ;BACKUP THE POINTER MVI A,20H ;SPACE RST 2 ;TO THE CONSOLE MVI A,08H ;BACK SPACE RST 2 JMP GL1 GL3:HH R IS PRINTED OR WHEN ;THE NEXT BYTE IS THE SAME AS WHAT WAS IN A (GIVEN BY THE ;CALLER). OLD A IS STORED IT B, OLD B IS LOST. ; ;'OTSTG' LOOKS FOR A BACK-ARROW. SINGLE QUOTE, OR DOUBLE ;QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACK-ARROW, ;OUTPUT A CR WITHOUT A LF. IF SINGLE OR DOUBLE QUOTE, PRINT ;THE STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE. ;AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED ;OVER (USUALLY A JUMP INSTRUCTION). ; ;'PRTNUM' PRINTS THE NUMBER HIDE ;0786H DIVIDE HL BY 10 MOV A,B ;RESULT 0? ORA C ; JZ PN3 ;08D2H YES, WE GOT ALL XTHL ;NO, SAVE REMAINDER DCR L ;AND COUNT SPACE PUSH H ;HL IS OLD BC ' MOV H,B ;MOVE RESULT TO BC MOV L,C JMP PN2 ;08C2H AND DIVIDE BY 10 PN3: ;08D2 POP B ;WE GOT ALL DIGITS IN PN4: ;08D3 DCR C ;THE STACK MOV A,C ;LOOK AT SPACE COUNT ORA A JM PN5 ;08DFH NO LEADING BLANKS MVI A,' ' ;20H LEADING BLANKS RST 2 ; JMP PN4 ;08D3H MORE? PN5: ;08DF PRINT SIGN MOV A,B RST 2 MOV E,L ;LASHH SHLD LOPLNT ;09CDH POP H SHLD LOPLN ;09CFH POP H SHLD LOPPT ;09D1H PP1: ;0932 PUSH B ;BC = RETURN ADDRESS RET PUSHA: ;0934 +++PUSHA+++ LXI H,STKLMT ;0FAFH CALL CHGSGN ;07A6H POP B ;BC = RETURN ADDRESS DAD SP ;IS STACK NEAR THE TOP? JNC QSORRY ;080DH YES, SORRY FOR THAT. LHLD LOPVAR ;09C9H ELSE SAVE LOOP VAR. $ MOV A,H ;BUT IF LOPVAR IS 0 ORA L ;THAT WILL BE ALL JZ PU1 ;095AH LHLD LOPPT ;09D1H ELSE, MORE TO SAVE PUSH H LHLD LOPLN ;09CFH PUSH H LHLD LOPLNT ;09CHJMP CHKIO ;0985H JUMP TO CONSOLE STATUS CI1: ;09A8 CPI 3 ;IS IT 03 (^C) JNZ POPR ;0981H NO, POP THE REGISTERS AND GO ON JMP RSTART ;0181H RESTART ; LSTROM: ;09B0 OUT 0FFH ;OUTPUT ROUTINE, THE PORT # IS CHANGED BY THE RET ;BASIC PROGRAM. ;THIS IS THE WAIT COMMAND. THE INPUT PORT # SPECIFIED IN ;THE BASIC PROGRAM IS READ IN A LOOP UNTIL THE "J" MASK ;RESULTS IN A NON-ZERO VALUE. WAITCOM: ;09B3 IN 0FFH ;INPUT PORT "I" XRA H ;EX-OR WITH "K", IF GIVEN IN PROGRAM ANA L ;MASK WITH HIN HL. LEADING BLANKS ARE ADDED ;IF NEEDED TO PAD THE NUMBER OF SPACES TO THE NUMBER IN C. ;HOWEVER, IF THE NUMBER OF DIGITS IS LARGER THAN THE # IN ;C, ALL DIGITS ARE PRINTED ANYWAY. NEGATIVE SIGN IS ALSO ;PRINTED AND COUNTED IS. POSTIVE SIGN IS NOT. ; ;'PRTLN' PRINTS A SAVED TEXT LINE WITH LINE # AND ALL. ; ; PRTSTG: ;087F +++PRTSTG+++ MOV B,A PS1: ;0880 LDAX D ;GET A CHARACTER INX D ;BKUMP POINTER CMP B ;SAME AS OLD A? RZ ;YES RETURN RST 2 ;ELSE PRINT IT CPI 0DH ;WAS IHT REMAINDER IN E PN6: ;08E2 D MOV A,E ;CHECK DIGIT IN E CPI 0AH ;10 IS FLAG FOR NO MORE POP D RZ ;IF SO, RETURN ADI '0' ;30H ELSE CONVERT TO ASCII RST 2 ;AND PRINT THE DIGIT JMP PN6 ;08E2H GO BACK FOR MORE PRTLN: ;08ED +++PRTLN+++ LDAX D MOV L,A ;LOW ORDER LINE # INX D ;HIGH ORDER LINE # LDAX D ;PRINT 4 DIGIT LINE # MOV H,A INX D MVI C,4 CALL PRTNUM ;08B1H MVI A,' ' ;20H FOLLOWED BY A BLANK RST 2 SUB A ;AND THEN THE TEXT CALL PRTSTG ;087FH RET ; ;+++MVUP+++MVHDH PUSH H LHLD LOPINC ;09CBH PUSH H LHLD LOPVAR ;09C9H PU1: ;095A PUSH H PUSH B ;BC = RETURN ADDRESS RET ; ;THIS IS THE TERMINAL OUTPUT ROUTINE THE ASCII ;CHARACTER IS IN THE A REG. IF CR, LF IS ADDED ; OC2: ;095D JNZ OC3 ;0962H IT IS ON POP PSW ;IT IS OFF RET ;RESTORE AF AND RETURN OC3: ;0962 POP PSW ;COME HERE TO DO OUTPUT PUSH B PUSH D PUSH H STA OCSW-1 ;09BFH STORE THE CHARACTER AT OCSW-1 MOV E,A ;MOVE ASCII CHARACTER TO BE OUTPUT FROM A TO E MVI C,2 ;Hz"J" JZ WAITCOM ;09B3H LOOP IF ZERO RST 6 ; ;INP COMMAND THE PORT # IS CHANGED BY THE BASIC PROGRAM ; INCOMM: ;09BB IN 0FFH ;INPUT PORT # (X) MOV L,A ;RETURN THE NUMBER RET ;IN THE L REG. NOP ;STORAGE REG. FOR CONSOLE OUTPUT CHARACTER OCSW: ;09C0 RST 7 ;STORAGE REG. FOR CONSOLE INPUT CHARACTER CURRNT: ;09C1 SWITCH FOR OUTPUT NOP NOP STKGOS: ;09C3 SAVES SP IN 'GOSUB' NOP NOP VARNXT: ;09C5 TEMP STORAGE NOP NOP STKINP: ;09C7 SAVES SP IN 'INPUT' NOP NOP H T CR? JNZ PS1 ;0880H NO, NEXT RET ;YES RETURN OTSTG: ;088B +++OTSTG+++ RST 1 DB '"',(RSTO27-OTSTG) MVI A,'"' ;22H IT IS A (") OT1: ;0890 PRINT UNTIL ANOTHER CALL PRTSTG ;087FH CPI 0DH ;WAS LAST ONE A CR? POP H ;RETURN ADDRESS JZ RUNNXL ;031BH WAS CR, RUN NEXT LINE OT2: ;0899 SKIP THREE BYTES ON RETURN INX H RSTO27: INX H INX H PCHL ;RETURN OT3: ;089D RST 1 ;IS IT A (') ? DB '''',(RSTO28-OT3) MVI A,'''' ;27H YES, DO SAME RSTO28: JMP OT1 ;0890H AS IN (") OT4: H DOWN+++PAPA+++& PUSHA+++ ; ;'MVUP' MOVES A BLOCK UP FROM WHERE DE-> TO WHERE BC-> UNTIL ;DE = HL ; ;'MVDOWN' MOVES A BLOCK DOWN FROM WHERE DE-> TO WHERE HL-> ;UNTIL DE = BC ; ;'POPA' RESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE ;STACK ; ;'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SAVE AREA INTO THE ;STACK ; MVUP: ;0900 +++MVUP+++ RST 4 RZ ;DE = HL, RETURN LDAX D ;GET ONE BYTE STAX B ;MOVE IT INX D ;INCREASE BOTH POINTERS INX B JMP MVUP ;0900H UNTIL DONE MVDOWN:H CONSOLE OUTPUT CALL 5 ;CALL BDOS, PRINT THE CHARACTER ON THE CONSOLE LDA OCSW-1 ;09BFH RELOAD THE CHARACTER CPI 0DH ;IS IT CR? JNZ LDACC ;097EH NO, JUMP LDACC MVI E,0AH ;YES, SEND LF TO THE TERMINAL MVI C,2 ;OUTPUT TO TERMINAL CALL 5 ;CALL BDOS LDACC: ;097E LDA OCSW-1 ;09BFH RELOAD THE CHARACTER POPR: ;0981 RESTORE ALL THE REGISTERS POP H POP D POP B RET ; ;THIS IS CONSOLE STATUS, 00 RETURNED IN A, IF READY FOR INPUT. ;FF RETURNED IF NO INPUT. ; CHKIO: ;0985 PUSHH N LOPVAR: ;09C9 'FOR' LOOP SAVE AREA NOP NOP LOPINC: ;09CB INCREMENT NOP NOP LOPLNT: ;09CD LIMIT NOP NOP LOPLN: ;09CF LINE NUMBER NOP DB 0 LOPPT: ;09D1 TEXT POINTER DB 0,0 RANPNT: ;09D3 RANDOM NUMBER POINTER DB 0,1 TXTUNF: ;09D5 ->UNFILLED TEXT AREA (END OF PROGRAM TEXT) DW TXTBGN ;INITIAL VALUE TXTBGN: ;09D7 TEXT SAVE AREA BEGINS DB 'M' MSAG1: ;09D8 DB 7FH,7FH,7FH,'SHERRY BROTHERS ' DB 'TINY BASIC VER. ' MSAG2: ;09FB DB '3.1',0DH ;STACK POINTER SETUP ROUTH R ;08A5 RST 1 ;IS IT BACK-ARROW? DB '_',(RSTO29-OT4) ; MVI A,8DH ;YES, CR WITHOUT LF RST 2 ;DO IT TWICE TO GIVE RST 2 ;TTY ENOUGH TIME (SHOULD WE CALL THE RUBOUT ROUTINE?) POP H ;RETURN ADDDRESS RSTO29: JMP OT2 ;0899H OT5: ;08B0 RET ;NONE OF THE ABOVE PRTNUM: ;08B1 +++PRTNUM+++ PUSH D ; LXI D,0AH PUSH D MOV B,D DCR C CALL CHKSGN ;07A3H CHECK SIGN JP PN1 ;08C1H NO SIGN MVI B,'-' ;2DH B-SIGN DCR C ;'-' TAKES SPACE PN1: ;08C1 PUSH B ;SAVE PN2: ;08C2 CALL DIVH ;0909 +++MVDOWN+++ MOV A,B SUB D ;TEST IF DE = BC JNZ MD1 ;0911H NO, GO MOVE MOV A,C ;MAYBE, OTHER BYTE? SUB E RZ ;YES, RETURN MD1: ;0911 DCX D ;ELSE MOVE A BYTE DCX H ;BUT FIRST DECREASE LDAX D ;BOTH POINTERS AND MOV M,A ;THEN DO IT JMP MVDOWN ;0909H LOOP BACK POPA: ;0918 POP B ;BC = RETURN ADDRESS POP H ;RESTORE LOPVAR, BUT SHLD LOPVAR ;09C9H =0 MEANS NO MORE MOV A,H ORA L JZ PP1 ;0932H YEP, GO RETURN POP H ; NOP, RESTORE OTHERS SHLD LOPINC ;09CBH POP H B ;PUSH REGISTERS PUSH D PUSH H MVI C,0BH ;CONSOLE STATUS CALL 5 ;CALL BDOS ORA A ;READY? JNZ CONTLO ;0994H YES, GET INPUT CHARACTER JMP POPR ;0981H NO, POP THE REGISTERS AND RETURN ; ;THIS IS THE CONSOLE INPUT ROUTINE, ASCII CHARACTER IS ;RETURNED IN A . ; CONTLO: ;0994 MVI C,1 ;CONSOLE INPUT CALL 5 ;CALL BDOS CPI 0FH ;IS IT BACK-SPACE (^I)? JNZ CI1 ;09A8H NO,SKIP TO CI1 LDA OCSW ;09C0H YES, RELOAD THE BACK-SPACE CMA ;COMPLEMENT (F0H) STA OCSW ;09C0H STORE BACK I(IINE SETSTK: ;09FF MVI A,0FFH ;INITIALIZE SWITCH FOR OUTPUT STA OCSW ;09C0H MVI A,0AH RST 2 SUB A LXI D,MSAG1 ;09D8H CALL PRTSTG ;087FH PRINT THE SIGN ON MESSAGE LDA 7 STA RSTART+2 ;0183H LOAD TOP OF AVAILABLE RAM INTO SP DCR A ;LOAD SP-100H INTO THE FOLLOWING ROUTINES STA TV00+2 ;0119H : STA TV11+2 ;0126H : STA ST33+2 ;01A5H : STA ST44+2 ;01E5H : STA IP33+2 ;05ABH : STA SIZE1+2 ;0705H : STA GETLN+3 ;0817H : STA PUSHA+2 ;0936H : LXI H,ST1 ;0184H LOAD ADDRESSIjNE STARTS ;WITH A NON-ZERO NUMBER, THIS NUMBER IS THE LINE NUMBER. THE ;LINE NUMBER AND THE REST OF THE LINE ; IS STORED IN MEMORY. IF A LINE WITH THE SAME ;LINE NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE. ;IF THE REST OF THE LINE IS "CR" ONLY, IT IS NOT STORED AND ;AND ANY EXISTING LINE WITH THE SAME NUMBER IS DELETED. ; ;AFTER A LINE IS INSERTED, REPLACED, OR DELETED, THE PROGRAM ;LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILLI UPDATE ST4: ;01D2 POP B ;GET READY TO INSERT LHLD TXTUNF ;09D5H BUT FIRST CHECK IF POP PSW ;THE LENGTH OF THE NEW LINE PUSH H ;IS 3 (LINE # AND CR) CPI 3 ;THEN DO NOT INSERT JZ RSTART ;0181H MUST CLEAR THE STACK ADD L ;COMPUTE THE NEW TXTUNF MOV L,A MVI A,0 ADC H MOV H,A ;HL->NEW UNFILLED AREA ST44: ;01E3 LXI D,VARBGN ;0F00H CHECK TO SEE IF THERE RST 4 ;IS ENOUGH SPACE JNC QSORRY ;080DH SORRY, NO ROOM SHLD TXTUNF ;09D5H OK, UPDATE TXTUNF POP D ;DE->OLD UNFILLED AREAIKE' DB (POKE SHR 8) +128 DB POKE AND 0FFH DB 'WAIT' DB (WAIT SHR 8) +128 DB WAIT AND 0FFH DB 'IF' DB (IFF SHR 8) +128 DB IFF AND 0FFH DB 'GOTO' DB (GOTO SHR 8) +128 DB GOTO AND 0FFH DB 'GOSUB' DB (GOSUB SHR 8) +128 DB GOSUB AND 0FFH DB 'RETURN' DB (RETURN SHR 8) +128 DB RETURN AND 0FFH DB 'REM' DB (REM SHR 8) +128 DB REM AND 0FFH DB 'FOR' DB (FOR SHR 8) +128 DB FOR AND 0FFH DB 'INPUT' DB (IP1 SHR 8) +128 DB IP1 AND 0FFH DB 'PRINT' DB (PRINT SHR 8) +128Iy OF ST1 (FIRST START ROUTINE) SHLD 0101H ;STORE THIS ADDRESS AT 101 (NEW JUMP VECTOR AFTER ;THE BLOCK MOVE TO PAGE 0). JMP ST1 ;0184H START THE PROGRAM PG0: ;0A50 THIS BLOCK IS MOVED INTO PAGE 0 XTHL ;RST 1 RST 5 CMP M JMP TC1 ;012FH CRLF1: ;0A56 +++CRLF+++ MVI A,0DH ; PUSH PSW ;RST 2 LDA OCSW ;09C0H PRINT CHARACTERS ONLY ORA A ;IF OCSTW IS ON JMP OC2 ;095DH REST OF THIS IS AT OC2 CALL EXPR2 ;0616H +++EXPR+++ RST 3 PUSH H ;EVALUATE AN EXPRESSION JMP EXPR1 ;05D2H REST I) BE ;TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE NUMBER, ;AND CONTROL IS TRANSFERED TO "DIRECT". ; ;THE MEMORY LOCATION "CURRNT" PIONTS TO THE LINE NUMBER ;THAT IS CURRENTLY BEING INTERPRETED. WHILE WE ARE IN ;THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND ; RSTART: ;0181 LXI SP,2000H ;THIS POINTER IS MODIFIED TO EQUAL TOP OF AVAILABLE ST1: ;0184 MEMORY CALL CRLF ;+CRLF+ JUMP TO HERE LXI D,OK ;0172H DE->STRING SUB A ;A=0 CALL PRTSTG ;087FH PRINT STRING UI CALL MVDOWN ;0909H POP D ;DE->BEGIN, HL->END POP H CALL MVUP ;0900H MOVE NEW LINE TO SAVE JMP ST3 ;019DH AREA ; +++TABLES+++DIRECT+++& EXEC+++ ; ;THIS SECTION OF THE CODE TESTS A STRING AGIANST A TABLE ;WHEN A MATCH IS FOUND, CONTROL IS TRANSFERED TO THE SECTION ;OF CODE ACCORDING TO THE TABLE ;AT 'EXEC' DE SHOULD POINT TO THE STRING AND HL SHOULD POINT ;TO THE TABLE-1 AT 'DIRECT' DE SHOULD POINT TO THE STRING ;HL WILL BE SET TO POINT TO TAB1-1, WHICH IS THE TABLE FOR I DB PRINT AND 0FFH DB 'STOP' DB (STOP SHR 8) +128 DB STOP AND 0FFH DB (DEFLT SHR 8) +128 DB DEFLT AND 0FFH DB 'YOU CAN ADD MORE' TAB4: ;027F FUNCTIONS DB 'RND' DB (RND SHR 8) +128 DB RND AND 0FFH DB 'INP' DB (INP SHR 8) +128 DB INP AND 0FFH DB 'PEEK' DB (PEEK SHR 8) +128 DB PEEK AND 0FFH DB 'USR' DB (USR SHR 8) +128 DB USR AND 0FFH DB 'ABS' DB (ABS SHR 8) +128 DB ABS AND 0FFH DB 'LOG2' DB (LOG2 SHR 8) +128 DB LOG2 AND 0FFH DB 'ALOG2' DB (ALOG2 SHR 8) I OF IT IS AT EXPR1 DB 'W' MOV A,H ;+++COMP+++ RST 4 CMP D ;COMPARE HL WITH DE RNZ ;RETURN CORRECT C AND MOV A,L ;Z FLAGS CMP E ;BUT OLD A IS LOST RET DB 'AN' LDAX D ;+++IGNBLK+++ RST 5 CPI ' ' ;20H IGNORE BLANKS RNZ ;IN TEXT (WHERE DE->) INX D ;AND RETURN THE FIRST JMP 28H ;NON-BLANK CHAR. IN A POP PSW ;+++FINISH+++ RST 6 CALL FIN ;07CDH CHECK END OF COMMAND JMP QWHAT ;07E0H PRINT "WHAT?" IF WRONG DB 'G' RST 5 ;+++TSTV+++ RST 7 SUI '@' ;40H TEST VARIABLES RC ; C:I NTIL CR LXI H,ST2+1 ;0195H LITERAL 0 SHLD CURRNT ;09C1H CURRNT->LINE # = 0 ST2: ;0194 ; LXI H,0 SHLD LOPVAR ;09C9H SHLD STKGOS ;09C3H ST3: ;019D MVI A,'>' ;3EH PROMPT '>' AND CALL GETLN ;0814H READ A LINE PUSH D ;DE->END OF LINE ST33: ;01A3 LXI D,BUFFER ;0F37H DE->BEGINING OF LINE CALL TSTNUM ;013EH TEST IF IT IS A NUMBER RST 5 ; MOV A,H ;HL = VALUE OF # OR ORA L ;0 IF NO NUMBER POP B ;BC->END OF LINE JZ DIRECT ;02D5H DCX D ;BACKUP DE AND SAVE MOV A,H ;VALUE OF LII o ;ALL DIRECT AND INDIRECT STATEMENT COMMANDS. ; ;A '.' IN THE STRING WILL TERMINATE THE TEST AND THE PARTIAL ;MATCH WILL BE CONSIDERED AS A MATCH E.G. 'P.','PR.','PRIN.' ;ALL MATCH 'PRINT'. ; ;THE TABLE CONSISTS OF A NUMBER OF ITEMS. EACH ITEM ;IS A STRING OF CHARACTERS WITH BIT 7 SET TO 0 AND ;A JUMP ADDRESS HI-LO WITH BIT 7 OF THE HIGH BYTE ;SET TO 1 ; ;END OF TABLE IS AN ITEM WITH A JUMP ADDRESS ONLY. IF THE ;STRING DOES NOT MATCH, THIS IS THE DEFAULT. ; I +128 DB ALOG2 AND 0FFH DB 'SIZE' DB (SIZE SHR 8) +128 DB SIZE AND 0FFH DB (XP40 SHR 8) +128 DB XP40 AND 0FFH DB 'YOU CAN ADD MORE' TAB5: ;02B1 "TO" IN "FOR" DB 'TO' DB (FR1 SHR 8) +128 DB FR1 AND 0FFH DB (QWHAT SHR 8) +128 DB QWHAT AND 0FFH TAB6: ;02B7 "STEP" IN "FOR" DB 'STEP' DB (FR2 SHR 8) +128 DB FR2 AND 0FFH DB (FR3 SHR 8) +128 DB FR3 AND 0FFH TAB8: ;02BF RELATIONAL OPERATORS DB '>=' DB (XP11 SHR 8) +128 DB XP11 AND 0FFH DB '#' DB (XP12 SHR 8) +128 DI nNOT A VARIABLE JMP TV0 ;JUMP TV0 AND CALL PARN MVPG0: ;0AA0 MOVE THE BLOCK FROM PG0 TO MVPG0-1 INTO PAGE 0 0008H. LXI H,8 ;DESTINATION LXI D,PG0 ;0A50H SOURCE MVLOOP: ;0AA6 BLOCK MOVE LDAX D MOV M,A INX H INX D MVI A,'@' ;40H BLOCK LENGTH CMP L JNZ MVLOOP ;0AA6H LXI H,SETSTK ;09FFH SHLD 0101H JMP BEGIN ;0100H JUMP INTO THE PROGRAM END OF COMMAND JMP QWHAT ;07E0H PRINT "WHAT?" IF WRONG DB 'G' RST 5 ;+++TSTV+++ RST 7 SUI '@' ;40H TEST VARIABLES RC ; C:I!NE # THERE STAX D DCX D MOV A,L STAX D PUSH B ;BC,DE->BEGIN. END PUSH D MOV A,C SUB E PUSH PSW ;A=# OF BYTES IN LINE CALL FNDLN ;0857H FIND THIS LINE IN SAVE PUSH D ;AREA DE->SAVE AREA JNZ ST4 ;01D2H NZ: NOT FOUND, INSERT PUSH D ;Z: FOUND DELETE IT CALL FNDNXT ;0873H FIND THE NEXT LINE DE->NEXT LINE POP B ;BC ->LINE TO BE DELETED LHLD TXTUNF ;09D5H HL->UNFILLED SAVE AREA CALL MVUP ;0900H MOVE UP TO DELETE MOV H,B ;TEXTUNF->UNFILLED AREA MOV L,C ; SHLD TXTUNF ;09D5HI#TAB1: ;01F9 DIRECT COMMANDS DB 'LIST' DB (LIST SHR 8) +128 DB LIST AND 0FFH DB 'RUN' DB (RUN SHR 8) +128 DB RUN AND 0FFH DB 'NEW' DB (NEW SHR 8) +128 DB NEW AND 0FFH DB 'LOAD' DB (LOAD SHR 8) +128 DB LOAD AND 0FFH DB 'SAVE' DB (SAVE SHR 8) +128 DB SAVE AND 0FFH DB 'BYE' DB 80H,0 TAB2: ;021A DIRECT/STATMENT DB 'NEXT' DB (NEXT SHR 8) +128 DB NEXT AND 0FFH DB 'LET' DB (LET SHR 8) +128 DB LET AND 0FFH DB 'OUT' DB (OUT1 SHR 8) +128 DB OUT1 AND 0FFH DB 'POJJB XP12 AND 0FFH DB '>' DB (XP!3 SHR 8) +128 DB XP13 AND 0FFH DB '=' DB (X15 SHR 8) "Dp@Oǘ0HAHppCAτOFD5!( "##$!!,())!( "##$!,())' )"'!( "##$"$""$",$* $"")'"&"$#!& %*)"('*""" " #'"$))$#,"'" ,&!$""" " &!-J ST STORED LINE, STORE ITS ADDRESS (IN ;'CURRNT' AND START TO EXECUTE IT. NOTE THAT ONLY THOSE ;COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM. ; ;THERE ARE 3 MORE ENTRIES IN 'RUN': ;'RUNNXL' FINDS THE NEXT LINE, STORES ITS ADDRESS AND EXECUTES IT. ;'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT. ;'RUNSML' CONTINUES THE EXECUTION ON SAME LINE. ; ; ;'GOTO EXPR(CR)' EVALUATES THE EXPRESSION. FIND THE TARGET LINE, ;AND JUMP TO 'RUNTSL' TO DO IT. ; NEW: ;0306 +++NEW(CR)+++ Jf0XP33: CALL MULTIPLY JMP XP25 ;0699H FINISHED(,LOGBAS10BAK$jklmnopqrstuvwLOGBAS10$$$ XP33 MUL J}J4X3 ;02F7H INX H ;HL->TABLE CMP M ;IF MATCH, TEST NEXT JZ EX1 ;02DAH MVI A,7FH ;ELSE SEE IF BIT 7 DCX D ;OF TABLE IS SET, WHICH CMP M ;IS THE JUMP ADDR. (HI) JC EX5 ;02FEH C:YES MATCHED EX2: ;02ED ;NC:NO FIND JUMP ADDR. INX H CMP M JNC EX2 ;02EDH INX H ;BUMP THE NEXT TABLE ITEM POP D ;RESTORE STRING POINTER JMP EX0 ;02D8H TEST AGIANST NEXT ITEM EX3: ;02F7 MVI A,7FH ;PARTIAL MATCH, FIND EX4: ;02F9 INX H ;JUMP ADDR., WHICH IS CMP M ;FLAGED BY BIT 7. JNC EX4 ;02F9H JCALL ENDCHK ;07DCH LXI H,TXTBGN ;09D7H SHLD TXTUNF ;09D5H STOP: ;030F +++STOP(CR)+++ CALL ENDCHK ;07DCH JMP RSTART ;0181H RUN: ;0315 +++RUN(CR)+++ CALL ENDCHK ;07DCH LXI D,TXTBGN ;09D7H FIRST SAVED LINE RUNNXL: ;031B +++RUNNXL++ LXI H,0 ;FIND WHATEVER LINE # CALL FL1 ;085FH C:PASSED TXTUNF, QUIT. JC RSTART ;0181H RUNTSL: ;0324 +++RUNTSL+++ XCHG SHLD CURRNT ;09C1H SET 'CURRENT'->LINE # XCHG INX D ;BUMP PASS LINE # INX D RUNSML: ;032B +++RUNSML+++ CALL CHKIO ;0985H FINDJ GJ`@  :   0     R 򰰰J EX5: ;02FE MOV A,M ;LOAD HL WITH THE JUMP INX H ;ADDR. FROM THE PABLE MOV L,M ANI 7FH ;MASK OFF BIT 7 MOV H,A POP PSW ;CLEAN UP THE GARBAGE AND PCHL ;GO DO IT. ; ; ;WHAT FOLLOWS IS THE CODE TO EXECUTE DIRECT AND STATMENT ;COMMANDS. CONTROL IS TRANSFERED TO THESE POINTS VIA THE ;COMMAND TABLE LOOKUP CODE OF 'DIRECT' AND 'EXEC' IN LAST ;SECTION. AFTER THE COMMAND IS EXECUTED, CONTROL IS ;TRANSFERED TO OTHER SECTIONS AS FOLLOWS: ; ; ;FOR 'LIST', 'NEW', AND 'STOP', GO BACK TJ  COMMAND IN TAB2 LXI H,TAB2-1 ;0219H AND EXICUTE IT. JMP EX0 ;02D8H GOTO: ;0334 +++GOO EXPR+++ RST 3 ; PUSH D ;SAVE FOB ERROR ROUTINE CALL ENDCHK ;07DCH MUST FIND A CR CALL FNDLN ;0857H FIND THE DARGET LINE JNZ AHOW ;0167H NO SUBH LINE # POP PSW ;CLEAR THE "PUSH DE" JMP RUNTRL ;0324H GO DO IT ; ;THE FOLLOWING ROUTINES DO THE DISK COMMUNICATION ; LOAD: RST 5 PUSH H CALL H03E5 ;03E5H PUSH D PUSH B LXI D,$RS@@ϞpprAǘ@Ϙpp@r@ϜppJ  /J J O 'RSTART' ;FOR 'RUN', GO EXECUTE THE FIRST STORED LINE IF ANY, ELSE ;GO BACK TO 'RSTART'. ;FOR 'GOTO' AND 'GOSUB' : GO EXECUTE THE TARGET LINE ;FOR 'RETURN' AND 'NEXT': GO BACK TOO SAVED RETURN LINE. ;FOR ALL OTHERS: IF 'CURRENT' ~0, GO TO 'RSTART',ELSE ;GO EXECTTE NEXT B_Xã $"'"$$$"" @ggBI L! $g 88y 88y $LD!a$' 'Ld'' @''L IL' gL88y 88y $a$' 'O''B@88y"d@aa$'IL''IJ]I 0FFH JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKRD: ;035E READ THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,14H ;READ SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS CPI 1 ;ERROR CODE? JC NEWFIL ;0381H JNZ QHOW ;0166H ERROR MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP D ;RESTORE REGISTERS POP B POP D POP H RST 6 NEWFIL: ;0381 POP D LXI H,80H DAD D XCHG JMP DSKRD ;035EH SAVE: RST 5 PJCX%  : K:KL#>A/)&KWITH ^C ; ;PRINT COMMAND IS 'PRINT ....;' OR 'PRINT ....(CR)' ;WHERE "...." IS A LIST OF EXPRESSIONS, FORMATS, BAKARROWS, ;AND STRINGS. THESE ITEMS ARE SEPARATED BY COMMAS. ; ;A FORMAT IS A FOUND SIGN FOLLOWED BY A NUMBER. IT CONTROLS ;THE NUMBER OF SPACES THE VALUE OF A EXPRESSION IS GOING TO ;BE PRINTED. IT STAYS EFFECTIVE FOR THE REST OF THE PRINT ;COMMAND UNLESS CHANGED BY ANOTHER FORMAT. IF NO FORMAT IS ;SPECIFIED. 6 POSITIONS WILL BE USED. ; ;A STRING IS QUOTED IN A PAIR OF SINK ;SUBROUTINE 'RETURN'. IN ORDER THAT 'GOSUB' CAN BE NESTED ;(AND EVEN RECURSIVE), THE SAVE AREA MUST BE STACKED. ;THE STACK POINTER IS SAVED IN 'STKGOS'. THE OLD 'STKGOS' IS ;SAVED IN THE STACK. IF WE ARE IN THE MAIN ROUTINE, 'STKGOS' ;IS ZERO (THIS WAS DONE BY THE "MAIN" SECTION OF THE CODE), ;BUT WE STILL SAVE IT AS A FLAG FOR NO FURTHER 'RETURN'S. ; ;'RETURN(CR)' UNDOES EVERYTHING THAT 'GOSUB' DID, AND THUS ;RETURN THE EXECUTION TO THE COMMAND AFTER THE MOST RECENT ;'GOSUB'. IF 'STDGOSKAME ;VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP. ;IF THAT IS THE CASE, THEN THE OLD 'FOR' LOOP IS DEACTIVATED. ;(PURGED FROM THE STACK.) ; ;'NEXT VAR' SERVES AS THE LOGICAL (NOT NECESSARILY PHYSICAL) ;END OF THE 'FOR' LOOP. THE CONTROL VARIABLE VAR. IS CHECKED ;WITH THE 'LOPVAR'. IF THEY ARE NOT THE SAME, TB1 DIGS IN ;THE STACK TO FIND THE RIGHT ONE AND PURGES ALL THOSE THAT ;DID NOT MATCH EITHER WAY, TB1 THEN ADDS THE 'STEP' TO ;THAT VARIABLE AND CHECK THE RESULT WITH THE KrUSH H CALL L03E5 ;03E5H PUSH D PUSH B LXI D,5CH ;DE=FCB ADDRESS MVI C,13H ;DELETE FILE CALL 5 ;CALL BDOS LXI D,5CH ;DE=FCB ADDRESS MVI C,16H ;MAKE A FILE CALL 5 ;CALL BDOS CPI 0FFH ;ERROR? JZ QHOW ;0166H XRA A STA 7CH LXI D,TXTUNF ;09D5H DSKWR: ;03AD WRITE TO THE DISK PUSH D MVI C,1AH ;SET DMA ADDRESS CALL 5 ;CALL BDOS MVI C,15H ;WRITE SEQUENTIAL LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS ORA A JNZ QHOW ;0166H POP D LDA TXTUNF+1 ;09D6H WRITE TO DISK UNTIL KGLE OR A PAIR OF ;DOUBLE QUOTES. ; ;A BACK-ARROW MEANS GENERATE A (CR) WITHOUT (LF) ; ;A (CRLF) IS GENERATED AFTER THE ENTIRE LIST HAS BEEN ;PRINTED OR IF THE LIST IS A NULL LIST. HOWEVER IF THE LIST ;ENDED WITH A COMMA NO (CRLF) IS GENERATED. ; LIST: ;0420 TEST IF THERE IS A # CALL TSTNUM ;013EH IF NO # WE GET A 0 CALL ENDCHK ;07DCH CALL FNDLN ;0857H FIND THIS OR THE NEXT LINE LS1: ;0429 JC RSTART ;0181H C:PASSED TXTUNF CALL PRTLN ;08EDH PRINT THE LINE CALL CHKIO ;0985HK' IS 0, IT INDICATES THAT WE ;NEVER HAD A 'GOSUB' AND IS THUS AN ERROR. ; ; GOSUB: ;0470 CALL PUSHA ;0934H SAVE THE CURRENT "FOR" RST 3 ;PARAMETERS PUSH D ;AND TEXT POINTER CALL FNDLN ;0857H FIND THE TARGET LINE JNZ AHOW ;0167H NOT THERE SAY "HOW?" LHLD CURRNT ;09C1H FOUND IT, SAVE OLD PUSH H ;'CURRNT' OLD 'STKGOS' LHLD STKGOS ;09C3H PUSH H LXI H,0 ;AND LOAD NEW ONES SHLD LOPVAR ;09C9H DAD SP SHLD STKGOS ;09C3H JMP RUNTSL ;0324H THEN RUN THAT LINE RETURN: ;0490 CAKLIMIT. IF IT ;IS WITHIN THE LIMIT, CONTROL LOOPS VACK TO THE COMMAND ;FOLLOWING THE 'FOR'. IF OUTSIDE THE LIMIT, THE SAVE AREA ;IS PURGED AND EXECUTION CONTINUES. ; ; FOR: ;04A9 CALL PUSHA ;0934H SAVE THE OLD SAVE AREA CALL SETVAL ;07BAH SET THE CONTROL VAR. DCX H ;HL IS ITS ADDRESS SHLD LOPVAR ;09C9H SAVE THAT LXI H,TAB5-1 ;USE "EXEC" TO LOOK JMP EX0 ;02D8H FOR THE WORD "TO" FR1: ;04B9 RST 3 ;EVALUATE THE LIMIT SHLD LOPLNT ;09CDH SAVE THAT LXI H,TAB6-1 ;USE 'EXEC' TO LOK  CMP D ;TXTUNF JC CLFIL ;03D9H JNZ DSKLOOP ;03D1H LDA TXTUNF ;09D5H CMP E ; JC CLFIL ;03D9H DSKLOOP: ;03D1 LXI H,80H DAD D XCHG JMP DSKWR ;03ADH CLFIL: ;03D9 MVI C,10H ;CLOSE FILE LXI D,5CH ;DE=FCB ADDRESS CALL 5 ;CALL BDOS POP B ;RESTORE REGISTERS POP D POP H RST 6 L03E5: ;03E5 LXI H,5CH MVI M,0 L03EA: ;03EA FILL 64H BYTES WITH SPACES (20H) INX H MVI M,' ' ;20H MVI A,64H CMP L JNZ L03EA ;03EAH FILL LOOP RETURN INX H ; THE NEXT 3 BYTES "TBI" K  STOP IF ^C CALL FL1 ;085FH FIND NEXT LINE JMP LS1 ;0429H AND LOOP BACK PRINT: ;0438 MVI C,6 ;C= # OF SPACES RST 1 ;IF NULL LIST & ";" DB ';' DB 6 CALL CRLF ;GIVE (CR-LF) AND JMP RUNSML ;032BH B_NTINUE SAME LINE PR2: ;0443 ; RST 1 ;IF NULL, LIST (CR) DB 0DH,6 CALL CRLF ;ALS_GIVE CR-LF AND JMP RUNNXL ;031BH GO TO NEXT LINE PR0: ;044C RST 1 ;ELSE IS IT FORMAT? DB '#' DB 5 RST 3 ;YES, EVALUATE EXPR. MOV C,L ;AND SAVE IT IN C. JMP PR3 ;045AH LOOK FOR MORE TO PRINT K LL ENDCHK ;07DCH THERE MUST BE A CR LHLD STKGOS ;09C3H OLD STACK POINTER MOV A,H ;0 MEANS NOT EXIST ORA L JZ QWHAT ;07E0H SO WE SAY "WHAT?" SPHL ;ELSE, RESTORE IT POP H SHLD STKGOS ;09C3H AND THE OLD 'STKGOS' POP H SHLD CURRNT ;09C1H AND THE OLD 'CURRNT' POP D ;OLD TEXT POINTER CALL POPA ;0918H OLD "FOR" PARAMETERS RST 6 ;AND WE ARE BACK HOME ; ; ;+++FOR+++& NEXT+++ ; ;'FOR' HAS TWO FORMS: ;'FOR VAR=EXP1 TO EXP2 STEP EXP3' AND 'FOR VAR=EXP1 TO EXP2' ;(WHERE EXP3 ASSUMEK OK JMP EX0 ;02D8H FOR THE WORD 'STEP' FR2: ;04C3 ; RST 3 ;FOUND IT, GET STEP JMP FR4 ;04CAH FR3: ;04C7 LXI H,1 ;NOT FOUND, SET TO ONE FR4: ;04CA SHLD LOPINC ;09CBH SAVE THAT TOO FR5: ;04CD LHLD CURRNT ;09C1H SAVE CURRENT LINE # SHLD LOPLN ;09CFH XCHG ;AND TEXT POINTER SHLD LOPPT ;09D1H LXI B,0AH ;DIG INTO STACK TO LHLD LOPVAR ;09C9H FIND 'LOPVAR' XCHG MOV H,B MOV L,B ;HL=0 NOW DAD SP ;HERE IS THE STACK DB '>' FR7: ;04E2 DAD B ;EACH LEVEL IS 10 DEEP MOV A,MK E MVI M,'T' ;54H INX H MVI M,'B' ;42H INX H MVI M,'I' ;49H L03FC: ;03FC INX H ;FILL FROM "TBI" TO 5C6B WITH 00 MVI M,0 MVI A,6BH CMP L JNZ L03FC ;03FCH LXI H,5DH L0408: ;0408 LDAX D CPI 0DH RZ CPI '!' ;21H JC QWHAT ;07E0H CPI 5BH JNC QWHAT ;07E0H MOV M,A INX H INX D MVI A,65H CMP L JNZ L0408 ;0408H RET ; ; ;+++LIST+++& PRINT+++ ; ;LIST HAS 2 FORMS ;'LIST(CR)' LISTS ALL SAVED LINES ;'LIST #(CR)' START LIST AT THIS LINE # ;YOU CAN STOP LIST KPR1: ;0454 CALL OTSTG ;088BH OR IS IT A STRING? JMP PR8 ;0467H IF NOT, MUST BE EXPR. PR3: ;045A RST 1 ;IF ",", GO FIND NEXT DB ',',6 CALL FIN ;07CDH IN THE LIST JMP PR0 ;044CH CALL CRLF ;LIST ENDS RST 6 PR8: ;0467 RST 3 ;EVALUATE THE EXPR PUSH B CALL PRTNUM ;08B1H PRINT THE VALUE POP B JMP PR3 ;045AH MORE TO PRINT? ; ; ;+++GOSUB+++& RETURN+++ ; ;'GOSUB EXPR;' OR 'GOSUB EXPR (CR)' IS LIKE THE 'GOTO' ;COMMAND, EXCEPT THAT THE EXECUTION CAN BE CONTINUED AFTER THE K 1). ;TB1 WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE ;CURRENT VALUE OF EXP1. IT ALSO EVALUATES EXP2 AND EXP3 ;AND SAVE ALL TOGATHER WITH THE TEXT POINTER ETC. IN ;THE 'FOR' SAVE AREA. WHICH CONSISTS OF 'LOPVAR', 'LOPINC', ;'LOPLMT', 'LOPLN', AND 'LOPPT'. IF THERE IS ALREADY SOMETHING ;IN THE SAVE AREA (THIS IS INDICATED BY A NON-ZERO ;'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK ;BEFORE THE NEW ONE OVER WRITES IT. ;TB1 WILL THEN DIG IN THE STACK AND FIND OUT IF THIS SLL[ ;GET THAT OLD 'LOPVAR' INX H ; ORA M JZ FR8 ;0503H ZERO SAYS NO MORE IN IT MOV A,M DCX H CMP D ;SAME AS THIS ONE? JNZ FR7 ;04E2H MODIA,M ;THE OTHER HALF? CMP E JNZ FR7 ;04E2H XCHG ;YEV ϙ"'",$ ),*'&")$&,$  &"' "(*#+")$&*$") #)$&"'(*%'"'")"'"""!#)"!*$*'"*) ")"'+ ! $''+ $&"LLQ  N,!+L]7! AH  LL , "WHAT?" SHLD VARNXT ;09C5H YES SAVE IT NX0: ;050F PUSH D ;SAVE TEXT POINTER XCHG LHLD LOPVAR ;09C9H GET VAR IN 'FOR' MOV A,H ORA L ;0 SAYS NEVER HAD ONE JZ AWHAT ;07E1H SO WE ASK "WHAT?" RST 4 ;ELSE WE CHECK THEM JZ NX3 ;0527H OK, THEY AGREE POP D ;NO, LETS SEE CALL POPA ;0918H PURGE CURRENT LOOP LHLD VARNXT ;09C5H AND POP ONE LEVEL JMP NX0 ;050FH GO CHECK AGAIN NX3: ;0527 MOV E,M ;COME HERE WHEN AGREED INX H ; MOV D,M ;DE=VALUE OF VAR LHLD LOPINC ;09CBH PUSH H L{$UL LL OMULTIPLY: MVI C,8 ;MULTIPLIER IN A, MULTIPLICAND IN DE, PRODUCT IN HL MULTI: DAD H ;SHIFT LEFT PRODUCT. ** LOOP COUNTER IN C. ** SIGN IN B RAL ;SHIFT LEFT MULTIPLIER JNC CHCNTI ;GO ON IF CARRY=0 DAD D ;ADD MULTIPLICAND TO PRODUCT IF CARRY=1 CHC;NTI: DCR C ;GO TO THE NEXT BIT JNZ MULTI RET ;FINISHED@L  L L L LLQ  >" ' L