* PROGRAM: BANNER * AUTHOR: RICHARD CONN * VERSION: 1.0 * DATE: 22 FEB 82 * DERIVATION: From Public Domain Program, Author Unknown * PREVIOUS VERSIONS: None VERS EQU 10 ;VERSION NUMBER ********************************* * * * B A N N E R P R I N T * * * ********************************* * * BANNER is a program which prints large (5x7) block letters * on the LST: Device in response to user input from the * keyboard. BANNER is invoked in several ways: * BANNER * -- is printed on the LST: device; ex: * BANNER HELLO * BANNER /T * -- Multi-Text Line Input Mode; the user may * type several successive lines to be printed; * the user exits by typing ^C * BANNER /? * -- Built-In HELP Information is printed * ********************************* * User-Customized Parameters * ********************************* TEXT EQU 'T' ;OPTION CHAR TO INVOKE TEXT ENTRY MODE MCHARS EQU 16 ;MAX NUMBER OF CHARS/LINE ********************************* * Constants * ********************************* BDOS EQU 0005H FCB EQU 005CH BUFF EQU 0080H CTRLC EQU 03H CR EQU 0DH LF EQU 0AH TAB EQU 09H READLN EQU 10 ;Input Line Editor OUTL EQU 5 ;OUTPUT TO LST: OUTC EQU 2 ;OUTPUT TO CON: ORG 100H START: LXI H,0 ;SAVE STACK PTR DAD SP ;HL=OLD SP SHLD STACK LXI SP,STACK ;NEW STACK CALL PMSG DB 'BANNER Version ' DB VERS/10+'0','.',(VERS MOD 10)+'0' DB CR,LF DB 0 LDA FCB+1 ;CHECK FOR OPTION CPI '/' ;OPTION CAUGHT? JNZ ONE$LINE ;IF NO OPTION, PROCESS ONLY 1 LINE LDA FCB+2 ;CHECK FOR TEXT INPUT CPI TEXT ;TEXT CHAR? JZ BTEXT ;INPUT TEXT LINES ; ; Print BANNER Help Message ; HELP: CALL PMSG ;PRINT MESSAGE TO USER DB CR,LF,'BANNER is invoked by a command line like:' DB CR,LF,' BANNER ' DB CR,LF,'In which case will be printed and control ' DB CR,LF,'returned to CP/M, like "BANNER HELLO" to print' DB CR,LF,'"HELLO", or' DB CR,LF,' BANNER /o' DB CR,LF,'where ''/o'' is ''/T'' to invoke Text Entry' DB CR,LF,'Mode in which the user may enter several sequential ' DB CR,LF,'Banner Lines to be printed. Any other option ' DB CR,LF,'prints this Help Message and Exits.' DB 0 * * Exit BANNER * EXIT: LHLD STACK ;GET OLD STACK PTR SPHL ;LOAD SP RET * * PRINT BANNER WHEN CONTAINED IN COMMAND LINE * ONE$LINE: LXI H,BUFF ;PT TO INPUT LINE MOV A,M ;GET CHAR COUNT ORA A ;PRINT HELP MESSAGE IF NO CHARS JZ HELP MOV B,A ;CHAR COUNT IN B DCR B ;COUNT DOWN BY 1 TO ELIMINATE LEADING SPACE JZ HELP LXI D,BLINE ;PT TO BANNER LINE BUFFER MOV A,B ;GET CHAR COUNT STAX D ;STORE CHAR COUNT INX H ;PT TO FIRST CHAR (SPACE) INX H ;PT TO CHAR AFTER SPACE INX D ;PT TO NEXT POSITION IN BUFFER OL1: MOV A,M ;GET NEXT CHAR STAX D ;PUT IT INX H ;PT TO NEXT INX D DCR B ;COUNT DOWN JNZ OL1 CALL BANNER ;PRINT BANNER JMP EXIT ;EXIT TO CP/M * * Process Multiple Line Input * BTEXT: CALL PMSG DB CR,LF,'BANNER Multiple Line Input' DB CR,LF,' Input Line or ^C to Return to CP/M' DB CR,LF DB 0 BTEXTL: CALL PMSG DB 'BANNER? ',0 LXI D,INLINE ;INPUT LINE MVI C,READLN ;BDOS READLN FUNCTION CALL BDOS CALL PMSG ;NEW LINE DB CR,LF,0 CALL BANNER ;PRINT BANNER LINE JMP BTEXTL ;CONTINUE * * PRINT BANNER CONTAINED IN BLINE BUFFER (BLINE=CHAR CNT) * BANNER: LXI H,BLINE ;STORE ENDING MOV A,M ;GET CHAR COUNT CPI MCHARS+1 ;BEYOND CHAR LIMIT? JC BANNER1 ;CONTINUE IF NOT CALL PMSG DB CR,LF,'Truncation Error -- Line too long',CR,LF DB 0 JMP EXIT ;RETURN TO CALLER BANNER1: INX H ;PT TO FIRST CHAR ADD L ;ADD TO LOW-ORDER BYTE MOV L,A ;PT TO BYTE MVI M,0 ;STORE MVI D,80H ;PT TO MSB+1 CBAN: LXI H,BLINE+1 ;SET PTR TO FIRST CHAR MOV A,M ;CHECK FOR NO CHARS ORA A ;ENDING ZERO? JZ CB4 ;4 CRLF'S IF SO 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 CALL CAPS ;CAPITALIZE 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 CB4: CALL CRLF ;4 CALL CRLF CALL CRLF 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 * * CAPITALIZE CHAR IN A * CAPS: CPI 61H ;LOWER CASE? RC ANI 5FH ;MASK OUT BIT 5 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 LSTOUT ;PRINT CHAR IN C PRINT2: INX H ;PT TO NEXT BYTE DCR B ;COUNT DOWN JNZ PRINT1 MVI C,' ' ;PRINT THREE SPACES CALL LSTOUT CALL LSTOUT CALL LSTOUT POP B ;RESTORE BC RET PRINT3: MOV E,C ;SAVE CHAR MVI C,' ' ;PRINT CALL LSTOUT MOV C,E ;GET CHAR JMP PRINT2 * * SUPPORT ROUTINES * PMSG: XTHL ;GET PTR TO STRING 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 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 PMSG2: XTHL ;RESTORE HL, PTR RET CRLF: MVI C,CR CALL LSTOUT MVI C,LF JMP LSTOUT LSTOUT: PUSH H ! PUSH B ! PUSH D MOV E,C MVI C,OUTL ;OUTPUT TO LST: CALL BDOS POP D ! POP B ! POP H RET CONOUT: PUSH H ! PUSH B ! PUSH D MOV E,C MVI C,OUTC ;OUTPUT TO CON: CALL BDOS POP D ! POP B ! POP H RET 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 * * 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 * * FOR EXAMPLE, THE ENTRY FOR '*' IS 22H,14H,7FH,14H,22H; THIS GENERATES: * * * 00100 R 6 * * * * 10101 E 5 * *** 01110 A 4 * * 00100 D 3 * *** 01110 2 * * * * 10101 D 1 * * 00100 O 0 * ^^^^^ W * 21712 N ^ * 24F42 B * HHHHH I * T * 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 NEXTCH: DS 2 LLEN EQU 80 ;NUMBER OF CHARS IN LINE, MAX INLINE: DB LLEN ;CHAR COUNT FOR INLINE BLINE: DS LLEN+1 ;NUMBER OF BYTES IN LINE