;ECHO31.ASM Disables/enables console output. Assembles ;4/22/87 (Useful mainly in batch jobs.) with ASM.COM. ;Roy Lipscomb ; ; Copyright 1987, Logic Associates, Chicago. ; Permission granted for free distribution only. ; Cannot be sold without prior written permission. ; ; ;Version 3.1: [] Employs an improved ECHO ON algorithm, one compatible with ; utilities that clone the BIOS jumptable. (Thanks to Stan ; Shaffer for pointing out this problem.) ; [] Corrects out-of-place quotation marks in help screen. ; ;Version 3: [] Allows pseudo-control codes (e.g., two-char "=Z"). ; [] Uses "-" to toggle upper/lower case. ; ;Version 2: [] Combines ECHON and ECHOFF into one program, ECHO. ; [] Verifies the location of the echo switch. ; [] Compatible with XSUB. ; [] Employs new syntax, similar to ECHO in PC-DOS. ; ;Please address any comments or suggestions to-- ; ; Roy Lipscomb ; Logic Associates ; 1433 W. Thome ; Chicago, IL 60660 ; ;---------------------------------------------------------- org 100h jmp begin ;......................................................... ;equates. ul equ '/' ;char for "toggle upper/lower case." ct equ '~' ;char for "convert next char to ctl." nc equ '+' ;char for "text done, no cr/lf." no equ 0 yes equ 255 bell equ 7 cr equ 0dh lf equ 0ah dirio equ 6 ;direct console i/o function. bdos equ 5 on equ jmp off equ ret warmboot equ 0 bdos equ 5 fcb equ 5ch ;default fcbs, containing first word fcb2 equ 6ch ; and second word respectively of the ; command line. textloc equ 82h ;command-line text location. ;options: noopt equ 0 ;no further action. help equ 1 ;display instructions. swoff equ 2 ;disable console output. swon equ 3 ;enable console output. text equ 4 ;display command-line text. ;......................................................... ;messages. helpmsg: db cr,lf,ul,'ECHO31 E',ul,'nables-disables console output.' db cr,lf,ul,'C',ul,'opyright 1987, ',ul,'L',ul,'ogic ' db ul,'A',ul,'ssociates, 60660' db cr,lf,' ',ul,'F',ul,'or free distribution only.' ;db cr,lf db cr,lf,'---------------------------------------' db cr,lf db cr,lf,' ',ul,'D',ul,'isable output: ',ul,'ECHO OFF',ul db cr,lf db cr,lf,' ',ul,'E',ul,'nable output: ',ul,'ECHO ON',ul db cr,lf db cr,lf,' ',ul,'D',ul,'isplay "text,"' db cr,lf,' whether on-off: ',ul,'ECHO',ul,' text' db cr,lf db cr,lf,' ',ul,'D',ul,'isplay help: ',ul,'ECHO HELP',ul db cr,lf,' or ',ul,'ECHO H',ul db cr,lf,' or ',ul,'ECHO ?',ul db cr,lf db cr,lf,'* "',ul,ul,'" means "',ul,'T',ul,'oggle upper-lower case":' db cr,lf,' ',ul,'W',ul,'rite "',ul,'',ul,'ram',ul,'',ul,' disk" ' db 'for "',ul,'RAM',ul,' disk".' db cr,lf,'* "',ct,ct,'" means "',ul,'C',ul,'ontrol-".' db ' (',ul,'E',ul,'.g., "',ct,ct,'',ul,'Z',ul,'".)' db cr,lf,'* "',nc,nc,'" means "',ul,'I',ul,'gnore carriage return."' db cr,lf,'* ',ul,'B',ul,'ypass above by ' db '"',ul,ul,ul,ul,'", "' db '"',ct,ct,ct,ct,'"' db ' or "',nc,nc,nc,nc,'".' db cr,lf db cr,lf,'---------------------------------------' endomess: db 0 errmsg: db bell db cr,lf,'***> ',ul,'N',ul,'o action. ',ul,'S',ul,'witch not found. <***' crlf: db cr,lf,0 ;......................................................... ;work locations. tablen equ 6 ;length of entry in table below. tsttab: db '? ',help db 'H ',help db 'HELP ',help db 'OFF ',swoff db 'ON ',swon db 0,text option: db 0 ;option desired by user. echosw: dw 0 ;location of echo switch (bios jump table). error: db no ;error in locating echo switch? upper: db no ;display this char in upper case? oldchar: db 0 ;latest character displayed by ECHO. ;-------------------------------------------------------- ; mainline ; ;-------------------------------------------------------- begin: xra a ;initialize old-char area. sta oldchar call findsw ;locate the echo on/off switch. ;if not found, set "error" = yes. call findparm ;analyze parm, return option. cpi help ;asking for help? cz dhelp cpi text ;display text? cz dtext lda error ;echo-switch unlocated? cpi yes lda option cz derror cpi swon ;turn on? cz turnon cpi swoff ;turn off? cz turnoff ret ;return to CP/M. ;-------------------------------------------------------- ; determine option ; ;-------------------------------------------------------- ;on exit, a = option code (for help, ON, OFF, or text.) findparm: lxi h,fcb+1 ;address test-table xchg ; and start of command lxi h,tsttab-tablen ; line. push d push h findpr1: pop h pop d lxi b,tablen ;bump to next table entry. dad b inr m ;end of table? dcr m jz findpr8 ; yes, assume text: exit. push d ;save for next test. push h call chekopt ;is this the option? jnz findpr1 ; no, test next option. ; yes, a = option code. pop d ;flush stack. pop h mov b,a ;save option code. cpi text ;is it text option? jz findpr9 ; yes, keep code, exit. lda fcb2+1 ;only one word on command line? cpi ' ' jz findpr9 ; yes, keep code, exit. findpr8: mvi b,text ;change code to "text." findpr9: mov a,b ;get code into a. sta option ;save the code. ret ;return option code in A. ;........................................................ ; is this the option? ; ;........................................................ ;on exit, z = no if no match. ; else z = yes, a = option code. chekopt: mvi b,tablen-1 ;match all chars (skip code). chekop2: ldax d ;fcb char matches... inx d cmp m ; ...test char? inx h jnz chekop9 ; no, test next tab entry. dcr b ; yes: all 4 chars done? jnz chekop2 ; no, do next char. mov a,m ; yes, get opt code. chekop9: ret ;-------------------------------------------------------- ; locate echo switch ; ;-------------------------------------------------------- ;on exit, if switch found: store address of switch, ; set z = yes. findsw: mvi a,yes ;initialize error flag. sta error call isxsub ;is xsub active? jz findsw4 ; yes, use pointer in XSUB. lhld warmboot+1 ; no, use normal pointer. findsw4: call tstsw ;looks like switch location? jnz findsw9 ; no, exit. shld echosw ; yes, save location. mvi a,no ;turn off error flag. sta error findsw9: ret ;........................................................ ; is xsub present? ; ;........................................................ ;on exit, if yes, z=yes, hl=pointer to bios jump table. isxsub: lhld bdos+1 ;get pointers that indicate xchg ; whether xsub is present. lhld warmboot+1 ;test for presence of xsub. mov a,d cmp h ;warmboot/bdos same page? jnz isxs9 ; no, xsub not present. mov a,l ;exactly 29h bytes apart? sui 29h cmp e jnz isxs9 ; no, xsub not present. ;get true warmboot vector into hl dcx h mov d,m dcx h mov e,m xchg isxs9: ret ;........................................................ ; hl -> possible location of switch? ; ;........................................................ ;on entry, h points into possible first page of bios. ; ;on exit, if "no," z = no. ; if "yes," z=yes, ; hl=switch location. tstsw: mvi l,0ch ;adjust to proper offset, mov a,m ; get content. cpi on ;is content either "on" jz tstws9 ; or "off"? if neither, ; then switch not found. cpi off tstws9: ret ;if "not switch", z = no. ;-------------------------------------------------------- ; turn switch ON ; ;-------------------------------------------------------- turnon: lhld echosw mov b,m ;get old value of switch. mvi m,on ;set switch to new value. call teleoff ;turn on clone (if any) of that switch... cz teleoff ;...and clone of THAT switch, cz teleoff ;...etc. cz teleoff ;...etc. mvi a,noopt ;disable further options. ret ;........................................................ ;turn off any clones (of the on/off switch) that may have ; created by some utility, e.g., a ramdisk driver. teleoff: inx h mov e,m inx h mov d,m xchg mov a,m ;another off switch? cpi off jnz teleof8 mov b,m ; yes, save old value of switch ("OFF"), mvi m,on ; set switch to ON. teleof8: mov a,m cpi jmp ;is this one more in a chain of jumps? ret ; if yes, z flag = yes. ;-------------------------------------------------------- ; turn switch OFF ; ;-------------------------------------------------------- turnoff: lhld echosw mov b,m ;get old value of switch. mvi m,off mvi a,noopt ;disable further options. ret ;-------------------------------------------------------- ; process appropiate message ; ;-------------------------------------------------------- dhelp: lxi d,helpmsg call display ret ;........................................................ derror: lxi d,errmsg call display ret ;........................................................ dtext: lda fcb+1 ;blank line? cpi ' ' jz dtext2 ; yes, skip. lxi d,textloc ;point to command line text. call display dtext2: lda oldchar ;suppress cr/lf? cpi nc lxi d,crlf ; yes, point to "blank line." cnz display ret ;-------------------------------------------------------- ; display a message ; ;-------------------------------------------------------- ;on entry, de = msg address. display: lda error ;is switch unlocated? cpi yes push d ;(save address of message) cnz turnon ; no: turn it on, and... pop d push b ; ...save old switch. jmp display6 ; yes: try display anyway. display2: lhld oldchar ;get previous char into l, sta oldchar ; save new char. mov b,a ;store new char in b. call doul ;if ul char: process, and skip jz display5 ; display if appropriate. call docntl ;if make-ctl: process, and skip jz display5 ; display if appropriate. call donc ;if "nc" char: process, and skip jz display5 ; display if appropriate. display4: mov a,b ;reget new char. push d call setcase ;set char to upper or call chario ; lower case, then output. pop d lda oldchar ;indicate old char was displayed. ori 80h sta oldchar display5: inx d display6: ldax d ora a ;null? jnz display2 ; no, go process. display8: pop b lda error ;error locating switch? cpi yes jz display9 ; yes, exit. lhld echosw ; no, restore old content mov m,b ; of switch. display9: mvi a,noopt ;disable further actions, sta error ; including error msg. ret ;........................................................ ; set char to upper/lower case ; ;........................................................ ;on entry, a = b = new char, l = old char. ;on exit, if z = yes, then skip display of char. doul: mov a,b cpi ul ;current char is ul char? mvi a,1 ;(set to display char) jnz doul9 ; no, exit. lda upper ;toggle upper/lower case. cma sta upper mov a,b cmp l ;old char undisplayed ul char? mvi a,1 ;(set to display char) jz doul9 ; yes, display new char (ul char). xra a ; no, skip display doul9: ora a ;set flag. ret ;........................................................ ; build control char ; ;........................................................ ;on entry, a = b = new char, l = old char. ;on exit, if z = yes, then skip display of char. docntl: mvi a,ct ;old char is undisplayed make-ctl? cmp l jz docntl4 ; yes, skip. cmp b ; no, new char is an make-ctl? mvi a,1 ;(clear a.) jmp docntl9 ; yes/no, exit. (if yes, skip display) docntl4: sub b ;new char also = make-ctl? jz docntl8 ; yes, exit and display. mov a,b ; no, convert new char into ani 1fh ; control char, and mov b,a docntl8: ori 1 ; display char. docntl9: ret ;........................................................ ; set to end without cr/lf ; ;........................................................ ;on entry, a = b = new char, l = old char. ;on exit, if z = yes, then skip display of char, ; and point to end of message. donc: mvi a,nc ;old char is undisplayed "nc" char? cmp l ;(if displayed, was second of prev pair). jz donc4 ; yes, skip. cmp b ;new char is an "nc" char? jz donc8 ; yes, skip display. mvi a,1 ;(set to display) jmp donc9 ; no, display the char. donc4: cmp b ;new char also = "nc" char? mvi a,1 ;(set to display) jz donc9 ; yes, display new char. lxi d,endomess-1 ; no, end message immediately, ; without cr/lf. donc8: xra a ; don't display this char. donc9: ora a ;set flag. ret ;........................................................ ; set char to upper/lower case ; ;........................................................ ;on entry and exit, a = character. setcase: cpi 'A' ;alphabetic character? jc setcase9 cpi 'Z'+1 jnc setcase9 ; no, exit. setcase4: mov e,a lda upper ;want upper case? cpi yes mov a,e jz setcase9 ; yes, keep upper case. ori 20h ; no, convert to lower. setcase9: ret ;........................................................ ; output a character. ; ;........................................................ ;on entry, a = character to be output. chario: mov e,a mvi c,dirio call bdos ret ;-------------------------------------------------------- end