IMD 1.16: 29/05/2007 18:24:40 FOGCPM.055 6/86 --FOGCPM055BAKSLASHCOMBAKSLASHDOC BAKSLASHASM @ COM @ DOC%CALL-CPMCOMz !"CALL-CPMDOC$#$%&'COMPARE COM ()COMPARE DOC*COMPASC COM +,COMPBIN COM -.COMPARE ASM/012CRCK4 COM 34CRCK4 DOC567CRCK4 ASMV89:;<=>?@ABDIAL COM=CDEFGHIJDIAL DOC,KLMNOPDUPUSR21COMQDUPUSR21ASM:RSTUVWXYHP COM Z[HP-PL COM\]^HP-HP-PLDOCO_`abcdefghINUSE11 COMijkINUSE11 DOC) PROCESSOR: ASM DEPENDENCIES: NONE NOTES: Set "DUP" to true, to define a version which will write "/.SUB" out to disk to facilitate re-executing the same commands. To re-execute them, REN $$$.SUB=/.SUB then ^C. Alternatively, PIP $$$.SUB=/.SUB You might wish to name the version of this program assembled with DUP true, as ".COM (but this will "screw up" the Master CATalog system which reauires its "-name.xxx" to be the first file found) A program for quickie, use once and throw away submits. The command syntax is: A>/ [[;] ... ] is program was written because the abstract for volume 40 states that 40.1 works only under CP/M version 1.4, and that the source code cannot be provided. This version overcomes both of these difficulties. (Note: 40.1 "1.4 only" meant "not 1.3". it does work with 2.2 ) PROCESSOR: ASM DEPENDENCIES: NONE NOTES: Set "DUP" to true, to define a version which will write "/.SUB" out to disk to facilitate re-executing the same commands. To re-execute them, REN $$$.SUB=/.SUB then;/.ASM by John M. Kodis ;CP/M U.G. contrubution November 1980 ; ;The "slant" program reads a command line which ;may contain several program invocations. A $$$.SUB ;file is built with these commands. This file is ;then executed. ; ;For example, the command line: ; ;/ asm copy; load copy; dir copy*.*; type copy.prn ; ;will build a file containing commands to assemble ;and load the file named 'copy', search the directory ;for all copy programs, and type the COPY.PRN file. ; ;Based on "/.ASM", CPMUG 40.1. This program was ;written because the abstract for volume 40 states ;that 40.1 works only under CP/M version 1.4, ;and that the source code cannot be provided. This ;version overcomes both of these difficulties. ; (Note: 40.1 "1.4 only" meant "not 1.3". ; it does work with 2.2 ) ; ;PROCESSOR: ASM ;DEPENDENCIES: NONE ;NOTES: Set "DUP" to true, to define a version ; which will write "/.SUB" out to disk ; to facilitate re-executing the same commands. ; To re-execute them, REN $$$.SUB=/.SUB ; then ^C. Alternatively, PIP $$$.SUB=/.SUB ; ; You might wish to name the version of this ; program assembled with DUP true, as ".COM ; ; (but this will "screw up" the Master CATalog ; system which reauires its "-name.xxx" to be ; the first file found) ; ; A program for quickie, use once and throw away submits. ; ; The command syntax is: ; ; A>/ [[;] ... ] ; closef equ 16 delete equ 19 writef equ 21 makef equ 22 dmaf equ 26 ; boot equ 0 ;for a warm start bdos equ 5 ;cp/m entry point chcnt equ 080h ;character count cibuf equ 081h ;console input buffer tpa equ 100h ;transient program area ; dup equ 0 ; org tpa ; slant: lxi h,chcnt mov a,l add m inr a mov l,a mvi m,0 ;zero the byte after the end of the command line. ; lxi d,cibuf ;de is the source pointer. lxi h,subbuf+1;hl is the destination pointer. ; nxtcmd: ldax d cpi ' ' jnz xfer ;skip over leading blanks. inx d jmp nxtcmd ; xfer: ldax d ana a ;end of line? jz cmdend cpi ';' ;end of command? jz cmdend mov m,a ;if neither, xfer it to the output buffer, inx d inx h ;bump both pointers, jmp xfer ;and try again. ; cmdend: mvi m,0 ;zero the byte after the end of the line. mov a,l dcr a ani 7fh ;accumulator has character count. mov b,a ;save it. mov a,l ani 80h mov l,a ;hl points to the character count byte. mov m,b ; ldax d ana a ;if we've reached the end of the input line... jz fileit ;let's "file it". lxi b,129 dad b inx d ;point to the next character in the input. jmp nxtcmd ;loop back for the next command. ; fileit: push h ;save address of last zone if dup lxi d,xfcb mvi c,delete call bdos endif lxi d,fcb mvi c,delete call bdos ;delete any existing command files. ; if dup lxi d,xfcb mvi c,makef call bdos endif lxi d,fcb mvi c,makef call bdos ;create the new command files. ; pop h wrloop: push h xchg mvi c,dmaf call bdos ; if dup lxi d,xfcb mvi c,writef call bdos endif lxi d,fcb mvi c,writef call bdos ;write the new commands, one command per ;disk sector, writing the last command first. ; pop h ;get current dma address lxi d,-128 dad d lxi d,subbuf mov a,l sub e mov a,h sbb d jnc wrloop ; if dup lxi d,xfcb mvi c,closef call bdos endif lxi d,fcb mvi c,closef call bdos ;close the files after writing the last sector. ; rst boot ;back to cp/m via a warm start. ;changing this to a "ret" will return ;to CP/M without the warm start, and so ;the command file will not be executed ;until the next boot from this disk. ; fcb: db 1, '$$$ SUB' dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 xfcb: db 1, '/ SUB' dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; org ($+0ffh) and 0ff00h ; subbuf: ds 0 ; end slant kef call bdos ;create the new command files. ; pop h wrloop: push h xchg mvi c,dmaf call bdos ; if dup lxi d,xfB@~?ܿ]iO rHyMz*6+"6c͋!G|>ʆN#xc!ɾ q! sz{:0?|ʷl&ͩA}g }o|gҫ!/ P:5yx}259\b*3͋+~͢͢*3͋0+~"3! P͢*3͋6̓*1i͋!X P|}>*6~#"6rG }'+#-+|3/;=C~S<]>wXʳxʳ#>x&>x(>x)>x*>x0:ڑ!3 P*6rw#'r'M+6+͋}>!^ Pͽͽ ?? ? ! P=? ?q =?ͽ ?ʋ=?ͽ0o&r͑ҭ)T]))08ÖM>r'!z Pr! Po&r))))8OxXxM>>'! P͑ 07gaW7GA?77~#F $+"6>25!i"1!"3! P̓n&>LL̓O̓G>y>n&ɹn&>*1i͋ʜ+~+^+V"1!@ P*3͋´!E P+"3~!88^#VXX{ozgXDM!z X͘`iX͘Xz|}o|g Xz4|}o|g#Xzg{oXzg{oXzg{oaWi+aWihaWihaWiihaÈa|L L#L|/g}/oLL! PG*1͋p#"1! P>|}G*31͋p#"3! P 8ER_yma(%ͱ͠ͺ:+6 !ͺʘ!ͺcͺc>! THE ANSWER IS HEX. WELCOME TO THE `WHATIS` EXPRESSION EVALUATOR. OPERATORS: & DYADIC AND * DYADIC MULTIPLY + DYADIC ADD OR MONADIC PLUS - DYADIC SUBTRACT OR MONADIC NEGATE (2'S COMPLEMENT) / DYADIC DIVIDE // DYADIC REMAINDER < DYADIC LESS THAN > DYADIC LESS THAN <= DYADIC LESS THAN OR EQUAL == DYADIC EQUAL >= DYADIC GRTR THAN OR EQUAL << DYADIC OR MONADIC ROTATE LEFT >> DYADIC OR MONADIC ROTATE LEFT | DYADIC INCLUSIVE OR || DYADIC EXCLUSIVE OR ~ MONADIC ONE'S COMPLEMENT ~= DYADIC NOT EQUAL STRINGS MUST BE INCLUDED BETWEEN TWO ' ' (ABOVE #7 KEY) EXAMPLES: 5*(3-(6*2))<=(#FFE/2) 'CAT' < 'DOG' EVALUATES TO =1 HEX DIGITS ARE DENOTED BY A '#' AND BE LESS THAN FFFF FOR FURTHER INSTRUCTIONS SEE 'DR. DOBBS', VOLUME 3, PG 416 PLEASE TYPE IN YOUR EXPRESSION: $EXPRESSION MISSINGMISSING LEFT PARENTHESISILLEGAL CHARACTEROPERATOR STACK UNDERFLOWMISSING END OF STRING QUOTESINGLE QUOTE MUST FOLLOW X AND xILLEGAL HEX DIGITMISSING END OF HEX CONSTANT QUOTEILLEGAL LEFT PARENTHESISOPERAND STACK OVERFLOWOPERATOR STACK OVERFLOWINVALID EQUALS OPERATORDIVISION BY ZEROOPERAND STACK UNDERFLOWOPERATOR MISSING"!9"!>2: S25  >@2:0:Ƃo&>w:?r!a"~# ( !$ a(}0 >( >D >) > >( >H >) (z{ 80 8x 0 _z/W{/_> > :"* (`?` for info.) --->> $/ bk1{ tOD C2D42> D> D:v8 { t29O͝ q2 b2z2N/P/"* (`?` for info.) --->> $/ bk1{ tOD C2D42> D> D:v8 K * Z-80 DISASSEMBLER MICRONICS, INC. Version 1.3$ Documentation for @.COM ~~~~~~~~~~~~~~~~~~~~~~~ @.COM is an online expression evaluator for CP/M`s CCP. I never had a calculator handy when I needed one most ,so threw together this program and saved it on each of my working disks. It acts as a calculator in the same manner as the calculator or immediate mode of BASIC. The expression may be included in the command line or input from the program itself. The expression evaluator package originally came in raw form from October 1978 Dr. Dobb`s Journal - page 34 by Mike Gabrielson. It now requires CP/M to run (developed under CP/M 2.2 on a DISCUS 2D/B). This is useful for machine language programming with its HEX arithmatic and Boolean operators. The answers are both in deciaml and hex. This demonstates evaluating an expression from command level. After completion, the program returns control to CPM. Ex- A>@ #F-5 10(D) 000A(H) --->> program outputs this answer A> But if we just enter `@` at command level, the evaluator will be brought up and expressions will be input through a built in mini-editor. Unlike entering the expression at command level , this alternative allows you to remain in the evalutor to do many calcultions. To return to CP/M, type '^C' or just hit 'RETURN'. Ex- A>@ (`?` for info.) --->> 1+2+3+4 10(D) 0000A(H) (`?` for info.) --->> -- note it doesnt return to CPM. A short command summary is provided in the program if you press `?` as the first character of the expression line. This will not work from the command level. Ex- (`?` for info,) ? ---- instructions printed ---- Operators: =-=-=-=-= ( - precedence bracket (for expression nesting) & dyadic and * dyadic multiply + dyadic add or monadic plus - dyadic subtract or monadic negate (two`s complement) / dyadic divide // dyadic remainder < dyadic less than > dyadic greater than <= dyadic less then or equal == dyadic equal >= dyadic greater than or equal << dyadic or monadic rotate left >> dyadic or monadic rotate right | dyadic inclusive OR || dyadic exclusive OR ~ monadic one`s complement ~= dyadic not equal Constants =-=-=-=-= All constants are evaluated as 16 bit unsigned integers with overflow ignored. The values may range from 0 to 65535 decimal or 0 to #FFFF hex and may be one or all of the following types: 1) Decimals - 12635 2) Hexadecimal - #F23D 3) Strings - 'ABC' Relational Operators =-=-=-=-=-=-=-=-=-=- The dyadic operators: == ~= <= >= < > are used to form expressions that evaluate to either zero or one. If the relation is true, the operators produce a result of one. A false comparison results in zero: Expression Evaluated result Ex- 5 == 5 1 3+(2~=6) 4 (1<=2)<=3 1 #FFFF<0 0 The operators << and >> can be used as dyadic or monadic operators to rotate (not shift) 16 bit operands. Rotation implies wraparound of bits. Shifting can be accomplished with the multiply and divide operators. When used as monadic operators operands are rotated one bit. When used as dyadic operators, the first operand specifies the number of bits to rotate. Ex- <<2 4 >>3 #8001 >>(<<2) 2 3>>#f0 #1E String Operations =-=-=-=-=-=-=-=-= If a string constant appears in an expression with operators, the value of the string is the ASCII code of the string`s first character. An exception to this rule occurs when two strings appear with a relational operator: then a character by character comparision of the two strings is performed, using the ASCII code to determine relative order. If the two strings are of unequal length, the shorter is padded on the right with blanks. Ex- 'A'+1 #42 'ABC'&#FF #41 'CAT'<'dog' 1 'PAD'=='PAD ' 1 '123'==#31 1 Closing =-=-=-= This is a hacked together program and has not been thoroughly tested. If you find any bugs please pass them on to me via a `BBS` or other channel. Robert Lansdale  String Operations =-=-=-=-=-=-=-=-= If a string constant appears in an expression with operators, the value of the string is the ASCII code of the string`s first character. An exception to this rule occurs when two strings appear with a relational operator: then a character by character comparision of the two strings is performed, using the ASCIIò%́!!9s!c">=!'"@=!"@=!"=!"=!}2B=!D}2C=!I}2D=!R}2E=!}2F=!}2G=!!B=*=3!\"=!"=!"=!͞!9s#r!9^!eʐ!9^!Eʐ!=*>=!\͐*@=*@=!͐*=*=!͐*=*=!͐!͐*=*=!K͐*=*=!y͐*=*=!͐!G!͐!!%!9s!9^!e!9^!E!G!!9^!1)!9^!2<l!9^!3O< !9^!4b !9^!5u7 !9^!Gʍ! INTERACTIVE CP/M FUNCION CALL EXERCISERBY: Superior Software Corporation 01/05/84 YOU have 5k of user definable memory starting at %5u ( %4x ) ------MENU------- | ------VARIABLES------- E...Exit to CP/M | A = %5u %4x 1...View memory | BC = %5u %4x 2...Do BDOS CALL | DE = %5u %4x 3...Build FCB | HL = %5u %4x 4...View FCB&BFR | ----MEMORY POINTERS---- 5...change a var. | PFCB= %5u %4x | PBFR= %5u %4x | PMSC= %5u %4x Your Choice ́! 9^#V̀́!G!! 9s!1!(͐!9!!Z!9͑4L!! 9s*=! 9s#r!!_!9͑4v!! 9s*=! 9s#r!!d!9͑4 !! 9s*=! 9s#r!!i!9͑4!! 9s*=! 9s#r! 9^z!! 9^#V You can view memory addressed by one of the following pointersPBFR, PFCB, PMSC or HL Which to use ? PBFRPFCBPMSCHĹ!G!1!G!1! 1͎!9s!9^!y!9^!Y*@= 4*@=*@= *@=!*@="*=*@=%">=*@= 5:*@=4:*=*@=%">=*@=v*@=v*@=v*@=v*@= ʆ*=*@=%"=!,W A R N I N G - SOME CALLS SUCH AS (19) MAY BE DANGEROUSYou should have your BC variable set to the CP/M function and your DE variable set if needed. PROCEED ? (Y/N) ́!\!9s#r!G! ͐!9^!9^V3!9s#r!G!9^#V!9s! ͐!9*=! 9&!9^!9^#VsEnter Drive # Default=0,A=1,B=2,C=3,...G=7 (?=63) Enter the file name and type ́!\!9s#r!!9^#V ́!G!!9s!1 ͐!9!9x4!9s#r!9^o5ʤ !G!e 1!=!9^#V!9! ͑4 !!9s!9V3"@=!9^#V!9! ͑4B !!9s!9V3"=!9^#V!9! ͑4q !!9s!9V3"=!9^#V!9! ͑4  !!9s!9V3"=!9^#V!9! ͑4 !!9s!9V3"=!9^#V!9! ͑4 !!9s!9V3"=!9^z0 !G! 1!}}|!}|!}|}|?>o&zo&| }|>o&|o&z2c9%:c9||0/g}/o#z>/W{/_>DM!>2b9))Q#}o|gi :b9=2b9I}:b9=2b9I}DM!>))҈ =€}}/o|/g#}||g}o{_|I|7g}o·{_)}}o|gN#F# N#F#z{##^#VBK^#Vz#y####x#~#fo}|>?o&}|>o&{_|g}oI|g}o~# x^!9d9~#y!|7́!<"j9!9!9^#V!ó! 9^#V"j9!9!9^#V!ó*j9!9^#Vͳ́! 9^#VBK!</ /`i#DM+s!`isW`i! 9~#foW!! 9^#V́! 9^#V!9~#fo+s#r!ʹ!9^#VDMʹ`i#+s`i ¹o!u`i! 9~#fo!! 9^#V́! 9N#FGp`i~#fo+s#r! -́! 9N#F`i~g!<`i#DM+^ͳd!=!9s#r#+^!0^ 9^ !>9^#V! x!>9s#r .ʹ !!@9s#r#+^!0ʹ 9ʹ !@9^#V! x!@9s#ru l #+^!:9!T9~#fos#r55Ø!d+!!:9!T9~#fo##s#r++^#VF95Ø!eO!fO!gu!!9!T9~#fos#ra9a9Ø!!:9!T9~#fo##s#r++^#V895B#!9!!>955$!9!49s#ri#!:9559"!9! !>95765͂$!9!49s#r!-!69~#fo+s#rs:"!9! !>955͂$!9!49s#ri#!9! !>955$!9!49s#ri#!9!!>955$!9!49s#ri#!:95Y9!49s#rx4!89s#rÁ#eʽ"!"!!B9^#V!"!"!B9^#V!9! 9a9a9a9!9! 9!49s#rx4!89s#r!!@9s#rÁ#!:95Y9!9!69s#rsi#o!d!u="xc"s"e"f"c#,#!9!49~#fo!89s#r!89^#V!@9~#foʤ#!@9^#V!89s#r!D9~##!>9~#fo+s#r#!89~#fo#!B9^#V`ìî#!!69s#r#!69~#fo#s#r!49^#V~<$!69^#V!@9~#fo<$!49~#fo#s#r+^`ì#!D9~#s$!>9~#fo+s#r#!89~#fos$! `ìF$~$`ìǺ!9N#F!9^#V`iF95!956ͼ7Y9r9^+s! 9`iF9(65͂75G6˜$́!9N#F!9^#V! 9559ʚ%! 95Y9p! 9!955975;65`iͪF95!956ͼ7Y9)r9^+s! 9`iͪF9(65͂75!955͂$!9*&ù%i%i*d9DM*f9o&i%o&i*d9*+++*f9DM*h9!9N#F#^#Vkb6#> 6 #=&>6#=& : >R& Aڌ&[C&@O&aڌ&{Ҍ&`w# .m&ʆ&U&͓&w#V&{o|g ʆ&͓&w#w&!!|a{ !9^#V*9!9}|ھ&*9"9|!́!!!93!:o&p9s!("9!9DM!"A:*A:ʕ(`i^! *'`i^! 2'`i#DM'`i^zʕ(`i^!>S'!g'`i^!<F(!`i#DM^! †'`i^! ʉ'g'`i`i#DM~'`i^! ´'`i^! '!`i#DM+s'Î'*|'!?)'!_)C(!(!S4!;4!(!;4!x4!! 0! (Ò(`i*A:#"A:+)9s#r`i#DM~ʒ(`i^! €(`i^! ʏ(!`i#DM+sÒ(Z('!9*A:@(Can't open file for redirection: ́! 9~#(!(03͹%A:$$$.SUB́!"<!́!con:CON:lst:LST:prn:PRN:pun:PUN:rdr:RDR:́!9^#V!!9^#V_)́!K=!!9s#rÑ)!9~#fo#s#r!9^#V! ʳ)nf(½)x)!"4C4>4# *4!M4!}!}!9^#V#~#foxu4~u4# d4!9~#foʍ4#Ä4}!9^#V#^#V#N#F*4!9^#V#^#V#N#Fd4!9^#V#~#foxu4~4# 4d4!9^#V#^#V#N#F4!9^#V#n~55#5!|!9^#V#n45#+5x5 +~455!9~ i5 i5 i5~5!9~A~5[~5!}!9~a~5{i5!!9~0~5:~5i5!9~aڦ5{Ҧ5 o&!9~Aڼ5[Ҽ5 o&!*(=5!*&=w#w#w#w*&=~#~#~#~"<*&=V+^+V+^*<"<*(=s#r#s#r*<*(=*&="(="&=*&=>w#=6*&=~9#L68=ɯ<*&=*(=###{6]66Y6Y6]6+6*&=*(=#6*&=*(=#³6*&=*(=#6*&=*(=#6*&=*(=#6*&=~/w#7*(=~?G*&=^#V#~#fo))'7#7DM*&=s#r#q#p*(=~?W*&=###~^7~w+P7L77~w+b7^7~#s7O:6*&= 2 2*w#"wɯ2^2r!"u"wR<   NO FILE1 FILE$!l. ;U ]!mͶD~# ;!\R ;*Q*S}|ڮ!"S*Q{zҠ*O.š*S"Sl*S"Q!"S*O*Q}>*S#"Sɯ2:2N!"Q"S.<  NO FILE2 FILE$G4!FILES UNEQUAL AFTER $  PLAST DATA READ FROM FILE 1: $ *-,~ ʨ w w ڱұ_:<2<2͝ $ 2> w>(_͜͜:2>)w\Ð|*w,"!~0Y24+EOF FILE 1, NOT FILE 2 $  X:Yg^EOF FILE 2 BEFORE FILE 1 $  ͂FILES MATCH, LENGTH IS $   Ð ڥ0_w#¶N BYTES $2>)w\Ð|*w,"!~0*S#"Sɯ2:2N!"Q"S.<  NO FILE2 FILE$G4!FILES UNEQUAL AFTER $  PLAST DATA READ FROM FILE 1: $ *-,~ ʨ w w ڱұ_:<2<2͝ $ 2> w>(_͜͜:2>)w\Ð|*w,"!~0Y24+EOF FILE 1, NOT FILE 2 $  X:Yg^EOF FILE 2 BEFORE FILE 1 $  ͂FILES MATCH, LENGTH IS $   Ð ڥ0_w#¶N BYTES $2>)w\Ð|*w,"!~0 prompt, type COMPARE fildescr1 fildescr2 where fildescr is of the form d:filename.typ. If the two files have the same name but are on separate drives, at the A> prompt, type COMPARE filename.typ B: yp. If the two files have the same name but are on separate drives, at the A> prompt, type COMPA1COMPASC.COM 02/11/82 $ :m 6 ]!m_B~# 9!\P 9w Gͻ ͋ ͖ 1ͻ ͯ 2F *s*u}|!"u*s{z*qP¼*u"uÎ*u"s!"u*q*s}>*u#"uɯ2\2p!"s"uP<  NO FILE1 FILE$!l, 9S ]!m_B~# 9!\P 9J *O*Q}|ڬ!"Q*O{zҞ*M,˜*Q"Qj*Q"O!"Q*M*O}>*Q#"Qɯ282L!"O"Q,<  NO FILE2 FILE$!" zw# x>2!&" Vw;# x&@>2!&f "#8̅F:}*Y8:–*&Yą +~#ʩPP~""*ʉ¿**ʉ:<2 FILES UNEQUAL $ $****** FILE 1: $ *PA*** FILE 2: $ *P> p_Ri*EOF $ ~_# p++HH"":<2ͼFILES UNEQUAL $ ****** FILE 1: $ **** FILE 2: $ ***#"*#"FpY H#"H#"" *|/g}/o#"~ #Tzwu# x`z>2!"*" *|/g}/o#&"~ #¢Vw# x®>2!&"*&YFYFY ~###~  #:)>8FILES MATCH$  >> +J~ȸ#Pz{w#_u# x`z>2!"*" *|/g}/o#&"~ #¢Vw# x® zw# x>2!&" Vw;# x&@>2!&f "#8̅F:}*Y8:–*&Yą +~#ʩPP~""*ʉ¿**ʉ:<2 FILES UNEQUAL $ $****** FILE 1: $ *PA*** FILE 2: $ *P> p_Ri*EOF $ ~_# p++HH"":<2ͼFILES UNEQUAL $ ****** FILE 1: $ **** FILE 2: $ ** 1COMPBIN.COM 09-09-82 $ :m 6 ]!m͋B~# 9!\P 9w Gͻ ͋ ͖ 1ͻ ͯ 2G *s*u}|!"u*s{z*qP¼*u"uÎ*u"s!"u*q*s}>*u#"uɯ2\2p!"s"uP<  NO FILE1 FILE$!l, 9S ]!m͋B~# 9!\P 9K *O*Q}|ڬ!"Q*O{zҞ*M,˜*Q"Qj*Q"O!"Q*M*O}>*Q#"Qɯ282L!"O"Q,<  NO FILE2 FILE$!" zw# x>2"!'" Vw># x)C>2"!'|#}l)i:J~4y:JL:“*ͅ~:¬*'ͅ"#y*)4@M4 ³:<2FILES UNEQUAL $ ****** FILE 1: $ **a:*** FILE 2: $ **ai#]R ́pcz*EOF $ "ͅ~#> †*~#Ҳ Ҵ>.¦<Ɛ'@'> > _"":<2 FILES UNEQUAL $ #****** FILE 1: $ **eD*** FILE 2: $ **e*"*"Ĺes"s"" *|/g}/o#"~ # šzwʻ# x¦>2"!"*" *|/g}/o#'"~ #AVw # x>2"!'"*'ͅ*ͅ*ͅGͅ:TicFILES MATCH$  i+}o}#)yz{w#‹"~ # šzwʻ# x¦>2"!"*" *|/g}/o#'"~ # zw# x>2"!'" Vw># x)C>2"!'|#}l)i:J~4y:JL:“*ͅ~:¬*'ͅ"#y*)4@M4 ³:<2FILES UNEQUAL $ ****** FILE 1: $ **a:*** FILE 2: $ **ai#]R ́pcz*EOF $ "ͅ~#> †*~#Ҳ Ҵ>.¦<Ɛ'@'> > _"":<2 FILES U;COMPARE.ASM ;11/??/77 ORIGINALLY WRITTEN BY WARD CHRISTENSEN ;12/31/77 ADD PICKUP OF SECOND FILENAME IF BLANK ;01/08/77 ADD SEQIO MACLIB TO READ BIG BLOCKS BSIZE EQU 4096 ;DISK BUFFER SIZE (TIMES 2) ORG 100H MACLIB SEQIO MOVE MACRO ?F,?T,?L MVI B,?L LXI D,?F LXI H,?T CALL MOVER ENDM ;TYPE SINGLE CHAR OR CHAR IN A TYPE MACRO ?C IF NOT NUL ?C MVI A,?C ENDIF PUSH B PUSH D PUSH H PUT CON POP H POP D POP B ENDM PRINT MACRO ?L LOCAL Z CALL Z IRP ?M, DB ?M ENDM DB '$' Z POP D MVI C,@MSG CALL @BDOS ENDM ; ;COMPARE.ASM - COMPARES 2 FILES ; ;COMMAND FORMAT: COMPARE NAME1 NAME2 ; IF NAME2 = NAME1 BUT IS ON B DISK, ; JUST TYPE: COMPARE NAME1 B: ; PRINT <'COMPARE.COM 1/8/78',0DH,0AH> ; ;INIT STACK ; POP H ;GET CP/M RET ADDR SHLD EXIT+1 ;MODIFY RETURN ADDR LXI SP,STACK ;GET MY STACK ; ;IF THE SECOND FCB IS BLANK, ;MOVE IN THE NAME FROM THE FIRST ; LDA @TFCB+17 CPI ' ' JNZ MOVE2 ;NOT BLANK MOVE @TFCB+1,@TFCB+17,11 ; ;'DECLARE' BOTH FCB'S ; MOVE2 FILE INFILE,FILE1,,1,,BSIZE FILE INFILE,FILE2,,2,,BSIZE ; ;COMPARE THE 2 FILES 1 BYTE AT A TIME ; COMP CALL READ1 MOV B,A ;SAVE CHAR PUSH B CALL READ2 POP B CMP B JZ COMP ; ;FILES UNEQUAL ; UNEQUAL PRINT 'FILES UNEQUAL AFTER ' PRBYTES LXI D,BYTES MVI C,@MSG CALL @BDOS PRINT <'LAST DATA READ FROM FILE 1:',0DH,0AH> LHLD PRTPTR DCR L MVI B,0 PRTLP INR L MOV A,M CPI 0DH JZ GOTCR CPI 0AH JZ TYPEIT CPI 9 ;TAB JZ TYPEIT CPI ' ' JC HEX CPI 7FH JNC HEX TYPEIT TYPE LDA COL INR A STA COL CPI 60 JC NEXT XRA A STA COL PUSH B PUSH H PRINT <0DH,0AH> POP H POP B JMP NEXT GOTCR XRA A STA COL MVI A,0DH JMP TYPEIT HEX PUSH PSW ;SAVE CHAR TYPE '(' POP PSW PUSH PSW RAR RAR RAR RAR CALL NIBBL POP PSW CALL NIBBL LDA COL ADI 3 STA COL MVI A,')' JMP TYPEIT NEXT DCR B JNZ PRTLP JMP EXIT ; ;READ BYTE FROM FILE 1 ; READ1 GET FILE1 JZ EOF1 ;GOT EOF? LHLD PRTPTR MOV M,A INR L SHLD PRTPTR PUSH PSW ;SAVE CHAR LXI H,BYTES+5 READI MOV A,M ORI '0' ;IN CASE IT WAS BLANK INR A MOV M,A CPI '9'+1 ;TIME TO CARRY? JNZ READNC MVI M,'0' DCX H JMP READI READNC POP PSW RET ; ;EOF ON FILE 1 - SET FLAG, READ 2 ; EOF1 MVI A,'Y' STA EOFLG CALL READ2 PRINT <'EOF FILE 1, NOT FILE 2',0DH,0AH> JMP UNEQUAL ; READ2 GET FILE2 RNZ ;NO EOF ; ;GOT EOF ON FILE 2, MUST HAVE GOTTEN IT ON FILE 1 ; EOF2 LDA EOFLG CPI 'Y' JZ AOK PRINT <'EOF FILE 2 BEFORE FILE 1',0DH,0AH> JMP UNEQUAL ; ;A-OK - FILES MATCH ; AOK PRINT 'FILES MATCH, LENGTH IS ' LXI D,BYTES MVI C,@MSG CALL @BDOS ;NOTE THE FOLLOWING DOES NOT RESTORE CP/M'S ;STACK POINTER, BUT THAT IS 'OK' BECAUSE THE ;FIRST INSTRUCTION IN CP/M IS A LXI SP EXIT JMP $-$ ;CP/M RET ADDR (MODIFIED) ERXIT POP D ;GET MESSAGE MVI C,@MSG CALL @BDOS JMP EXIT NIBBL ANI 0FH CPI 10 JC NUM ADI 7 NUM ADI '0' TYPE RET ;MOVE FROM (DE) TO (HL) LENGTH IN B MOVER LDAX D MOV M,A INX D INX H DCR  B JNZ MOVER RET EOFLG DB 'N' COL DB 0 BYTES DB ' BYTES',0DH,0AH,'$' PRTPTR DW BUFF DS 30 ;STACK STACK EQU $ ;ORG TO PAGE BECAUSE 'INR L' USED TO LOOP THRU IT ORG ($+255) AND 0FF00H ;TO PAGE BUFF EQU $ REPT 16 DB ' ' ENDM BUFFERS EQU $ MEMSIZE EQU BUFFERS+@NXTB END  ; ;GOT EOF ON FILE 2, MUST HAVE GOTTEN IT ON FILE 1 ; EOF2 LDA EOFLG CPI 'Y' JZ AOK PRINT <'EOF FILE 2 BEFORE FILE 1',0DH,0AH> JMP UNEQUAL ; ;A-OK - FILES MATCH ; AOK PRINT 'FILES MATCH, LENGTH IS ' LXI D,BYTES MVI C,@MSG CALL @BDOS ;NOTE THE FOLLOWING DOES NOT RESTORE CP/M'S ;STACK POINTER, BUT THAT IS 'OK' BECAUSE THE ;FIRST INSTRUCTION IN CP/M IS A LXI SP EXIT JMP $-$ ;CP/M RET ADDR (MODIFIED) ERXIT POP D ;GET MESSAGE MVI C,@MSG CALL @BDOS JMP EXIT NIBBL ANI 0FH CPI 10 JC NUM ADI 7 NUM ADI '0' TYPE RET ;MOVE FROM (DE) TO (HL) LENGTH IN B MOVER LDAX D MOV M,A INX D INX H DCRCRCK.COM 4.2B 4/27/81!"9"_1_ʹ:] P++NO FILE NAME SPECIFIED++ $ͧCRCK ver 4.2B CTL-S pauses, CTL-C aborts :m2FƒôCRCKLIST$$$ ͖ Ăy0 ͖a 9**}|)!"*{z**" \ DISK FULL: CRCFILE$!"**#"ɯ22! "!"<ƒ k\ NO DIR SPACE: CRCFILE$1_ҋ:ʩ͊++FILE NOT FOUND++$ͧ ---------------------> SUM OF CRCS = :͐> ͻ:͐ʹ:F*}">ͷ<5 5 CANNOT CLOSE CRCFILE$YCRCKLISTCRC!"8x w# i!8d DONE$!epʃ!]!eͧ --> FILE: XXXXXXXX.XXX CRC = \<͊++OPEN FAILED++$!"!"!*!|' ʐ\5!~2#"!s\:͐> ͻ:͐ʹ**"Ã͊++FILE READ ERROR++$*|):oʌ|g}o"͙ ڢ0û~ͻ#~¨> ͻ> _:F{ͷ2h2|:!\  :\2! \ \A!\ \! \ \<7=Ɓo& ] 2h2|2xx~$#~# x :F*}¤">ͷ˜<  CANNOT CLOSE CRCFILE$ ++ABORTED++$ *_LE$1_ҋ:ʩ͊++FILE NOT FOUND++$ͧ ---------------------> SUM OF CRCS = :͐> ͻ:͐ʹ:F*}">ͷ<5 5 CANNOT CLOSE CRCFILE$YCRCKLISTCRC!"8x w# i!8d DONE$!epʃ!]!eͧ --> FILE: XXXXXXXX.XXX CRC = \<͊++OPEN FAILED++$!"!"!*!|' ʐ\5!~2#"!s\:͐> ͻ:͐ʹ**"Ã͊++FILE READ ERROR++$*|):oʌ|g}o"͙ ڢ0û~ͻ#~¨> ͻ> _:F{ͷ2h2|:!\  :\2 NOTE: The following .DOC file was taken from the file CRCK4.ASM Jim Switz FOG Executive Librarian 29 November 1983 ------------------------------------------------------------------------------ CRCK.ASM version 4.2B by Keith Petersen, W8SDZ (REVISED 4/27/ BY BRK) ----> NOTE: MUST BE ASSEMBLED BY MAC <---- (The file CRCK4.COM already exists and is operable. However, if you wish to modify this program, use HEXCOM.COM after MAC.COM to generate executable .COM file on the Osborne Executive [see Vol.4 Section 7 of Executive Guides]...JHS) CRCK is a program to read any CP/M file and print a CYCLIC-REDUNDANCY-CHECK number based on the CCITT standard polynominal: X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1 Useful for checking accuracy of file transfers. More accurate than a simple checksum. Optionally will write an output file to the default drive, listing the CRC's of all files checked in a single session. COMMANDS: CRCK [drive:] [F] Examples: CRCK MYFILE.ASM ;CHECK ONLY MYFILE.ASM CRCK *.ASM ;CHECK ALL .ASM FILES CRCK *.* F ;CHECK ALL FILES, MAKE FILE OF RESULTS Program updates/fixes (these are written in reverse order to minimize reading time to find latest update): 4/27/81 ADDED SUM OF CRC PRINTOUT AT END OF EXECUTION (BRK) 10/06/80 FIX TO ERASE TEMPORARY FILE WHEN OUTPUT FILE IS REQUESTED AND NAME NOT FOUND IN DIRECTORY. (KBP) 10/05/80 FIX ABORT ROUTINE TO CHECK FOR FILE REQUEST AND TO CLOSE INCOMPLETE FILE BEFORE ERASING IT. ADDED TESTS FOR NO FILE NAME AND FILE READ ERROR. (KBP) 10/04/80 ADD ROUTINE TO GIVE OPTION TO MAKE DISK FILE OF CRC's. FIXED MFA ROUTINE SO FIRST-TIME FLAG NOW SHOWS IF NO FILE FOUND. (KBP) 04/21/80 ADD MULTIPLE FILENAME FEATURE, PRINT NAME OF CURRENT FILE BEING READ, AND ALLOW OPERATOR ABORT. (KBP) 08/20/79 FIX BUG IN READIT ROUTINE WHICH SHOWED UP ONLY ON ALTCPM OPTION. (KBP) 08/19/79 ADD CONDITIONAL ASSEMBLY FOR CP/M ON H8 OR TRS-80. (KBP) 06/27/79 FIRST WRITTEN BY KEITH PETERSEN, W8SDZ /81 ADDED SUM OF CRC PRINTOUT AT END OF EXECUTION (BRK) 10/06/80 FIX TO ERASE TEMPORARY FILE WHEN OUTPUT FILE IS REQUESTED AND NAME NOT FOUND IN DIRECTORY. (KBP) 10/05/80 FIX ABORT ROUTINE TO CHECK FOR FILE REQUEST AND TO CLOSE INCOMPLETE FILE BEFORE ERASING IT. ADDED TESTS FOR NO FILE NAME AND FILE READ ERROR. (KBP) 10/04/80 ADD ROUTINE TO GIVE OPTION TO MAKE DISK FILE OF CRC's. FIXED MFA ROUTINE SO F; ; CRCK.ASM version 4.2B ; by Keith Petersen, W8SDZ ; (REVISED 4/27/ BY BRK) ; ;----> NOTE: MUST BE ASSEMBLED BY MAC <---- ; ;CRCK is a program to read any CP/M file and print ;a CYCLIC-REDUNDANCY-CHECK number based on the ;CCITT standard polynominal: ; X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1 ; ;Useful for checking accuracy of file transfers. ;More accurate than a simple checksum. ; ;Optionally will write an output file to the default ;drive, listing the CRC's of all files checked in a ;single session. ; ;COMMANDS: CRCK [drive:] [F] ; ;Examples: ; CRCK MYFILE.ASM ;CHECK ONLY MYFILE.ASM ; CRCK *.ASM ;CHECK ALL .ASM FILES ; CRCK *.* F ;CHECK ALL FILES, MAKE FILE OF RESULTS ; ;Program updates/fixes (these are written in reverse ;order to minimize reading time to find latest update): ; ;4/27/81 ADDED SUM OF CRC PRINTOUT AT END OF EXECUTION (BRK) ; ;10/06/80 FIX TO ERASE TEMPORARY FILE WHEN OUTPUT FILE IS ; REQUESTED AND NAME NOT FOUND IN DIRECTORY. (KBP) ; ;10/05/80 FIX ABORT ROUTINE TO CHECK FOR FILE REQUEST ; AND TO CLOSE INCOMPLETE FILE BEFORE ERASING ; IT. ADDED TESTS FOR NO FILE NAME AND FILE ; READ ERROR. (KBP) ; ;10/04/80 ADD ROUTINE TO GIVE OPTION TO MAKE ; DISK FILE OF CRC's. FIXED MFA ROUTINE ; SO FIRST-TIME FLAG NOW SHOWS IF NO FILE ; FOUND. (KBP) ; ;04/21/80 ADD MULTIPLE FILENAME FEATURE, PRINT ; NAME OF CURRENT FILE BEING READ, AND ; ALLOW OPERATOR ABORT. (KBP) ; ;08/20/79 FIX BUG IN READIT ROUTINE WHICH ; SHOWED UP ONLY ON ALTCPM OPTION. (KBP) ; ;08/19/79 ADD CONDITIONAL ASSEMBLY FOR CP/M ; ON H8 OR TRS-80. (KBP) ; ;06/27/79 FIRST WRITTEN BY KEITH PETERSEN, W8SDZ ; ;Define true and false ; FALSE EQU 0 TRUE EQU NOT FALSE ; ;Conditional assembly switches ; STDCPM EQU TRUE ;TRUE IS STANDARD CP/M ALTCPM EQU FALSE ;TRUE IS H8 OR TRS-80 NOSYS EQU FALSE ;TRUE IF SYS FILES NOT WANTED ; ;System equates ; BASE SET 0 IF ALTCPM BASE SET 4200H ENDIF ;ALTCPM ; ;Define write buffer size (presently set for 8k) ; BSIZE EQU 8*1024 ;DISK WRITE BUFFER SIZE ; ;BDOS equates ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CSTAT EQU 11 OPEN EQU 15 SRCHF EQU 17 SRCHN EQU 18 READ EQU 20 STDMA EQU 26 BDOS EQU BASE+5 FCB EQU BASE+5CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32 FCB2 EQU BASE+6CH ; ;Program starts here ; ORG BASE+100H ; MACLIB SEQIO ;DEFINE MACRO LIBRARY USED ; CRCK: JMP BEGIN ;JUMP AROUND IDENTIFICATION DB 'CRCK.COM 4.2B 4/27/81' ; BEGIN: LXI H,0 ;GET STACK... SHLD SUM ; INIT CRC SUM COUNTER DAD SP ;POINTER SO WE CAN... SHLD STACK ;SAVE IT LXI SP,STACK ;INITIALIZE LOCAL STACK CALL CRLF ;TURN UP A NEW LINE LDA FCB+1 CPI ' ' ;SEE IF NAME THERE JNZ BEGIN2 ;YES, CONTINUE CALL ERXIT ;PRINT MSG, THEN EXIT DB '++NO FILE NAME SPECIFIED++',CR,LF,'$' ; BEGIN2: CALL ILPRT ;PRINT: DB 'CRCK ver 4.2B',CR,LF DB 'CTL-S pauses, CTL-C aborts',CR,LF,0 LDA FCB2+1 ;GET OPTION STA FFLAG ;SAVE IT FOR LATER CPI 'F' ;FILE WANTED? JNZ AGAIN ;NO, SKIP FILE INIT ; ;'Declare' FCB for output file ;(temporarily named CRCKLIST.$$$) ; FILE OUTFILE,CRCFILE,,CRCKLIST,$$$,BSIZE ; AGAIN: LXI SP,STACK ;RE-INIT STACK POINTER CALL MFNAME ;SEARCH FOR NAMES JNC NAMTST ;ANOTHER FOUND, PRINT NAME LDA MFFLG1 ;NOTHING FOUND, CHECK... ORA A ;... FIRST TIME FLAG JZ DONE ;AT LEAST ONE WAS FOUND CALL ABEXIT ;PRINT MSG, THEN EXIT DB '++FILE NOT FOUND++$' ; DONE: CALL ILPRT ;PRINT "SUM OF CRC:" DB CR,LF,' ---------------------> SUM OF CRCS = ',0 LDA SUM+1 ; GET MSB CALL HEXO MVI A,' ' CALL TYPE LDA SUM ; GET LSB CALL HEXO CALL CRLF LDA FFLAG ;SEE IF WE'RE MAKING FILE CPI 'F' JNZ DONE2 ;NO, SKIP THE FILE STUFF ; ;Close CRCKLIST.$$$ FINIS CRCFILE ; ;Build FCB for final name of CRCKLIST.CRC FILE SETFILE,FINAL,,CRCKLIST,CRC ; ;Erase any existing old file ERASE FINAL ; ;Rename CRCKLIST.$$$ to CRCKLIST.CRC RENAME FINAL,CRCFILE ; ;Now exit to CP/M DONE2: CALL MSGEXIT ;PRINT DONE, THEN EXIT DB CR,LF,'DONE$' ; ;Test for names to ignore ; NAMTST: IF NOSYS LDA FCB+10 ;GET SYS ATTRIBUTE ANI 80H ;IS IT SYS? JNZ AGAIN ;YES, IGNORE THIS FILE ENDIF ;NOSYS ; ;Ignore files with .$$$ filetype (they are usually ;zero-length and clutter up our display. We also ;want to ignore our own CRCKLIST.$$$ temporary file). ; LXI H,FCB+9 ;POINT TO FILETYPE IN FCB CALL TSTBAD ;CHECK FOR .$$$ FILES JZ AGAIN ;IF ZERO FLAG, IGNORE THEM ; ;Move 8 characters from FCB+1 to FNAME LXI H,FCB+1 LXI D,FNAME LXI B,8 CALL MOVER ;Move 3 characters from FCB+9 to FNAME+9 LXI H,FCB+9 LXI D,FNAME+9 LXI B,3 CALL MOVER ;Now print filename.type CALL ILPRT ;PRINT: DB CR,LF,'--> FILE: ' FNAME: DB 'XXXXXXXX.XXX',TAB,TAB,'CRC = ',0 ; ;Open the file LXI D,FCB MVI C,OPEN CALL BDOS INR A JNZ RDINIT CALL ABEXIT DB '++OPEN FAILED++$' ; ;Initialize CRC to zero and set BUFAD to cause initial read RDINIT: LXI H,0 SHLD REM ;INIT REMAINDER TO ZERO LXI H,BASE+100H SHLD BUFAD ;INIT BUFFER ADRS ; ;This is the read loop READIT: LHLD BUFAD MOV A,H ;TIME TO READ? CPI BASE SHR 8 JZ NORD ;NO READ MVI C,CSTAT CALL BDOS ;CHECK FOR OPERATOR ABORT ORA A JZ READ2 ;NOTHING FROM OPERATOR MVI C,RDCON CALL BDOS ;GET CHARACTER INPUTTED CPI 'C'-40H ;CONTROL C? JZ ABEXT2 ;YES EXIT ; READ2: LXI D,FCB MVI C,READ ;READ ANOTHER SECTOR OF FILE CALL BDOS ORA A ;CHECK RETURN CODE JNZ FINISH ;ERROR OR EOF LXI H,BASE+80H ;BUFFER LOCATION ; NORD: MOV A,M ;GET FILE CHARACTER STA MESS ;SAVE FOR DIVP INX H SHLD BUFAD ;UPDATE BUFFER ADR CALL DIVP ;CALCULATE NEW CRC JMP READIT ;GO READ MORE CHARACTERS ; FINISH: CPI 1 ;NORMAL END-OF-FILE? JNZ FILERR ;NO, IT WAS A READ ERROR LDA REM+1 ;GET MSP OF CRC CALL HEXO ;PRINT IT MVI A,' ' CALL TYPE ;TYPE A SPACE LDA REM ;GET LSP OF CRC CALL HEXO ;PRINT IT CALL CRLF ;TURN UP NEW LINE LHLD REM ; GET PRESENT CRC XCHG LHLD SUM ; GET RUNNING SUM DAD D ; ADD THEM SHLD SUM ; SAVE BACK IN BUFFER JMP AGAIN ;SEE IF MORE FILES TO DO ; FILERR: CALL ABEXIT ;ABORT BECAUSE OF FILE READ ERROR DB '++FILE READ ERROR++$' ; ;--------------------------------------------- ;An 8080 routine for generating a CYCLIC- ;REDUNDANCY-CHECK. Character leaves that ;character in location REM. By Fred Gutman. ;From 'EDN' magazine, June 5, 1979 issue, page 84. ; DIVP: LHLD REM ;GET REMAINDER MOV A,H ANI 128 ;Q-BIT MASK PUSH PSW ;SAVE STATUS DAD H ;2 X R(X) LDA MESS ;MESSAGE BIT IN LSB ADD L MOV L,A POP PSW JZ QB2 ;IF Q-BIT IS ZERO ; QB: MOV A,H XRI 0A0H ;MS HALF OF GEN. POLY MOV H,A MOV A,L XRI 97H ;LS HALF OF GEN. POLY MOV L,A ; QB2: SHLD REM RET ;-------------------------------------------- ; ;Hex output ; HEXO: PUSH PSW ;SAVE FOR RIGHT DIGIT RAR ;RIGHT.. RAR ;..JUSTIFY.. RAR ;..LEFT.. RAR ;..DIGIT.. CALL NIBBL ;PRINT LEFT DIGIT POP PSW ;RESTORE RIGHT ; NIBBL: ANI 0FH ;ISOLATE DIGIT CPI 10 ;IS IS <10? JC ISNUM ;YES, NOT ALPHA ADI 7 ;ADD ALPHA BIAS ; ISNUM: ADI '0' ;MAKE PRINTABLE JMP TYPE ;PRINT IT, THEN RETURN ; ;Inline print routine ; ILPRT: XTHL ;SAVE HL, GET MSG ; ILPLP: MOV A,M ;GET CHAR CALL TYPE ;OUTPUT IT INX H ;POINT TO NEXT MOV A,M ;TEST ORA A ;..FOR END JNZ ILPLP XTHL ;RESTORE HL, RET ADDR RET ;RET PAST MSG ; ;Send carriage return, line feed to output ; CRLF: MVI A,CR ;CARRIAGE RETURN CALL TYPE MVI A,LF ;LINE FEED, FALL INTO 'TYPE' ; ;Send character in A register to output ; TYPE: PUSH B PUSH D PUSH H ANI 7FH ;STRIP PARITY BIT MOV E,A PUSH D CALL WRFILE ;WRITE TO FILE IF REQUESTED POP D MVI C,WRCON ;SEND CHARACTER TO CONSOLE CALL BDOS POP H POP D POP B RET ; ;Write character in E register to output file ; WRFILE: LDA FFLAG ;GET FILE TRIGGER CPI 'F' ;IS IT SET? RNZ ;NO, RETURN MOV A,E ;GET CHARACTER BACK PUT CRCFILE ;SEND IT TO THE FILE RET ; ;Multi-file access subroutine. Allows processing ;of multiple files (i.e. *.ASM) from disk. This ;routine builds the proper name in the FCB each ;time it is called. Carry is set if no more names ;can be found. The routine is commented in Pseudo ;code, each Pseudo code statement is in <<...>> ; MFNAME: ;<> MVI C,STDMA LXI D,BASE+80H CALL BDOS XRA A STA FCBEXT STA FCBRNO ;<> LDA MFFLG1 ORA A JZ MFN01 ;<> ;Save orig request LXI H,FCB LXI D,MFREQ LXI B,12 CALL MOVER LDA FCB STA MFCUR ;SAVE DISK IN CURR FCB ;<> LXI H,MFREQ LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHF LXI D,FCB CALL BDOS ;<> JMP MFN02 ; MFN01: ;<> LXI H,MFCUR LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHF LXI D,FCB CALL BDOS ;<> LXI H,MFREQ LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHN LXI D,FCB CALL BDOS ;<> MFN02: ;<> INR A STC RZ ;<> DCR A ANI 3 ADD A ADD A ADD A ADD A ADD A ADI 81H MOV L,A MVI H,BASE SHR 8 PUSH H ;SAVE NAME POINTER LXI D,MFCUR+1 LXI B,11 CALL MOVER ;<> POP H LXI D,FCB+1 LXI B,11 CALL MOVER ;<> XRA A STA FCBEXT STA FCBRNO STA MFFLG1 ;TURN OFF 1ST TIME SW ;<> RET ;------------------------------------------------ ; ;Check for .$$$ files ; TSTBAD: CALL TESTIT ;CHECK FIRST ONE FOR '$' RNZ ;NO, RETURN CALL TESTIT ;CHECK SECOND ONE RNZ ;NO, RETURN ;FALL INTO TESTIT TO CHECK THIRD ; TESTIT: MOV A,M ANI 7FH ;STRIP ATTRIBUTE CPI '$' ;CHECK FOR $ FILETYPE INX H RET ; ;Move (BC) bytes from (HL) to (DE) ; MOVER: MOV A,M STAX D INX H INX D DCX B MOV A,B ORA C JNZ MOVER RET ; ;Aborted - print reason. If making output file, ;close the incomplete file to update CP/M's bit map, ;then erase it. ; ABEXIT: POP D ;GET MSG ADRS MVI C,PRINT CALL BDOS ;PRINT MSG ; ABEXT2: LDA FFLAG ;SEE IF WE ARE MAKING FILE CPI 'F' JNZ ABEXT3 ;NO FILE, SKIP FILE STUFF FINIS CRCFILE ;CLOSE INCOMPLETE FILE ERASE CRCFILE ;ERASE INCOMPLETE FILE ; ABEXT3: CALL ERXIT ;PRINT MSG, EXIT DB CR,LF,CR,LF,'++ABORTED++$' ; ;Exit with message ; MSGEXIT:EQU $ ;EXIT W/"INFORMATIONAL" MSG ERXIT: POP D ;GET MSG MVI C,PRINT CALL BDOS ; ;Exit, restoring stack and return to CCP ; EXIT: LHLD STACK SPHL RET ;TO CCP ; ;Program storage area ; SUM: DW 0 ;BUFFER FOR SUM OF CRC'S FFLAG: DB 0 ;FILE WRITE REQUEST FLAG REM: DW 0 ;CRC REMAINDER STORAGE MESS: DB 0 ;CRC MESSAGE CHAR GOES HERE MFFLG1: DB 1 ;1ST TIME SWITCH MFREQ: DS 12 ;REQUESTED NAME MFCUR: DS 12 ;CURRENT NAME BUFAD: DS 2 ;READ BUFFER ADDRESS DS 60 ;STACK AREA STACK: EQU $ OLDSTK: DS 2 ;OLD STACK POINTER SAVED HERE ; ;Define location of file write buffer BUFFERS:EQU $ ; END CRCK te file to update CP/M's bit map, ;then erase it. ; ABEXIT: POP D ;GET MSG ADRS MVI C,PRINT CALL BDOS ;PRINT MSG ; ABEXT2: LDA FFLAG ;SEE IF WE ARE MAKING FILE CPI 'F' JNZ ABEXT3 ;NO FILE, SKIP FILE STUFF FINIS CRCFILE ;CLOSE INCOMPLETE FILEì+++AT H0 AT T S7=15 MODEMTATD =T+U B+ B+ $ 5+ U '+>2(=>2)=T+2)=@ >2)=T!7~~#> ~!<~~#!9" 1 *.|g"g!:w !> 2`͍WDIAL.COM (c)1983 Simon J. EwinsW R: Repeat dial routine F: File dial routine S: Search dial routine D: Directory routine K: Kill a file T: Type a file X: Execute named program I: Modem initialize string M: Modify X program name H: Hang-up ^C=Quit to CP/M. Select? (R(8F(qS,Dʫ Kʹ T I+ X M Hw >D2`W Enter number to dial: !G>~#̀:a>F2`W Enter filename: #>i2b͍i#OW Dialing from fileW: !j]W !G/#(/;(w#>ẁ:a(O;Oç;O>S2`͍W Filename? >o2bi)OW Area code to search: >!G:GW Is this area code long distance? ( 2c~W Enter a 7 digit # to start search: !J>:J:cY !PQ >12G>2R > 2G2H2I͍W Number Search Routine Saving numbers to fileW: !j]W ̀:aC I?͘>#5OW Saved: !G~( 5O~#>;5O> 5O> 5O" AW > 2`W NOTHING?:cY !K!J~<:(wk>0w~<:(wk>0w~<:(wk>0w~<:(wk>0w~<:(wk>0w~<:(wk>0w~<:k>>5OAO> 2a> ~!A~( ͒~#> ͒:`S W W : Try #>2d2e:w(C(5N(1*d#"d8 :w:w(t2f:w:fC(D2a2aW CONNECT:`S( (#:w:`F ;O >~2a> ~͚WDisconnecting...... > ͒?!~(͒#?! ~(͒#?:`S!G>:G!Gix( 2i:`S  >O(W +++ Can't find file. +++D!!!  !!C !9 !0 !' !  !5  !K   !h !> ~͚]D:bi ;A++ Undefined error ++++ File not open ++++ Disk full ++++ Input File not found ++++ Attempted read passed eof ++++ Directory full ++++ Error in closing file ++++ File was already open. ++ It is now closed, please try again.>͒v W File name to kill? >2dW File name to type? >i2b͍i#O/ (~ m ( ̽ d O;OW Done. Press any key for menu: ͽ ;O:d<2dWPress any key for next page or ^C to abort: >2dͽ d > ~͚:w(:w* W Loading file: !-]W.COM......., *g. *g.>w*g.|w*gw# x W Temporary modem init string change. To make a permanent change see .DOC file. Current string: !]W Enter new initialization string: >N0>2!OW ++ ERROR - Entry too long.DW Temporary modem program change. To make a permanent change see .DOC file. Current program: !-]W Enter new program name (no extension): >N 2,>2-.!--O!~(͒#> ͒:w?!!64>2 @"@͍ 7:@6x7*@##~#6+ü4m:/7C=m:1:3 7*@4 bk6 ʝO K) Q7 KB7> K> K: > @ ʝ2@O 7@ p77W4Y4!C=:@O~ʠ7 #Ô7!ɷ #"?~(w/"@d2 ,ʾ7w+2D W Directory for which drive? >N xA2[~2[AGDW Drive : = %%W files with͍WK free -------------------------------------- >;0>2[#yG]:[<2[0( W | gW Press any key for menu....(7?7??W >2[!>~(~# 2:ͭ>;???????????xx2=*O9"=:=2=@ !@Ns#Fr͡9ͪ9q#p*@^#V+*2̓:ͭ>;"***">*z$ |c##~2#~2#~2#^#V#"#^#V#"È*.;^#"#~2#~2#^#"2*ڥW+}ʶz Üi`:)= ^###~))))!o&:/oկ2u"!"u(73>*DMɯ+`o&~s*#"*z"*| s>~#z>?2u""!"u(Ͷ3£(`o&~ss*#"*z"*| sn*|6DM* + 'z x>2x"`i"*s#r#! xR*"*|g}o""*#"*}|i*"**}o|g"}|}*"y}**^Õ*DM*"*"** yW DIRALPHA -- Pointer Error*~#~*z*^#V*z"*^#V!z*##" y*DM+) +) Nq#Nq*DM+) +) N#F^#V`i: # # ~O#~?O#2"x? #8 8D8~w  ~:]@byy: w:G~y>xʩ ~/W~wʢDʢ~wÁ!""x ~~w*#"*z"ü ü*DM>22$կ~#:!,|!| ~A:A5<2#~:}?R2#~:}2G~#:p02 2OxGTx22}~:„#~,ʏ!ҧ >?”:G:O>~.»#ÚÚ*>?##> QO~!=_.:;,<>ɾ|}YmGGoGøGG\GyͺQBQCQDQEQHQLQMbSPcPSWQIQR bBCbDEbHLbAFjIXDjIYdrNZqZrNCqPrPOrPELDIAL RELghijDIAL PRNDIAL MAC01237FKNPQRSTUVf IAL MACRELCRFPRNJ#)y<=B3 SSc=@1=U2TUTc9@A!13U#/uAVWX| !d^#Vbk$w#*h*l*n!*j>*d~4>*hͲK>V>*l*ps#r*t6*d6*f~ʉ>*jͲʟ>*n*rs#r*v6*f6*d~>*p| ~2x#*ps#r*t5*l*ps#r*t6*p6#6:x>2x*f~$>*r:xw#*rs#r*v5T*n*rs#r*v6>:x*d62x>*v~ʔÄ*f6*jª>:xw ><24"2*2m*ʻ n  ʩʘʞvhw# **w#5*6*2*~*~ ʔʔ #À*%y%Þ6 #6 #:4**+~* ** +:4>~> ~>~6:4*2z{>~G:4x "~ 5,>#~l pyG>GO:4> ~Fitdn: ld a,13 call pout## ld a,(conin) ld (iy),a ret ; ds 100h stack: ds 2 ; ; ;........ end  ld a,1 call bbline## cp 0 jp z,sa2Q !R~#o|g6:N!S~Nw#A!S:R]~#ʱ ʛ , ʈ ʍʍʑbb byb byG>GO> ~§b2>2'd }0~n}o|g }o|gy:> ~ɯ2y0~> ~> ~ ~~~~ ~ ~>^~@~*.f/*. zO*. O*.x2y22:_:_ Y X OGa{_HW:H/W:r# x:HAzLI+|H{ozgt7}o|gtq}o|g}o}|g}o}o|gtqß|g}otq}o|g}o|g}o|g#}/o|/gկ2-!"+ͯ*+}o|g"+>2-͝*+:-tqF!"+|pE}p͝*+ͫ"+}o|gh"+}oiG!m!}$.*+ld (iy),a ret ; ds 100h stack: ds 2 ; ; ;........ end  ld a,1 call bbline## cp 0 jp z,sa2Q !R~#o|g6:N!S~Nw#A!S:R]~#ʱ ʛ , ʈ ʍʍʑbb byb byG>GO> ~§b2>2'd }0~n}o|g }o| DIAL is an extension to any terminal program allowing 3 dialing options and then the automatic load and execution of the terminal program itself. Of course the program that is loaded does not have to be a terminal or 'modem' program. I have had occasion to load and run 'wash', 'osd' and other utilities after dialing. Features and functions: 1. Continual dialing of a number or list of numbers from a file until one answers. 2. Searching of a range of numbers for a carrier. 6. Z80 code. 7. Typing of files. 8. Directory with disk system reset. This program will only run on z80 based machines. As distributed DIAL will run as-is on an Osborne-1 double-density machine with a Hayes Smartmodem connected to the rs232 port. A patch-list follows which should allow other auto-dial modems to be used. Other patches are indicated for video control on non-Osbornes. I would appreciate hearing from anyone who gets this program up and running on other hardware combinations as this will allow me to update DIAL towards a more universal version. Patches: ------- 106h = screen/keyboard iobyte value (assigns CON: to screen/keyboard) 107h = modem (rs232) iobyte value (assigns CON: to rs232) 108h = 5 byte escape or 'off-line' string (must end with 0) 10dh = 10 byte disconnect string (must end with 0) 117h = 21 byte modem initialize string (must end with 0) 12ch = number of characters in (terminal) program name to load with X option. 12dh = 10 bytes for terminal program name (must end with a 0) 137h = 5 byte clear screen string (must end with a 0) 13ch = 4 byte delete cursor string (your terminal's hex sequence to delete from the cursor to the end of the line) (must end with a 0) 141h = 6 byte dial string (your modem's command string to dial the number that follows) The following is an assembly listing of the patch area which you could modify with the values you need and after assembling it overlay the .hex file onto dial.com using ddt. After modifying dial.com enter: A>SAVE 31 DIAL.COM org 0108h ; conin: db 10010100b ;Screen/keyboard iobyte value ; rdrin: db 10010101b ;Modem (rs232) iobyte value ; escstr: db '+++',0,0 ;escape or 'go off-line' string ; hngmsg: db 'AT H0',13,0,0,0,0 ;disconnect string ; dinit: db 'AT T S7=15 ' ;modem initialize string db 0,0,0,0,0,0,0,0,0,0 ; filrun: db 5,'MODEM',0,0,0,0,0 ;name of program to run ;1st byte MUST be length of name ; clrscr: db 26,0,0,0,0 ;clear screen string ; dellin: db 27,54h,0,0,0 ;delete from cursor to end-of-line string ; dile: db 'ATD ' ;dial code ; ;........ end As coded above, a Smartmodem with an Osborne will run dial as described. The program is pretty well self prompting but a brief explanation of the functions follows: 1: The repeat option prompts for the number to dial. The number is dialed until a carrier is detected or the user aborts with ^C. 2: The file dial option will dial numbers sequentially from a file. At the end of the file the program loops back to the start again. This continues until a carrier is detected. The file must be structured as follows: #231-9538;comments etc. ie a # sign followed by the number, followed by a ; (semicolon) followed by any comments. Comments may continue for as many lines as you like as the program ignores all up to the next # sign. Example: #231-9538;.......RCP/M 1 Toronto #231-1262;.......RCP/M 2 Toronto #232-2644;.......Heath Toronto #423-3265;.......ETI Toronto #223-2625;.......Pet UG Toronto #624-5431;.......PSI Word-Pro Toronto #499-7023;.......PC Canada Toronto #222-3626;.......Nightowl Toronto #226-9260;.......Willowdale RCP/M, Toronto I keep two files on my modem disk, 1: phn.lst Which is a list of all phone numbers I have for Bulletin Boards &/or RCP/M Systems. If I want a number from a file I just use the Type option and get it. 2: phn.dil Which has those more commonly called numbers in it. If I want to just dial until I get a carrier I run the File dial option with the phn.dil file as the specified file. 3: The search function prompts for area code and whether or not it is long distance and then searches that area for carriers. If one is found it is stored to a disk file structured as shown for number 2: above. 4: Type will type a file one 'page' at a time. 5: Directory displays the directory for the selected drive and resets the disk system. (Any disk action also relogs the drives) 6: "M" will allow you to temporarily change the name of the program to be loaded when a carrier is found. 7: "I" will allow the temporary change of the modem initialization string. 8: "X" will jump to the named program without waiting for a carrier. 9: "K" will delete a file from the specified drive. When a carrier is found for all but the search option a bell is sounded until a key is struck at which time the named program is loaded. Simon Ewins, 08/13/83 676 Oriole Parkway, Toronto, Ontario. Phone: 416-484-9427 -------- end -------- rches that area for carriers. If one is found it is stored to a disk file structured as shown for number 2: above. 4: Type will type a file one 'page' at a time. 5: Directory displays the directory for the selected drive and resets the disk system. (Any disk action also relogs the drives) 6: "M" will allow you to temporarily change the name of the program to be loaded when a carrier is found. 7: "I" will allow the temporary change of the modem initialization string. 8:* 2:\=_<2\>?2h!m~#0> >W{_':N{2tY Invalid destination user #$2\<ª Originating file not found$=`!O :<2 ͻ\<ª:_ \ ͻ2\6$ !\ͻ!":22USER y ;log in to originating user y ; A>DUPUSR d:filename.typ x ;create files at destination user x ; Note that this program will totally duplicate the directory entry in ; all respects (except the user number, of course). This means that ; both entries will show the file with the same attributes, such as ; "read-only" or "system". The filename.typ may contain "?" and "*". ; ; The only known hazard in the use of this program occurs when erasing ; one of the duplicate entries. You must type control-c immediately ; after erasing the entry, so that cp/m is forced to rebuild the allocation ; vector for that drive. This is because the erase command frees the ; blocks shown for the erased file without checking if they are in use ; elsewhere. If you didn't type control-c, the next disk write would ; clobber these blocks, voiding all other pointers to the file. ; Unfortunately this would only be apparent the next time you tried ; to read the file from another user number, at which time you would ; read garbage. ; ; Please forward all comments, suggestions and improvements to: ; Bruce R. Ratoff ; 80 Gill Lane, Apt 1B ; Iselin, New Jersey 08830 ; ; ; bdos equ 5 ;cp/m entry point exit equ 0 ;cp/m exit point dfcb equ 5ch ;cp/m default fcb dbuff equ 80h ;default disk buffer ; pmessg equ 9 ;print message function seldsk equ 14 ;select drive function open equ 15 ;open file function close equ 16 ;close file function srchfst equ 17 ;search for first file match srchnxt equ 18 ;search for next file match delete equ 19 ;delete file function make equ 22 ;make file function attrib equ 30 ;set file attributes function gsuser equ 32 ;get/set user function ; ; org 100h begin: lhld bdos+1 ;set up a stack sphl ;at top of tpa mvi c,gsuser ;get our user # mvi e,0ffh call bdos sta ourusr ;save for later lda dfcb ;check for specific drive dcr a mov e,a ;set up for select disk call mvi c,seldsk inr a ;if no specified drive, skip call cnz bdos sub a ;now zap out drive spec sta dfcb mvi a,'?' ;force extent number wild sta dfcb+12 lxi h,dfcb+17 ;point to originating user # in cmd line mvi e,0 numlup: mov a,m ;get numeric (i hope) character inx h ;bump char pointer sui '0' ;remove ascii bias jc numdone cpi 10 ;check if past 9 jnc numdone ;any invalid char ends number mov d,a mov a,e ;get accumulated number add a ;times two add a ;times four add e ;times five add a ;times ten add d ;plus new digit mov e,a ;save accumulation jmp numlup ;loop back for next char numdone: lda ourusr ;make sure not same as us cmp e jz badusr mov a,e ;get destination user number sta dstusr ;save it cpi 16 ;legal? jc userok badusr: lxi d,ilgusr mvi c,pmessg ;bitch about illegal user # call bdos jmp exit ilgusr: db 'Invalid destination user #$' userok: sub a ;zero out file count sta filcnt lxi d,dfcb ;find the first file and get its block map mvi c,srchfst call bdos inr a ;search successful? jnz gotfile ;yes, go process rest lxi d,nofile mvi c,pmessg ;say "no file" call bdos jmp exit nofile: db 'Originating file not found$' gotfile: dcr a ;compensate for inr above rrc ;file offset to bits 5 and 6 rrc rrc ani 60h lxi h,dbuff  ;point to base of buffer mov c,a mvi b,0 dad b ;index by file offset push h ;save for the moment lxi b,filetable call filepoint ;get table pointer to hl xchg ;de now points to place in table lda filcnt inr a sta filcnt ;bump file count pop h ;hl points to directory entry mvi b,32 call blkmov ;copy entry into table mvi c,srchnxt ;search for another entry lxi d,dfcb call bdos inr a ;returns 0ffh at end of search jnz gotfile ;got another one...go save it ; ; end of directory encountered, now process them ; lda dstusr ;set to dest user mov e,a mvi c,gsuser call bdos ; ; main loop to set up one duplicate entry ; makefile: lxi b,filetable-32 ;allow for filcnt one greater than desired call filepoint push h ;save pointer lxi d,dfcb ;copy next name to default fcb mvi b,32 call blkmov sub a sta dfcb ;clear drive number lxi d,-20 ;point back to extent field dad d mvi m,'$' ;tag end of print here pop d ;get back pointer to start of entry inx d ;bump fwd to name mvi c,pmessg call bdos ;say what we're working on lxi h,dfcb lxi d,ourfcb ;copy name data to work fcb mvi b,14 call blkmov lxi h,0 shld ourfcb+14 ;zap frebyt, extlen lda ourfcb+9 ani 7fh ;clear r/o flag for create sta ourfcb+9 sub a sta ourfcb ;clear drive number lxi d,ourfcb mvi c,open call bdos ;check for existing file of same name inr a jnz makeok ;skip create if already there lxi d,ourfcb mvi c,make ;create the file call bdos inr a ;check for errors jnz makeok lxi d,makerr mvi c,pmessg ;say can't make file call bdos jmp exit makerr: db ', Cannot create file$' makeok: lxi h,dfcb+12 ;copy bookkeeping stuff from orig file lxi d,ourfcb+12 mvi b,20 call blkmov lda ourfcb+14 ;set update flag so that altered fcb ani 1fh ;gets written by close function sta ourfcb+14 ;(retain module # in low 5 bits) lxi d,ourfcb mvi c,close ;do a close to set size and block map call bdos inr a jnz closok ;check for errors lxi d,closerr mvi c,pmessg call bdos ;say close error jmp exit closerr: db ', Cannot close file$' closok: lda dfcb+9 ;was original file r/o? ora a ;set sign bit if yes jp nextfile ;done if no sta ourfcb+9 ;make our new file r/o to match lxi d,ourfcb mvi c,attrib ;do set attributes call call bdos nextfile: lxi h,filcnt ;point to file counter dcr m ;count it down jz exit ;exit if done lxi d,crlf mvi c,pmessg ;else do a crlf call bdos jmp makefile ;and go work on next one crlf: db 13,10,'$' ; ; ; subroutine to do block moves blkmov: mov a,m ;copy byte from m(hl) to m(de) stax d inx h ;bump pointers inx d dcr b ;loop for count in b jnz blkmov ret ; ; ; subroutine to index bc by file counter filepoint: lhld filcnt ;get file counter mvi h,0 ;force hi ord to 0 dad h ;multiply by 32 dad h dad h dad h dad h dad b ;use as index to file table ret ; ; ; ; filcnt: ds 1 ;count of files in filetable ourusr: ds 1 ;storage for our user number dstusr: ds 1 ;storage for destination user number ourfcb: ds 32 ;file control block for create function ; filetable equ $ ;start table here, take all avail memory ; end ew file r/o to match lxi d,ourfcb mvi c,attrib ;do set attributes call call bdos nextfile: lxi h,filcnt ;point to file counter dcr m ;count it down jz exit ;exit if done lxi d,crlf mvi c,pmessg ;else do a crlf call bdos jmp makefile ;and go work on next one crlf: db 13,10,'$' ; ; ; subroutine to do block moves blkmov: mov a,m ;copy byte from m(hl) to m(de) stax d inx h ;bump pointers inx d dcr b ;loop for count in b jnz blkmov ret ; ; ; subroutine to index bc by file counter filepoint: lhld filcnt ;get file counter mvi h,0 ;force hi ord to 0 dad h ;multiply by 32 dad h dad h dad h dad h dad b ;use as index to file table ret ; ; ; ; filcnt: ds 1 ;count of files in filetable ourusr% HP 1.0 - E.Meyer 9/84 !9"12~!:*]6!t6 #G!t:2}FʟB+-*ʔ^ʣ/ʅ%u&f|Q~> =) SsRr!!ut2{>2}!:!t:X:}!z{> 2t!"]>2~3!]6#3ͮ>2~3ͮ*]*_"_"]/ͮ*]|/g}/o#"]/ͮͦ|g}o"_/ͮͦ|g}o]ͮͦ*]ͮͦ*]ͮͦ ]ͮͦz´!]BKT] x] øͮͦR]ͮͦ]ͮF41_!m:]w#:^w/ͮF41_!m:~(~2]#~2^/+-*^/%&~=|sSrRF!4ʿ#J_ͮHqDzBʃCʌ!s9Ò!nÒ!Ò!)2s"q"7/**]*_:}!t^:~"]2~>->-/!_]!jl:s->>-> -MD!> گ)گ)= {ʰMD!>2"R?N*:=7i`~o o60#_sͲ͆W#͆_͗#_͗؃~Aڣ_0Ұ7~0¯#²Ͳ'd ~:ү0 گ=#~#01ðxGy$Oh&Ͳ~o&9d|G}GXX0:--> -dd|'ڌ„}ڌ u>0-|ګ£}ګ Ô>0-|¾}d ó>0-  >0-0-EyOx>0>1-d} -@>?>->^--_ɯ-#:!>-> -Hw/ͮF41_!m:~(~2]#~2^/+-*^/%&~=|sSrRF!4ʿ#J_ͮHqDzBʃCʌ!s9Ò!nÒ!Ò!)2s"q"7/**]*_:}!t^:~"]2~>->-/!_]!jl:s->>-> -MD!> گ)گ)= {ʰMD!>2"R?N*:=7i`~o o60#_sͲ͆W#͆_͗#_͗؃~Aڣ_0Ұ7~0¯#²Ͳ'd ~:ү0 گ=jHP+RSX ͍HP+ 1.0 - E.Meyer 9/84 :_FY͍Installed - use control-^ to call calculator.<͍Calculator no longer in RAM.M_㯆#͆ÍVHP+10RSX HP+ 1.0 - E.Meyer 9/84 "By2Aʉʗ ʮ2ʥ<{ M >2  {ʉʉ ʉ z *B#~_~Ì :!_~6!;!9"G1i2@! *!66 #!6 2?`+ʗ-ʌ*U^d/F%6&'|~ ʥ=SʡsʡRr!ڠ!762=>2?! !6 :?ʿ!<=> 26Ó!">2@!6#}ͼ>2@}**!"!"}*|/g}/o#"}u|g}o"!Ͱ}u|g}o}uڨ}uڨ}uڨ}uzu!BKT] xڨy}uR}u}4Ҩ1ڨ_!/:w#: w}4Ҩ1ڨ_!/:@ͼ~2#~2 +-*^/%&~=|sSrR!ʀ# _}H2D;BDCMè!BS!=S!S!25"@"!= *G*B:AO **!:?!6-ڟ:@—ͼ"2@>>!!!,.:5>>> MD!> ~)~)= {MD!>2C"ER?*E:C=i`~> >60#.B́UW#U_f#_f؃~Ar_07~0~#́'ͷͷdͷ ͷͷ~:~0~ ~=#~#01xGyOh&́~o&3|}''0:> 33|'[S}[ D>0|zr}z c>0|}dڕ Â>0 ڪ ß>00EyOûx>0>13} @>?>>^_ ɯ#  HB! H$$ @ I$H!B!B!$$I@IBIHIHDI$BBH!HABI$I$$ $DD $@$!I!BA@ AB"H !@H @A@ !!6-ڟ:@—ͼ"2@>>!!!,.:5>>> MD!> ~)~)= {MD!>2C"ER?*E:C=i`~> >60#.B́UW#U_f#_f؃~Ar_07~0~#́'ͷͷdͷ ͷͷ~:~0~ ~=#~#01xGyOh&́~o&3|}''0:> 33|'[S}[ D>0|zr}z c>0|}dڕ Â>0 ڪ ß>00EyOûx>0>13} @>?>>^ HP+.DOC ------- Documentation for HP+.COM Version 1.0 (c) Eric Meyer 9/84 Did you ever wonder what A00h/32 was, while editing source code? HP+.COM is a special version of my programmer's calculator program HP.COM, which allows the calculator to remain installed in RAM, always available for use, even within another program! The plain calculator program HP.COM will run on any CP/M 2 or 3 system. It operates much like a Hewlett-Packard RPN calculator, but has four display modes (bases). See HP.DOC for instructions on how to use the calculator. This file describes only the peculiar features of the RAM-based version, HP+. HP+.COM will ONLY work under CP/M Plus (3). When installed, it occupies 2.5K of RAM just under the BDOS. Do not install it more than once, or more RAM will be wasted. It can be called up for use at any time, until you do a cold boot (reset). It has "continuous memory" - if you exit and return to HP+, the stack and memories will remain unchanged. If you no longer need HP+ and wish to recover the memory it occupies, it can be removed from RAM. TO INSTALL THE CALCULATOR: A>HP+ TO REMOVE THE CALCULATOR: A>HP+ OFF TO USE THE CALCULATOR: Type control-caret (^^). (Note: if nothing happens immediately, follow the ^^ with RETURN.) The HP+ calculator should then appear on the line where your cursor was. Use the calculator according to the instructions in HP.DOC. When you're done, type a ^C to exit HP+. When you exit, HP+ returns you to EXACTLY where you were in the program you were running, which is still expecting input from you. The HP+ numeric display remains on your screen, but your program doesn't know that, so it doesn't matter. In an ordinary text editor, for example, it will be replaced by the text that's "really" there as soon as you start moving the cursor around. USING HP+ WITH UNUSUAL SOFTWARE HP+ will work as advertised above either from the CP/M "A>" prompt, or from within any program that does ordinary output to the screen, and ordinary input through a BDOS call (including BIOS calls through BDOS 50). HP+ may operate unexpectedly in programs that use memory-mapped video. For example, using HP+ from within the VDO-EX text editor on my Osborne Executive, the calculator appears at the bottom of the screen regardless of "cursor" position; and upon leaving HP+, that line may there- after appear in underlined video mode. However, these cosmetic differences do not interfere with use of the calculator, or normal editing. The only real problem is that HP+ will simply NOT work from programs that do input through direct BIOS calls. Now, there is NO excuse for software intended to be used under CP/M Plus to be written this way, but someone may have been sloppy. (My bundled Wordstar had this problem.) You may also be using software originally intended for CP/M 2. In any case, if you have some assembly language skills, you may be able to patch the offending program to work with HP+. You must replace any direct BIOS CONIN calls with a jump to a patch that sets up a BDOS 6 direct input call. Your program's operation should remain the same, but HP+ will now work in it. For example, here is the patch I had to install in my Wordstar 3.3. It has a routine 16DE that does direct BIOS calls by fetching the WMBOOT address from Page Zero. I found this by searching for LHLD 0001, which occurred at 1D75, followed by CALL 1777, MOV A,C, PCHL. When this is called for input, there is a 6 in A, which the subroutine at 1777 adds to WMBOOT, giving CONIN. So I changed CALL 1777 to CALL 02EB (a location in the MORPAT patch area), and at 02EB I put the following code: CPI 6, JNZ 1777, POP H, MVI C,6, MVI E,FD, JMP 0005. Thus the other BIOS calls continue undisturbed, but the jump to CONIN is replaced by one to BDOS 6. Afterwards, HP+ functioned perfectly from within Wordstar. ------------------------------------------------------------------------- HP.DOC ------ HP.COM is a simple "calculator" for programmers. It is modelled after a Hewlett-Packard with RPN logic. It can do addition, subtraction, multiplication, exponentiation, quotient, remainder, and bitwise logical operations. It has an 8-word stack and 3 memories. Best of all, it can display in any of four modes: hexadecimal, decimal, binary, and character. HP has been kept relatively small and simple, since I wanted to implement a RAM-resident version of it for use under CP/M Plus. This version, which can be used even from within other programs, is now available as HP+.COM. See HP+.DOC for details. All internal storage and arithmetic is unsigned 16 bit. Thus 65537 becomes 00001, -1 becomes 65535, and so on. Multiplication overflow and division by 0 generate errors, except that in binary and character modes, the display shows only the lowest 8 bits of 16, so 8-bit overflow does NOT usually cause an error. When you run HP, it will display its single operating line: A>hp HP 1.0 - E.Meyer 9/84 H> 0000 The "H" indicates Hex display mode, and the "0000" is the calculator display. The stack and memory are initialized to zero. Try pressing the following sequence of keys: "2", "+", 4, "*". You should see "00008", which is (0+2)*4. Type control-C (^C) to exit HP. This should give you the idea; now read on. If you have never used an RPN calculator, you'd better learn to first. ENTERING NUMBERS: Your "enter" (or "return") key, which I will henceforth call "", corresponds to the RPN "enter" key. It is used to separate two numbers entered in a row (or to intentionally duplicate the number in the display register on the stack). Typically you enter a string of digits, then hit to put the number on the stack. You do NOT hit after every number entry, as the other function keys ("+", etc) automatically terminate digit entry also. A maximum of 8 digits can be entered, after which the leading digits will begin to be discarded. On hitting (or another function key), the bell will ring if the string entered is not acceptable in the current display mode. You must then correct the string and try again. THE BACKSPACE KEY: Your backspace key (^H) works like the "<-" key on an HP-41C; it has two functions. During digit entry, it deletes the last digit typed. Otherwise, it zeros the current display (X) register, and leaves the stack lift disabled. DOING ARITHMETIC: The operations available, and the keys to invoke them are: "+" (addition, Y+X), "-" (subtraction, Y-X), "*" (multiplication, Y*X), "^" (exponentiation, Y^X), "/" (integer quotient, INT(Y/X)), "%" (remainder, X*(Y/X-INT(Y/X))), "&" (bitwise and, X&Y), "|" (bitwise or, X|Y), and "~" (negation [2's complement], ~X). Negation affects only the X register; the other operations use the values in the first two stack registers (X and Y), and return the result in the display (X), dropping the stack. The bell will ring if an undefined key is pressed as an operator. It will also ring, and multiplication "*" (also "^") will refuse to complete, if 16-bit overflow occurs. The same thing happens with "/" and "%" if division by 0 is attempted. The stack is left unchanged. Delete the offending operand and try again, if you wish. STACK OPERATIONS: You can clear the stack with control-X (^X) at any time. (Memory registers are not affected by ^X.) Also, you can exchange the contents of the two lowest registers (X<>Y) with the "=" exchange function. HP.COM does not have stack roll functions. MEMORY OPERATIONS: There are three memory registers (1-3), accessed with the commands "S" (or "s") for Store, and "R" (or "r") for Recall. To store the number in the display in register 2, for example, type "S2". To recall register 1 to the stack display, type "R1". THE ESCAPE KEY: Your escape key (ESC, or ^[) has two functions. First, it allows changing the display mode. You can type ESC H, ESC D, ESC B, or ESC C, and the display mode will change accordingly to Hex, Decimal, Binary, or Character. In hex mode, numbers display as four hex digits from 0000-FFFF. In decimal mode, you get five decimal digits from 00000-65535. In binary mode, the least significant byte of the number displays as 8 binary digits, 00000000-11111111. In character mode, the least significant 7 bits of the number display as an ASCII character, if printable, or as a "^" code otherwise. (Note: code 7F, DEL, will display as "^?".) Second, the ESC key allows you to enter as a digit those characters that would otherwise be calculator functions, namely "+-*^/%&|~=sSrR". For example to enter the character "s", use ESC s, not just "s" (or you will initiate a store to memory). Note that control codes (and the space, 20H) cannot be entered as data in character mode.  EXAMPLES Now it's time for some more practice. Try the following sample calculations. Press the keys shown, and see whether the answer you get is correct. In the problems, the "h" suffix indicates a hex number. (1) What is (122+31)*8 ? PRESS: ^X ESC D 1 2 2 3 1 + 8 * ANSWER: D> 01224 (2) How many 128-byte records are between addresses D000h and E100h? PRESS: ^X ESC H E 1 0 0 D 0 0 0 - ESC D 1 2 8 / ANSWER: D> 00034 (3) What character results from MVI A,'w' ANI 5FH (that is, "w"&5Fh) ? PRESS: ^X ESC C w ESC H 5 F & ESC C ANSWER: C> W (4) What does -115 look like in binary? PRESS: ^X ESC D 1 1 5 ~ ESC B ANSWER: B> 10001101 (5) What is 5 to the 4th power? PRESS: ^X ESC D 5 4 ^ ANSWER: D> 00625  B ANSWER: B> 10001101 (5) What is 5mory). Note that control codes (and the space, 20H) cannot be entered as data in character mode. !9"d 2f 2 1d  INUSE Version 1.1 :]/¿:^2f C INUSE is employed to print a banner on a user's terminal that said terminal is in use and by whom. A comment is asked for when INUSE is executed by the command line -- INUSE and this comment is printed with the INUSE Banner. After being asked for the comment, he is then asked for a password which should be typed to restore control. Both the comment and the password are typed in the usual fashion followed by a . After INUSE prints the Banner and the Comment, it waits for a user to hit the key, at which time it asks for the password. If the correct password is entered, control is restored to CP/M; otherwise, the Banner and Comment are reprinted and INUSE waits for the key again. The INUSE command takes three forms -- INUSE -- Runs INUSE INUSE /C -- Print INUSE Banner and Returns to CP/M INUSE /? -- Prints this HELP Message @ Comment? ! n Password? !k nE:f C@͵La|  Password? ! n!k  #5*d !a "i #zWl]OGpX͎X# [Ҋ_bk))u7~ʫ2#‘ 222Y 2KÙ#! ~# Eý> Exý##~#!   O2 2x # 2 22*. @O2*. Y*i ~#"i "g *g Lz ʳ , ʻw#I zw#az6*g Y~zI~  #Yuyu6 #6 ##z6z+~Iz zz6 +>E> E>E6#*g z{>E QE aE>#E#yG>GO> Em}pp**$bd#6I5p"AA"""> >EIQ>1!CEI1"AII6 $zIIIF>III&CDHP`6III60III>6"AA" @MP ~A]M9?HHH?III6AAAAAAA>IIIAHHH@AAIOAA"A  0AAAHHHxAECHLJy2III&@@@@p  pcc``CEIQaAAA AAA@ ?HHH?III6AAAAAAA>IIIAHHH@AAIOAA"A  0AAAHHHxAECHLJy2III&@@@@p  pcc``CEIQaOAA"A  0AAAHHHxPECHLJy2III&@@@@p  pcc``CEIQaAAA AAA@ ?HHP?III6AAAAAAA>IIIAHHH@AAIOAA"A  0AAAHHHxAECPHLJy2III&@@@@p  pcc``CEIQaOAA"A  0* INUSE *z ʳ , ʻw#I zw#az6*g Y~zI~  #Yuyu6 #6 ##z6z+~Iz zz6 +>E> E>E6#*g z{>E QE aE>#E#yG>GO> Em}pp**$bd#6I5p"AA"""> >EIQ>1!CEI1"AII6 $zIIIF>III&CDHP`6III60III>6"AA" @MP ~A]M9?HHH?III6AAAAAAA>IIIAHHH@AAIOAA"A  0AAAHHHxAECHLJy2III&@@@@p  pcc``CEIQaAAA AAA@ ?HHH?III6AAAAAAA>IIIAHHH@AAIOAA"A  0* PROGRAM: INUSE * AUTHOR: RICHARD CONN * VERSION: 1.1 * DATE: 6 MAR 82 * DERIVATION: From BANNER Version 1.0 by Richard Conn ... which was from: * DERIVATION: From Public Domain BANNER Program, Author Unknown * PREVIOUS VERSIONS: 1.0 (12 Jan 82) * ********************************* * * * I N U S E P R I N T * * * ********************************* * * INUSE is a program which prints large (5x7) block letters * on the CON: Device the word 'INUSE'. When first started up, INUSE * asks for a password, to which the user gives a desired password. * INUSE is intended to be terminated by the user typing an Escape Character * and then giving the original password. * * INUSE is executed in one of three forms: * INUSE -- Normal operation * INUSE /C -- Print INUSE Banner and Return to CP/M (C is for Continue) * INUSE /? -- Prints HELP Info SHLD START ; SAVE START OF STRING * INLINE RESTART LOOP INL0: LHLD START ; GET START OF STRING MVI C,0 ; SET CHAR COUNT * MAIN LOOP INL1: CALL CIN ; GET INPUT CHAR CPI NULL ; DO NOT PERMIT JZ INL1 CPI BS ; BACKSPACE? JZ INBS CPI DEL ; DELETE? JZ INDEL CPI TAB ; TABULATE? JZ INTAB CPI CR ; CARRIAGE RETURN? JZ INCR CPI LF ; LINE FEED? JZ INLF CPI CTRLU ; CTRL-U? JZ RESTRT CPI CTRLX ; CTRL-X? JZ REXSTRT CPI CTRLR ; CTRL-R? JZ RETYPE MOV M,A ; STORE CHAR INX H ; PT TO NEXT CALL CTRL ; PRINT CHAR INR C ; INCR CHAR CNT JMP INL1 * * ** INLINE MODULES ** * * TAB -- TABULATE TO NEXT TAB STOP INTAB: MOV M,A ; STORE INX H ; PT TO NEXT CHAR POSITION CALL INTAB0 ; TABULATE JMP INL1 * CTRL-R -- RETYPE CURRENT LINE RETYPE: MVI M,0 ; STORE END OF STRING CHAR MVI C,0 ; RESET CHAR CNT LHLD START ; GET START ADDRESS CALL HASH ; PRINT HASH CHAR RETY1: MOV A,M ; GET CHAR ORA A ; ZERO? JZ INL1 ; CONTINUE CALL CTRL ; PRINT IT MOV A,M ; GET CHAR AGAIN CPI TAB ; DON'T COUNT IF JZ RETY2 CPI BEL ; DON'T COUNT IF JZ RETY2 INR C ; INCR CHAR CNT RETY2: INX H ; PT TO NEXT CHAR JMP RETY1 * CTRL-U -- ERASE LINE AND RESTART RESTRT: CALL HASH ; PRINT HASH CHAR JMP INL0 ; START UP AGAIN * CTRL-X -- ERASE (AND BACKSPACE) LINE AND RESTART REXSTRT: MOV A,C ; CHECK FOR EMPTY LINE ORA A ; 0 CHARS? JZ INL0 CALL EXBS ; JMP REXSTRT * LINE FEED -- INSERT AND ECHO INLF: MVI M,CR ; STORE INX H ; PT TO NEXT MVI M,LF ; STORE INX H ; PT TO NEXT MVI C,0 ; RESET CHAR CNT CALL CRLF ; NEW LINE JMP INL1 * DELETE -- DELETE PREVIOUS CHAR AND ECHO DELETED CHAR INDEL: CALL BOL ; BEGINNING OF LINE? JZ INL1 ; CONTINUE DCX H ; BACK UP MOV A,M ; GET CHAR CALL CTRL ; PRINT CHAR CPI BEL ; DON'T CHANGE COUNT IF JZ INL1 INR C ; INCR DISPLAY CHAR COUNT JMP INL1 * BACKSPACE -- DELETE PREVIOUS CHAR AND BACK UP CURSOR INBS: CALL EXBS ; EXECUTE JMP INL1 * BACKSPACE ROUTINE EXBS: CALL BOL ; BEGINNING OF LINE? RZ ; CONTINUE IF SO DCR C ; DECR COUNT DCX H ; BACK UP  MVI A,BS ; PRINT CALL COUT MVI A,' ' ; CALL COUT MVI A,BS ; CALL COUT RET * CARRIAGE RETURN -- DONE; STORE ENDING ZERO INCR: MVI M,0 ; STORE ENDING ZERO CALL CRLF ; NEW LINE POP PSW ; RESTORE PSW POP B ; RESTORE REGS POP D POP H RET * * ** SUPPORT ROUTINES ** * BOL -- RETURNS W/ZERO FLAG SET IF USER AT BEGINNING OF LINE * BOL: XCHG ; DE=HL LHLD START ; GET START ADR XCHG ; HL RESTORED MOV A,D ; CHECK FOR MATCH CMP H ; MATCH? RNZ ; NO MATCH MOV A,E ; CHECK FOR COMPLETE MATCH CMP L RNZ ; NO MATCH PUSH PSW ; SAVE FLAGS MVI A,BEL ; BEEP CALL COUT POP PSW RET * CTRL -- IF CHAR>=, PRINT IT; OTHERWISE, PRINT AS CTRL-CHAR CTRL: CPI ' ' ; ? JC CTRL1 JMP COUT ; PRINT IT NORMALLY CTRL1: CPI TAB ; TRAP JZ INTAB0 JMP COUT ; PRINT * HASH -- PRINT HASH MARK FOLLOWED BY HASH: MVI A,'#' ; PRINT HASH CHAR CALL COUT JMP CRLF * INTAB0 -- TABULATE ON SCREEN INTAB0: MOV A,C ; GET CHAR CNT ANI 7 ; MASK FOR DIFFERENCE FROM 8 MOV B,A ; STORE IN REG B TEMPORARILY MVI A,8 ; SUBTRACT FROM 8 SUB B MOV B,A ; COUNT IN B ADD C ; ADD TO CHAR COUNT MOV C,A MVI A,' ' ; IN A INTAB1: CALL COUT ; PRINT DCR B ; COUNT DOWN JNZ INTAB1 RET * * CHARACTER TABLE * THE CHARACTERS REPRESENTED IN THIS TABLE ARE IN A 5X7 FORMAT * THE FIRST BYTE IN EACH ENTRY REPRESENTS THE FIRST CHAR TO PRINT, ETC * THE BITS 6 TO 0 REPRESENT LINES (SUCCESSIVE) TO PRINT FOR THE CHAR * CHARS: DB 00H,00H,00H,00H,00H ; DB 00H,00H,7DH,00H,00H ;EXCLAMATION MARK DB 00H,70H,00H,70H,00H ;" DB 14H,7FH,14H,7FH,14H ;# DB 12H,2AH,7FH,2AH,24H ;$ DB 62H,64H,08H,13H,23H ;% DB 36H,49H,35H,02H,05H ;& DB 00H,00H,70H,00H,00H ;' DB 1CH,22H,41H,00H,00H ;( DB 00H,00H,41H,22H,1CH ;) DB 22H,14H,7FH,14H,22H ;* DB 08H,08H,3EH,08H,08H ;+ DB 00H,01H,06H,00H,00H ;, DB 08H,08H,08H,08H,08H ;- DB 00H,03H,03H,00H,00H ;. DB 02H,04H,08H,10H,20H ;/ DB 3EH,45H,49H,51H,3EH ;0 DB 11H,31H,7FH,01H,01H ;1 DB 21H,43H,45H,49H,31H ;2 DB 22H,41H,49H,49H,36H ;3 DB 0CH,14H,24H,7FH,04H ;4 DB 7AH,49H,49H,49H,46H ;5 DB 3EH,49H,49H,49H,26H ;6 DB 43H,44H,48H,50H,60H ;7 DB 36H,49H,49H,49H,36H ;8 DB 30H,49H,49H,49H,3EH ;9 DB 00H,00H,36H,00H,00H ;: DB 00H,01H,16H,00H,00H ;; DB 08H,14H,22H,41H,00H ;< DB 14H,14H,14H,14H,14H ;= DB 00H,41H,22H,14H,08H ;> DB 20H,40H,4DH,50H,20H ;? DB 7EH,41H,5DH,4DH,39H ;@ DB 3FH,48H,48H,48H,3FH ;A DB 7FH,49H,49H,49H,36H ;B DB 7FH,41H,41H,41H,41H ;C DB 7FH,41H,41H,41H,3EH ;D DB 7FH,49H,49H,49H,41H ;E DB 7FH,48H,48H,48H,40H ;F DB 7FH,41H,41H,49H,4FH ;G DB 7FH,08H,08H,08H,7FH ;H DB 41H,7FH,41H,80H,80H ;I DB 03H,01H,01H,01H,7FH ;J DB 7FH,08H,14H,22H,41H ;K DB 7FH,01H,01H,01H,01H ;L DB 7FH,20H,10H,20H,7FH ;M DB 7FH,30H,08H,06H,7FH ;N DB 7FH,41H,41H,41H,7FH ;O DB 7FH,48H,48H,48H,78H ;P DB 7FH,41H,45H,43H,7FH ;Q DB 7FH,48H,4CH,4AH,79H ;R DB 32H,49H,49H,49H,26H ;S DB 40H,40H,7FH,40H,40H ;T DB 7FH,01H,01H,01H,7FH ;U DB 70H,0CH,03H,0CH,70H ;V DB 7FH,02H,04H,02H,7FH ;W DB 63H,14H,08H,14H,63H ;X DB 60H,10H,0FH,10H,60H ;Y DB 43H,45H,49H,51H,61H ;Z DB 7FH,41H,41H,41H,00H ;[ DB 20H,10H,08H,04H,02H ;\ DB 00H,41H,41H,41H,7FH ;] DB 04H,08H,10H,08H,04H ;^ DB 01H,01H,01H,01H,01H ;_ DB 00H,40H,20H,10H,00H ;@ DB 3FH,48H,48H,48H,3FH ;A DB 7FH,49H,49H,49H,36H ;B DB 7FH,41H,41H,41H,41H ;C DB 7FH,41H,41H,41H,3EH ;D DB 7FH,49H,49H,49H,41H ;E DB 7FH,48H,48H,48H,40H ;F DB 7FH,41H,41H,49H,4FH ;G DB 7FH,08H,08H,08H,7FH ;H DB 41H,7FH,41H,80H,80H ;I DB 03H,01H,01H,01H,7FH ;J DB 7FH,08H,14H,22H,41H ;K DB 7FH,01H,01H,01H,01H ;L DB 7FH,20H,10H,20H,7FH ;M DB 7FH,30H,08H,06H,7FH ;N DB 7FH,41H,41H,41H,7FH ;O DB 7FH,48H,48H,48H,78H ;P DB 7FH,41H,45H,43H,7FH ;Q DB 7FH,48H,4CH,4AH,79H ;R DB 32H,49H,49H,49H,26H ;S DB 40H,40H,7FH,40H,40H ;T DB 7FH,01H,01H,01H,7FH ;U DB 70H,0CH,03H,0CH,70H ;V DB 7FH,02H,04H,02H,7FH ;W DB 63H,14H,08H,14H,63H ;X DB 60H,10H,0FH,10H,60H ;Y DB 43H,45H,49H,51H,61H ;Z * * BUFFERS * DS 40 ;20-ELT STACK STACK: DS 2 ;TOP OF BANNER STACK; CP/M STACK CONTFLG: DS 1 ;0=DON'T CONTINUE, 'C'=CONTINUE START: DS 2 ;START ADDRESS OF INPUT STRING NEXTCH: DS 2 LLEN EQU 80 ;NUMBER OF CHARS IN LINE, MAX INLINE: DB LLEN ;CHAR COUNT FOR INLINE DS LLEN+1 RDLINE: DB LLEN ;CHAR COUNT FOR RDLINE DS LLEN+1 COMMENT: DB LLEN DS LLEN+1 BLINE: DB '* INUSE *',0 ; MESSAGE END H,08H,08H,7FH ;H DB 41H,7FH,41H,80H,80H ;I DB 03H,01H,01H,01H,7FH ;J DB 7FH,08H,14H,22H,41H ;K DB 7FH,01H,01H,01H,01H ;L DB 7FH,20H,10H,20H,7FH ;M DB 7FH,30H,08H,06H,7FH ;N DB 7FH,41H,41H,41H,7FH ;O DB 7FH,48H,48H,48H,78H ;P DB 7FH,41H,45H,43H,7FH ;Q DB 7FH,48H,4CH,4AH,79H ;R DB 32H,49H,49H,49H,26H ;S DB 40H,40H,7FH,40H,40H ;T DB 7FH,01H,01H,01H,7FH ;U DB 70H,0CH,03H,0CH,70H ;V DB 7FH,02H,04H,02H,7FH ;W DB 63H,14H,08H,14H,63H ;X DB 60H,10H,0FH,10H,60H ;Y DB 43H,45H,49H,51* PROGRAM: INUSE * AUTHOR: RICHARD CONN * VERSION: 1.1 * DATE: 6 MAR 82 * DERIVATION: From BANNER Version 1.0 by Richard Conn ... which was from: * DERIVATION: From Public Domain BANNER Program, Author Unknown * PREVIOUS VERSIONS: 1.0 (12 Jan 82) VERS EQU 11 ;VERSION NUMBER ********************************* * * * I N U S E P R I N T * * * ********************************* * * INUSE is a program which prints large (5x7) block letters * on the CON: Device the word 'INUSE'. When first started up, INUSE * asks for a password, to which the user gives a desired password. * INUSE is intended to be terminated by the user typing an Escape Character * and then giving the original password. * * INUSE is executed in one of three forms: * INUSE -- Normal operation * INUSE /C -- Print INUSE Banner and Return to CP/M (C is for Continue) * INUSE /? -- Prints HELP Info * ********************************* * User-Customized Parameters * *********************************  ESC EQU 1BH ; ESCAPE CHARACTER TO INPUT PASSWORD ********************************* * Constants * ********************************* BOOT EQU 0000H JTABL EQU BOOT+1 BDOS EQU BOOT+5 FCB EQU BOOT+005CH BUFF EQU BOOT+0080H CTRLC EQU 03H * * ASCII SPECIAL CHARACTER EQUATES * NULL EQU 0 ; NULL BEL EQU 7 ; BELL BS EQU 8 ; BACKSPACE TAB EQU 9 ; TAB LF EQU 10 ; LINE FEED CR EQU 13 ; CARRIAGE RETURN CTRLR EQU 'R'-40H ; CTRL-R CTRLU EQU 'U'-40H ; CTRL-U CTRLX EQU 'X'-40H ; CTRL-X DEL EQU 7FH ; DELETE CHAR ORG 100H LXI H,0 ; GET STACK PTR DAD SP SHLD STACK ; SAVE IT XRA A ; A=0 STA CONTFLG ; CLEAR CONTINUE FLAG STA COMMENT ; CLEAR COMMENT LINE LXI SP,STACK ; SET NEW SP CALL PMSG ; PRINT PROMPT DB CR,LF,'INUSE Version ',VERS/10+'0','.',(VERS MOD 10)+'0',CR,LF DB 0 LDA FCB+1 ; GET FIRST CHAR OF FCB CPI '/' ; QUERY? JNZ IN1 LDA FCB+2 ; GET 2ND CHAR STA CONTFLG ; SET FLAG CPI 'C' ; CONTINUE? JZ INUSE CALL PMSG DB CR,LF,' INUSE is employed to print a banner on a user''s' DB CR,LF,'terminal that said terminal is in use and by whom. A' DB CR,LF,'comment is asked for when INUSE is executed by the' DB CR,LF,'command line -- ' DB CR,LF,' INUSE' DB CR,LF,'and this comment is printed with the INUSE Banner.' DB CR,LF,'After being asked for the comment, he is then asked for' DB CR,LF,'a password which should be typed to restore control.' DB CR,LF,'Both the comment and the password are typed in the' DB CR,LF,'usual fashion followed by a .' DB CR,LF,' After INUSE prints the Banner and the Comment, it' DB CR,LF,'waits for a user to hit the key, at which' DB CR,LF,'time it asks for the password. If the correct password' DB CR,LF,'is entered, control is restored to CP/M; otherwise,' DB CR,LF,'the Banner and Comment are reprinted and INUSE waits' DB CR,LF,'for the key again.' DB CR,LF,' The INUSE command takes three forms --' DB CR,LF,' INUSE -- Runs INUSE' DB CR,LF,' INUSE /C -- Print INUSE Banner and Returns to' DB ' CP/M' DB CR,LF,' INUSE /? -- Prints this HELP Message' DB CR,LF,0 JMP EXIT IN1: CALL PMSG DB ' Comment? ',0 LXI H,COMMENT CALL SINLINE ; READ LINE FROM CON: CALL PMSG DB ' Password? ',0 LXI H,INLINE CALL SINLINE ; READ LINE FROM CON: INUSE: CALL SPACER ; SPACE DOWN ON SCREEN CALL BANNER ; PRINT INUSE MESSAGE LDA CONTFLG ; CONTINUE? CPI 'C' ; 'C' IF SO JZ EXIT CALL PRCMT ; PRINT COMMENT ON NEXT LINE CALL SPACER ; SPACE DOWN ON SCREEN INUSE1: CALL CIN ; GET CHAR ANI 7FH ; MASK MSB CPI 61H ; SMALL A? JC INUSE2 CPI 61H+26+1 ; > SMALL Z? JNC INUSE2 SUI 20H ; CAPITALIZE INUSE2: CPI ESC ; ESCAPE CHAR? JNZ INUSE1 CALL PMSG DB CR,LF,' Password? ',0 LXI H,RDLINE CALL SINLINE ; READ LINE FROM CON: LXI H,INLINE ; COMPARE PASSWORDS LXI D,RDLINE INUSE3: LDAX D ; GET NEXT CHAR CMP M ; COMPARE JNZ INUSE ; NEW BANNER IF NO MATCH INX H ; PT TO NEXT INX D ORA A ; DONE? JNZ INUSE3 * *  Exit INUSE * EXIT: LHLD STACK ;GET OLD STACK PTR SPHL ;LOAD SP RET * * PRINT BANNER CONTAINED IN BLINE BUFFER * BANNER: MVI D,80H ;PT TO MSB+1 CBAN: LXI H,BLINE ;SET PTR TO FIRST CHAR SHLD NEXTCH CALL CRLF ;NEW LINE MOV A,D ;GET BIT PTR RRC ;ROTATE ANI 7FH ;MASK OUT MSB MOV D,A ;SET BIT PTR JZ CB2 ;NEW LINE AND THEN EXIT CB1: CALL CONIN ;GET NEXT CHAR MOV C,A ;CHAR IN C ORA A ;DONE? JZ CBAN ;DO NEXT LINE IF SO CALL CONV ;GET ADDRESS OF DATA IN HL JC CB1 ;SKIP IF ERROR CALL PRINT ;PRINT 5 CHARS FOLLOWED BY TWO SPACES JMP CB1 ;CONTINUE CB2: CALL CRLF ;1 CRLF RET * * COMPUTE POINTER TO TABLE ENTRY OF CHAR IN REG A * ON INPUT, A=CHAR; ON OUTPUT, HL=PTR TO TABLE ENTRY (1ST BYTE) * CONV: PUSH B ;SAVE BC PUSH D ;SAVE DE SUI ' ' ;CONVERT TO 0 RC ;INVALID CHAR CPI 7BH-' ' ;IN RANGE? JNC CNVER ;INVALID CHAR MOV E,A ;VALUE IN E MVI D,0 ;VALUE IN DE MOV H,D ;VALUE IN HL MOV L,E DAD H ;VALUE * 2 DAD H ;VALUE * 4 DAD D ;HL = VALUE * 5 LXI D,CHARS ;POINT TO BEGINNING OF TABLE DAD D ;HL PTS TO ELEMENT IN TABLE POP D ;RESTORE DE POP B ;RESTORE BC ORA A ;CLEAR CARRY RET CNVER: STC ;SET CARRY FOR INVALID CHAR POP D ;RESTORE DE POP B ;RESTORE BC RET * * PRINT CHAR IN C ACCORDING TO THE ENTRY PTED TO BY HL * BIT MASK IS IN D * PRINT: PUSH B ;SAVE BC (C=CHAR) MVI B,5 ;5 BYTES/CHAR PRINT1: MOV A,M ;GET BIT SET ANA D ;MASK FOR BIT IN QUESTION JZ PRINT3 ;IF ZERO, PRINT CALL CONOUT ;PRINT CHAR IN C PRINT2: INX H ;PT TO NEXT BYTE DCR B ;COUNT DOWN JNZ PRINT1 MVI C,' ' ;PRINT THREE SPACES CALL CONOUT CALL CONOUT CALL CONOUT POP B ;RESTORE BC RET PRINT3: MOV E,C ;SAVE CHAR MVI C,' ' ;PRINT CALL CONOUT MOV C,E ;GET CHAR JMP PRINT2 * * PRINT COMMENT ON SCREEN IF ANY * PRCMT: CALL CRLF ; NEW LINE LXI H,COMMENT ; PT TO CHAR COUNT MVI B,0 ; SET TAB COUNT PRCMT1: MOV A,M ; GET CHAR INX H ; PT TO NEXT ORA A ; DONE IF ZERO JZ PRCMT2 CPI TAB ; TABULATE? JZ PRCMTAB CALL COUT ; PRINT CHAR INR B ; INCREMENT CHAR COUNT JMP PRCMT1 PRCMTAB: MVI A,' ' ; CALL COUT INR B ; INCR CHAR COUNT MOV A,B ; GET CHAR COUNT ANI 7 ; DONE WITH TAB? JNZ PRCMTAB JMP PRCMT1 PRCMT2: CALL CRLF ; NEW LINE RET * * SUPPORT ROUTINES * SPACER: MVI B,8 ; GO DOWN SCREEN SPACE0: CALL CRLF ; NEW LINE DCR B ; COUNT DOWN JNZ SPACE0 RET PMSG: XTHL ;GET PTR TO STRING PMSG0: MVI B,0 ;SET TAB COUNTER PMSG1: MOV A,M ;GET NEXT BYTE INX H ;PT TO NEXT ORA A ;DONE? JZ PMSG2 CPI TAB ;TABULATE? JZ PMSG$TAB CPI CR ;NEW LINE? JZ PMSG$CR CPI LF ;SKIP LF JZ PMSG1 MOV C,A ;CHAR IN C CALL CONOUT ;PRINT CHAR INR B ;INCR CHAR COUNT JMP PMSG1 PMSG$TAB: MVI C,' ' ;PRINT CALL CONOUT ;PRINT INR B ;INCR POSITION COUNT MOV A,B ;GET IT ANI 7 ;DONE? JNZ PMSG$TAB JMP PMSG1 ;PROCESS NEXT CHAR PMSG$CR: CALL CRLF ;NEW LINE JMP PMSG0 PMSG2: XTHL ;RESTORE HL, PTR RET CRLF: MVI C,CR CALL CONOUT MVI C,LF CALL CONOUT MVI C,0 ; 2 S CALL CONOUT ; FALL THRU FOR 2ND * * PRINT CHAR IN C * CONOUT: PUSH PSW ; SAVE REG A AND FLAGS PUSH H ; SAVE REGS PUSH D PUSH B LHLD JTABL ; GET ADDRESS OF JUMP TABLE MVI L,12 ; CONSOLE OUTPUT ADR LXI D,CRET1 ; SET UP RET ADR PUSH D ; ... ON STACK PCHL CRET1: POP B ; RESTORE REGISTERS POP D POP H POP PSW ; RESTORE REG A AND FLAGS RET * * PRINT CHAR IN A * COUT: PUSH B ; SAVE BC MOV C,A ; CHAR IN C CALL CONOUT ; PRINT IN C POP B ; RESTORE BC RET * * INPUT CHAR IN A FROM BIOS * CIN: PUSH H ; SAVE REGS PUSH D PUSH B LHLD JTABL ; GET ADDRESS OF JUMP TABLE MVI L,9 ; CONSOLE INPUT ADR LXI D,CRET2 ; SET UP RET ADR PUSH D ; ... ON STACK PCHL CRET2: POP B ; RESTORE REGISTERS POP D POP H RET * * INPUT NEXT CHAR IN BUFFER IN A * CONIN: PUSH H ! PUSH D ! PUSH B LHLD NEXTCH ;GET NEXT CHAR PTR MOV A,M ;GET CHAR INX H ;PT TO NEXT SHLD NEXTCH ANI 7FH ;MASK MSB IF ANY POP B ! POP D ! POP H RET * * SINLINE -- * INPUT LINE EDITOR * INPUT A LINE FROM CON: INTO THE BUFFER POINTED TO BY H&L * INPUT LINE EDITING CHARACTERS ARE -- * -- DELETE PREVIOUS CHAR AND BACK UP CURSOR (SOFTCOPY) * -- DELETE PREVIOUS CHAR AND ECHO IT (HARDCOPY) * -- INPUT COMPLETE * -- SKIP DOWN TO NEXT LINE AND INSERT * CTRL-X -- ERASE CURRENT LINE AND BACK UP CURSOR (SOFTCOPY) * CTRL-U -- ERASE CURRENT LINE (HARDCOPY) * CTRL-R -- RETYPE CURRENT LINE * SINLINE: PUSH H ; SAVE REGS PUSH D PUSH B PUSH PSW ; SAVE PSW SHLD START ; SAVE START OF STRING * INLINE RESTART LOOP INL0: LHLD START ; GET START OF STRING MVI C,0 ; SET CHAR COUNT * MAIN LOOP INL1: CALL CIN ; GET INPUT CHAR CPI NULL ; DO NOT PERMIT JZ INL1 CPI BS ; BACKSPACE? JZ INBS CPI DEL ; DELETE? JZ INDEL CPI TAB ; TABULATE? JZ INTAB CPI CR ; CARRIAGE RETURN? JZ INCR CPI LF ; LINE FEED? JZ INLF CPI CTRLU ; CTRL-U? JZ RESTRT CPI CTRLX ; CTRL-X? JZ REXSTRT CPI CTRLR ; CTRL-R? JZ RETYPE MOV M,A ; STORE CHAR INX H ; PT TO NEXT CALL CTRL ; PRINT CHAR INR C ; INCR CHAR CNT JMP INL1 * * ** INLINE MODULES ** * * TAB -- TABULATE TO NEXT TAB STOP INTAB: MOV M,A ; STORE INX H ; PT TO NEXT CHAR POSITION CALL INTAB0 ; TABULATE JMP INL1 * CTRL-R -- RETYPE CURRENT LINE RETYPE: MVI M,0 ; STORE END OF STRING CHAR MVI C,0 ; RESET CHAR CNT LHLD START ; GET START ADDRESS CALL HASH ; PRINT HASH CHAR RETY1: MOV A,M ; GET CHAR ORA A ; ZERO? JZ INL1 ; CONTINUE CALL CTRL ; PRINT IT MOV A,M ; GET CHAR AGAIN CPI TAB ; DON'T COUNT IF JZ RETY2 CPI BEL ; DON'T COUNT IF JZ RETY2 INR C ; INCR CHAR CNT RETY2: INX H ; PT TO NEXT CHAR JMP RETY1 * CTRL-U -- ERASE LINE AND RESTART RESTRT: CALL HASH ; PRINT HASH CHAR JMP INL0 ; START UP AGAIN * CTRL-X -- ERASE (AND BACKSPACE) LINE AND RESTART REXSTRT: MOV A,C ; CHECK FOR EMPTY LINE ORA A ; 0 CHARS? JZ INL0  CALL EXBS ; JMP REXSTRT * LINE FEED -- INSERT AND ECHO INLF: MVI M,CR ; STORE INX H ; PT TO NEXT MVI M,LF ; STORE INX H ; PT TO NEXT MVI C,0 ; RESET CHAR CNT CALL CRLF ; NEW LINE JMP INL1 * DELETE -- DELETE PREVIOUS CHAR AND ECHO DELETED CHAR INDEL: CALL BOL ; BEGINNING OF LINE? JZ INL1 ; CONTINUE DCX H ; BACK UP MOV A,M ; GET CHAR CALL CTRL ; PRINT CHAR CPI BEL ; DON'T CHANGE COUNT IF JZ INL1 INR C ; INCR DISPLAY CHAR COUNT JMP INL1 * BACKSPACE -- DELETE PREVIOUS CHAR AND BACK UP CURSOR INBS: CALL EXBS ; EXECUTE JMP INL1 * BACKSPACE ROUTINE EXBS: CALL BOL ; BEGINNING OF LINE? RZ ; CONTINUE IF SO DCR C ; DECR COUNT DCX H ; BACK UP MVI A,BS ; PRINT CALL COUT MVI A,' ' ; CALL COUT MVI A,BS ; CALL COUT RET * CARRIAGE RETURN -- DONE; STORE ENDING ZERO INCR: MVI M,0 ; STORE ENDING ZERO CALL CRLF ; NEW LINE POP PSW ; RESTORE PSW POP B ; RESTORE REGS POP D POP H RET * * ** SUPPORT ROUTINES ** * BOL -- RETURNS W/ZERO FLAG SET IF USER AT BEGINNING OF LINE * BOL: XCHG ; DE=HL LHLD START ; GET START ADR XCHG ; HL RESTORED MOV A,D ; CHECK FOR MATCH CMP H ; MATCH? RNZ ; NO MATCH MOV A,E ; CHECK FOR COMPLETE MATCH CMP L RNZ ; NO MATCH PUSH PSW ; SAVE FLAGS MVI A,BEL ; BEEP CALL COUT POP PSW RET * CTRL -- IF CHAR>=, PRINT IT; OTHERWISE, PRINT AS CTRL-CHAR CTRL: CPI ' ' ; ? JC CTRL1 JMP COUT ; PRINT IT NORMALLY CTRL1: CPI TAB ; TRAP JZ INTAB0 JMP COUT ; PRINT * HASH -- PRINT HASH MARK FOLLOWED BY HASH: MVI A,'#' ; PRINT HASH CHAR CALL COUT JMP CRLF * INTAB0 -- TABULATE ON SCREEN INTAB0: MOV A,C ; GET CHAR CNT ANI 7 ; MASK FOR DIFFERENCE FROM 8 MOV B,A ; STORE IN REG B TEMPORARILY MVI A,8 ; SUBTRACT FROM 8 SUB B MOV B,A ; COUNT IN B ADD C ; ADD TO CHAR COUNT MOV C,A MVI A,' ' ; IN A INTAB1: CALL COUT ; PRINT DCR B ; COUNT DOWN JNZ INTAB1 RET * * CHARACTER TABLE * THE CHARACTERS REPRESENTED IN THIS TABLE ARE IN A 5X7 FORMAT * THE FIRST BYTE IN EACH ENTRY REPRESENTS THE FIRST CHAR TO PRINT, ETC * THE BITS 6 TO 0 REPRESENT LINES (SUCCESSIVE) TO PRINT FOR THE CHAR * CHARS: DB 00H,00H,00H,00H,00H ; DB 00H,00H,7DH,00H,00H ;EXCLAMATION MARK DB 00H,70H,00H,70H,00H ;" DB 14H,7FH,14H,7FH,14H ;# DB 12H,2AH,7FH,2AH,24H ;$ DB 62H,64H,08H,13H,23H ;% DB 36H,49H,35H,02H,05H ;& DB 00H,00H,70H,00H,00H ;' DB 1CH,22H,41H,00H,00H ;( DB 00H,00H,41H,22H,1CH ;) DB 22H,14H,7FH,14H,22H ;* DB 08H,08H,3EH,08H,08H ;+ DB 00H,01H,06H,00H,00H ;, DB 08H,08H,08H,08H,08H ;- DB 00H,03H,03H,00H,00H ;. DB 02H,04H,08H,10H,20H ;/ DB 3EH,45H,49H,51H,3EH ;0 DB 11H,31H,7FH,01H,01H ;1 DB 21H,43H,45H,49H,31H ;2 DB 22H,41H,49H,49H,36H ;3 DB 0CH,14H,24H,7FH,04H ;4 DB 7AH,49H,49H,49H,46H ;5 DB 3EH,49H,49H,49H,26H ;6 DB 43H,44H,48H,50H,60H ;7 DB 36H,49H,49H,49H,36H ;8 DB 30H,49H,49H,49H,3EH ;9 DB 00H,00H,36H,00H,00H ;: DB 00H,01H,16H,00H,00H ;; DB 08H,14H,22H,41H,00H ;< DB 14H,14H,14H,14H,14H ;= DB 00H,41H,22H,14H,08H ;> DB 20H,40H,4DH,50H,20H ;? DB 7EH,41H,5DH,4DH,39H ;@ DB 3FH,48H,48H,48H,3FH ;A DB 7FH,49H,49H,49H,36H ;B DB 7FH,41H,41H,41H,41H ;C DB 7FH,41H,41H,41H,3EH ;D DB 7FH,49H,49H,49H,41H ;E DB 7FH,48H,48H,48H,40H ;F DB 7FH,41H,41H,49H,4FH ;G DB 7FH,08H,08H,08H,7FH ;H DB 41H,7FH,41H,80H,80H ;I DB 03H,01H,01H,01H,7FH ;J DB 7FH,08H,14H,22H,41H ;K DB 7FH,01H,01H,01H,01H ;L DB 7FH,20H,10H,20H,7FH ;M DB 7FH,30H,08H,06H,7FH ;N DB 7FH,41H,41H,41H,7FH ;O DB 7FH,48H,48H,48H,78H ;P DB 7FH,41H,45H,43H,7FH ;Q DB 7FH,48H,4CH,4AH,79H ;R DB 32H,49H,49H,49H,26H ;S DB 40H,40H,7FH,40H,40H ;T DB 7FH,01H,01H,01H,7FH ;U DB 70H,0CH,03H,0CH,70H ;V DB 7FH,02H,04H,02H,7FH ;W DB 63H,14H,08H,14H,63H ;X DB 60H,10H,0FH,10H,60H ;Y DB 43H,45H,49H,51H,61H ;Z DB 7FH,41H,41H,41H,00H ;[ DB 20H,10H,08H,04H,02H ;\ DB 00H,41H,41H,41H,7FH ;] DB 04H,08H,10H,08H,04H ;^ DB 01H,01H,01H,01H,01H ;_  DB 00H,40H,20H,10H,00H ;@ DB 3FH,48H,48H,48H,3FH ;A DB 7FH,49H,49H,49H,36H ;B DB 7FH,41H,41H,41H,41H ;C DB 7FH,41H,41H,41H,3EH ;D DB 7FH,49H,49H,49H,41H ;E DB 7FH,48H,48H,48H,40H ;F DB 7FH,41H,41H,49H,4FH ;G DB 7FH,08H,08H,08H,7FH ;H DB 41H,7FH,41H,80H,80H ;I DB 03H,01H,01H,01H,7FH ;J DB 7FH,08H,14H,22H,41H ;K DB 7FH,01H,01H,01H,01H ;L DB 7FH,20H,10H,20H,7FH ;M DB 7FH,30H,08H,06H,7FH ;N DB 7FH,41H,41H,41H,7FH ;O DB 7FH,48H,48H,48H,78H ;P DB 7FH,41H,45H,43H,7FH ;Q DB 7FH,48H,4CH,4AH,79H ;R DB 32H,49H,49H,49H,26H ;S DB 40H,40H,7FH,40H,40H ;T DB 7FH,01H,01H,01H,7FH ;U DB 70H,0CH,03H,0CH,70H ;V DB 7FH,02H,04H,02H,7FH ;W DB 63H,14H,08H,14H,63H ;X DB 60H,10H,0FH,10H,60H ;Y DB 43H,45H,49H,51H,61H ;Z * * BUFFERS * DS 40 ;20-ELT STACK STACK: DS 2 ;TOP OF BANNER STACK; CP/M STACK CONTFLG: DS 1 ;0=DON'T CONTINUE, 'C'=CONTINUE START: DS 2 ;START ADDRESS OF INPUT STRING NEXTCH: DS 2 LLEN EQU 80 ;NUMBER OF CHARS IN LINE, MAX INLINE: DB LLEN ;CHAR COUNT FOR INLINE DS LLEN+1 RDLINE: DB LLEN ;CHAR COUNT FOR RDLINE DS LLEN+1 COMMENT: DB LLEN DS LLEN+1 BLINE: DB '* INUSE *',0 ; MESSAGE END  41H,7FH,41H,80H,80H ;I DB 03H,01H,01H,01H,7FH ;J DB 7FH,08H,14H,22H,41H ;K DB 7FH,01H,01H,01H,01H ;L DB 7FH,20H,10H,20H,7FH ;M DB 7FH,30H,08H,06H,7FH ;N DB 7FH,41H,41H,41H,7FH ;O DB 7FH,48H,48H,48H,78H ;P DB 7FH,41H,45H,43H,7FH ;Q DB 7FH,48H,4CH,4AH,79H ;R DB 32H,49H,49H,49H,26H ;S DB 40H,40H,7FH,40H,40H ;T DB 7FH,01H,01H,01H,7FH ;U DB 70H,0CH,03H,0CH,70H ;V DB 7FH,02H,04H,02H,7FH ;W DB 63H,14H,08H,14H,63H ;X DB 60H,10H,0FH,10H,60H ;Y DB 43H,45H,49H,51H,61H ;Z * * BUFFERS * DS 40 ;20-ELT STACK STACK: DS 2 ;TOP OF BANNER STACK; CP/M STACK CONTFLG: DS 1 ;0=DON'T CONTINUE, 'C'=CONTINUE START: DS 2 ;START ADDRESS OF INPUT STRING NEXTCH: DS 2 LLEN EQU 80 ;NUMBER OF CHARS IN LINE, MAX INLINE: DB LLEN ;CHAR1    9̺  : G V: O: G>ʌxʌlN_yڷʷ ll/ ʙvv>2OlҾ   þ 9̺ ¾9! Nyʾھl 9̔tv… > Õ ʙ¢  ̺ 9! Nl: 2 > Wx!@ ozSsCc Z>w>>w!@ : O>dG>w# )#w#0: E! Nx2. [ |G >Gl|G>G†:. G: ʢҭ÷:. G!@ oҺ$  #~ʺPz÷> )   ͣ.G: ̓x2 !, ~!) w!- ~!* wZ &   ͣʘG: Oxp̓X!@ : o>wx!@ o>wx2 !, ~!& w!- ~!' wZ  :! _·>:" >0!, w  ã:" 0x:x!, w0WW!! {o~0x:x!- w0_zO-z2, {2- yG'G''Gy yG'G0_x0Wx! NG j  ã   l_  : Q  Q Z!~~_#  TYPWRYT.COM version 1.8 A program to make the computer/printer emulate a typewriter. (c)1983 John Fox$ Type: ctrl-C - to quit ctrl-L - to set left margin ctrl-R - to set right margin ctrl-T - to set tabs ctrl-P - to switch between single and double spacing ctrl-Q - for this help menu HIT SPACE BAR TO CONTINUE$ TAB ALTERATION Type: S To SET a tab here. C To CLEAR the tab here. To CLEAR ALL TABS. To leave tabs UNALTERED. $ Right margin is now: $ Left margin is now: $ Hit to leave UNCHANGED or Hit & then to put margin at CURRENT POSITION or Enter new margin value & hit : $ ?$ Left margin cannot be greater than right!!!  ?$A$$65$15$ESCAPE> & then to put margin at CURRENT POSITION or En to set left margin ctrl-R - to set right margin ctrl-T - to set tabs ctrl-P - to switch between single and double spacing ctrl-Q - for this help menu HIT SPACE BAR TO CONTINUE$ TAB ALTERATION Type: S To SET a tab here. C To CLEAR the tab here. To CLEAR ALL TABS. To leave tabs UNALTERED. $ Right margin is now: $ Left margin is now: $ Hit promp fro CP/ typ "SAV 10 N:FILENAME.COM wher i th driv yo wan i copie t an FILENAME.CO i th nam b whic yo wan i saved. Th revers linefee i implemente fo th C-Ito F10-4 whic use Qum sprin values Firs a escap characte i sen t th printe (1Bh an the th linefee characte (0Ah) T alte thi procedur th progra mus b eithe reassemble o patche wit DDT I reassemble g t th locatio labele "revlinfd: an chang th value sen t th printer I patche wit DD g t locatio 0601h Ther ar si byte availabl beginnin wit thi one Inser whateve serie o value th printe needs Mak sur t chec tha th location after the las byte contains a 00. Thi progra i release fo non-commercia us an distribution Commercia us withou th author' writte permission is forbidden. - Joh Fox 215 W. 91st Street New York, N.Y. 10024 ; ; ;*************************************************** ; TYPWRYT.COM vers.1.88 (c) 1983 John Fox ;*************************************************** ;This is a program to make the computer when coupled ;with a printer emulate a typewriter. It sends ;keyboard input directly to the printer, adds either ;one or two line feeds for each CR, allows margins ;and tabs to be selected, and rings the bell 10 ;spaces before the right margin is reached. It ;allows the "Wordstar diamond" keys to be used as ;follows: ^S=backspace, ^D=space, ^X=linefeed, and ;^E=reverse linefeed. ; ;CUSTOMIZATION NOTES: ;The default margin values are 15 for the left ;margin and 65 for the right. These may be changed ;by inserting new hex values at "lmrgvalue:" and ;"rmrgvalue:". The ASCII representation of the two ;values should then be inserted at "oldlval:" and ;"oldrval:" so that the screen message will correspond ;to the new values. Finally the default tab stop for ;the right margin should be moved to the position of ;the new right margin in the tab field ("tabs:"). ; ;The default spacing is single. This may be changed ;to double by putting any odd number at "spcvalue". ; ;An easier method of accomplishing the same thing is ;to assemble the program as is, to run it and modify ;the values as part of a program run, to exit the ;program and to save it with its modified values. ; ;The reverse linefeed is implemented for the C-Itoh ;F10-40 which uses Qume sprint values. First an ;escape character is sent to the printer (1Bh) ;and then the linefeed character (0Ah). To alter ;this procedure go to the subroutine called ;"Reverse Line Feed" and change the values sent to ;the printer. ; ;NOTE TO PROGRAMERS: This has been my first practical ;exercise in assembly language programing, and I am ;sure it is as inelegant as a program can be and ;still work. Nevertheless it does work and seems to ;be without operating bugs. Please note that when ;the following source code is assembled the first part ;of the tabspace fills with ascii values from an ;earlier part of the program. ; bdos equ 05h clear equ 1ah cr equ 0dh lf equ 0ah ctrlc equ 03h ctrld equ 04h ctrle equ 05h ctrll equ 0ch ctrlp equ 10h ctrlq equ 11h ctrlr equ 12h ctrls equ 13h ctrlt equ 14h ctrlx equ 18h bell equ 07h pbuff equ 09h ; ; START OF PROGRAM ; org 100h setup: mvi c,2 ;clear screen and home cursor mvi e,clear call bdos lxi sp,stack ;point to local stack lxi b,00h ;initialize stack push b push b push b lxi d,signon ;display sign-on menu mvi c,pbuff call bdos lxi d,menu mvi c,pbuff call bdos mvi c,1 ;read console call bdos cpi ctrll ;check for l-margin set cz lmargset cpi ctrlr ;check for r-margin set cz rmargset cpi ctrlt ;check for tab set cz tabcntrl cpi ctrlp ;check for spaceset cz setspace cpi ctrlc ;check for abort jz 00 cpi 20h ;check for space jnz setup ;if not, go back to menu start: mvi c,2 ;clear screen and home cursor mvi e,clear call bdos mvi c,5 ;set printer at 0 column mvi e,cr call bdos spaceovr: pop b ;get old counter out of stack lda lmrgvalue ;get left margin mov b,a ;store in counter again: push b ;save counter mvi e,20h ;send space to printer mvi c,5 call bdos pop b dcr b jnz again ;repeat until counter=0 lda rmrgvalue ;get endline position mov c,a lda lmrgvalue ;get counter position mov b,a push b ;and store both in stack getchr: mvi c,1 ;get character to print call bdos cpi 08 ;is it backspace jnz cntrlchr ;if not, next test bckspc: pop b mvi a,0 ;if so don't go to left cmp b ;of zero nop jz leftend dcr b ;decrement counter push b mov a,b cpi 00h ;check for deadend left jz leftend ;if so dead end mvi c,5 ;if not send backspace to printer mvi e,08h call bdos jmp getchr ;get next character cntrlchr: cpi 1bh ;is it a control character jc control ;if so go to control program prntchr: mvi c,5 ;otherwise print character mov e,a call bdos colpos: pop b ;get position along line inr b push b ;store new position in counter mov a,c ;get endline position in accumulator sub b ;find out how many spaces left to line jc zero cpi 0h jz zero cpi 10 ;is it 10 spaces jnz getchr ;if not get next character mvi c,2 ;if so ring bell mvi e,bell call bdos jmp getchr ;and get next character zero: mvi e,2fh ;if zero mark end of sentence mvi c,2 call bdos endline: mvi c,1 ;then read console call bdos cpi cr ;is it crrtrn jz nxtline ;if so execute and start newline push a ;if not save input in stack mvi e,08h ;and send cursor back mvi c,2 call bdos pop a ;get input from stack cpi ctrls ;is it left arrow key jnz bksp ;if so mvi e,08h ;send backspace to console mvi c,2 call bdos jmp bckspc ;and reenter main loop bksp: cpi 08 ;is it backspace jz bckspc ;if so reenter main loop cpi 1bh ;is it esc jnz endcntrl mvi a,50 ;if so add 50 to endline counter pop b add c mov c,a push b jmp getchr ;and go back for next character endcntrl: cpi 1bh ;is it a control character jnc endline ;if not dead end push a ;if so save input in stack mvi e,20h ;and send cursor forward to mvi c,2 ;compensate for a nonprinting chr call bdos pop a ;get input again cpi ctrle ;is it a linefeed down cz backfeed ;if so do it cpi ctrlx ;is it a linefeed jnz setmrg ;if not next test mvi e,0ah ;if so send one to console mvi c,2 call bdos mvi e,0ah ;and one to printer mvi c,5 call bdos jmp endline setmrg: cpi ctrlc ;is it an abort jz 00 cpi 09 cz untab cpi ctrlq ;is it a request for help cz question cpi ct rlp ;is it a space set cz setspace cpi ctrll ;is it a left margin set cz lmargset cpi ctrlr ;is it a right margin set deadend: jnz endline ;deadend if it is anything else call rmargset pop b ;get old countervalues lxi h,rmrgvalue ;get new margin value mov c,m push b ;store new value in counter mov a,c ;get line position sub b jz endline ;if no spaces left deadend jc endline jmp getchr ;otherwise get next character ; ; ;MAIN CONTROL PROGRAM control: cpi ctrlc ;is it an abort jz 00 cpi ctrlq ;is it a request for help cz question cpi 09h ;is it a tab cz untab cz dotab cpi 14h ;is it a tabset cz tabcntrl cpi ctrls ;is it a backspace jnz spck mvi e,08h ;if so send one to console mvi c,2 call bdos jmp bckspc ;and reenter main loop spck: cpi ctrld ;is it a space jnz crrtrn mvi e,20h ;if so send one to console mvi c,2 call bdos mvi a,20h ;get set with space to print jmp prntchr ;and reenter main loop crrtrn: cpi cr ;is it carriage return jz nxtline cpi ctrle ;is it a linefeed down cz backfeed ;if so do it cpi ctrlx ;is it a linefeed jnz lsp ;if so mvi e,0Ah ;send linefeed to console mvi c,2 call bdos mvi e,0Ah ;and one to printer mvi c,5 call bdos lsp: cpi ctrlp ;is it a linespace set cz setspace cpi ctrll ;is it a l-margin set cz lmargset cpi ctrlr ;is it a r-margin set cz rmargset pop b ;get old counter values lxi h,rmrgvalue ;get new margin value mov c,m push b ;and store in counter jmp getchr ; ; ;SUBROUTINES ; ; ;SINGLE OR DOUBLE SPACING ; setspace: lda spcvalue ;load current spacing (lsb only) adi 01h ;change lsb sta spcvalue mvi a,0h ;reset accumulator ret ; ; ;CONTROL PROGRAM TO SET AND CLEAR TABS ; tabcntrl: mvi c,2 ;clear screen and home cursor mvi e,clear call bdos mvi c,pbuff ;display tab menu lxi d,tabmsg call bdos  mvi c,1 ;get console input call bdos mov d,a ;and save it for later pop h ;get copy of counter pop b push b push h mov a,b ;in accumulator lxi h,tabs ;point to tabspace add l ;offset to current position mov l,a ;along line mov a,d ;get character entered cpi 53h ;is it 'S' or 's' jz tabset ;if so go to set the tab cpi 73h jz tabset cpi 43h ;is it 'C' or 'c' jz tabclear ;if so go to clear the tab cpi 63h jz tabclear cpi 1bh ;is it 'esc' jz tabzap ;if so go to clear all tabs cpi cr ;is it a carriage return jnz tabcntrl ;if none of above repeat message tabquit: mvi c,2 ;if carriage return were done already mvi e,clear ;clear screen and home cursor call bdos call movovr ;set cursor according to counter ret ;and return to main loop ; ;SET TAB AT CURRENT CARRIAGE POSITION ; tabset: mvi a,01h ;load accumulator with flag mov m,a ;and set tab mvi a,00h ;clear accumulator jmp tabquit ; ;CLEAR TAB AT CURRENT CARRIAGE POSITION ; tabclear: mvi a,00h ;blank accumulator mov m,a ;and clear tab jmp tabquit ; ;CLEAR ALL TABS EXCEPT RIGHT MARGIN ; tabzap: lxi h,tabs ;point to start of tabspace lda rmrgvalue ;get right margin value mov c,a ;put it in register for later mvi a,100 ;find difference between sub c ;100 decimal and right margin mov b,a ;save that in b for later mvi a,00h wipeout: mov m,a ;and start clearing tabs inx h dcr c jnz wipeout ;repeat till right margin reached inx h ;pass over right margin wipemore: mov m,a ;and continue wiping out inx h dcr b jnz wipemore ;until 100 is reached jmp tabquit ; ; ;CANCEL OUT THE DEFAULT CPM TAB MOVEMENT ON VIDEO SCREEN ; untab: pop d ;get current counter pos. pop b ;in b register push b push d lda rmrgvalue ;check if at endline cmp b jnz getpos ;if not go ahead inr b ;otherwise make room for marker getpos: lxi h,lmrgvalue mov c,m mov a,b sta countbff ;store counter for later sub c ;find correct cursor position jnz nonzero ;go below if non-zero mvi c,2 ;if zero home cursor mvi e,cr call bdos xra a ;zero accumulator ret ;then execute tab nop nonzero: jnc mod8 ;if positive go below mov b,a ;if negative save the value push b mvi c,2 ;and send cursor to zero posit. mvi e,cr call bdos pop b ;get neg value again mvi a,00 ;find how far cursor was to sub b ;left of zero position mov b,a negpos: push b ;save this amount as counter mvi c,2 mvi e,08h ;move cursor back one space call bdos pop b dcr b ;until it is where it started jnz negpos ;before the tab xra a ret ;then execute the tab nop mod8: sbi 8 ;if right of zero find how far jnc mod8 ;from a CPM default tab position mov b,a mvi a,0 sub b ;since screen has put cursor at mov b,a ;a CPM default position for tab mvbck push b ;we must mvi c,2 ;back cursor back on monitor ! mvi e,08h ;to compensate for tab call bdos pop b dcr b jnz mvbck ret ; ;EXECUTE A HORIZONTAL TAB ; dotab: lda countbff ;get a copy of the counter mov b,a ;put copy in b register lda rmrgvalue ;check for endline sub b jz notab jnc tabit notab: mvi c,2 mvi e,bell call bdos pop h ;clear return address from stack jmp zero ;and go to endline in main loop tabit: lda countbff ;get counter in acc. again mov b,a lxi h,tabs ;point to tab space add l ;offset to current position mov l,a ;along line jnc moveit inr h moveit: push h ;save address push b ;and save counter copy mvi c,2 ;send space to console mvi e,20h call bdos mvi c,5 ;send space to printer mvi e,20h call bdos pop b ;get counter copy again pop h ;get address again inx h ;move to next point in tabspace inr b ;adjust counter copy mov a,m ;get value at that point in tabspace cpi 00h ;if zero jz moveit ;repeat pop h ;otherwise get real counter pop d ;in d register mov d,b ;replace it with adjusted copy push d ;and store it push h ;and save return address mov a,d cmp e ;at right margin? (lsbyte of counter) jnz tabdone ;if not return to main loop pop h ;if at right mrg clear return address jmp zero ;and go to mark endline in main loop tabdone: mvi a,00 ;clear accumulator ret ;and return ; ;LEFT MARGIN CONTROL lmargset: mvi c,2 ;clear screen mvi e,clear call bdos lxi d,oldlmsg ;display old margin value message mvi c,pbuff call bdos lxi d,oldlval ;followed by the old numerical value mvi c,pbuff call bdos lmsg: lxi d,mrgmsg ;print margin change message mvi c,pbuff call bdos lcalc: call mrgcalc ;get new margin value cpi 0ffh ;check for bypass jz ldn errchkl: mov b,a ;otherwise put it in register lda rmrgvalue ;get right margin value sub b jp strl ;if right>left ok call woops ;give error message jmp lcalc ;and go back for another entry strl: mov a,b ;get new margin from register sta lmrgvalue ;store it lxi h,valbuff ;get tens value from ascii value buffer mov a,m lxi h,oldlval ;put it in tens of old left value mov m,a lxi h,valbuff+1 ;get ones value from ascii value buffer mov a,m lxi h,oldlval+1 ;put it in ones of old left value mov m,a ldn: mvi c,2 ;clear screen mvi e,clear call bdos call movovr ret ; ; ;RIGHT MARGIN CONTROL rmargset: mvi c,2 ;clear screen mvi e,clear call bdos lxi d,oldrmsg ;display old margin message mvi c,pbuff call bdos lxi d,oldrval ;followed by old numerical value mvi c,pbuff call bdos rmsg: lxi d,mrgmsg ;print margin change message mvi c,pbuff call bdos rcalc: call mrgcalc ;calculate new margin value cpi 0ffh ;check for bypass jz rdn errchkr: mov b,a ;otherwise store new value in register lda lmrgvalue ;get left margin value mov c,a mov a,b sub c jp strr ;if right>left ok call woops ;otherwise give error message jmp rcalc ;and go back for another entry strr: lxi h,tabs ;point to tabspace lda rmrgvalue ;get old margin value add l ;offset to old-margin tab position mov l,a mvi a,00h mov m,a ;and blank it mov a,b ;get new margin again from register lxi h,tabs ;point to tabspace add l ;offset to new-margin tab position mov l,a mvi a,01h mov m,a ;and set it mov a,b ;get new margin again from register sta rmrgvalue ;and store it where we can use it lxi h,valbuff ;get tens value from ascii value buffer mov a,m lxi h,oldrval ;and store it in old right margin value mov m,a lxi h,valbuff+1 ;get ones value from ascii value buffer mov a,m lxi h,oldrval+1 ;and store it in old right margin value mov m,a rdn: mvi c,2 ;clear screen mvi e,clear call bdos call movovr ret ; ; ;NEW MARGIN ENTRY mrgcalc: mvi c,0ah ;set up to read console buffer lxi d,cnsbff call bdos lda cnsbff+1 ;get number of chrs entered mov e,a ;put copy of number in register cpi 0 ;if zero jnz onward mvi a,0ffh ;return signal value in A ret ;and return to margcontrol onward: cpi 1 ;if one jnz stkl lda cnsbff+2 ;check for escape cpi 1bh ;if not jnz oneonly ;jump to prep for one digit call crspos ;otherwise get cursor position jmp calcdn ;and return to load it as margin oneonly: mvi a,30h ;if not, put ascii 0 lxi h,valbuff ;in tens place of value buffer mov m,a jmp ones ;and proceed to ones calculation stkl: cpi 02 ;if two jz tens ;proceed to tens calculation lxi d,wrong ;if three send warning message mvi c,pbuff call bdos jmp mrgcalc ;and repeat tens: lda cnsbff+2 ;if two get first digit cpi 48 ;check for ascii number jc nonascii ;if not give warning cpi 58 jnc nonascii lxi h,valbuff ;if so store in left value buffer mov m,a sui 30h ;then convert to binary add a ;multiply by 10 mov d,a add a add "a add d mov d,a ;store result in register ones: lxi h,cnsbff+1 ;load buff 0-address mov a,e ;load offset for next chr add l ;adjust address mov l,a mov a,m ;get next character cpi 48 ;check for ascii number jc nonascii ;if not reprint message cpi 58 jnc nonascii lxi h,valbuff+1 ;if so store in left value buffer mov m,a ;one's place sui 30h ;then convert to binary mov e,a ;store in register mov a,d ;get msdigit add e ;calculate final result calcdn: ret ; ; TO SET MARGIN AT CURSOR POSITION ; crspos: pop b ;get copy of cursor pos. counter pop d ;into accumulator pop h pop a push a push h push d push b mov c,a ;put copy of it in c register call ascii ;convert it to ascii mov a,d ;get tens value sta valbuff ;store it in Ascii value buffer mov a,e ;get ones value sta valbuff+1 ;store it in Ascii value buffer mov a,c ;get its binary value in acc ret ;and return to margcalc program ; ; ; CONVERT ACCUMULATOR TO ASCII AND RETURN VALUE IN DE REGISTER PAIR ; ascii: ani 0f0h ;blank low order nibble rrc ;bring 16s to 1s place rrc rrc rrc mov b,a ;multiply by 6 add b ;and decimal adjust daa mov b,a add b daa add b daa mov b,a ;and store mov a,c ;get raw binary value ani 0fh ;blank high order nibble cpi 0ah ;is low order nibble >9 mov a,c ;get raw binary again jc calc ;if l.o.nibble <9 proceed adi 6 ;otherwise decimal adjust calc: add b ;add to previous value daa mov b,a ;save it ani 0fh ;blank tens value adi 30h ;translate ones to ascii mov e,a ;and store it in ones register mov a,b ;get decimal adjusted value again ani 0f0h ;blank ones rrc ;bring tens value to l.o.nibble rrc rrc rrc adi 30h ;translate it to ascii mov d,a ;and store it in tens register ret ;return to crspos program ; ; ;MOVE CURSOR OVER AFTER MARGIN RESET TO ITS SCREEN POS. BEFORE RESET ; movovr: pop h ;pop first ret address pop d ;pop second ret address pop b ;pop counter push b ;restore them all push d push h mov a,b ;get counter copy in acc. ora a ;if it is zero return rz ;to calling program lxi h,lmrgvalue ;if not get left margin mov c,m sub c ;and subtract it from counter rz ;if same return mov b,a ;otherwise mv: push b ;save adjusted counter value mvi c,2 ;and send space to console mvi e,20h call bdos pop b ;get counter copy again dcr b ;decrement it jnz mv ;and repeat until zero ret ; ; ;FAILURE TO ENTER ASCII NUMBER OR TOO MANY DIGITS nonascii: lxi d,wrong ;give warning message mvi c,pbuff call bdos jmp mrgcalc ;and set up for new input ; ;LEFT MARGIN GREATER THAN RIGHT woops: lxi d,nope ;display error message mvi c,pbuff call bdos ret ;and restart calculation ; ;LEFT END OF LINE ; leftend: pop b ;restore counter to inr b ;the way it was before push b ;the illegal backspace mvi c,2 ;restore screen to mvi e,20h ;the way it was before call bdos ;the illegal backspace jmp getchr ;reenter the main loop ; ;SET UP NEW LINE nxtline: mvi c,5 ;send cr to printer mov e,a call bdos mvi c,2 ;add linefeed to screen mvi e,lf call bdos mvi c,5 ;send lf to printer mvi e,lf call bdos lda spcvalue ;get space code rar ;put lsb in carry jnc spaceovr ;if 0 start line mvi c,2 ;if not add another linefeed mvi e,lf ;to screen call bdos mvi c,5 ;and another lf to printer mvi e,lf call bdos newline: jmp spaceovr ;go to start of line ; ;REPEAT THE HELP MENU ; question: mvi c,pbuff ;display command menu lxi d,menu call bdos mvi c,1 ;wait for input call bdos cpi 03h ;check for abort jz 00h mvi c,2 ;otherwise clear screen mvi e,clear call bdos call movovr ;get cursor into position ret ;and return to main loop ; ;REVERSE LINE FEED ; backfeed: lxi h,revlinfd ;point to reverse linefeed seq. mov a,m ;get first byte ora a ;check if zero rz ;if so don't do rlinefeed nextbyte: mov a,m ;get byte ora a ;check if zero jz rlfdone ;if so do rlf on screen and stop mov e,a ;if not put in sending register push h ;store pointer mvi c,5 ;set up for proper bdos call call bdos ;and send to printer pop h ;get pointer again inx h ;point to next byte jmp nextbyte ;go back to send it rlfdone: mvi e,0bh ;get terminal's reverse linefeed ;code in sending register mvi c,2 ;set up proper bdos call call bdos ;and send to console ret ; ; ;STORAGE AREA ; ; ; ; revlinfd: db 1Bh,0Ah,00h,00h,00h,00h ;this should be whatever ;sequence is necessary for the ;individual printer's reverse linefeed. ;Be sure to terminate the string with ;a 0 value. ; ; signon: db cr,lf,lf,' TYPWRYT.COM' db cr,lf,' version 1.8' db cr,lf,lf,' A program to #make the computer/printer' db cr,lf,' emulate a typewriter.' db cr,lf,' (c)1983' db ' John Fox$' menu: db cr,lf,lf,lf,lf,'Type: ctrl-C - to quit' db cr,lf,' ctrl-L - to set left margin' db cr,lf,' ctrl-R - to set right margin' db cr,lf,' ctrl-T - to set tabs' db cr,lf,' ctrl-P - to switch between' db cr,lf,' single and double spacing' db cr,lf,' ctrl-Q - for this help menu' db cr,lf,lf,lf,lf db ' HIT SPACE BAR TO CONTINUE$' ; ; tabmsg: db cr,lf,lf,' TAB ALTERATION' db cr,lf,lf db lf,lf,'Type: S To SET a tab here.' db cr,lf,' C To CLEAR the tab here.' db cr,lf,' To CLEAR ALL TABS.' db cr,lf,' To leave tabs UNALTERED. ' db 24h oldrmsg: db cr,lf,lf,'Right margin is now: $' oldlmsg: db cr,lf,lf,'Left margin is now: $' ; mrgmsg: db cr,lf,lf,'Hit to leave UNCHANGED' db cr,lf,' or' db cr,lf,'Hit & then to put margin' db cr,lf,' at CURRENT POSITION' db cr,lf,' or' db cr,lf,'Enter new margin value & hit : $' ; ; wrong db lf,' ',0bh db ' ?',08h,08h,08h,08h,24h ; nope: db lf,lf,'Left margin cannot be greater than right!!! ' db 08h,08h,08h,08h,08h,0bh,0bh,' ?' db 08h,08h,08h,08h,24h ; lmrgvalue: db 0Fh rmrgvalue: db 41h spcvalue: db 00h cnsbff: db 03h,02h,00h,00h,24h,24h oldrval: db 36h,35h,24h oldlval: db 31h,35h,24h valbuff: db 00h,00h countbff: ds 2h ds 10h ; ;IN TAB SPACE THAT FOLLOWS A "db 01h" SIGNIFIES A DEFAULT ;TAB POSITION ; tabs: ds 41h db 01h ds 30h ; ;SPACE FOR LOCAL STACK ds 20h stack: end ;********************************************************************* 1ͮ&6`i"*-ͭ[ͮ͢c>2C!"@*@N#F#"@!C5>>O=~c>sy/w>sq>{++#{^=      ͮy!"@L>!3N#F#=>:@:A>>~c>y/w#{ͮ*@͑;*@)"@*!}¸¸      ͮL!C6@*%.~,{s >7`o. X,{ nͮL**|¹}!C6@*%=~,~,,y >7`o= X,X,,y !C5*# *+****##}&1yq#{OV1JfͮK͑ͮV͖;͉ͮ|͖}O͟y0:ڪ_ͷ> ^#V#ͮ User Maintenance Problem Identification & Reliability Enhancement COPYRIGHT (C) 1979, 1980 by Mel Cruts $ADDRESS: $ BAD BITS: $ROUTINE 1-BOOMERANG $ROUTINE 2-HALF SLOW $ADDRESS BIT $ROUTINE 4-SCRAMBLE $ROUTINE 8-SPIRAL $$O:%<2%> > >* '^=      ͮy!"@L>!3N#F#=>:@:A>>~c>y/w#{ͮ*@͑;*@)"@*!}¸¸      ͮL!C6@*%.~,{s >7`o. X,{ nͮL**|¹}!C6@*%=~,~,,y >7`o= X,X,,y !C5*# *+****##}&1yq#{OV1JfͮK͑ͮV͖;͉ͮ|͖}O͟y0:ڪ_ͷ> ^#V#ͮ User Maintenance Problem Identification & Reliability Enhancement COPYRIGHT (C) 1979, 1980 by Mel Cruts $ADDRESS: $ BAD BITS: $ROUTINE 1-BOOMERANG $ROUTINE 2-HALF SLOW $ADDRESS BIT $ROUTINE 4-SCRAMBLE $ROUTINE 8-SPIRAL $$O:%<2%> >UMPIRŠ i comprehensiv memor tes progra implementin tw tes algorithm develope a th Universit o Illinois Th algorithm wer publishe i Jun 197 'IEEŠ TRANSACTIONӠ O COMPUTERS' Th Universit o Illinoi tes algorithm ar th 'BOOMERANG an th 'HAL SLOW tes routines Als include ar two test routines I devised. Th tes wil automaticall siz th TP an tes al o memor u th star o BDOS Ther ar onl thre contro codes ^ wil caus th tes t restart ^ wil caus jum t addres zer (i.e war boot) an ^ wil caus th progra t sto o start Th ^ functio i particularll usefu i th 'SCRAMBLE an 'SPIRAL routin t sto t tes causin refres verificatio o dynami memories Anothe ^ wil caus th tes t star u again Bot th 'SCRAMBLE an 'SPIRAL tes routine us rando dat s thi i fai tes o memor arra fo patter sensitivity. Send any comments or sug$gestions to: Mel Cruts DIGITAL DELI COMPUTER STORE 80 WEST EL CAMINO REAL MOUNTAIN VIEW, CA. 94040 Th algorithm wer publishe i Jun 197 'IEEŠ TRANSACTIONӠ O COMPUTERS' Th Universit o Illinoi tes algorithm ar th 'BOOMERANG an th 'HAL SLOW tes routines Als include ar two test routines I devised. Th tes wil automaticall siz th TP an tes al o memor u th star o BDOS Ther ar onl thre contro codes ^ wil caus th tes t restart ^ wil caus jum t addres zer (i.e war boot) an ^ wil caus th progra t sto o start Th ^ functio i particularll usefu i th 'SCRAMBLE an 'SPIRAL routin t sto t tes causin refres verificatio o dynami memories Anothe ^ wil caus th tes t star u again Bot th 'SCRAMBLE an 'SPIRAL tes routine us rando dat s thi i fai tes o memor arra fo patter sensitivity. Send any comments or sugUNSPOOL Ver 3.3/T/P$ i!~ W!&xA ~#4&bxe {X~#o}oaG33o:‹*‹#w#w# z*"!9~#fo"t*"X* "dm !wm!w>2m!w:2m!w m!w:\<2\\İq W Invalid operation attempted under UNSPOOL. Program aborted.$2!91W2«:-:!>)2:!5> Š2!~ڧ F75G A6G G4:ʉ n ]Ê:< Ê:G>B22=2> Ê_:_WW:_W2#W W2:_ WW*W:_ W7: W1:( W ny WW1:H W*!" Wv W!3"!"!2"!" Unspooling in progress.$ UNSPOOL Completed.$ Do you want to cancel UNSPOOL? {Y|N} ?>$ UNSPOOL Cancelled.$W1:( W!Z" !f"+2 $HD @I$$HI"AB@""I$ H$" !A$$II$yC M:İWW":>İq W Invalid operation attempted under UNSPOOL. Program aborted.$2!91W2«:-:!>)2:!5> Š2!~ڧ F75G A6G G4:ʉ n ]Ê:< Ê:G>B22=2> Ê_:_WW:_W2#W W2:_ WW*W:_ W7: W1 Documentation for UNSPOOL Version 3.2 for CP/M 2.0 and up. AUTHOR: Gary P. Novosielski Rutherford, NJ (201) 935-4087 Evenings and weekends. INTRODUCTION: UNSPOOL is a program to send a standard CP/M file such as a .PRN or .ASM file to the system's list or punch device, while still allowing nearly all other system operations to take place. The file is transferred during periods when console is waiting for input. SYNTAX: UNSPOOL [d:]filename.ext [dev] or UNSPOOL dummy OFF [square brackets denote optional parameters] Where d: is an optional drive spec such as A: or B:. If not entered, the current default drive is assumed. filename.ext is the name of the CP.M file to be printed/punched. dev is the symbolic name of the output device to be used. Note that the colon (:) usually present in device names is NOT entered. Valid devices are LST and PUN, which refer to the physical devices assigned to the logical LST: and PUN: devices at the time UNSPOOL is started, as well as PAG, a special name recognized by unspool. PAG refers to the same physical device as LST, but supplies automatic paging % of output by inserting Form Feed characters into the output. This is useful for UNSPOOLing source files, which normally contain no Form Feeds. LST is normally used for .PRN files, or other types which have Form Feeds Revised 82-01-06 Page 1 of 6 already included. If not specified, LST is assumed.  special name recognized by unspool. PAG refers to the same physical device as LST, but supplies automatic paging ; title 'Quick Set - File Attribute Bit Set Program' ; ; 7Jan84 by Mike Griswold, Ft. Worth, TX ; ; This program allows for setting the three system ; attribute bits, t1', t2', t3', to the control R/O, ; SYS and Archive features. Usage is: ; QS file.typ {options} ; ; where options are: ; R for R/O ; S for SYS ; A for Archive ; ; All other option letters are ignored. Only the ; first three letters in the option field are ; used, all others are ignored. To turn off an ; attribute use QS without the option letter. ; ; ; ; aseg ; for RMAC ; org 0100h start: lxi sp,0100h lda 05dh ; see if file specified cpi ' ' jz no$file ; give usage message xra a sta ro ; initialize attribute flags sta sys sta arch lda 06dh ; first option field call get$opt ; decode it lda 06eh ; next call get$opt lda 06fh ; last call get$opt lxi d,05ch ; point to FCB mvi c,30 ; set attribute function call 5 call signoff ; tell what happened jmp 0 ; exit ; ; Check byte in A for legal options and set ; attribute flag if found. ; get$opt: cpi 'R' jnz get1 sta ro lda 065h ; t1 ori 80h ; set t1' sta 065h get1: cpi 'S' jnz get2 sta sys lda 066h ori 80h sta 066h ; set t2' get2: cpi 'A' jnz get3 sta arch lda 067h ori 80h sta 067h ; set t3' get3: ret ; ; Display file's new attributes. ; signoff: push psw ; save error code mvi a,'$' sta 068h ; set end of string lxi h,05ch call sout pop psw ; retrieve error ora a jz sign0 ; no error lxi h,mess0 ; else file not found call sout ret sign0: lxi h,mess1 call sout lxi h,dirmess lda sys ora a jz sign1 lxi h,sysmess sign1: call sout lxi h,rwmess lda ro ora a jz sign2 lxi h,romess sign2: call sout lxi h,armess lda arch ora a cnz sout ret ; ; Output string from HL until '$'. ; sout: xchg ; DE points to string mvi c,09 call 5 ret ; ; Print usage string if no file was given. ; no$file: lxi h,usage call sout jmp 0 ; abort ; ; Message strings ; mess0: db ' not found.',0dh,0ah,'$' mess1: db ' set to: $' dirmess:db 'DIR $' sysmess:db 'SYS $' rwmess: db 'RW $' romess: db 'RO $' armess: db 'Archive$' ; usage: db 0dh,0ah,'QS usage is: QS filename options' db 0dh,0ah,0ah,'where legal options are:' db 0dh,0ah,0ah,09h,'R - Sets RO attribute' db 0dh,0ah,09h,'S - Sets SYS attribute' db 0dh,0ah,09h,'A - Sets Archive attribute$' ; ; Local storage ; ro: ds 1 ; RO flag sys: ds 1 ; SYS flag arch: ds 1 ; Archive flag ; end 0100h ive attribute$' ; ; Local storage ; ro: ds 1 ; RO flag sys: ds 1 ; SYS flag arch: d lda sys ora a jz sign1 lxi h,sysmess sign1: call sout lxi h,rwmess lda ro ora a jz sign2 lxi h,romess sign2: call sout lxi h,armess lda arch ora a cnz sout ret ; ; Output string from HL until '$'. ; sout: xchg ; DE points to string mvi c,09 call 5 ret ; ; Print usage string if no file was given. ; no$file: lxi h,usage call sout jm This is the release date of the disk. BAKSLASHDOC BAKSLASHASM @ COM @ DOC CALL-CPMCOM =CALL-CPMDOC #COMPARE COM (COMPARE DOC *COMPASC COM +COMPBIN COM -COMPARE ASM / CRCK4 COM 3CRCK4 DOC 5 CRCK4 ASM 8+COMPASC .COM 4B 28 1536 12 COMPBIN .COM 71 B3 1536 12 COMPARE .ASM E3 01 3456 27 CRCK4 .COM FF 8C 1408 11 CRCK4 .DOC D9 B1 2560 20 CRCK4 .ASM EE DC 11008 86 DIAL .COM FB 92 7808 61 DIAL .DOC 54 17 5632 44 DUPUSR21.COM ED 56 512 4 DUPUSR21.ASM CA F1 7424 58 HP .COM CC D5 1536 12 HP+ .COM 74 DC 2432 19 HP-HP+ & Fog Library Disk FOG-CPM.055 Copyright (1986) by Fog International Computer Users Group to the extent not copyrighted by the original author for the exclusive use and enjoyment of its members. Any reproduction or distribution for profit or personal gain is strictly forbidden. For information, contact FOG, P. O. Box 3474, Daly City, CA. 94015-0474. as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. Utilities for most CP/M computers. Filename Description -06-00 .86 This is the release date of the disk. -CPM055 .DOC This is the description of the disk contents. BAKSLASH.COM 2AA6 1K [Backslash 1 of 3] Originally name "\.COM", this program allows multiple commands on a line. ASseMbler source is included. BAKSLASH.DOC 2B39 2K [Backslash 2 of 3] BAKSLASH.ASM 229E 4K [Backslash 3 of 3] @ .COM 56F4 4K [Expression Eval. 1 of 2] An On-line Expression Evalulator (calculator) in decimal and hexadecimal. @ .DOC 500F 5K [Expression Eval. 2 of 2] CALL-CPM.COM AE14 16K [CALL-CPM 1 of 2] Menu-driven program to learn how CP/M calls work. CALL-CPM.DOC F7B5 5K [CALL-CPM 2 of 2] COMPARE .COM C3A2 2K [Compare files 1 of 5] Compares two files and reports any differences. MAC source and two special implementations are included. COMPASC for comparing ASCII files and COMPBIN for BINARY file comparisons COMPARE .DOC 153D 1K [Compare files 2 of 5] COMPASC .COM 4B28 2K [Compare files 3 of 5] COMPBIN .COM 71B3 2K [Compare files 4 of 5] COMPARE .ASM E301 4K [Compare files 5 of 5] CRCK4 .COM FF8C 2K ver. 4.0 [CRCK 1 of 3] Perform Cyclic Redundancy Check to verify files. MAC source is included. CRCK4 .DOC D9B1 3K ver. 4.0 [CRCK 2 of 3] CRCK4 .ASM EEDC 11K ver. 4.0 [CRCK 3 of 3] DIAL .COM FB92 8K [Dial 1 of 2] Automatic dialing program for Hayes SmartModem & compatibles. DIAL .DOC 5417 6K [Dial 2 of 2] DUPUSR21.COM ED56 1K ver. 2.1 [Duplicate User 1 of 2] Create duplicate directory entry in other user areas. ASseMbler source code is included. DUPUSR21.ASM CAF1 8K ver. 2.1 [Duplicate User 2 of 2] HP-HP-PL.DOC CE79 10K [HP and HP+ 1 of 3] Programmers calculator. HP is for CP/M 2.2 and HP+ (HP-PL) is a special memory resident version for CPM+. HP .COM CCD5 2K [HP and HP+ 2 of 3] HP-PL .COM 74DC 3K [HP and HP+ 3 of 3] INUSE11 .COM B73F 3K ver. 1.1 [In Use 1 of 3] Prints a message on your screen and locks the keyboard. Requires password before further use of the computer. Prevents use of your computer when you have to leave it in the middle of an operation. INUSE11 .DOC 064B 8K ver. 1.1 [In Use 2 of 3] INUSE11 .ASM D88E 16K ver. 1.1 [In Use 3 of 3] TYPWRYT .COM BE08 3K [Typewriter 1 of 3] Use your computer and printer like a typewriter. Requires a daisy-wheel printer. ASseMbler source is included. TYPWRYT .DOC 2D49 4K [Typewriter 2 of 3] TYPWRYT .ASM F655 23K [Typewriter 3 of 3] UMPIRE .COM BD74 2K [Umpire 1 of 2] Tests all available memory in TPA. UMPIRE .DOC 09DF 2K [Umpire 2 of 2] UNSPOL33.COM 80B4 2K ver. 3.3 [Unspool 1 of 2] Send a file to the printer in background mode. UNSPOL .DOC 2EEB 3K ver. 3.3 [Unspool 2 of 2] QUICKSET.ASM DCB5 3K Source for QS (on FOG-CPM.005), a program to set the file attribute bit.  Requires password before further use of the computer. Prevents use of your computer when you have to leave it in the middle of an operati'