* 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