;**************************** ;KENTUCKY MODIFIED PERKINS BRAILLER SOFTWARE ;KENTUCKY BUREAU FOR THE BLIND ;WAYNE D. THOMPSON, P.E. NOVEMBER 1982 ;THIS SOFTWARE IS DESIGNED FOR USE IN THE ;KENTUCKY MODIFIED PERKINS BRAILLER. REFERENCE ;THE KMPB TECHNICAL MANUAL FOR DETAILED INFORMATION ;ON THE HARDWARE MODIFICATIONS REQUIRED TO THE ;PERKINS BRAILLER. REFERENCE THE KMPB USER'S MANUAL ;FOR OPERATING INSTRUCTIONS AND INFORMATION ON THE ;USE OF THIS SOFTWARE. ;VERSION 1.40 (LAST REVISION 01-04-85) ;**************************** ;REGISTER ASSIGNMENTS ;R7' -- CURRENT LINE POSITION ;R6' -- CURRENT CARRIAGE POSITION ;R5' -- LINE BUFFER POINTER / CELL COUNTER ;R4' -- GENERAL PURPOSE ;R3' -- GENERAL PURPOSE ;R2' -- RESERVED FOR INTERRUPT SERVICE ROUTINE ;R1' -- RESERVED FOR INTERRUPT SERVICE ROUTINE ;R0' -- RAM POINTER & MISC ;R7 -- CHARACTER PASS ;R6 -- GENERAL PURPOSE ;R5 -- DELAY ROUTINE COUNTER ;R4 -- CARRIAGE DIRECTION (01=RIGHTBOUND, FF=LEFTBOUND) ;R3 -- LINE FEED MOTOR TABLE POINTER (PAGE 3) ;R2 -- CARRIAGE MOTOR TABLE POINTER (PAGE 3) ;R1 -- RAM POINTER & MISC ;R0 -- RAM POINTER & MISC ;**************************** ;I/O PORT ASSIGNMENTS ;P10 -- USART RESET (OUTPUT) ;P11 -- KEYBOARD LATCH RESET (OUTPUT) ;P12 -- USART TRANSMITTER READY (INPUT) ;P13 -- USART CONTROL/DATA (OUTPUT) ;P14 -- USART CHIP SELECT (OUTPUT) ;P15 -- BAUD RATE SELECT LSB (OUTPUT) ;P16 -- BAUD RATE SELECT NSB (OUTPUT) ;P17 -- BAUD RATE SELECT MSB (OUTPUT) ;P20 -- I/O & MEMORY EXPANSION BUS (I/O) ;P21 -- I/O & MEMORY EXPANSION BUS (I/O) ;P22 -- I/O & MEMORY EXPANSION BUS (I/O) ;P23 -- I/O & MEMORY EXPANSION BUS (I/O) ;P24 -- EXTERNAL RAM ENABLE = 1 (OUTPUT) ;P25 -- 8243 I/O EXPANDER SELECT (OUTPUT) ;P26 -- RS232 TRANSMIT ENABLE = 1 (OUTPUT) ;P27 -- TAPE REC CKT ENABLE = 0 (OUTPUT) ;WITH P25 LOW ;P40 -- KEYSWITCH 1 (INPUT) ;P41 -- KEYSWITCH 2 (INPUT) ;P42 -- KEYSWITCH 3 (INPUT) ;P43 -- KEYSWITCH 4 (INPUT) ;P50 -- KEYSWITCH 5 (INPUT) ;P51 -- KEYSWITCH 6 (INPUT) ;P52 -- SPACE KEYSWITCH (INPUT) ;P53 -- CARRIAGE HOME (INPUT) ;P60 -- DOT 1 SOLENOID (OUTPUT) ;P61 -- DOT 2 SOLENOID (OUTPUT) ;P62 -- DOT 3 SOLENOID (OUTPUT) ;P63 -- DOT 4 SOLENOID (OUTPUT) ;P70 -- DOT 5 SOLENOID (OUTPUT) ;P71 -- DOT 6 SOLENOID (OUTPUT) ;P72 -- EMBOSS SOLENOID (OUTPUT) ;P73 -- AUDIO SIGNAL (OUTPUT) ;WITH P25 HIGH ;P40 -- BAUD RATE DEFAULT SWITCH LSB (INPUT) ;P41 -- BAUD RATE DEFAULT SWITCH NSB (INPUT) ;P42 -- BAUD RATE DEFAULT SWITCH MSB (INPUT) ; (000=110, 001=300, 010=1200, 011=2400, ; 100=4800, 101=9600, 110=TAPE REC, ; 111=TAPE PLAY) ;P43 -- STOP BIT DEFAULT SWITCH (INPUT) ; (LOW=1 BIT, HIGH=2 BITS) ;P50 -- CHAR LENGTH DEFAULT SWITCH LSB (INPUT) ;P51 -- CHAR LENGTH DEFAULT SWITCH MSB (INPUT) ; (00=5, 01=6, 10=7, 11=8) ;P52 -- PARITY ENABLE DEFAULT SWITCH (INPUT) ; (LOW=OFF, HIGH=ON) ;P53 -- PARITY TYPE DEFAULT SWITCH (INPUT) ; (LOW=ODD, HIGH=EVEN) ;P60 -- CARRIAGE STEPPER MOTOR PHASE 1 (OUTPUT) ;P61 -- CARRIAGE STEPPER MOTOR PHASE 2 (OUTPUT) ;P62 -- CARRIAGE STEPPER MOTOR PHASE 3 (OUTPUT) ;P63 -- CARRIAGE STEPPER MOTOR PHASE 4 (OUTPUT) ;P70 -- LINEFEED STEPPER MOTOR PHASE 1 (OUTPUT) ;P71 -- LINEFEED STEPPER MOTOR PHASE 2 (OUTPUT) ;P72 -- LINEFEED STEPPER MOTOR PHASE 3 (OUTPUT) ;P73 -- LINEFEED STEPPER MOTOR PHASE 4 (OUTPUT) ;**************************** ;RESIDENT DATA MEMORY LOCATION ASSIGNMENTS FLAGS1 EQU 20H ;BIT FLAGS AS FOLLOWS: ;BIT 0: EMBOSS CTRL CHR 0=NO,1=YES ;BIT 1: CTRL CHR NEXT 0=NO,1=YES ;BIT 2: FORCE LINEFEED 0=NO,1=YES ;BIT 3: SOFT HNDSH 0=COM ENB,1=COM DIS ;BIT 4: BUFFER FULL 0=NO,1=YES ;BIT 5: BUF FULL TONE REQ 0=NO,1=YES ;BIT 6: EMB ON REQUEST 0=NO,1=YES ;BIT 7: EMB OFF REQUEST 0=NO,1=YES MAXLIN EQU 21H ;(MAX LINES -1) PER PAGE ; (31 NORM MODE, 47 GRAPHIC MODE) FLAGS2 EQU 22H ;BIT FLAGS AS FOLLOWS: ;BIT 0: EMBOSS 0=ON,1=OFF ;BIT 1: GRAPHICS MODE 0=NO,1=YES ;BIT 2: GRAPHICS REM CTRL 0=DIS,1=ENB ;BIT 3: AUTO SCROLL 0=NO,1=YES ;BIT 4: PAGE STATUS 0=ENGAGED,1=REL ;BIT 5: CHAR CASE 0=UPPER,1=LOWER ;BIT 6: INTERRUPTS 0=DISALLOW,1=ALLOW ;BIT 7: DUPLEX 0=FULL,1=HALF LMARG EQU 23H ;LEFT MARGIN CHAR POS EDPFLG EQU 24H ;EDIT PRINT IN USE FLAG 0=NO,1=YES SPARE1 EQU 25H ;SPARE RMARG EQU 26H ;RIGHT MARGIN CHAR POS SPCBIT EQU 27H ;SAVE SPECIAL BIT STATUS HERE ; (BIT 7=P27, BIT 6=P26, BIT 0-5=0) SPARE EQU 28H ;SPARE BSCHAR EQU 29H ;DEFINABLE BACKSPACE CHAR HSTEP EQU 2AH ;CURRENT HORIZONTAL STEPS PER CELL VSTEP EQU 2BH ;CURRENT VERTICAL STEPS PER LINE HNDSHK EQU 2CH ;0=DTR/DSR, 1=X-ON/X-OFF, 2=NONE LINEWD EQU 2DH ;CURRENT LINE WIDTH= ; MAXCEL-(LM-1)-(MAXCEL-RM) FLAGS3 EQU 2EH ;BIT FLAGS AS FOLLOWS: ;BIT 0: AUTO LF XMIT 0=NO,1=YES ;BIT 1: AUTO LF REC 0=NO,1=YES ;BIT 2: SPARE ;BIT 3: SPARE ;BIT 4: SPARE ;BIT 5: RECEIVE ERROR 0=NO,1=YES ;BIT 6: SPARE ;BIT 7: SPARE LINBUF EQU 2FH ;LINE BUFFER LENGTH (PAGE 15) BCP EQU 30H ;BUFFER CHAR PRINT POINTER (0-255) ; (LAST CHAR + 1) BCE EQU 31H ;BUFFER CHAR END POINTER (0-255) ; (LAST CHAR + 1) BPP EQU 32H ;BUFFER PAGE PRINT POINTER (0-14) ; (CURRENT PAGE) BPE EQU 33H ;BUFFER PAGE END POINTER (0-14) ; (CURRENT PAGE) ECC EQU 34H ;EDIT CURSOR CHAR PTR (0-255) ECP EQU 35H ;EDIT CURSOR PAGE PTR (0-14) CELUSD EQU 36H ;CELLS USED COUNTER LINTYP EQU 37H ;LINE TYPE (1=CR,2=LF, ; 3=MAX CELLS,4=EOT,5=FF) USART EQU 38H ;USART MODE BYTE PASS EQU 39H ;MISC PARAMETER PASSING ECTR EQU 3AH ;EDIT LINE COUNTER OR REMOTE CHR CTR MAXCEL EQU 3BH ;MAX CELLS AVAIL. PER LINE (42 OR 51) CARPOS EQU 3CH ;CARRIAGE POSITION TO START NEXT LINE ; (0=RB, 1-51=LB, 255=IN USE) BELL EQU 3DH ;BELL POSITION (1-254) BAUDRT EQU 3EH ;CURRENT BAUD RATE CODE (0-7) SAVEA EQU 3FH ;SAVE ACCUM HERE DURING INTERRUPT ;**************************** ;MISC CONSTANTS FREQLO EQU 28H ;LOW TONE FREQ (156 HZ) FREQHI EQU 05H ;HIGH TONE FREQ (1250 HZ) FREQEH EQU 04H ;EXTRA HIGH TONE FREQ (1562 HZ) TONESH EQU 05H ;SHORT TONE DURATION (5X20=100MS) TONEES EQU 02H ;EXTRA SHORT TONE (2X20=40MS) TONELG EQU 14H ;LONG TONE DURATION (20X20=400MS) TONENO EQU 80H ;NO TONE DURATION (1X128=128MS) ENSOL EQU 0DFH ;ENABLE SOLENOID PORT ENKBD EQU 0DFH ;ENABLE KEYBOARD PORT ENMOT EQU 20H ;ENABLE MOTOR PORT ENDIP EQU 20H ;ENABLE DIP-SWITCH PORT ENRAM EQU 10H ;ENABLE RAM BUFFER DISRAM EQU 0EFH ;DISABLE RAM BUFFER KBDRS EQU 0FDH ;KEYBOARD RESET PULSE START KBDRE EQU 02H ;KEYBOARD RESET PULSE END ;CELLS/SEC=1000/(DELED+DELSR+(6XDELCS)) DELED EQU 29 ;DELAY FOR EMBOSS DURATION (MSEC) DELSR EQU 53 ;DELAY FOR SOLENOID RELEASE (MSEC) DELCS EQU 8 ;DELAY FOR CARRIAGE MOTOR STEP (MSEC) ; (TIMES SIX STEPS PER CELL) DELLS EQU 13 ;DELAY FOR LINE FEED MOTOR STEP (MSEC) NORMVS EQU 19 ;NORMAL VERTICAL STEPS PER LINE NORMHS EQU 6 ;NORMAL HORIZONTAL STEPS PER CELL GRAPVS EQU 13 ;GRAPHICS VERTICAL STEPS PER LINE GRAPHS EQU 5 ;GRAPHICS HORIZONTAL STEPS PER CELL ;**************************** ;CHORD COMMANDS C2 EQU 42H ;BACKSPACE BCHORD EQU 43H ;BAUD RATE KCHORD EQU 45H ;BREAK COMM LINE CCHORD EQU 49H ;EMBOSS CONTROL CHARACTERS C46 EQU 68H ;CARRIAGE RETURN / LINE FEED C36 EQU 64H ;COMMAND MODE C3456 EQU 7CH ;CHAR, STOP BIT, & PAGE LENGTHS DCHORD EQU 59H ;FULL/HALF DUPLEX C1 EQU 41H ;EMBOSS ON C5 EQU 50H ;EMBOSS OFF ECHORD EQU 51H ;EDIT MODE QCHORD EQU 5FH ;STRING/COMMAND TERMINATOR HCHORD EQU 53H ;SOFTWARE/HARDWARE HANDSHAKING C1256 EQU 73H ;TRANSMIT DATA RCHORD EQU 57H ;REMOTE MODE LCHORD EQU 47H ;LOWER CASE UCHORD EQU 65H ;UPPER CASE C45 EQU 58H ;PAGE READY C456 EQU 78H ;PAGE RELEASE PCHORD EQU 4FH ;EVEN/ODD/NONE PARITY TCHORD EQU 5EH ;LOAD/SAVE TAPE WCHORD EQU 7AH ;SET BELL LOCATION SCHORD EQU 4EH ;SCROLL BUFFER (256 CHAR'S) NCHORD EQU 5DH ;CLEAR BUFFER GCHORD EQU 5BH ;GRAPHICS MODE MCHORD EQU 4DH ;SET & CLEAR MARGINS JCHORD EQU 5AH ;AUTO LINE FEED C4 EQU 48H ;CONTROL CHARACTER NEXT XCHORD EQU 6DH ;TRANSMIT ENABLE ;**************************** ORG 0 JMP START ;POWER-ON RESET, JUMP OVER ;INTERRUPT SERVICE ROUTINE ;**************************** DB 140 ;STORE SOFTWARE VERSION ; NUMBER HERE (IN DECIMAL) ;**************************** ;INTERRUPT SERVICE ROUTINE ;GETS A CHARACTER FROM THE USART AND ;PLACES IT IN THE BUFFER AT BCE & BPE ORG 03H SEL RB1 MOV R1,#SAVEA MOV @R1,A ;SAVE ACCUM ANL P1,#0E7H ;ENABLE USART (FOR DATA) MOVX A,@R1 ;GET CHAR ANL A,#7FH ;STRIP 8TH BIT ORL P1,#10H ;DISABLE USART MOV R2,A ;SAVE CHAR ;CHECK FOR X-ON/X-OFF CHAR IF SOFT HNDSH SET MOV R1,#HNDSHK ;SOFTWARE HANDSHAKE ON? MOV A,@R1 MOV R1,#FLAGS1 CPL A JB0 INT0 ;NO MOV A,R2 ;YES XRL A,#13H ;X-OFF? JNZ INT15 ;NO MOV A,#08H ;YES ORL A,@R1 ;SET FLAG TO COM DIS JMP INT16 INT15 MOV A,R2 ;X-ON? XRL A,#11H JNZ INT0 ;NO MOV A,#0F7H ;YES ANL A,@R1 ;SET FLAG TO COM ENB INT16 MOV @R1,A JMP INT2 ;CHECK FOR END OF AVAILABLE BUFFER SPACE INT0 MOV A,#14 MOV R1,#BPE XRL A,@R1 ;LAST PAGE? JNZ INT1 ;NO. MOV R1,#BCE ;YES. MOV A,@R1 CPL A ;LAST CHAR OF LAST PAGE? JZ INT2 ;YES. NO ROOM FOR CHAR, SO IGNORE. MOV A,@R1 ;NO. XRL A,#9BH ;100 CHARS FROM END? JNZ INT1 ;NO. ;PERFORM HANDSHAKE MOV R1,#FLAGS1 ;YES MOV A,@R1 ;MARK BUF FULL ORL A,#30H ; & MARK BUF FULL TONE REQUEST MOV @R1,A MOV R1,#HNDSHK ;GET HANDSHAKE TYPE MOV A,@R1 JNZ INT11 MOV A,#25H ;HARDWARE ORL P1,#08H ANL P1,#0EFH ;ENABLE USART (FOR COMMAND) MOVX @R1,A ;DISABLE DTR LINE ORL P1,#10H ;DISABLE USART JMP INT1 INT11 JB1 INT1 ;NONE INT13 IN A,P1 ;SOFTWARE JB2 INT12 ;TRANSMITTER READY? JMP INT13 ;NO INT12 ANL P1,#0E7H ;SEL USART DATA INPUT MOV A,#13H ;LOAD 'DC3' MOVX @R1,A ;SEND IT ORL P1,#10H ;DISABLE USART ;PUT CHAR IN BUFFER INT1 MOV R1,#BPE ;GET PAGE MOV A,@R1 JB0 INT3 ;BUILD RAM PAGE ADDR AT P2 ANL P2,#0FEH ;CLR BIT 0 JMP INT4 INT3 ORL P2,#1 ;SET BIT 0 INT4 JB1 INT5 ANL P2,#0FDH ;CLR BIT 1 JMP INT6 INT5 ORL P2,#2 ;SET BIT 1 INT6 JB2 INT7 ANL P2,#0FBH ;CLR BIT 2 JMP INT8 INT7 ORL P2,#4 ;SET BIT 2 INT8 JB3 INT9 ANL P2,#0F7H ;CLR BIT 3 JMP INT10 INT9 ORL P2,#8 ;SET BIT 3 INT10 ORL P2,#10H ;ENABLE RAM MOV R1,#BCE ;GET RAM LOCATION MOV A,@R1 MOV R1,A MOV A,R2 ;RECOVER CHAR MOVX @R1,A ;STORE CHAR IN BUFFER ANL P2,#DISRAM ;DISABLE RAM ;UPDATE POINTERS MOV R1,#BCE INC @R1 ;INC CHAR POINTER MOV A,@R1 JNZ INT14 MOV R1,#BPE INC @R1 ;INC PAGE POINTER INT14 MOV A,R2 ;RECOVER CHAR XRL A,#0DH ;CARRIAGE RETURN CHAR? JNZ INT2 ;NO MOV R1,#FLAGS3 ;YES MOV A,@R1 ANL A,#2 ;AUTO LF REC ENABLED? JZ INT2 ;NO MOV R2,#0AH ;LOAD LF CHAR JMP INT0 ;GO STORE IT INT2 MOV R1,#SAVEA MOV A,@R1 ;RECOVER ACCUM RETR ;**************************** ;DTRON AND DTROFF SUBROUTINES ;SETS DTR LINE ON USART TRUE OR FALSE DTRON DIS I MOV A,#27H ;ON COMMAND JMP DTR1 DTROFF DIS I MOV A,#25H ;OFF COMMAND DTR1 ORL P1,#08H ;SELECT CTRL INPUT ANL P1,#0EFH ;ENABLE USART (FOR COMMAND) MOVX @R0,A ;SEND IT ORL P1,#10H ;DISABLE USART EN I RETR ;**************************** ;KBIN SUBROUTINE ;CHECKS KEYBOARD FOR CHAR AVAILABLE. ;IF AVAIL, CHAR IS RETURNED IN A. ;IF NOT, RETURN WITH A=0. KBIN SEL RB0 JT1 KB2 ;JMP IF CHAR WAITING CLR A RETR KB2 JT0 KB2 ;LOOP HERE TILL ALL KEYS RELEASED MOV R5,#5 CALL DELAY ;DELAY TO INSURE RELEASE JT0 KB2 ;JMP IF KEYS STILL DEPRESSED ANL P2,#ENKBD ;GET CHAR FROM KBD LATCH MOVD A,P4 MOV R7,A MOVD A,P5 SWAP A ORL A,R7 ANL A,#7FH ;MASK OFF BIT 7 ANL P1,#KBDRS ;RESET KEYBOARD LATCH ORL P1,#KBDRE RETR ;RETURN WITH CHAR IN A ;**************************** ;EMBOSS SUBROUTINE ;ENTER WITH CHAR TO EMBOSS IN R7. ;IF NO ROOM ON LINE TO EMBOSS, EXIT WITH F1=0. ;IF ENOUGH ROOM TO EMBOSS, EXIT WITH F1=1. EMBOSS CLR F1 SEL RB0 MOV R0,#FLAGS2 MOV A,#1 ;LOAD EMBOSS MASK ANL A,@R0 ;EMBOSS ON? JZ EMB4 ;YES CPL F1 ;NO RETR EMB3 CALL CELL RETR EMB4 MOV A,R4 ;GET DIR XRL A,#1 ;RIGHTBOUND? JZ EMB2 ;YES MOV R0,#LMARG MOV A,@R0 ;GET LEFT MARGIN SEL RB1 XRL A,R6 ;AT MARGIN? JNZ EMB1 ;NO RETR ;YES EMB2 MOV R0,#RMARG MOV A,@R0 ;GET RIGHT MARGIN SEL RB1 XRL A,R6 ;AT MARGIN? JNZ EMB1 ;NO RETR ;YES EMB1 CPL F1 ;NOT END OF LINE SEL RB0 MOV A,R7 ;GET CHAR JB6 EMB3 ;JUMP IF 'SPACE' ANL P2,#ENSOL ;ENABLE SOLENOID PORT MOV A,R7 ;GET CHAR MOVD P6,A ;SEND LSN TO SOL SWAP A ANL A,#3 ;MASK OFF UNUSED BITS MOVD P7,A ;SEND MSN TO SOL CALL CELL ANL P2,#ENSOL MOV A,#4 ;ACTIVATE EMBOSS SOL ORLD P7,A MOV R5,#DELED ;DELAY FOR EMBOSS DURATION CALL DELAY CLR A ;RELEASE ALL SOLENOIDS MOVD P7,A MOVD P6,A MOV R5,#DELSR ;DELAY FOR SOL RELEASE CALL DELAY RETR ;**************************** ;GETMAX SUBROUTINE ;CHECKS TO SEE IF TEMP BRAILLE LINE BEING BUILT ;IN LINE BUFFER HAS REACHED MAX CELLS AVAILABLE ;ON CURRENT LINE FOR EMBOSSING. IF YES, SET A=0. ;ENTER WITH PRESENT CELL COUNT IN R5' GETMAX SEL RB0 MOV R1,#CELUSD ;GET CELLS USED MOV A,@R1 CPL A INC A ;SUB FROM LINE WIDTH MOV R1,#LINEWD ; TO GET CELLS AVAIL ADD A,@R1 SEL RB1 ;COMPARE TO PRESENT XRL A,R5 ; CELL COUNT. RETR ;IF MAX, A=0 ;**************************** ;GETLIN SUBROUTINE ;GETS ASCII CHARACTERS FROM MAIN BUFFER AND COMPOSES ;THE NEXT BRAILLE LINE IN THE LINE BUFFER (PAGE 15). ;LINES ARE TERMINATED BY CR,LF,FF IN ASCII TEXT, ;REACHING MAX PERMITTED CELLS PER LINE, OR ;REACHING END OF ASCII TEXT FOR X MILLISECONDS. ;WITHIN LINE BUFFER, CTRL CHARS HAVE BIT 7=1 ;REGISTER USAGE: ;R1 -- MISC POINTER ;R0' -- LINE BUFFER POINTER ;R4' -- ASCII CHAR SAVE ;R5' -- CELL COUNTER ;R3' -- LINE BUF PAGE # GETLIN CALL EOT ;END OF TEXT? JF1 GETL1 ;NO. SEL RB0 MOV R1,#FLAGS1 ;MAIN BUF FULL? MOV A,@R1 CPL A JB4 GETL5 ;NO MOV R1,#FLAGS2 ;AUTO SCROLL ON? MOV A,@R1 CPL A JB3 GETL27 ;NO SEL MB1 ;YES CALL SCROLL ;SCROLL BUFFER SEL MB0 RETR GETL27 MOV R1,#FLAGS1 ;BUF FULL TONE REQUEST? MOV A,@R1 JB5 GETL28 ;YES RETR ;NO GETL28 ANL A,#0DFH MOV @R1,A ;RESET TONE REQUEST CALL BFTONE ;SOUND BUF FULL SIGNAL GETL5 RETR GETL1 CLR A SEL RB1 MOV R3,#15 ;INIT LINE BUF PAGE # MOV R0,A ;CLR LINE BUF POINTER MOV R5,A ;CLR CELL COUNTER GETL0 CALL GETCHR ;GET NEXT CHR FROM BUFFER SEL RB0 MOV R1,#EDPFLG ;CAME HERE FROM EDIT MODE PRINT? MOV A,@R1 JZ GETL29 ;NO CALL SEND ;YES. ECHO CHARS GETL29 MOV A,R7 SEL RB1 MOV R4,A ;SAVE CHAR ANL A,#60H ;CTRL CHAR? JNZ GETL2 ;NO. ;CONTROL CHARACTER PROCESSING SEL RB0 ;YES MOV R1,#FLAGS1 ;EMBOSS CTRL CHAR? MOV A,@R1 CPL A JB0 GETL24 ;NO SEL MB1 ;YES CALL ROOM ;ROOM FOR 2 CELLS? SEL MB0 JF1 GETL12 ;YES JMP GETL4 ;NO GETL24 SEL RB1 SEL MB1 CALL GPHCTL ;SI OR SO GRAPHICS CTRL? SEL MB0 JF1 GETL8 ;YES. TREAT SAME AS CR TERM MOV A,R4 XRL A,#0DH ;CR? JZ GETL8 ;YES MOV A,R4 ;NO XRL A,#0AH ;LF? JZ GETL14 ;YES MOV A,R4 ;NO XRL A,#0CH ;FF? JZ GETL25 ;YES GETL12 SEL RB1 MOV A,R4 ADD A,#32 ;LOOK-UP CTRL CODE MOVP3 A,@A ORL A,#80H ;SET BIT 7 (CTRL CHR FLAG) CALL STOCHR ;STORE BRAILLE CODE INC R0 JMP GETL11 ;NOT CONTROL CHARACTER GETL2 MOV A,R4 ;RECOVER CHAR ANL A,#60H ;LOWER CASE? XRL A,#60H JNZ GETL3 ;NO MOV A,R4 ;YES ADD A,#-64 JMP GETL23 GETL3 MOV A,R4 ;RECOVER 'NORMAL' CHAR ADD A,#-32 ;LOOK-UP GETL23 MOVP3 A,@A CALL STOCHR ;STORE BRAILLE CODE INC R5 INC R0 ;LINE TERMINATED BY MAX CELLS? GETL11 CALL GETMAX ;REACHED MAX YET? JNZ GETL6 ;NO GETL4 SEL RB0 ;YES MOV R1,#LINTYP MOV @R1,#3 ;SET LINE TYPE SEL RB1 MOV A,R0 ;ZERO CHR COUNT MEANS NO JNZ GETL21 ; ROOM FOR CTRL CHR EMBOSS CALL LINEX ;OTHERWISE, FINISH SAME AS JMP GETL22 ; CR TERMINATION ;LINE TERMINATED BY END OF TEXT? GETL6 CALL EOT ;END OF TEXT? JF1 GETL0 ;NO. GET ANOTHER CHAR SEL RB0 ;YES MOV R1,#LINTYP ;SET LINE TYPE MOV @R1,#4 GETL7 JMP GETL20 ;FINISH SAME AS LF TERM ;LINE TERMINATED BY CR GETL8 SEL RB0 MOV R1,#LINTYP MOV @R1,#1 ;SET LINE TYPE GETL9 SEL RB1 MOV A,R0 ;IS LINE A SINGLE CR CHAR? JNZ GETL21 ;NO CALL EOT ;YES. END OF TEXT? JF1 GETL22 ;NO. SKIP CR ACTION CALL CARET ;YES. DO CR ACTION GETL22 SEL RB0 MOV R1,#CELUSD ;CLR CELLS USED CTR MOV @R1,#0 RETR GETL21 SEL RB0 MOV R1,#LINBUF ;STORE LINE BUF LENGTH MOV @R1,A MOV R1,#CELUSD MOV A,@R1 ;LEFT JUSTIFY LINE? JNZ GETL19 ;NO CALL SETCAR ;YES. INIT CARRIAGE FLAGS GETL19 JMP GETL13 ;LINE TERMINATED BY FF GETL25 SEL RB0 MOV R1,#LINTYP ;SET LINE TYPE MOV @R1,#5 SEL RB1 MOV A,R0 ;IS LINE A SINGLE FF CHAR? JNZ GETL7 ;NO. FINISH SAME AS LF TERM CALL WAITPG ;YES. DO FORM FEED RETR ;LINE TERMINATED BY LF GETL14 MOV A,R0 ;IS LINE A SINGLE LF CHAR? JNZ GETL16 ;NO CALL LINEX ;YES. DO LINE FEED SEL RB0 MOV R1,#FLAGS1 ;RESET FORCED LF FLAG MOV A,#0FBH ANL A,@R1 MOV @R1,A RETR GETL16 SEL RB0 MOV R1,#LINTYP ;SET LINE TYPE MOV @R1,#2 GETL20 SEL RB0 MOV R1,#CELUSD MOV A,@R1 ;STARTING NEW LINE? MOV R1,#CARPOS JZ GETL17 ;YES MOV @R1,#0FFH ;MARK CARRIAGE 'IN USE' JMP GETL18 GETL17 MOV @R1,#0 ;SET TO RIGHTBOUND GETL18 MOV R1,#CELUSD MOV A,@R1 SEL RB1 ADD A,R5 ;ADD CURRENT CELL COUNT SEL RB0 ; AND STORE MOV @R1,A SEL RB1 MOV A,R0 SEL RB0 MOV R1,#LINBUF MOV @R1,A ;STORE LINE BUF LENGTH GETL13 SEL RB1 MOV R5,#0 ;CLR CHAR PTR FOR PRTLIN RETR ;**************************** ;PRTLIN SUBROUTINE ;EMBOSS NEXT CHAR IN LINE BUFFER ;ENTER WITH LOC OF NEXT CHAR IN R5' ;(IF STARTING NEW LINE R5' WILL BE COMPUTED) ;IF CHAR BIT 7=1 THEN EXPAND TO TWO CELLS INDICATING ;CONTROL CHAR (DOT-4 FOLLOWED BY LETTER) PRTLIN SEL RB0 MOV R0,#LINBUF ;LINE BUF EMPTY? MOV A,@R0 JZ PRTL17 ;YES PRTL0 MOV R0,#FLAGS1 ;FORCE LF? MOV A,@R0 CPL A JB2 PRTL10 ;NO MOV A,@R0 ;YES. RESET FLAG ANL A,#0FBH MOV @R0,A CALL LINEX ;DO LF PRTL10 MOV R0,#CARPOS ;NEED TO POSITION CARRIAGE? MOV A,@R0 MOV R7,A ;SAVE POS XRL A,#0FFH JZ PRTL6 ;NO. MOV A,R7 ;YES. RIGHTBOUND? JNZ PRTL1 ;NO. CALL CARET ;YES. MOVE TO LEFT MARGIN. JMP PRTL4 PRTL1 MOV A,R7 ;GET DESIRED CELL POSITION SEL RB1 CPL A ;SUB IT FROM CURRENT CAR POS INC A ADD A,R6 JZ PRTL5 ;JUMP IF ALREADY AT CORRECT POS SEL RB0 MOV R7,A ;SAVE # OF CELLS TO MOVE JC PRTL2 MOV R4,#1 ;SET RIGHT CPL A ;CORRECT FOR NEGATIVE VALUE INC A MOV R7,A ;SAVE IT JMP PRTL3 PRTL2 MOV R4,#0FFH ;SET LEFT PRTL3 CALL CELL ;MOVE ONE CELL DJNZ R7,PRTL3 ;AGAIN PRTL5 SEL RB0 MOV R4,#0FFH ;YES. SET TO LEFTBOUND. ;CARRIAGE IS NOW AT CORRECT CELL POSITION & DIR SET PRTL4 SEL RB1 MOV R0,#CARPOS ;MARK CARRIAGE FLAG 'IN USE' MOV @R0,#0FFH SEL RB0 ;SET LINE BUFFER POINTER MOV A,R4 ;GET DIR XRL A,#0FFH ;LEFTBOUND? JZ PRTL7 ;YES. SEL RB1 ;NO. RIGHTBOUND MOV R5,#0 ;SET LINE BUF POINTER TO JMP PRTL6 ; BEGINNING PRTL7 SEL RB1 MOV R0,#LINBUF ;GET LINE BUF LENGTH MOV A,@R0 DEC A ;CHANGE LENGTH TO POINTER MOV R5,A ;SET LINEBUF POINTER TO END ;EMBOSS NEXT CHAR IN LINE BUFFER PRTL6 SEL RB1 MOV A,R5 MOV R0,A ;GET POINTER MOV A,#1FH ;SELECT PAGE 15 & ENABLE RAM SEL RB0 MOV R0,#SPCBIT ORL A,@R0 SEL RB1 DIS I OUTL P2,A ;ENABLE RAM MOVX A,@R0 ;GET CHAR ANL P2,#DISRAM ;DISABLE RAM EN I MOV R4,A ;SAVE CHAR JB7 PRTL14 ;IS IT CTRL CHAR? JMP PRTL8 ;NO PRTL14 MOV R0,#FLAGS1 ;EMBOSS CTRL CHAR'S? MOV A,@R0 CPL A JB0 PRTL15 ;NO SEL RB0 ;YES MOV A,R4 ;GET DIR VALUE DEC A JZ PRTL13 SEL RB1 ;LEFTBOUND MOV A,R4 ;RECOVER CHAR ANL A,#7FH ;STRIP CTRL FLAG SEL RB0 MOV R7,A CALL EMBOSS ;EMBOSS IT MOV R7,#08H CALL EMBOSS ;EMBOSS DOT-4 PREFIX JMP PRTL12 PRTL15 CALL BELLCH ;SOUND BELL IF CTRL-G JMP PRTL12 PRTL13 SEL RB0 ;RIGHTBOUND MOV R7,#08H CALL EMBOSS ;EMBOSS DOT-4 PREFIX SEL RB1 PRTL8 MOV A,R4 ;RECOVER CHAR ANL A,#7FH ;STRIP CTRL FLAG SEL RB0 MOV R7,A CALL EMBOSS ;EMBOSS IT PRTL12 SEL RB0 MOV A,R4 ;GET DIR VALUE SEL RB1 ADD A,R5 ;UPDATE BUF CHAR POS MOV R5,A ;SAVE IT XRL A,#0FFH ;END OF LINE BUF? (IF LB) JZ PRTL9 ;YES. MOV R0,#LINBUF MOV A,@R0 ;GET LINE LENGTH XRL A,R5 ;END OF LINE BUF? (IF RB) JNZ PRTL17 ;NO ;FINISHED EMBOSSING LINE BUFFER PRTL9 MOV R0,#LINTYP ;GET LINE TYPE MOV A,@R0 MOV R5,A ;SAVE IT XRL A,#1 ;CR TERMINATED? JNZ PRTL18 ;NO MOV R0,#CELUSD ;CLR CELLS USED CTR MOV @R0,A JMP PRTL11 PRTL18 MOV A,R5 XRL A,#2 ;LF TERMINATED? JZ PRTL16 ;YES MOV A,R5 XRL A,#5 ;FF TERMINATED JZ PRTL20 ;YES MOV A,R5 XRL A,#3 ;MAX CELLS TERM? JNZ PRTL19 ;NO MOV R0,#CELUSD ;CLR CELLS USED CTR MOV @R0,A MOV R0,#FLAGS1 ;SET FORCED LF FLAG MOV A,#4 ORL A,@R0 MOV @R0,A JMP PRTL11 PRTL20 CALL WAITPG ;DO FORM FEED JMP PRTL11 PRTL19 MOV A,R5 XRL A,#4 ;END OF TEXT TERM? JZ PRTL11 ;YES PRTL16 CALL LINEX ;DO LINE FEED PRTL11 MOV R0,#LINBUF ;MARK LINE BUF EMPTY MOV @R0,#0 PRTL17 RETR ;**************************** ;ROLLS PAPER OUT ONE LINE AND WAITS FOR ;PAPER CHANGE IF NECESSARY LINEX CALL LINE JF1 LINEX1 CALL WAITPG LINEX1 RETR ;**************************** ;ASCII/BRAILLE CONVERSION TABLE ;TABLE PAGE 'POSITION + 32' IS THE ASCII DECIMAL CODE FOR ;THE EQUIV BRAILLE TABLE 'VALUE'. ORG 300H TABLE DB 40H ;#32 SPACE DB 2EH ;#33 ! DB 10H ;#34 " DB 3CH ;#35 # DB 2BH ;#36 $ DB 29H ;#37 % DB 2FH ;#38 & DB 04H ;#39 ' DB 37H ;#40 ( DB 3EH ;#41 ) DB 21H ;#42 * DB 2CH ;#43 + DB 20H ;#44 , DB 24H ;#45 - DB 28H ;#46 . DB 0CH ;#47 / DB 34H ;#48 0 DB 02H ;#49 1 DB 06H ;#50 2 DB 12H ;#51 3 DB 32H ;#52 4 DB 22H ;#53 5 DB 16H ;#54 6 DB 36H ;#55 7 DB 26H ;#56 8 DB 14H ;#57 9 DB 31H ;#58 : DB 30H ;#59 ; DB 23H ;#60 < DB 3FH ;#61 = DB 1CH ;#62 > DB 39H ;#63 ? ;FOR THE FOLLOWING TABLE ENTRIES, 'POSITION +32' IS THE ;ACTUAL ASCII CODE FOR UPPER CASE CHARACTERS. ;'POSITION - 32' FOR CONTROL CHARACTERS. ;'POSITION + 64' FOR LOWER CASE CHARACTERS. ;CHOICE OF LOWER CASE OR CONTROL CHAR DEPEND ON ;'CASE' & 'CTLCHR' FLAGS SET AT TIME OF TABLE LOOK-UP. DB 08H ;#64 @ ` NULL DB 01H ;#65 A a SOH DB 03H ;#66 B b STX DB 09H ;#67 C c ETX DB 19H ;#68 D d EOT DB 11H ;#69 E e ENQ DB 0BH ;#70 F f ACK DB 1BH ;#71 G g BELL DB 13H ;#72 H h BS DB 0AH ;#73 I i HT DB 1AH ;#74 J j LF DB 05H ;#75 K k VT DB 07H ;#76 L l FF DB 0DH ;#77 M m CR DB 1DH ;#78 N n SO DB 15H ;#79 O o SI DB 0FH ;#80 P p DLE DB 1FH ;#81 Q q DC1 DB 17H ;#82 R r DC2 DB 0EH ;#83 S s DC3 DB 1EH ;#84 T t DC4 DB 25H ;#85 U u NAK DB 27H ;#86 V v SYNC DB 3AH ;#87 W w ETB DB 2DH ;#88 X x CAN DB 3DH ;#89 Y y EM DB 35H ;#90 Z z SUB DB 2AH ;#91 [ { ESC DB 33H ;#92 \ | FS DB 3BH ;#93 ] } GS DB 18H ;#94 ^ ~ RS DB 38H ;#95 _ DEL US ;**************************** ;STEPPER MOTOR SEQUENCE TABLE MOTTOP DB 0AH DB 06H DB 05H MOTBOT DB 09H ;**************************** ;SEND SUBROUTINE ;ENTER WITH CHAR TO BE TRANSMITTED TO USART IN R7 SEND SEL RB0 MOV R0,#SPCBIT ;IS RS232 XMIT ENABLED? MOV A,@R0 JB6 SEND7 ;YES JMP SEND5 SEND7 MOV R0,#PASS ;TEMP SAVE CHAR MOV A,R7 MOV @R0,A SEND1 EN I IN A,P1 ;TRANSMITTER READY? JB2 SEND2 ;YES JMP SEND1 ;NO SEND2 DIS I MOV R0,#HNDSHK MOV A,@R0 ;HARDWARE HANDSHAKE? JNZ SEND3 ;NO ORL P1,#08H ;SELECT CONTROL INPUT ANL P1,#0EFH ;ENABLE USART MOVX A,@R0 ;READ USART STATUS JB7 SEND4 ;DSR TRUE? ORL P1,#10H ;NO. DISABLE USART JMP SEND0 SEND3 JB1 SEND4 ;SOFTWARE HANDSHAKE? MOV R0,#FLAGS1 ;YES MOV A,@R0 ;COM ENABLED? JB3 SEND6 ;NO ;SEND CHAR SEND4 MOV R0,#PASS ;RECOVER CHAR MOV A,@R0 ANL P1,#0E7H ;SELECT USART DATA INPUT MOVX @R0,A ;SEND CHAR ORL P1,#10H ;DISABLE USART SEND5 EN I RETR ;CHECK FOR USER CLEARING OF HARDWARE HANDSHAKE HANGUP SEND0 CALL KBIN ;WANT TO CLEAR HANGUP? XRL A,#C36 JNZ SEND1 ;NO. TRY AGAIN MOV R0,#HNDSHK ;YES MOV @R0,#2 ;SET HANDSHAKE TO NONE JMP SEND1 ;CHECK FOR USER CLEARING OF SOFTWARE HANDSHAKE HANGUP SEND6 CALL KBIN ;WANT TO CLEAR HANGUP? XRL A,#C36 JNZ SEND1 ;NO. TRY AGAIN MOV A,@R0 ;YES ANL A,#0F7H ;SIMULATE RECEPTION OF X-ON BY MOV @R0,A ; ENABLING COM FLAG CALL LOCBEL ;BEEP TO INDICATE CLEARING JMP SEND1 ;***************************** ;SELECT TYPE OF HANDSHAKING (H-CHORD H,S,N) ;H=HARDWARE (DTR/DSR) ;S=SOFTWARE (X-ON/X-OFF) ;N=NONE HANDSH CALL GETKBD ;GET PARAMETER MOV R0,#HNDSHK XRL A,#13H ;H? JNZ HANDS1 ;NO MOV @R0,#0 ;YES. SET TO 'HARDWARE' JMP COMAND HANDS1 MOV A,R7 XRL A,#0EH ;S? JNZ HANDS2 ;NO MOV @R0,#1 ;SET TO 'SOFTWARE' MOV R0,#FLAGS1 ;SET TO X-ON MOV A,#0F7H ANL A,@R0 MOV @R0,A JMP COMAND HANDS2 MOV @R0,#2 ;SET TO 'NONE' JMP COMAND ;**************************** ;SET AUTOMATIC SCROLLING FEATURE ;IF ON, BUFFER AUTOMATICALLY SCROLLS AWAY THE OLDEST ;PAGE OF DATA WHEN THE BUFFER BECOMES FULL. ;(S-CHORD Y,N) ;Y=YES, N=NO AUTOSC CALL GETKBD ;GET PARAMETER MOV R0,#FLAGS2 XRL A,#3DH ;Y? JNZ AUTOS1 ;NO MOV A,#08H ;YES. SET TO 'YES' ORL A,@R0 MOV @R0,A JMP COMAND AUTOS1 MOV A,#0F7H ;SET TO 'NO' ANL A,@R0 MOV @R0,A JMP COMAND ;**************************** ;EMBOSS CONTROL CHARACTERS (C-CHORD Y,N) ;ALL RECEIVED CTRL CHARS MAY BE EMBOSSED ;IN FORMAT: DOT 4, CHAR ;Y=YES, N=NO EMBCTL CALL GETKBD ;GET PARAMETER MOV R0,#FLAGS1 XRL A,#3DH ;Y? JNZ EMBCT1 ;NO MOV A,#1 ;YES. SET TO 'YES' ORL A,@R0 MOV @R0,A JMP COMAND EMBCT1 MOV A,#0FEH ;SET TO 'NO' ANL A,@R0 MOV @R0,A JMP COMAND ;***************************** ;BELLCH SUBROUTINE ;SOUNDS BELL IF CTRL-G IN R4' BELLCH MOV A,R4 ;RECOVER CHAR XRL A,#9BH ;CTRL-G (BELL)? JNZ BELLC1 CALL LOCBEL ;SOUND BELL BELLC1 RETR ;**************************** ;GETCHR SUBROUTINE ;GETS NEXT ASCII CHAR FROM MAIN BUFFER AND ;RETURNS IT IN ACCUM AND R7. UPDATE POINTERS. GETCHR SEL RB0 CALL GET ;GET CHAR MOV R7,A ;SAVE CHAR MOV R0,#BCP INC @R0 ;INC PRINT POINTER MOV A,@R0 ;NEXT PAGE? JNZ GETCH1 ;NO. MOV R1,#BPP INC @R1 ;YES. INC PAGE POINTER. GETCH1 MOV A,R7 ;RECOVER CHAR RETR ;**************************** ;GET SUBROUTINE ;GETS CHAR FROM BUFFER AT LOCATION ;BCP & BPP AND RETURNS IT IN A. GET SEL RB0 DIS I MOV R1,#BPP ;GET BUF PAGE MOV A,@R1 ORL A,#10H MOV R1,#SPCBIT ORL A,@R1 OUTL P2,A ;ENABLE RAM MOV R0,#BCP ;GET PTR MOV A,@R0 MOV R0,A MOVX A,@R0 ;READ CHAR FROM RAM ANL P2,#DISRAM ;DISABLE RAM EN I RETR ;**************************** ;SELECT BAUD RATE (B-CHORD X) ;WHERE X IS ONE OF SIX AVAILABLE BAUD RATES (1-6) ;1=110 BAUD,2=300,3=1200,4=2400,5=4800,6=9600 BAUDSL SEL RB0 CALL GETKBD ;GET X CALL ASCII ;CONVERT DEC A ;DERIVE BAUD RATE ANL A,#7 MOV R0,#BAUDRT ;SAVE IT MOV @R0,A SEL MB1 CALL BAUD ;SET BAUD RATE SEL MB0 JMP COMAND ;**************************** ;WAITPG SUBROUTINE ;GO TO END OF PAGE, SOUND EOP ALERT, THEN ;WAIT FOR PAGE READY CHORD BEFORE RETURNING. ;EXIT WITH F1=1 WAITPG SEL RB1 MOV R0,#FLAGS2 ;EMBOSS ON? MOV A,@R0 ANL A,#1 JNZ WAITP3 ;NO CALL CARET ;RETURN CARRIAGE WAITP2 CALL LINE ;DO FORM FEED JF1 WAITP2 CLR A MOV R7,A ;RESET LINE COUNTER ORL P2,#ENMOT ;ENABLE MOTOR PORT MOVD P7,A ;RELEASE LF MOTOR MOV R0,#FLAGS2 ;SET PAGE RELEASED FLAG MOV A,#10H ORL A,@R0 MOV @R0,A CALL BEEP2H ;SOUND EOP ALERT ;CALL HERE IF PAGE ALREADY RELEASED WAITP4 CALL GETKBD ;CHK KBD XRL A,#NCHORD ;CLEAR BUFFER CHORD? JNZ WAITP1 ;NO CALL CLRBUF ;YES. CLEAR IT JMP WAITP4 WAITP1 CALL PAGRDY JF1 WAITP3 JMP WAITP4 ;NOT PAGE RDY CHORD WAITP3 RETR ;**************************** ;PAGRDY SUBROUTINE ;ENTER WITH KEYBOARD CHAR IN R7 ;IF PAGE RELEASED THEN CHAR 'MUST' BE ;(4,5)-CHORD (PAGE READY). IF CHAR REQUIRES FURTHER ;PROCESSING, RETURN WITH F1=0. PAGRDY SEL RB0 CLR F1 MOV R0,#FLAGS2 ;PAGE RELEASED? MOV A,@R0 ANL A,#10H JZ PAGRD1 ;NO. MOV A,R7 ;YES. GET CHAR XRL A,#C45 ;PAGE READY CHORD? JZ PAGRD2 ;YES. CALL BEEPLO ;NO RETR PAGRD2 MOV A,#0EFH ;RESET PAGE READY FLAG ANL A,@R0 MOV @R0,A ORL P2,#ENMOT ;ENABLE MOTOR PORT MOV R3,#MOTTOP ;INIT MOTOR TABLE POINTER MOV A,R3 ;INIT LF MOTOR MOVP3 A,@A MOVD P7,A CPL F1 PAGRD1 RETR ;**************************** ;SETCAR SUBROUTINE ;ENTER WITH CELL COUNT OF NEXT LINE IN R5' ;DETERMINE DIRECTION OF EMBOSS AND CARRIAGE ;START POSITION. SETCAR SEL RB1 MOV A,R5 ;CELL COUNT=0? JZ SETCA4 ;YES. DO NOT SET CARRIAGE CLR C ;DIVIDE IT BY 2 RRC A MOV R0,#LMARG ;ADD IT TO LEFT MARGIN TO GET ADD A,@R0 ; BREAK POINT = (R5'/2)+LM CPL A ;SUBTRACT IT FROM CARRIAGE POS INC A ADD A,R6 JC SETCA1 ;IF CAR POS >= BREAK POINT, LEFTBOUND CLR A JMP SETCA5 ;IF CAR POS < BREAK POINT, RIGHTBOUND SETCA1 MOV A,R5 MOV R0,#LMARG ADD A,@R0 ;ADD LEFT MARGIN SETCA5 MOV R0,#CARPOS MOV @R0,A ;STORE CARRIAGE START POS SETCA4 RETR ;**************************** ;EOT SUBROUTINE ;DETERMINES WHEN END OF TEXT IS REACHED BY COMPARING ;BUFFER PRINT POINTERS TO END POINTERS. ;IF AT END, RETURN WITH F1=0. EOT SEL RB0 MOV R6,#1 ;INIT 'SECOND TRY' FLAG EOT0 CLR F1 MOV R0,#BCP ;GET BUFFER CHAR PRINT PTR MOV R1,#BCE ;GET BUFFER CHAR END PTR MOV A,@R0 XRL A,@R1 ;SAME? JZ EOT1 ;YES CPL F1 ;NO RETR EOT1 MOV R0,#BPP ;GET BUF PAGE PRINT PTR MOV R1,#BPE ;GET BUF PAGE END PTR MOV A,@R0 XRL A,@R1 ;SAME? JZ EOT2 ;YES CPL F1 ;NO RETR EOT2 MOV A,R6 JZ EOT3 MOV R5,#40 ;WAIT 40 MSEC, THEN CALL DELAY ; CHECK A SECOND TIME TO DEC R6 ; MAKE SURE DATA RECEPTION JMP EOT0 ; HAS STOPPED EOT3 RETR ;**************************** ;GETKBD SUBROUTINE ;WAITS FOR CHAR FROM KEYBOARD AND ;RETURNS IT IN R7 AND A GETKBD SEL RB0 GETKB1 CALL KBIN ;GET CHAR JZ GETKB1 MOV R7,A RETR ;**************************** ;ASCII SUBROUTINE ;ENTER WITH BRAILLE CODE IN R7 ;EXIT WITH CORRESPONDING ASCII CODE IN A AND ;BRAILLE CODE IN R7 ;EXIT WITH A=FF IF INVALID CHAR ASCII SEL RB0 MOV R6,#32 ;INIT TABLE POS COUNTER MOV R0,#0 ;INIT TOP OF TABLE PTR ASC1 MOV A,R0 MOVP3 A,@A XRL A,R7 ;COMPARE CHAR TO TABLE ENTRY JZ ASC2 INC R6 ;INC POS COUNTER INC R0 ;INC TABLE PTR MOV A,R0 ;END OF TABLE? JB6 ASC7 ;YES JMP ASC1 ;NO ;TABLE POS IN R6 IS NOW THE ASCII ROOT VALUE ASC2 MOV R0,#FLAGS1 ;CTRL CHR FLAG SET? MOV A,@R0 JB1 ASC8 ;YES JMP ASC3 ;NO ASC8 ANL A,#0FDH ;RESET CTRL CHR FLAG MOV @R0,A MOV A,R6 JB6 ASC4 ;VALID CTRL CHR? ASC7 MOV A,#0FFH RETR ASC4 ANL A,#0BFH ;CONVERT TO ASCII CTRL CHR RETR ASC3 MOV R0,#FLAGS2 ;LOWER CASE FLAG SET? MOV A,@R0 ANL A,#20H JNZ ASC5 ;YES MOV A,R6 ;RECOVER CHAR RETR ASC5 MOV A,R6 ;IS IT A CHR THAT CAN BE JB6 ASC6 ; LOWER CASE? RETR ;NO ASC6 ORL A,#20H ;YES.CONVERT TO LOWER CASE RETR ; ASCII. ;**************************** ;CLRBUF SUBROUTINE ;CLEARS BUFFER AND HANDSHAKES TO RE-ENABLE ;DATA RECEPTION CLRBUF CALL GETKBD XRL A,#7FH ;IS IT (1,2,3,4,5,6)-CHORD? JNZ CLRBU1 ;NO. IGNORE CLR BUF COMMAND DIS I SEL MB1 CALL INIT50 ;INIT POINTERS & FLAGS CALL RESUME ;HANDSHAKE SEL MB0 EN I RETR CLRBU1 CALL BEEPLO RETR ;**************************** ;HALFDU SUBROUTINE ;EMBOSSES CHAR IN R7 IF IN HALF DUPLEX MODE ;IF NO ROOM ON PAGE, EXIT WITH F1=0 HALFDU SEL RB0 CLR F1 MOV R0,#FLAGS2 ;HALF DUPLEX? MOV A,@R0 JB7 HALF1 ;YES CPL F1 ;NO HALF2 RETR HALF1 CALL EMBOSS ;EMBOSS CHAR JF1 HALF2 ;ROOM ON LINE? CALL CRLF ;NO JF1 HALF3 ;ROOM ON PAGE? RETR ;NO HALF3 CALL EMBOSS ;NOW EMBOSS CHAR RETR ;**************************** ;EOTSET SUBROUTINE ;SETS BUFFER PRINT POINTERS BCP & BPP EQUAL TO ;BUFFER END POINTERS BCE & BPE EOTSET SEL RB0 MOV R0,#BPE MOV A,@R0 DEC R0 MOV @R0,A DEC R0 MOV A,@R0 DEC R0 MOV @R0,A RETR ;**************************** START SEL MB1 CALL INIT ;INITIALIZE SYSTEM VARIABLES & I/O SEL MB0 CALL KBIN ;"PRINTER MODE" REQUEST? JZ COMAND ;NO MOV R0,#HNDSHK ;YES. SET HANDSHAKE TO HARDWARE MOV @R0,#0 MOV R0,#FLAGS2 ;SET AUTO SCROLL "ON" MOV A,@R0 ORL A,#08H ANL A,#7FH ;SET TO FULL DUPLEX MOV @R0,A JMP REMOTE ;GO TO REMOTE MODE ;**************************** ;COMMAND ROUTINE ;THIS ROUTINE REPRESENTS 'READY' STATUS OF THE SYSTEM ;IT CONSTANTLY READS THE KEYBOARD AWAITING THE ENTRY OF ;A COMMAND CHORD. UPON ENTRY OF A VALID COMMAND, CONTROL ;IS TRANSFERRED TO THE CORRESPONDING ROUTINE AND UPON ;COMPLETION OF THAT ROUTINE CONTROL ALWAYS RETURNS HERE ;AND AWAITS THE NEXT COMMAND. COMAND DIS I SEL RB0 CALL READY ;SOUND READY PROMPT COM1 CALL GETKBD ;GET COMMAND MOV R0,#COMTAB ;LOAD TABLE START ADDR COM2 MOV A,R0 MOVP A,@A ;GET TABLE VALUE MOV R6,A ;SAVE IT XRL A,#0FFH ;END OF TABLE? JNZ COM4 ;NO CALL BEEPLO ;YES. INVALID COMMAND JMP COMAND COM4 MOV A,R7 XRL A,R6 ;MATCH TABLE COMMAND? JNZ COM3 ;NO INC R0 ;YES MOV A,R0 JMPP @A ;GO TO PROPER JUMP COM3 INC R0 ;ADVANCE TO NEXT INC R0 ; TABLE ENTRY INC R0 INC R0 JMP COM2 ;****************************** ;COMAND ROUTINE JUMP TABLE COMTAB DB RCHORD,$+2 ;REMOTE MODE JMP REMOTE DB JCHORD,$+2 ;AUTO LINE FEED JMP AUTOLV DB NCHORD,$+2 ;CLEAR BUFFER JMP BUFCLR DB CCHORD,$+2 ;EMBOSS CTRL CHAR JMP EMBCTL DB BCHORD,$+2 ;BAUD RATE JMP BAUDSL DB C3456,$+2 ;CHAR,STOP BIT,& PAGE LEN JMP LENGTV DB DCHORD,$+2 ;FULL/HALF DUPLEX JMP SETDUV DB ECHORD,$+2 ;EDIT MODE JMP EDITV DB HCHORD,$+2 ;SOFTWARE/HARDWARE HNDSHK JMP HANDSH DB C1256,$+2 ;TRANSMIT DATA JMP XMTDAT DB PCHORD,$+2 ;CHANGE PARITY JMP PARITV DB TCHORD,$+2 ;TAPE MODE JMP TAPEV DB GCHORD,$+2 ;GRAPHICS MODE JMP GRAPHV DB WCHORD,$+2 ;SET BELL LOCATION JMP SETBEV DB C2,$+2 ;SET BACKSPACE CHAR JMP SETBSV DB SCHORD,$+2 ;SET AUTO SCROLL JMP AUTOSC DB C456,$+2 ;PAGE RELEASE JMP PAG DB XCHORD,$+2 ;TRANSMIT ENABLE JMP XMTENV DB C36,$+2 ;COMMAND MODE JMP COMAND DB 0FFH ;END OF TABLE MARKER ;**************************** ;CELL SUBROUTINE ;ENTER WITH CARRIAGE DIRECTION IN R4. ;CAUSES CARRIAGE TO MOVE ONE BRAILLE CELL LEFT OR RIGHT ;UPDATES CURRENT CARRIAGE POSITION IN R6' CELL SEL RB0 MOV R0,#FLAGS2 ;EMBOSS ON? MOV A,@R0 ANL A,#1 JNZ CELL2 ;NO MOV R0,#HSTEP ;LOAD STEPS PER CELL MOV A,@R0 MOV R6,A CELL1 CALL MOVE ;MOVE ONE STEP DJNZ R6,CELL1 MOV A,R4 ;GET DIR VALUE SEL RB1 ADD A,R6 ;UPDATE CARRIAGE POS MOV R6,A ;SAVE IT ANL P2,#0DFH ;DISABLE MOTOR PORT CELL2 RETR ;**************************** ;LINE SUBROUTINE ;CAUSES PAPER TO ADVANCE TO NEXT LINE. ;IF NO ROOM LEFT ON PAGE, EXIT WITH F1=0. ;IF ENOUGH ROOM FOR NEW LINE, EXIT WITH F1=1. LINE CLR F1 SEL RB0 MOV R0,#FLAGS2 ;EMBOSS ON? MOV A,@R0 ANL A,#1 JZ LINE3 ;YES CPL F1 ;NO RETR LINE3 MOV R0,#MAXLIN ;ROOM LEFT ON PAGE? MOV A,@R0 SEL RB1 XRL A,R7 JZ LINE4 ;END OF PAGE LINE1 CPL F1 ;NOT END OF PAGE INC R7 ;INC LINE COUNTER SEL RB0 MOV R0,#VSTEP ;LOAD STEPS PER LINE MOV A,@R0 SEL RB1 MOV R4,A LINE2 CALL ROLL DJNZ R4,LINE2 ANL P2,#0DFH ;DISABLE MOTOR PORT LINE4 RETR ;**************************** ;MOVE SUBROUTINE ;ENTER WITH CARRIAGE DIRECTION IN R4. ;MOVES CARRIAGE ONE MOTOR STEP LEFT OR RIGHT. MOVE SEL RB0 ORL P2,#ENMOT ;ENABLE MOTOR PORT MOV A,R2 ;GET POINTER ADD A,R4 ;SEQUENCE TO NEXT TABLE VALUE MOV R2,A XRL A,#MOTTOP-1 ;TOP OF TABLE? JNZ MOVE1 ;NO MOV R2,#MOTBOT ;YES, SET TO BOT OF TABLE JMP MOVE2 MOVE1 MOV A,R2 XRL A,#MOTBOT+1 ;BOT OF TABLE? JNZ MOVE2 ;NO MOV R2,#MOTTOP ;YES, SET TO TOP OF TABLE MOVE2 MOV A,R2 ;GET NEW POINTER MOVP3 A,@A ;GET MOTOR VALUE FROM TABLE MOVD P6,A ;SEND TO MOTOR MOV R5,#DELCS ;DELAY FOR CARRIAGE MOTOR STEP CALL DELAY RETR ;**************************** ;ROLL SUBROUTINE ;ROLLS PAPER UP ONE MOTOR STEP ROLL SEL RB0 ORL P2,#ENMOT ;ENABLE MOTOR PORT DEC R3 ;DEC LF STEPPER MOTOR POINTER MOV A,R3 XRL A,#MOTTOP-1 ;TOP OF TABLE? JNZ ROLL1 ;NO MOV R3,#MOTBOT ;YES, SET TO BOT OF TABLE ROLL1 MOV A,R3 ;GET NEW POINTER MOVP3 A,@A ;GET MOTOR VALUE FROM TABLE MOVD P7,A ;SEND TO MOTOR MOV R5,#DELLS ;DELAY FOR PAPER ROLL CALL DELAY RETR ;**************************** ;STOCHR SUBROUTINE ;STORES CHAR IN RAM ;ENTER & EXIT WITH CHAR IN A, CHAR LOC IN R0', ;AND PAGE LOC IN R3' STOCHR SEL RB0 MOV R7,A ;SAVE CHAR MOV R0,#SPCBIT ;COPY P26 & P27 MOV A,@R0 SEL RB1 ORL A,R3 ;GET PAGE ORL A,#10H DIS I OUTL P2,A ;ENABLE RAM SEL RB0 MOV A,R7 ;GET CHAR SEL RB1 MOVX @R0,A ;STORE CHAR ANL P2,#DISRAM ;DISABLE RAM EN I RETR ;**************************** ;RELEASE PAGE, WAIT FOR PAGE READY CHORD, ;AND RETURN TO COMMAND MODE. PAG CALL WAITPG JMP COMAND ;**************************** ;TRANSMIT DATA (1,2,5,6)-CHORD ;THIS ROUTINE AUTOMATICALLY TRANSMITS ALL TEXT IN THE ;BUFFER TO THE RS232 PORT THEN RETURNS TO COMMAND MODE. ;TYPE (3,6)-CHORD AT ANY TIME TO ABORT TRANSMISSION. ;DATA CANNOT BE RECEIVED WHILE IN TRANSMIT MODE. XMTDAT DIS I SEL MB1 CALL SERON ;ENABLE RS232 XMIT CALL SNDBUF ;SEND THE BUFFER SEL MB0 JMP COMAND ;**************************** ;CRLF SUBROUTINE ;PERFORMS CARRIAGE RETURN & LINE FEED CRLF CALL LINE ;DO LINE FEED JF1 CRLF1 ;END OF PAGE? RETR ;YES CRLF1 CALL CARET ;DO CARRIAGE RETURN RETR ;**************************** ;CARET SUBROUTINE ;RETURNS CARRIAGE TO LEFT MARGIN & SETS DIR TO RIGHTBOUND CARET SEL RB0 MOV R0,#FLAGS2 ;EMBOSS ON? MOV A,@R0 ANL A,#1 JZ CARET1 ;YES RETR ;NO CARET1 MOV R4,#0FFH ;SET DIR TO BACKWARD CARET0 SEL RB0 MOV R0,#LMARG ;AT LEFT MARGIN-1? MOV A,@R0 DEC A SEL RB1 XRL A,R6 JZ CARET3 ;YES CALL CELL ;MOVE BACK ONE CELL JMP CARET0 CARET3 SEL RB0 MOV R4,#1 ;SET DIR TO FORWARD RETR ;**************************** ;BEEP SUBROUTINE ;ENTER WITH BEEP DURATION IN R6 (IN 20 MSEC UNITS) ;AND BEEP FREQ IN R5 (PERIOD IN 160 MICRO-SEC UNITS). ;USES REGISTERS A,R0,R1,R5,R6,R7 BEEP SEL RB0 ANL P2,#ENSOL ;SELECT SPK PORT MOV R7,#08H ;LOAD SPKR BYTE MOV R0,#0FFH ;R0 COUNTS # OF 80 MICRO-SEC LOOPS MOV A,R5 MOV R1,A ;TEMP SAVE FREQ IN R1 BEEP0 MOV A,R1 ;RECOVER FREQ VALUE MOV R5,A BEEP1 MOV A,#0FFH ;DELAY IN THIS LOOP MOV T,A ;FOR R5 80-MICRO-SEC STRT T ;INTERVALS TO TIME BEEP2 JTF BEEP3 ;ONE HALF-CYCLE. JMP BEEP2 BEEP3 DJNZ R0,BEEP4 ;END OF 20 MSEC UNIT? DJNZ R6,BEEP4 ;END OF TOTAL DURATION? JMP BEEP6 BEEP4 DJNZ R5,BEEP1 ;END OF HALF-CYCLE? MOV A,R7 ;YES, TOGGLE SPKR CPL A MOV R7,A JB3 BEEP5 ANLD P7,A JMP BEEP0 BEEP5 ORLD P7,A JMP BEEP0 BEEP6 RETR ;**************************** ;BEEPHI SUBROUTINE ;CAUSES A SINGLE HIGH FREQ SHORT BEEP ;USED IN COMMAND MODE 'READY' PROMPT BEEPHI SEL RB0 MOV R6,#TONESH MOV R5,#FREQHI CALL BEEP RETR ;**************************** ;BEEPEH SUBROUTINE ;CAUSES A SINGLE EXTRA HIGH FREQ SHORT BEEP ;USED IN COMMAND MODE 'READY' PROMPT BEEPEH SEL RB0 MOV R6,#TONESH MOV R5,#FREQEH CALL BEEP RETR ;**************************** ;BEEPHL SUBROUTINE ;CAUSES A SINGLE HIGH FREQ LONG BEEP BEEPHL SEL RB0 MOV R6,#TONELG MOV R5,#FREQHI CALL BEEP RETR ;**************************** ;BEEPLO SUBROUTINE ;CAUSES A SINGLE LOW FREQ LONG BEEP ;INDICATES ERROR CONDITION BEEPLO SEL RB0 MOV R6,#TONELG MOV R5,#FREQLO CALL BEEP RETR ;**************************** ;BEEP2H SUBROUTINE ;CAUSES TWO HIGH FREQ LONG BEEPS ;INDICATES END OF PAGE BEEP2H SEL RB0 CALL BEEPHL ;BEEP HIGH MOV R5,#TONENO ;PAUSE CALL DELAY CALL BEEPHL ;BEEP HIGH AGAIN RETR ;**************************** ;READY SUBROUTINE ;CAUSES A TWO-TONE, HIGH-LOW SOUND ;INDICATES COMMAND MODE 'READY' PROMPT READY CALL BEEPEH ;BEEP EXTRA HIGH CALL BEEPHI ;BEEP HIGH RETR ;**************************** ;LOCBEL SUBROUTINE ;CAUSES A SINGLE EXTRA SHORT HIGH FREQ BEEP ;INDICATES CTRL-G OR BELL LOCATION LOCBEL SEL RB0 MOV R6,#TONEES MOV R5,#FREQHI CALL BEEP RETR ;**************************** ;ERDY SUBROUTINE ;CAUSES TWO EXTRA SHORT HIGH FREQ BEEPS ;INDICATES EDIT MODE 'READY' PROMPT ERDY CALL LOCBEL ;BEEP MOV R5,#TONENO ;PAUSE CALL DELAY CALL LOCBEL ;BEEP AGAIN MOV R5,#TONENO CALL DELAY RETR ;****************************** ;BFTONE SUBROUTINE ;CAUSES 4 EXTRA SHORT HIGH FREQ BEEPS ;INDICATES BUFFER FULL CONDITION BFTONE CALL ERDY CALL ERDY RETR ;****************************** ;THE FOLLOWING ARE VECTORS NECESSARY TO ;ACCESS ROUTINES IN MEMORY BANK 1 PARITV SEL MB1 JMP PARITY LENGTV SEL MB1 JMP LENGTH EDITV SEL MB1 JMP EDIT TAPEV SEL MB1 JMP TAPE GRAPHV SEL MB1 JMP GRAPHC AUTOLV SEL MB1 JMP AUTOLF SETBSV SEL MB1 JMP SETBSC SETDUV SEL MB1 JMP SETDUP XMTENV SEL MB1 JMP XMTENB SETBEV SEL MB1 JMP SETBEL ;**************************** ;DELAY SUBROUTINE ;ENTER WITH DESIRED DELAY (IN MSEC) IN R5 DELAY SEL RB0 MOV A,#0F4H ;LOAD TIMER WITH (-12) MOV T,A ; AND COUNT UP TO 0 STRT T ;80 MICRO-SEC PER COUNT DELAY1 JTF DELAY2 ; GIVES .96 MSEC PER LOOP JMP DELAY1 ; THEREFORE EACH LOOP IS DELAY2 DJNZ R5,DELAY ; APPROX 1 MSEC (ASSUMING RETR ; 6MHZ CLOCK) ;**************************** ;REMOTE MODE (R-CHORD) ;PLACES UNIT IN REMOTE MODE ;CHARACTERS TYPED ARE TRANSMITTED ;(AND EMBOSSED IF IN HALF-DUPLEX MODE) ;CHARACTERS RECEIVED ARE BUFFERED (4K) AND EMBOSSED ;(EMBOSSING OCCURS ONLY IF 'EMBOSS ON' FLAG IS ON) ;ALLOWABLE CHORD ENTRIES WHILE IN REMOTE MODE ARE: ;(3,6)-CHORD -- RETURN TO COMMAND MODE ;(4,6)-CHORD -- CARRIAGE RETURN / (LINE FEED OPTIONAL) ;K-CHORD -- SEND BREAK ;L-CHORD -- LOWER CASE ;U-CHORD -- UPPER CASE ;(4,5)-CHORD -- PAGE READY ;(4,5,6)-CHORD -- PAGE RELEASE ;N-CHORD, (1,2,3,4,5,6)-CHORD -- CLEAR BUFFER ;(4)-CHORD -- CONTROL CHAR FOLLOWS ;(1)-CHORD -- EMBOSS ON ;(5)-CHORD -- EMBOSS OFF ;(2)-CHORD -- SEND BACKSPACE (& PERFORM ONE IF IN HALF DUP) ;M-CHORD -- SET OR CLEAR MARGINS ;THIS ROUTINE REPEATEDLY POLLS THE KEYBOARD ;(FOR NEW CHARACTERS TO SEND) AND THE BUFFER ;(FOR CHARACTERS AWAITING EMBOSSING). CHARACTERS ;RECEIVED BY THE USART FROM A REMOTE SOURCE ARE ;SERVICED BY THE INTERRUPT ROUTINE. REMOTE MOV R0,#FLAGS1 ;MAIN BUF FULL? MOV A,@R0 JB4 REM11 ;YES CALL DTRON ;ENABLE DTR LINE REM11 MOV R0,#ECTR ;CLR CHAR SENT COUNTER MOV @R0,#0 SEL MB1 CALL SERON ;ENABLE RS232 XMIT SEL MB0 EN I ;POLL KEYBORD FOR CHARACTERS REM0 CALL LOCBEL ;SOUND REMOTE MODE PROMPT REM1 CALL KBIN ;KBD CHAR WAITING? JNZ REM17 ;YES REM16 JMP REM50 ;NO. REM3 XRL A,#40H ;SPACE? JZ REM4 ;YES JMP REM18 ;NO REM17 MOV R7,A ;YES. SAVE CHAR CALL PAGRDY ;PAGE READY CHORD? JF1 REM16 MOV A,R7 ;NO. JB6 REM3 ;CHORD? (OR SPACE) REM4 CALL HALFDU ;HALF-DUPLEX? JF1 REM2 ;WAS ROOM LEFT ON PAGE? JMP REM24 ;NO. REM2 CALL ASCII ;GET ASCII EQUIV MOV R7,A ;SAVE ASCII XRL A,#0FFH ;INVALID CHAR? JZ REM15 ;YES. CALL SEND ;SEND BYTE TO USART (IN R7) MOV R0,#ECTR INC @R0 ;INC CHAR COUNT MOV A,@R0 MOV R0,#BELL ;BELL LOC YET? XRL A,@R0 JNZ REM15 ;NO CALL LOCBEL ;YES. SOUND IT REM15 JMP REM50 ;CHK BUFFER ;KEYBOARD CHAR IS A CHORD REM18 MOV A,R7 XRL A,#C36 ;COMMAND MODE CHORD? JNZ REM9 CALL DTROFF ;DISABLE DTR LINE DIS I JMP COMAND REM9 MOV A,R7 XRL A,#C46 ;CRLF CHORD? JNZ REM6 MOV R0,#FLAGS2 ;HALF DUPLEX? MOV A,@R0 ANL A,#80H JZ REM5 ;NO. CALL CRLF ;YES. PERFORM LOCAL CRLF. JF1 REM5 ;ROOM ON PAGE? JMP REM24 ;NO. REM5 MOV R7,#0DH ;SEND CR CALL SEND MOV R0,#ECTR ;CLR CHAR COUNT MOV @R0,#0 MOV R0,#FLAGS3 ;AUTO LINE FEED ON? MOV A,@R0 ANL A,#1 JZ REM50 ;NO. MOV R7,#0AH ;YES. SEND LF. CALL SEND JMP REM50 ;CHK BUFFER REM6 MOV A,R7 XRL A,#KCHORD ;K-CHORD? JNZ REM19 DIS I ORL P1,#08H ;SELECT CONTROL ON USART ANL P1,#0EFH ;ENABLE USART MOV A,#2FH ;SEND BREAK COMMAND MOVX @R0,A ;(OUTL BUS NOT PERMITTED) MOV R5,#250 ;DELAY 1/4 SECOND CALL DELAY MOV A,#27H ;END BREAK COMMAND MOVX @R0,A ORL P1,#10H ;DISABLE USART EN I JMP REM0 REM19 MOV A,R7 XRL A,#C1 ;EMBOSS ON CHORD? JNZ REM20 MOV R0,#FLAGS1 ;SET 'EMB ON' REQUEST FLAG MOV A,#40H ORL A,@R0 MOV @R0,A JMP REM0 REM20 MOV A,R7 XRL A,#C5 ;EMBOSS OFF CHORD? JNZ REM7 MOV R0,#FLAGS1 ;SET 'EMB OFF' REQUEST FLAG MOV A,#80H ORL A,@R0 MOV @R0,A JMP REM0 REM7 MOV A,R7 XRL A,#LCHORD ;L-CHORD? JNZ REM8 MOV R0,#FLAGS2 ;SET TO LOWER CASE MOV A,@R0 ORL A,#20H MOV @R0,A JMP REM50 REM8 MOV A,R7 XRL A,#UCHORD ;U-CHORD? JNZ REM10 MOV R0,#FLAGS2 ;SET TO UPPER CASE MOV A,@R0 ANL A,#0DFH MOV @R0,A JMP REM50 REM10 MOV A,R7 XRL A,#C456 ;PAGE RELEASE CHORD? JNZ REM12 REM24 CALL WAITPG JMP REM0 REM12 MOV A,R7 XRL A,#NCHORD ;CLEAR BUFFER CHORD? JNZ REM13 CALL CLRBUF JMP REM0 REM13 MOV A,R7 XRL A,#C4 ;CONTROL CHAR PREFIX CHORD? JNZ REM21 MOV R0,#FLAGS1 ;SET 'CTRL CHAR NEXT' FLAG MOV A,#2 ORL A,@R0 MOV @R0,A MOV R7,#08H CALL HALFDU ;EMBOSS DOT 4 IF HALF-DUP JF1 REM50 ;WAS ROOM LEFT ON PAGE? JMP REM24 ;NO REM21 MOV A,R7 XRL A,#MCHORD ;MARGIN CHANGE CHORD? JNZ REM22 SEL MB1 CALL MARGIN SEL MB0 JMP REM0 REM22 MOV A,R7 XRL A,#C2 ;BACKSPACE CHORD? JNZ REM14 MOV R0,#FLAGS2 ;HALF DUPLEX? MOV A,@R0 ANL A,#80H JZ REM23 ;NO SEL MB1 ;YES CALL BACK ;PERFORM LOCAL BACKSPACE SEL MB0 REM23 MOV R0,#BSCHAR ;LOAD BACKSPACE CHAR MOV A,@R0 MOV R7,A CALL SEND ;SEND IT MOV R0,#ECTR ;DEC CHAR COUNT MOV A,#0FFH ADD A,@R0 MOV @R0,A JMP REM50 REM14 CALL BEEPLO ;INVALID CHORD JMP REM0 ;POLL BUFFER FOR CHARACTER AWAITING EMBOSSING REM50 SEL RB0 MOV R0,#LINBUF MOV A,@R0 ;LINE BUFFER EMPTY? JNZ REM51 ;NO. SEL MB1 CALL EMBREQ ;EMBOSS ON/OFF REQUEST? SEL MB0 MOV R0,#FLAGS1 ;CLEAR REQUEST FLAGS MOV A,#3FH ANL A,@R0 MOV @R0,A CALL GETLIN ;YES. GET NEXT LINE FROM BUFFER REM51 CALL PRTLIN ;EMBOSS NEXT CHAR IN LINE BUFFER JMP REM1 ;POLL KEYBOARD AGAIN ;**************************** ;CLEAR BUFFER (N-CHORD) BUFCLR CALL CLRBUF ;INIT POINTERS & FLAGS JMP COMAND ;**************************** PAGE ;**************************** ;INIT SUBROUTINE ;INITIALIZE SYSTEM VARIABLES AND ALL I/O PORTS INIT ANL P2,#DISRAM ;DISABLE RAM BUFFER ANL P2,#ENSOL ;ENABLE SOL PORT CLR A MOVD P6,A ;TURN OFF ALL SOLENOIDS MOVD P7,A MOVD A,P4 ;SET KEYBOARD PORT TO INPUT MOVD A,P5 ANL P1,#KBDRS ;RESET KEYBOARD ORL P1,#KBDRE SEL RB0 MOV R2,#MOTTOP ;INIT MOTOR TABLE POINTERS MOV R3,#MOTTOP MOV R4,#0FFH ;SET CARRIAGE DIR TO LEFTBOUND ORL P2,#ENMOT ;ENABLE MOTOR PORT MOV A,R2 ;INIT CARRIAGE MOTOR PORT MOVP3 A,@A MOVD P6,A MOVD P7,A ;INIT LF MOTOR PORT MOVD A,P4 ;SET DIP SW PORT TO INPUT MOVD A,P5 INIT1 ANL P2,#ENKBD ;ENABLE KBD PORT MOVD A,P5 ;READ CARRIAGE HOME SWITCH JB3 INIT2 ;HOME YET? INIT0 SEL MB0 ;NO CALL MOVE ;MOVE CARRIAGE ONE STEP LEFT SEL MB1 JMP INIT1 ;CHECK HOME SWITCH AGAIN INIT2 MOV R4,#1 ;SET CARRIAGE DIR TO RIGHTBOUND MOV R0,#MAXLIN ;25 LINES PER PAGE MOV @R0,#25-1 MOV R0,#LMARG ;SET LEFT MARGIN TO 1 MOV @R0,#1 MOV R0,#RMARG ;SET RIGHT MARGIN TO 42 MOV @R0,#42 MOV R0,#MAXCEL ;SET MAX CELLS AVAIL TO 42 MOV @R0,#42 SEL RB1 MOV R0,#SPCBIT ;INIT RS232 PORT ON & MOV A,#0C0H ; INIT TAPE CKT OFF OUTL P2,A MOV @R0,A CLR A MOV R6,A ;CLR CARRIAGE POS MOV R7,A ;CLR LINE POS MOV R5,A ;CLR LINE BUFFER POINTER MOV R0,#FLAGS2 ;INIT VARIOUS CONTROL FLAGS MOV @R0,A MOV R0,#FLAGS1 MOV @R0,A MOV R0,#FLAGS3 MOV @R0,A MOV R0,#EDPFLG ;CLR EDIT MODE PRINT IN USE FLAG MOV @R0,A MOV R0,#HSTEP ;SET NORMAL HORIZ STEPS PER CELL MOV @R0,#NORMHS MOV R0,#VSTEP ;SET NORMAL VERT STEPS PER LINE MOV @R0,#NORMVS MOV R0,#HNDSHK ;NO HANDSHAKE MOV @R0,#2 MOV R0,#LINEWD ;LINE WIDTH=42 MOV @R0,#42 MOV R0,#CELUSD ;CELLS USED COUNTER MOV @R0,A MOV R0,#BELL ;SET BELL POSITION=35 MOV @R0,#35 MOV R0,#BSCHAR ;SET BACKSPACE CHR=ASCII 8 MOV @R0,#8 ;INITIALIZE 8251 USART ;NOTE -- SINCE THE HARDWARE DESIGN CALLS FOR ;'EXTERNAL' PROGRAM MEMORY, THE 'OUTL BUS' AND ;'INS BUS' INSTRUCTIONS ARE NOT ALLOWED. ;THUS, THROUGHOUT THIS PROGRAM, ALL I/O TO THE ;USART MUST BE DONE VIA THE 'MOVX' INSTRUCTIONS. INIT3 SEL RB0 ORL P1,#1 ;RESET USART MOV R5,#1 SEL MB0 CALL DELAY SEL MB1 ANL P1,#0FEH CALL MODE ;READ DEFAULT DIP-SWITCH MOV R0,#USART MOV @R0,A ;SAVE USART MODE BYTE ORL P1,#08H ;SELECT CONTROL INPUT ANL P1,#0EFH ;ENABLE USART MOVX @R0,A ;SEND MODE WORD MOV A,#35H ;SEND COMMAND WORD MOVX @R0,A ORL P1,#10H ;DISABLE USART MOV A,R7 ;SET BAUD RATE ANL A,#70H ;MASK OFF ALL BUT BAUD RATE SWAP A MOV R0,#BAUDRT ;SAVE BAUD RATE CODE MOV @R0,A CALL BAUD ;SET BAUD RATE ;FROM HERE TO END OF INIT IS CALLED TO CLEAR BUFFER INIT50 SEL RB0 MOV R0,#ECP ;CLEAR BUFFER POINTERS & FLAGS CLR A MOV R6,#7 INIT51 MOV @R0,A DEC R0 DJNZ R6,INIT51 MOV R0,#CARPOS ;INIT CARRIAGE POSITION MOV @R0,#0FFH RETR ;**************************** ;MODE SUBROUTINE ;READ DIP-SWITCH AND RETURN CONTENTS IN R7 ;CONSTRUCT USART MODE BYTE AND RETURN IN A MODE ORL P2,#ENDIP ;ENABLE DIP-SW PORT MOVD A,P4 ;READ BAUD RATE & STOP BITS SWAP A MOV R7,A MOVD A,P5 ;READ PARITY & CHR LENGTH ORL A,R7 ;COMBINE NIBBLES MOV R7,A ;AND SAVE IN R7 JB1 MODE1 ;CHECK DUPLEX JMP MODE2 ;KEEP AT 'FULL' MODE1 MOV R0,#FLAGS2 ;CHANGE TO 'HALF' MOV A,@R0 ORL A,#80H MOV @R0,A MOV A,R7 MODE2 MOV R0,#4AH ;CONSTRUCT USART MODE BYTE ;IN R0 (BAUD RATE FACTOR=16X) ANL A,#0FH ;MASK OFF ALL BUT CHR LENGTH RL A ;AND PARITY & SHIFT TO RL A ;PROPER POSITION ORL A,R0 ;FORM NEW MODE BYTE MOV R0,A ;SAVE IT MOV A,R7 ;GET STOP BITS ANL A,#80H ORL A,R0 ;FORM NEW MODE BYTE RETR ;**************************** ;BAUD SUBROUTINE ;ENTER WITH BAUD RATE CODE IN A ;SETS BAUD RATE IN ACCORDANCE WITH THIS CODE: ;A=00 -- 110 BAUD ;A=01 -- 300 BAUD ;A=02 -- 1200 BAUD ;A=03 -- 2400 BAUD ;A=04 -- 4800 BAUD ;A=05 -- 9600 BAUD ;A=06 -- TRANSMIT CLK FROM TAPE RECORD ;A=07 -- RECEIVE CLK FROM TAPE PLAY BAUD SEL RB0 ORL P1,#20H ;SET LSB OF BAUD RATE (P15) JB0 BAUD1 ANL P1,#0DFH ;CLR LSB BAUD1 ORL P1,#40H ;SET NSB (P16) JB1 BAUD2 ANL P1,#0BFH ;CLR NSB BAUD2 ORL P1,#80H ;SET MSB (P17) JB2 BAUD3 ANL P1,#7FH ;CLR MSB BAUD3 RETR ;**************************** ;SELECT PARITY OPTION (P-CHORD E,O,N) ;E=EVEN, O=ODD, N=NONE PARITY SEL RB0 CALL GETK ;GET PARAMETER MOV R0,#USART JB2 PARIT2 ;E? MOV A,#30H ;YES. SET TO 'EVEN' ORL A,@R0 MOV @R0,A ;SAVE IT JMP PARIT4 PARIT1 MOV A,#0EFH ;SET TO 'NONE' ANL A,@R0 MOV @R0,A ;SAVE IT JMP PARIT4 PARIT2 JB3 PARIT1 ;O? MOV A,#10H ;YES. SET TO 'ODD' ORL A,@R0 ANL A,#0DFH MOV @R0,A ;SAVE IT PARIT4 CALL NEWMOD ;SEND NEW MODE BYTE TO USART SEL MB0 JMP COMAND ;**************************** ;NEWMOD SUBROUTINE ;SEND NEW MODE BYTE TO USART ;ENTER WITH NEW MODE BYTE IN LOCATION ;POINTED TO BY R0. NEWMOD DIS I ORL P1,#08H ;SELECT CONTROL INPUT ANL P1,#0EFH ;ENABLE USART MOV A,#40H ;LOAD RESET COMMAND MOVX @R0,A ;SEND IT MOV A,@R0 ;LOAD NEW MODE BYTE MOVX @R0,A ;SEND IT MOV A,#35H ;LOAD COMMAND WORD MOVX @R0,A ;SEND IT ORL P1,#10H ;DISABLE USART RETR ;**************************** ;GRAPHICS MODE (G-CHORD Y,N) OR (G-CHORD R Y,N) ;Y=YES, N=NO, R=REMOTE CTRL FLAG ;ENABLING THIS MODE SIMPLY DECREASES CELL & LINE ;ADVANCE DISTANCE SO THAT "ALL" POTENTIAL DOTS ON A ;PAGE WILL BE EQUALLY SPACED FROM EACH OTHER. ;USE R PARAMETER TO ENABLE OR DISABLE REMOTE CTRL OF ;GRAPHICS MODE THRU THE SI & SO CTRL CHARS. GRAPHC SEL RB0 CALL GETK ;GET PARAMETER XRL A,#3DH ;Y? JNZ GRAPH1 ;NO CALL GRAPH8 ;ENABLE GRAPHICS JMP GRAPH3 ;CALL HERE TO ENABLE GRAPHICS GRAPH8 CALL MAR7 ;CLEAR MARGINS SEL MB0 CALL CARET ;INIT CARRIAGE SEL MB1 MOV A,#2 ;YES. SET FLAG MOV R0,#FLAGS2 ORL A,@R0 MOV @R0,A MOV R0,#HSTEP ;SET GRAPHICS MOTOR STEPS MOV @R0,#GRAPHS MOV R0,#VSTEP MOV @R0,#GRAPVS MOV R0,#MAXLIN ;SET DEFAULT PAGE LENGTH=37 MOV @R0,#37-1 MOV R0,#MAXCEL ;SET GRAPHICS MAX CELLS AVAIL MOV @R0,#51 CALL MAR7 ;SET MARGINS TO GRAPHIC DEFAULT RETR GRAPH1 MOV A,R7 XRL A,#1DH ;N? JNZ GRAPH2 ;NO CALL GRAPH9 ;DISABLE GRAPHICS JMP GRAPH3 ;CALL HERE TO DISABLE GRAPHICS GRAPH9 CALL MAR7 ;CLEAR MARGINS SEL MB0 CALL CARET ;INIT CARRIAGE SEL MB1 MOV A,#0FDH ;YES. RESET FLAG MOV R0,#FLAGS2 ANL A,@R0 MOV R0,A MOV R0,#MAXCEL ;SET NORM MAX CELLS AVAIL MOV @R0,#42 MOV R0,#HSTEP ;SET NORMAL MOTOR STEPS MOV @R0,#NORMHS MOV R0,#VSTEP MOV @R0,#NORMVS CALL MAR7 ;SET MARGINS TO NORM DEFAULT MOV R0,#MAXLIN MOV @R0,#25-1 RETR GRAPH2 SEL MB0 MOV A,R7 XRL A,#17H ;R? JNZ GRAPH4 ;NO CALL GETKBD ;Y OR N? MOV R0,#FLAGS2 JB5 GRAPH5 MOV A,@R0 ;N ANL A,#0FBH ;DISABLE REM CTRL MOV @R0,A JMP COMAND GRAPH5 MOV A,@R0 ;Y ORL A,#4 ;ENABLE REM CTRL MOV @R0,A JMP COMAND GRAPH4 CALL BEEPLO ;INVALID PARAM GRAPH3 SEL MB0 JMP COMAND ;**************************** ;GPHCTL SUBROUTINE ;CALLED FROM 'GETLIN' THIS ROUTINE ENABLES GRAPHICS ;MODE IF REMOTELY RECEIVED CHAR IS A CTRL-O (SI) & ;DISABLES GRAPHICS IF IT IS A CTRL-N (SO). GRAPHICS ;REMOTE CTRL FLAG MUST BE SET IN EITHER CASE. ;ENTER WITH CTRL CHAR IN R4' ;SET F1=1 IF REMOTE FLAG IS ON AND SI OR SO IS RECEIVED GPHCTL CLR F1 SEL RB0 MOV R0,#FLAGS2 MOV A,@R0 ANL A,#4 ;REM CTRL FLAG SET? JZ GPHC3 ;NO. IGNORE CTRL CHAR SEL RB1 MOV A,R4 ;RECOVER CHAR XRL A,#0FH ;'SHIFT-IN' CHAR? JNZ GPHC2 ;NO CALL GRAPH8 CPL F1 MOV R0,#0 ;CLR LINE BUF PTR RETR GPHC2 MOV A,R4 XRL A,#0EH ;'SHIFT-OUT' CHAR? JNZ GPHC3 CALL GRAPH9 CPL F1 MOV R0,#0 ;CLR LINE BUF PTR GPHC3 RETR ;**************************** ;ASCBIN SUBROUTINE ;CONVERTS ASCII CHARS 0-9 TO BINARY VALUES ;ENTER & EXIT CHAR IN A ;IF ASCII CHAR IS NOT 0-9, SET F1=1 ASCBIN SEL RB0 CLR F1 MOV R7,A ;SAVE CHAR ANL A,#0F0H XRL A,#30H JNZ ASCB2 ;INVALID MOV A,R7 JB3 ASCB1 ;POSSIBLY INVALID ASCB0 ANL A,#0FH ;VALID RETR ASCB1 ADD A,#6 JB3 ASCB3 ;VALID ASCB2 CPL F1 ;INVALID RETR ASCB3 MOV A,R7 JMP ASCB0 ;**************************** ;X10 SUBROUTINE ;ENTER WITH NUMBER 0-9 IN BINARY IN A ;EXIT WITH NUMBER TIMES TEN IN A X10 SEL RB0 CLR C RLC A ;X2 MOV R6,A ;SAVE IT RLC A ;X4 RLC A ;X8 ADD A,R6 ;X8+X2=X10 RETR ;**************************** ;ROOM SUBROUTINE ;CALLED BY GETLIN. DETERMINES IF 2 CELLS ARE ;AVAILABLE FOR EMBOSSING CTRL CHAR. ;IF NOT, SET F1=0 ;CORRECTS POINTERS AND COUNTERS AS REQUIRED ROOM SEL RB1 CLR F1 INC R5 ;INC CELL COUNT SEL MB0 CALL GETMAX ;WILL THERE BE ROOM? SEL MB1 JZ ROOM1 ;NO INC R5 ;YES CPL F1 RETR ROOM1 DEC R5 ;CORRECT CELL COUNT CALL DECBCP ;DEC BUF PRINT PTRS RETR ;**************************** ;THESE ROUTINES ENABLE OR DISABLE THE RS232C TRANSMIT ;LINE AND SET CORRESPONDING FLAG (BIT 6 OF SPCBIT). SEROFF SEL RB0 MOV R0,#SPCBIT MOV A,@R0 ANL A,#0BFH ;SET FLAG (BIT 6=0) MOV @R0,A SEROF1 ANL P2,#0BFH ;DISABLE RS232 XMIT RETR SERON SEL RB0 ORL P2,#40H ;ENABLE RS232 XMIT MOV R0,#SPCBIT MOV A,@R0 ORL A,#40H ;SET FLAG (BIT 6=1) MOV @R0,A RETR ;**************************** ;RESUME SUBROUTINE ;RESUMES COMMUNICATION BY PERFORMING THE ;CURRENT HANDSHAKING TYPE ;CLEAR 'BUF FULL' FLAG RESUME SEL RB0 MOV R0,#FLAGS1 ;CLR BUF FULL FLAG MOV A,@R0 ANL A,#0EFH MOV @R0,A MOV R0,#FLAGS3 ;CLR BUF FULL TONE MOV A,@R0 ; REQUEST FLAG ANL A,#0EFH MOV @R0,A MOV R0,#HNDSHK ;GET HANDSHAKE TYPE MOV A,@R0 JNZ RESUM1 SEL MB0 ;HARDWARE CALL DTRON ;SET DTR TRUE SEL MB1 RETR RESUM1 XRL A,#2 ;NONE? JNZ RESUM3 ;YES RETR RESUM3 IN A,P1 ;SOFTWARE JB2 RESUM2 ;TRANSMITTER READY? JMP RESUM3 ;NO RESUM2 ANL P1,#0E7H ;SEL USART DATA INPUT MOV A,#11H ;LOAD 'DC1' MOVX @R0,A ;SEND IT ORL P1,#10H ;DISABLE USART RETR ;**************************** ;THIS SUBROUTINE CALLS GETKBD FROM MB1 ;TO SAVE MEMORY GETK SEL MB0 CALL GETKBD SEL MB1 RETR ;**************************** ;FULL OR HALF DUPLEX (D-CHORD F,H) ;F=FULL, H=HALF SETDUP SEL MB0 CALL GETKBD ;GET PARAMETER MOV R0,#FLAGS2 JB4 SETDU1 MOV A,@R0 ;SET TO 'FULL' ANL A,#7FH MOV @R0,A JMP COMAND SETDU1 MOV A,@R0 ;SET TO 'HALF' ORL A,#80H MOV @R0,A JMP COMAND ;**************************** ;SELECT USART CHAR LENGTH, USART STOP BIT LENGTH, ;OR BRAILLE PAGE LENGTH ;COMMAND FORMAT: (3,4,5,6)-CHORD X Y ;WHERE X=C FOR CHAR LENGTH & Y=7 OR 8 ;OR, X=S FOR STOP BIT LENGTH & Y=1 OR 2 ;OR, X=P FOR PAGE LENGTH & Y=01 THRU 47 LENGTH SEL RB0 CALL GETK ;GET PARAMETER XRL A,#09H ;C? JNZ LENG5 ;NO CALL GETK ;GET CHAR LENGTH MOV R0,#USART JB4 LENG3 ;7 OR 8? MOV A,#0CH ;SET TO '8' ORL A,@R0 JMP LENG0 ;SEND IT LENG3 MOV A,#08H ;SET TO '7' ORL A,@R0 ANL A,#0FBH JMP LENG0 ;SEND IT LENG5 MOV A,R7 XRL A,#0EH ;S? JNZ LENG8 ;NO CALL GETK ;GET STOP BIT LENGTH MOV R0,#USART JB3 LENG6 MOV A,#0C0H ;TWO STOP BITS ORL A,@R0 JMP LENG0 ;SEND IT LENG6 MOV A,#7FH ;ONE STOP BIT ANL A,@R0 LENG0 MOV @R0,A ;SAVE IT JMP PARIT4 ;SEND NEW MODE BYTE TO USART LENG8 MOV A,R7 XRL A,#0FH ;P? JNZ LENG9 ;NO SEL MB0 SEL RB1 CALL GETKBD ;GET 1ST # CALL ASCII ;CONVERT TO ASCII SEL MB1 CALL ASCBIN ;CONVERT TO BINARY JF1 LENG9 ;INVALID CHAR CALL X10 ;MULTIPLY BY 10 MOV R3,A ;SAVE IT SEL MB0 CALL GETKBD ;GET 2ND # CALL ASCII ;CONVERT TO ASCII SEL MB1 CALL ASCBIN ;CONVERT TO BINARY JF1 LENG9 ;INVALID CHAR ADD A,R3 ;ADD TO TENS DIGIT DEC A JB6 LENG9 ;INVALID IF OVER 64 MOV R0,#MAXLIN MOV @R0,A ;STORE NEW PAGE LENGTH SEL MB0 JMP COMAND LENG9 SEL MB0 ;INVALID CALL BEEPLO JMP COMAND ;**************************** ;EMBREQ SUBROUTINE ;TURNS EMBOSSER ON OR OFF DEPENDING ON WHICH ;REQUEST FLAG IS SET. EMBREQ MOV R0,#FLAGS1 ;CHECK EMBOSS ON/OFF REQUEST FLAGS MOV A,@R0 ANL A,#0C0H JZ EMBRE1 ;NO REQUESTS MOV R0,#FLAGS2 JB6 EMBRE2 EMBRE3 MOV A,#1 ;EMB OFF REQ ORL A,@R0 MOV @R0,A RETR EMBRE2 MOV A,#0FEH ;EMB ON REQ ANL A,@R0 MOV @R0,A EMBRE1 RETR ;**************************** ;BACKSPACE SUBROUTINE ;WILL CAUSE LOCAL BACKSPACE OF CARRIAGE ;IF IN HALF DUPLEX MODE BACK SEL RB0 SEL MB0 MOV R0,#LMARG ;AT LEFT MARGIN? MOV A,@R0 DEC A SEL RB1 XRL A,R6 JNZ BACK1 SEL MB1 RETR BACK1 SEL RB0 MOV R4,#0FFH ;SET DIR TO BACKWARD CALL CELL ;MOVE BACK ONE CELL MOV R4,#1 ;SET DIR TO FORWARD SEL MB1 RETR ;**************************** ;SCROLL SUBROUTINE ;CAUSES MAIN BUFFER TO SCROLL ONE PAGE ;(256 BYTES) THUS SCROLLING AWAY THE OLDEST PAGE ;OF DATA. HANDSHAKE TO RE-ENABLE DATA RECEPTION. SCROLL DIS I SEL RB0 MOV R0,#BPE MOV A,@R0 ;LESS THAN ONE PAGE OF TEXT? JNZ SCROL1 ;NO CALL INIT50 ;YES. CLEAR BUFFER JMP SCROL2 SCROL1 CLR A MOV R0,#ECC ;INIT CURSOR PTRS MOV @R0,A ; TO PAGE 0 INC R0 MOV @R0,A CALL LODPTR ;INIT BUFFER PTRS INC @R0 ; TO PAGE 1 CALL EDD3 ;SCROLL BUF ONE PAGE MOV R0,#BPP ;DEC PAGE PRINT PTR MOV A,@R0 DEC A MOV @R0,A SCROL2 SEL MB0 CALL LOCBEL ;BEEP BECAUSE SCROLLING SEL MB1 ; IS FINISHED CALL RESUME ;HANDSHAKE EN I RETR ;**************************** ;LODPTR SUBROUTINE ;LOADS POINTERS ECP & ECC WITH BPP & BCP, ;OR, BPP & BCP WITH ECP & ECC. ;CALL HERE FOR CURSOR TO BUFFER LODPTR SEL RB0 MOV R0,#ECC ;LOAD CHAR PRINT PTR MOV A,@R0 MOV R0,#BCP MOV @R0,A MOV R0,#ECP ;LOAD PAGE PRINT PTR MOV A,@R0 MOV R0,#BPP MOV @R0,A RETR ;CALL HERE FOR BUFFER TO CURSOR LODPT1 SEL RB0 MOV R0,#BCP ;LOAD CHAR CURSOR PTR MOV A,@R0 MOV R0,#ECC MOV @R0,A MOV R0,#BPP ;LOAD PAGE CURSOR PTR MOV A,@R0 MOV R0,#ECP MOV @R0,A RETR ;**************************** ;RECERR SUBROUTINE ;CHECK STATUS OF USART. IF PARITY, OVERRUN, OR ;FRAMING ERROR HAS OCCURRED, SET ERROR FLAG RECERR SEL RB0 DIS I ORL P1,#08H ;SELECT CTRL INPUT ANL P1,#0EFH ;ENABLE USART MOVX A,@R0 ;READ STATUS ORL P1,#10H ;DISABLE USART EN I ANL A,#38H ;MASK OFF NON ERROR BITS JZ RECER1 ;ERROR DETECTED? MOV R0,#FLAGS3 ;YES MOV A,@R0 ;SET ERROR FLAG ORL A,#20H MOV @R0,A RECER1 RETR ;**************************** ;GETSTR SUBROUTINE ;GETS STRING FROM KEYBOARD AND STORES IT ;IN LINE BUFFER. TERMINATE STRING WITH (4,6)-CHORD ;(& SET R2'=1) OR Q-CHORD (& SET R2'=2). ABORT ;STRING INPUT WITH (3,6)-CHORD (& SET R2'=4). ;(4)-CHORD, (2)-CHORD, L-CHORD, & U-CHORD ARE ;ALLOWED WITHIN STRING. ;RETURN STRING LENGTH IN R1', TERM TYPE IN R2'. ;MAX STRING LENGTH=253. GETSTR SEL RB1 MOV R1,#0 ;INIT STRING CHAR COUNT MOV R3,#15 ;INIT LINE BUF PAGE ;GET CHAR & CHECK FOR STRING TERMINATOR GETS0 SEL RB0 CALL GETK XRL A,#QCHORD ;Q-CHORD TERM? JNZ GETS8 ;NO SEL RB1 MOV R2,#2 ;YES RETR GETS8 MOV A,R7 XRL A,#C46 ;CRLF TERM? JNZ GETS9 ;NO SEL RB1 MOV R2,#1 ;YES MOV A,R1 ;LOAD LOC MOV R0,A MOV A,#0DH ;LOAD CR SEL MB0 CALL STOCHR ;STORE CR CALL SEND ;SEND CR INC R0 ;INC LOC MOV A,#0AH ;LOAD LF CALL STOCHR ;STORE LF CALL SEND ;SEND LF INC R1 ;ADJUST STRING LENGTH INC R1 MOV R0,#FLAGS2 ;HALF DUPLEX? MOV A,@R0 ANL A,#80H JZ GETS15 ;NO CALL CRLF JF1 GETS15 CALL WAITPG GETS15 SEL MB1 RETR GETS9 MOV A,R7 XRL A,#C36 ;ABORT? JNZ GETS7 ;NO SEL RB1 MOV R2,#4 ;YES RETR ;CHECK FOR CHORD COMMAND GETS7 MOV A,R7 XRL A,#UCHORD ;UPPER CASE? JNZ GETS1 MOV R0,#FLAGS2 ;SET TO UPPER CASE MOV A,@R0 ANL A,#0DFH MOV @R0,A JMP GETS0 GETS1 MOV A,R7 XRL A,#LCHORD ;LOWER CASE? JNZ GETS2 MOV R0,#FLAGS2 ;SET TO LOWER CASE MOV A,@R0 ORL A,#20H MOV @R0,A JMP GETS0 GETS2 MOV A,R7 XRL A,#C2 ;BACKSPACE? JNZ GETS4 SEL RB1 MOV A,R1 JZ GETS3 ;DEC CHAR COUNT IF DEC R1 ; NON-ZERO CALL BACK JMP GETS0 GETS4 MOV A,R7 XRL A,#C4 ;CTRL CHAR NEXT? JNZ GETS5 MOV R0,#FLAGS1 MOV A,#2 ORL A,@R0 MOV @R0,A SEL MB0 MOV R7,#08H CALL HALFDU ;EMBOSS DOT 4 IF HALF-DUP JF1 GETS16 ;ROOM ON PAGE? CALL WAITPG ;NO JF1 GETS10 GETS16 CALL GETKBD ;GET CTRL CHAR GETS5 MOV A,R7 JB6 GETS12 ;JUMP IF CHORD (OR SPACE) SEL MB1 JMP GETS13 ;NORMAL CHAR GETS12 XRL A,#40H ;SPACE? JNZ GETS3 ;NO. INVALID CHORD GETS13 SEL MB0 SEL RB1 MOV A,R1 XRL A,#253 ;MAX STRING LENGTH? JNZ GETS11 ;NO GETS3 SEL MB0 CALL BEEPLO ;YES GETS10 SEL MB1 JMP GETS0 GETS11 CALL ASCII ;CONVERT JB7 GETS10 ;INVALID CTRL CHAR? MOV R2,A ;TEMP SAVE ASCII CHAR CALL HALFDU ;EMBOSS IT JF1 GETS14 ;ROOM ON PAGE? CALL WAITPG ;NO JF1 GETS10 GETS14 MOV A,R1 ;PUT R1' INTO R0' MOV R0,A MOV A,R2 ;RECOVER CHAR CALL STOCHR ;STORE CHAR CALL SEND ;SEND CHAR INC R1 ;INC CHAR COUNT SEL RB0 MOV R0,#BELL MOV A,@R0 SEL RB1 XRL A,R1 ;BELL POSITION? JNZ GETS6 ;NO CALL LOCBEL ;YES. SOUND IT GETS6 SEL MB1 JMP GETS0 ;***************************** ;AUTO LINEFEED J-CHORD [T,R] [Y,N] ;ENTER T OR R FOLLOWED BY Y OR N ;Y=YES, APPEND LF TO CR ;N=NO, DO NOT APPEND ;T=TRANSMITTED CR (FROM (4,6)-CHORD AT KBD ONLY) ;R=RECEIVED CR (ALL RECEIVED CR'S) AUTOLF CALL GETK ;TRANSMIT OR RECEIVE? MOV R0,#FLAGS3 JB3 AUTO2 ;T? CALL GETK ;NO JB5 AUTO3 ;Y OR N? MOV A,#0FDH ;DISABLE REC AUTO LF ANL A,@R0 JMP AUTO6 AUTO3 MOV A,#2 ;ENABLE REC AUTO LF ORL A,@R0 JMP AUTO6 AUTO2 CALL GETK JB5 AUTO5 ;Y OR N? MOV A,#0FEH ;DISABLE XMIT AUTO LF ANL A,@R0 JMP AUTO6 AUTO5 MOV A,#1 ;ENABLE XMIT AUTO LF ORL A,@R0 AUTO6 SEL MB0 MOV @R0,A JMP COMAND ;**************************** ;MOVCUR SUBROUTINE ;MOVES CURSOR POINTER FORWARD (IF R6=1) OR ;BACKWARD (IF R6=FFH) ONE BYTE. ;IF CURSOR IS AT BEGINNING OR END OF TEXT, SET F1=1. MOVCUR SEL RB0 CLR F1 MOV A,R6 JB7 MOVC2 CALL LODPTR ;FORWARD SEL MB0 CALL EOT ;END OT TEXT? SEL MB1 JF1 MOVC5 ;NO JMP MOVC1 ;YES MOVC5 MOV R0,#ECC MOV A,@R0 INC A MOV @R0,A JNZ MOVC1 ;NEXT PAGE? INC R0 ;YES MOVC6 INC @R0 ;INC PAGE MOVC1 CPL F1 RETR MOVC2 MOV R0,#ECC ;BACKWARD ADD A,@R0 MOV @R0,A JC MOVC3 ;NEXT PAGE? INC R0 ;YES MOV A,@R0 JZ MOVC4 ;ALREADY PAGE 0? MOV A,R6 ;NO ADD A,@R0 ;DEC PAGE MOV @R0,A MOVC3 RETR MOVC4 MOV R0,#ECC ;AT BEGIN OF BUF JMP MOVC6 ;CORRECT PTR ;**************************** ;DECBCP SUBROUTINE ;DECREMENTS BUFFER PRINT POINTERS DECBCP SEL RB0 MOV R0,#BCP ;GET BUFFER CHAR PRINT PTR MOV A,@R0 DEC A MOV @R0,A ;STORE NEW CHAR PTR XRL A,#0FFH ;PREVIOUS PAGE? JNZ DECBC1 ;NO MOV R0,#BPP ;YES. DEC PAGE PTR MOV A,@R0 DEC A MOV @R0,A ;STORE NEW PAGE PTR DECBC1 RETR ;**************************** ;SET ALTERNATE BACKSPACE CHARACTER ;(POWER-ON DEFAULT IS ASCII 8, BS CHR) SETBSC CALL ECNT ;GET ASCII DECIMAL EQUIV JF1 SETBS1 ; OF DESIRED BACKSPACE MOV R0,#ECTR ; CHAR FROM KEYBOARD MOV A,@R0 MOV R0,#BSCHAR MOV @R0,A ;SAVE IT SETBS1 SEL MB0 JMP COMAND ;**************************** ;ECNT SUBROUTINE ;ACCEPTS FROM KEYBOARD A 3 DIGIT NUMBER "N" ;BETWEEN 1 & 254 INCLUSIVE TERMINATED BY Q-CHORD. ;DEFAULT N=1. STORE N IN ECTR. ;SET F1=1 IF INVALID NUMBER. ;(USE R3',R4',& R5' FOR TEMP STORAGE OF DIGITS) ECNT SEL RB1 MOV A,#30H ;INIT WITH ASCII "0" MOV R3,A ;INIT LSD MOV R4,A ;INIT NSD MOV R5,A ;INIT MSD ;GET N SEL MB0 CALL GETKBD ;GET CHAR XRL A,#QCHORD ;Q-CHORD? JNZ ECNT2 ;NO MOV R0,#ECTR ;YES. SET TO DEFAULT OF 1 MOV @R0,#1 CLR F1 SEL MB1 RETR ECNT2 CALL ASCII ;CONVERT BRAILLE TO ASCII JB7 ECNT3 ;INVALID MOV R3,A ;STORE LSD CALL GETKBD XRL A,#QCHORD JZ ECNT1 MOV A,R3 ;SHIFT LSD TO NSD MOV R4,A CALL ASCII JB7 ECNT3 ;INVALID MOV R3,A ;STORE NEW LSD CALL GETKBD XRL A,#QCHORD JZ ECNT1 MOV A,R4 ;SHIFT NSD TO MSD MOV R5,A MOV A,R3 ;SHIFT LSD TO NSD MOV R4,A CALL ASCII JB7 ECNT3 ;INVALID MOV R3,A ;STORE NEW LSD CALL GETKBD XRL A,#QCHORD JZ ECNT1 ECNT0 SEL MB0 CALL BEEPLO ;INVALID ENTRY ECNT3 SEL MB1 CLR F1 CPL F1 ;SET INVALID FLAG RETR ;CONSTRUCT ECTR FROM R3',R4',& R5' ECNT1 SEL MB1 MOV R0,#ECTR MOV A,R3 ;GET "ONES" DIGIT CALL ASCBIN ;CONVERT ASCII TO BINARY JF1 ECNT0 ;INVALID? MOV @R0,A ;STORE IT MOV A,R4 ;GET "TENS" DIGIT CALL ASCBIN JF1 ECNT0 CALL X10 ;MULTIPLY TIMES 10 ADD A,@R0 ;ADD TO "ONES" MOV @R0,A ;STORE IT MOV A,R5 ;GET "HUNDREDS" DIGIT CALL ASCBIN JF1 ECNT0 MOV R3,A ;TEMP SAVE IT ANL A,#0FCH ;ABOVE 3? JNZ ECNT0 ;YES MOV A,R3 ;NO XRL A,#3 ;IS IT 3? JZ ECNT0 ;YES MOV A,R3 ;NO. VALID # THEN CALL X10 ;TIMES 10 CALL X10 ;TIMES 100 ADD A,@R0 ;ADD TO CURRENT TOTAL JC ECNT0 ;OVER 255? MOV @R0,A ;STORE IT XRL A,#255 ;EQUAL TO 255? JZ ECNT0 ;IF YES, DISALLOW CLR F1 RETR ;**************************** ;EDIT MODE (E-CHORD) ;THIS ROUTINE ALLOWS THE PRINTING, LOCATING, OR ;CHANGING OF TEXT WITHIN THE BUFFER VIA THE ;FOLLOWING FIVE EDIT FUNCTION COMMANDS: P,F,M,I,D ;NOTE: [N] IS AN OPTIONAL NUMBER BETWEEN 1 & 254 ;INCLUSIVE AND IF OMITTED TAKES THE DEFAULT VALUE ;OF 1. MEANS Q-CHORD (STRING/COMMAND TERMINATOR). ;EXAMPLES: P, MU34, FBROWN FOX, D254 ;P [N] PRINT N LINES ;F STRING FIND STRING ;M [T,B,UN,DN] MOVE TO TOP, BOTTOM, OR ; UP/DOWN N LINES ;I TEXT INSERT TEXT ;D [N] DELETE N LINES EDIT DIS I SEL RB0 SEL MB0 CALL CARET ;INIT CARRIAGE EDIT0 SEL RB0 SEL MB0 CALL ERDY ;SOUND EDIT PROMPT CALL GETKBD ;GET EDIT COMMAND SEL MB1 XRL A,#0FH ;P? JNZ EDIT1 JMP EDP EDIT1 MOV A,R7 XRL A,#0BH ;F? JNZ EDIT2 JMP EDF EDIT2 MOV A,R7 XRL A,#0DH ;M? JNZ EDIT3 JMP EDM EDIT3 MOV A,R7 XRL A,#0AH ;I? JNZ EDIT4 JMP EDI EDIT4 MOV A,R7 XRL A,#19H ;D? JNZ EDIT5 JMP EDD EDIT5 MOV A,R7 XRL A,#C36 ;COMMAND CHORD? JNZ EDIT9 SEL MB0 CALL EOTSET ;RESTORE PRINT PTRS TO EOT JMP COMAND EDIT9 MOV A,R7 XRL A,#C456 ;PAGE RELEASE CHORD? JNZ EDIT6 ;NO EDIT14 SEL MB0 CALL WAITPG ;RELEASE PAGE EDIT15 SEL MB1 JMP EDIT0 EDIT6 MOV R0,#FLAGS2 MOV A,R7 XRL A,#C1 ;EMBOSS ON CHORD? JNZ EDIT7 ;NO CALL EMBRE2 ;YES JMP EDIT0 EDIT7 MOV A,R7 XRL A,#C5 ;EMBOSS OFF CHORD? JNZ EDIT10 ;NO CALL EMBRE3 ;YES JMP EDIT0 EDIT10 MOV A,R7 XRL A,#NCHORD ;CLR BUF CHORD? JNZ EDIT12 ;NO SEL MB0 CALL CLRBUF ;YES SEL MB1 JMP EDIT0 EDIT12 MOV A,R7 XRL A,#C46 ;CRLF CHORD? JZ EDIT8 ;YES JMP EDIT13 ;NO EDIT8 SEL MB0 CALL CRLF ;YES. DO CRLF JF1 EDIT15 ;ROOM ON PAGE? SEL MB1 JMP EDIT14 ;NO EDIT13 SEL MB0 CALL BEEPLO ;INVALID CONDITION EDIT11 SEL MB1 JMP EDIT0 ;**************************** ;PRINT ROUTINE UNDER EDIT -- P [N] ;PRINTS N LINES FOLLOWING THE CURSOR ;(ALSO SENDS TEXT TO RS232 PORT FOR USE BY ;EXTERNAL SPEECH OR OTHER DEVICE) EDP SEL RB0 CALL ECNT ;GET N & LOAD ECTR JF1 EDP2 CALL LODPTR ;LOAD POINTERS SEL MB0 CALL DTRON EDP4 CALL EOT ;END OF TEXT? CPL F1 JF1 EDP2 ;YES CALL KBIN ;CHECK FOR USER ABORT XRL A,#C36 ;ABORT? JZ EDP2 ;YES MOV R0,#EDPFLG ;SET EDIT PRINT FLAG TO IN USE MOV @R0,#1 EDP3 CALL GETLIN ;GET NEXT LINE EDP1 SEL MB0 MOV R0,#LINBUF MOV A,@R0 ;DONE YET? JZ EDP5 ;YES CALL PRTLIN ;PRINT LINE SEL MB1 JMP EDP1 EDP5 MOV R0,#LINTYP ;FINISHED WITH LINE MOV A,@R0 XRL A,#3 ;MAX CELLS TERM? JZ EDP4 ;YES. GET REST OF LINE MOV A,@R0 XRL A,#5 ;FF TERM? JZ EDP4 ;YES. IGNORE IT MOV R0,#EDPFLG ;RESET EDIT PRINT FLAG TO MOV @R0,#0 ; NOT IN USE MOV R7,#0DH ;SEND 'CR' CALL SEND CALL GETLIN ;NO. DO FOLLOWING LF MOV R7,#0AH ;SEND 'LF' CALL SEND MOV R0,#ECTR MOV A,@R0 DEC A ;DEC LINE COUNT MOV @R0,A ;LAST LINE? JNZ EDP4 ;NO EDP2 SEL MB1 JMP EDIT0 ;YES ;**************************** ;DELETE ROUTINE UNDER EDIT -- D [N] ;DELETES N LINES FOLLOWING THE CURSOR EDD SEL RB1 CALL ECNT ;GET N & LOAD ECTR JF1 EDD9 MOV R1,#ECC ;SAVE CURSOR AT R2' & R5' MOV A,@R1 MOV R2,A INC R1 MOV A,@R1 MOV R5,A CALL LODPTR ;LOAD PTRS ;FIND END OF TEXT TO DELETE EDD8 SEL MB0 CALL EOT ;END OF TEXT? JF1 EDD1 ;NO SEL MB1 JMP EDD5 ;YES EDD1 CALL GETCHR ;GET CHAR FROM BUF XRL A,#0AH ;LF? JNZ EDD8 ;NO EDD2 MOV R1,#ECTR MOV A,@R1 DEC A ;DEC LINE COUNT MOV @R1,A ;LAST LINE? JNZ EDD8 ;NO CALL EOT ;END OF TEXT? JF1 EDD0 ;NO SEL MB1 ;YES JMP EDD5 EDD0 SEL MB1 ;YES CALL EDD3 ;SHIFT TEXT JMP EDD7 ;SHIFT REMAINING TEXT UP ;(ENTRY POINT FROM 'SCROLL' SUBROUTINE) EDD3 SEL MB0 SEL RB1 MOV R1,#ECC ;LOAD CURSOR IN R0' & R3' MOV A,@R1 MOV R0,A INC R1 MOV A,@R1 MOV R3,A EDD6 CALL GETCHR ;GET CHAR CALL STOCHR ;MOVE IT MOV A,R0 ;INC STORE PTR ADD A,#1 MOV R0,A JNC EDD4 INC R3 EDD4 CALL EOT ;END OF TEXT? JF1 EDD6 ;NO ;ADJUST END OF TEXT POINTER TO NEW LOC MOV A,R0 MOV R1,#BCE MOV @R1,A MOV A,R3 MOV R1,#BPE MOV @R1,A SEL MB1 RETR ;ADJUST END OF TEXT POINTER TO CURSOR EDD5 MOV R1,#ECC MOV A,@R1 MOV R1,#BCE MOV @R1,A MOV R1,#ECP MOV A,@R1 MOV R1,#BPE MOV @R1,A ;RESTORE CURSOR TO ORIGINAL POSITION EDD7 MOV R1,#ECC MOV A,R2 MOV @R1,A INC R1 MOV A,R5 MOV @R1,A EDD9 JMP EDIT0 ;**************************** ;MOVE ROUTINE UNDER EDIT -- M [T,B,UN,DN] ;MOVES EDIT CURSOR TO TOP (T) OR BOTTOM (B) ;OF BUFFER, OR, UP (U) OR DOWN (D) N LINES. EDM SEL RB0 CALL GETK ;GET MOVE PARAM XRL A,#1EH ;T? JNZ EDM1 ;NO MOV R0,#ECC ;INIT CURSOR MOV @R0,A INC R0 MOV @R0,A JMP EDIT0 ;YES. SET TO TOP EDM1 MOV A,R7 XRL A,#03H ;B? JNZ EDM2 ;NO MOV R0,#BCE ;YES. SET TO BOTTOM MOV A,@R0 MOV R0,#ECC MOV @R0,A MOV R0,#BPE MOV A,@R0 MOV R0,#ECP MOV @R0,A JMP EDIT0 EDM4 SEL MB0 CALL BEEPLO ;INVALID CONDITION EDM8 SEL MB1 JMP EDIT0 EDM2 MOV A,R7 XRL A,#25H ;U? JNZ EDM3 ;NO CALL ECNT ;GET N JF1 EDM8 MOV R6,#0FFH ;INIT R6 FOR BACKWARD MOV R0,#ECTR ;SINCE BACKWARD, INC N INC @R0 JMP EDM6 EDM3 MOV A,R7 XRL A,#19H ;D? JNZ EDM4 ;NO CALL ECNT ;GET N JF1 EDM8 MOV R6,#1 ;INIT R6 FOR FORWARD EDM6 CALL MOVCUR ;MOVE CURSOR 1 BYTE JF1 EDM8 CALL LODPTR ;LOAD POINTERS SEL MB0 CALL GETCHR ;GET CHAR FROM BUF SEL MB1 XRL A,#0AH ;LF? JNZ EDM6 ;NO EDM7 MOV R0,#ECTR ;YES MOV A,@R0 DEC A ;DEC LINE COUNT MOV @R0,A ;LAST LINE? JZ EDM5 ;YES EDM9 JMP EDM6 ;NO EDM5 MOV R6,#1 CALL MOVCUR ;ADJUST CURSOR EDM0 JMP EDIT0 ;**************************** ;INSERT ROUTINE UNDER EDIT -- I TEXT ;INSERTS TEXT BEGINNING AT CURSOR AND CONTINUING ;UNTIL Q-CHORD IS ENTERED (OR BUFFER BECOMES FULL). ;TERMINATE EACH LINE (MAX LENGTH=253) WITH ;(4,6)-CHORD AND WAIT FOR BEEP BEFORE ENTERING ;NEXT LINE. CURSOR IS PLACED AFTER LAST LINE. ;REGISTER USAGE: ;R4' -- LINE LENGTH (0-253) ;R0' -- CHAR LOC POINTER ;R3' -- PAGE LOC POINTER ;R1' -- GENERAL POINTER EDI SEL RB1 CALL GETSTR ;GET LINE MOV A,R1 ;GET LINE LENGTH MOV R4,A ;SAVE IT MOV A,R2 ;GET TERM TYPE JB2 EDI ;STRING INPUT ABORTED JB0 EDI1 ;CRLF TERM STRING JMP EDIT0 ;Q-CHORD TERM ;ROOM IN BUF FOR NEW LINE? EDI1 MOV R1,#BCE ;COMPUTE NEW END OF BUF MOV A,@R1 ADD A,R4 MOV R0,A ;SAVE NEW CHAR END MOV R1,#BPE MOV A,@R1 ADDC A,#0 ;ADD CARRY (IF ANY) MOV R3,A ;SAVE NEW PAGE END XRL A,#15 ;EXCEED BUF? JNZ EDI2 ;NO SEL MB0 ;YES. NOT ENOUGH ROOM CALL BEEPHL ;SOUND BUFFER FULL SIGNAL SEL MB1 EDI0 JMP EDIT0 ;MOVE CHARS AND/OR POINTERS TO MAKE ROOM FOR NEW LINE EDI2 MOV R1,#BCE ;LOAD BUF PRINT PTRS WITH MOV A,@R1 ; OLD BUF END PTRS DEC R1 MOV @R1,A MOV R1,#BPE MOV A,@R1 DEC R1 MOV @R1,A MOV R1,#BCE ;LOAD BUF END PTRS WITH MOV A,R0 ; NEW END VALUES MOV @R1,A MOV R1,#BPE MOV A,R3 MOV @R1,A ;REACHED CURSOR YET? EDI5 MOV R1,#BCP ;COMPARE SOURCE PTRS MOV A,@R1 ; TO CURSOR MOV R1,#ECC XRL A,@R1 ;SAME CHAR LOC? JNZ EDI3 ;NO MOV R1,#BPP ;YES MOV A,@R1 MOV R1,#ECP XRL A,@R1 ;SAME PAGE LOC? JZ EDI6 ;YES. DONE MOVING ;MOVE ANOTHER CHARACTER EDI3 CALL DECBCP ;DEC SOURCE PTRS DEC R0 ;DEC DESTINATION CHR PTR MOV A,R0 XRL A,#0FFH JNZ EDI4 DEC R3 ;DEC DESTINATION PAGE PTR EDI4 SEL MB0 CALL GET ;GET CHAR CALL STOCHR ;MOVE IT SEL MB1 JMP EDI5 ;GET NEXT CHAR ;ADJUST CURSOR TO NEW LOCATION EDI6 MOV R1,#ECC ;GET CURSOR CHAR MOV A,@R1 ADD A,R4 ;ADD STRING LENGTH MOV @R1,A ;SAVE CHAR LOC MOV R1,#ECP ;GET CURSOR PAGE MOV A,@R1 ADDC A,#0 ;ADVANCE PAGE IF NECESSARY MOV @R1,A ;SAVE PAGE LOC ;INSERT NEW LINE IN BUFFER MOV R1,#BCP ;LOAD DESTIN PTRS (R0' & MOV A,@R1 ; R3') WITH BCP & BPP MOV R0,A MOV R1,#BPP MOV A,@R1 MOV R3,A MOV @R1,#15 ;INIT SOURCE BCP & BPP PTRS MOV R1,#BCP ; TO LINE BUF MOV @R1,#0 SEL MB0 EDI8 CALL GETCHR ;GET CHR FROM LINE BUF CALL STOCHR ;PUT IT IN MAIN BUF INC R0 ;UPDATE MAIN BUF PTR MOV A,R0 JNZ EDI7 INC R3 ;INC PAGE EDI7 DJNZ R4,EDI8 CALL LOCBEL SEL MB1 JMP EDI ;GET NEW LINE ;**************************** ;FIND ROUTINE UNDER EDIT -- F STRING ;SEARCHES FORWARD THRU BUFFER FROM THE CURSOR ;UNTIL "STRING" IS FOUND. CURSOR IS PLACED AT ;BEGINNING OF LINE CONTAINING STRING. IF ;STRING IS NOT FOUND, CURSOR IS NOT MOVED. ;(MAX STRING LENGTH=253) ;REGISTER USAGE: ;R0' -- STRING CHAR POINTER (PAGE 15) ;R1' -- SAVE ORIGINAL ECC HERE ;R2' -- SAVE ORIGINAL ECP HERE ;R3' -- CURRENT STRING CHAR FOR COMPARISON ;R4' -- STRING LENGTH (0-253) ;R5' -- CHAR MATCH COUNT EDF SEL RB0 CALL GETSTR ;GET STRING IN LINE BUF MOV R6,#1 ;SET CURSOR MOVE TO FORWARD SEL RB1 MOV A,R1 MOV R4,A ;SAVE STRING LENGTH MOV A,R2 ;WAS STRING INPUT ABORTED? JB2 EDF13 ;YES MOV R0,#ECC ;SAVE ORIGINAL CURSOR POSITION MOV A,@R0 ; ECC & ECP AT R1' & R2' MOV R1,A MOV R0,#ECP MOV A,@R0 MOV R2,A EDF7 MOV A,R4 MOV R5,A ;LOAD CHAR MATCH COUNTER MOV R0,#0 ;LOAD STRING PTR CALL LODPTR ;LOAD BUF PTR WITH CURSOR JMP EDF11 ;CHK FOR EOT BEFORE STARTING EDF10 MOV A,#9FH ;GET STRING CHAR OUTL P2,A MOVX A,@R0 ANL P2,#DISRAM MOV R3,A ;SAVE IT SEL MB0 CALL GETCHR ;GET BUF CHAR SEL MB1 XRL A,R3 ;SAME? JNZ EDF8 ;NO ;CHARACTER MATCHES EDF9 INC R0 DJNZ R5,EDF11 ;MORE TO CHECK? JMP EDF14 ;NO. MATCH COMPLETE EDF11 SEL MB0 ;YES CALL EOT ;END OF TEXT? SEL MB1 JF1 EDF10 ;NO JMP EDF12 ;YES ;ADVANCE CURSOR ONE BYTE EDF8 MOV R0,#ECC INC @R0 ;INC CHAR LOC MOV A,@R0 JNZ EDF15 MOV R0,#ECP INC @R0 ;INC PAGE LOC EDF15 JMP EDF7 ;END OF TEXT & MATCH NOT FOUND EDF12 MOV R0,#ECC ;RESTORE CURSOR POINTERS MOV A,R1 XCH A,@R0 INC R0 MOV A,R2 XCH A,@R0 EDF13 JMP EDIT13 ;SOUND ERROR TONE AND ; RETURN TO EDIT ;STRING MATCH FOUND EDF14 SEL RB0 MOV R6,#0FFH CALL LODPT1 ;LOAD CURSOR EDF16 SEL MB1 CALL MOVCUR ;DEC IT JF1 EDI0 ;JUMP IF START OF BUF CALL LODPTR ;SAVE IN BUF PTRS SEL MB0 CALL GET ;GET CHR XRL A,#0AH ;LF? JNZ EDF16 ;NO MOV R6,#1 ;YES. ADVANCE CURSOR TO SEL MB1 ; FIRST CHR ON DESIRED LINE CALL MOVCUR EDF17 JMP EDIT0 ;**************************** ;SET BELL POSITION -- W-CHORD X ;WHERE X=1 TO 254 AND MEANS Q-CHORD SETBEL SEL RB1 CALL ECNT ;GET N JF1 SETB1 ;INVALID NUMBER MOV R0,#ECTR MOV A,@R0 MOV R0,#BELL MOV @R0,A ;STORE BELL POSITION SETB1 SEL MB0 JMP COMAND ;**************************** ;MARGIN SUBROUTINE ;NEXT CHAR FROM KEYBOARD MUST BE L, R, OR C ;L SETS LEFT MARGIN TO CURRENT CARRIAGE POSITION ;R SETS RIGHT MARGIN TO CURRENT CARRIAGE POSITION ;C CLEARS MARGINS (SETS LEFT=1 AND RIGHT=42 OR 51) MARGIN CALL GETK ;GET COMMAND PARAMETER SEL RB1 MOV R4,A ;SAVE PARM XRL A,#07H ;"L" ? JZ MAR8 JMP MAR1 MAR8 MOV R0,#LMARG ;CHANGE LEFT MARGIN MOV A,R6 JNZ MAR5 INC A MAR5 MOV @R0,A JMP MAR3 MAR1 MOV A,R4 XRL A,#17H ;"R" ? JNZ MAR2 MOV R0,#RMARG ;CHANGE RIGHT MARGIN MOV A,R6 MOV @R0,A JMP MAR3 MAR2 MOV A,R4 XRL A,#09H ;"C" ? JNZ MAR4 ;(ENTRY POINT TO CLEAR MARGINS FROM EXTERNAL ROUTINE) MAR7 SEL RB1 MOV R0,#LMARG ;SET LEFT MARGIN = 1 MOV @R0,#1 MOV R0,#MAXCEL MOV A,@R0 MOV R0,#RMARG ;SET RIGHT MARGIN = MAXCEL MOV @R0,A ;SET CURRENT LINE WIDTH 'LINEWD' TO (MAX-(LM-1)-(MAX-RM)) MAR3 MOV R0,#MAXCEL MOV A,@R0 MOV R1,A MOV R0,#RMARG ;COMPUTE (MAX-RM) MOV A,@R0 CPL A INC A ADD A,R1 MOV R0,#LMARG ;ADD LM-1 TO IT ADD A,@R0 DEC A CPL A ;SUB IT FROM MAXCEL INC A ADD A,R1 MOV R0,#LINEWD ;STORE IT MOV @R0,A RETR MAR4 SEL MB0 CALL BEEPLO ;INVALID PARAMETER SEL MB1 RETR ;**************************** ;SNDBUF SUBROUTINE ;CAUSES THE ENTIRE BUFFER (UP TO END OF TEXT) TO BE ;SENT TO USART SNDBUF SEL RB0 CLR A MOV R0,#BCP MOV @R0,A MOV R0,#BPP MOV @R0,A SEL MB0 CALL EOT ;BUFFER EMPTY? JF1 SNDB2 ;NO SEL MB1 RETR SNDB2 SEL MB0 CALL KBIN ;CHECK FOR USER ABORT XRL A,#C36 ;COMMAND CHORD? JNZ SNDB1 ;NO CALL EOTSET ;YES. RESTORE PTRS SEL MB1 RETR SNDB1 CALL GETCHR ;GET NEXT CHAR FROM BUF MOV R7,A CALL SEND ;SEND IT CALL EOT ;END OF TEXT? JF1 SNDB2 ;NO MOV R5,#0FFH ;DELAY UNTIL LAST CHAR CALL DELAY ; IS TRANSMITTED SNDB3 SEL MB1 ;YES RETR ;**************************** ;TAPE MODE (T-CHORD S,L) ;S (SAVE) -- SAVES BUFFER CONTENTS BY SENDING IT ;TO TAPE RECORDER INPUT. ;L (LOAD) -- LOADS BUFFER FROM TAPE PLAYER OUTPUT. ;COMPLETION OF EITHER OPTION, OR, ENTERING USER ;ABORT (3,6)-CHORD WILL RETURN CONTROL TO COMMAND MODE. ;IF ERRORS ARE DETECTED DURING READING, READING WILL ;CONTINUE BUT THE ERROR TONE WILL SOUND UPON COMPLETION. TAPE SEL RB0 DIS I MOV R0,#PASS MOV @R0,#0FAH ;STORE TAPE CHAR FORMAT- CALL NEWMOD ; 7 DATA,EVEN PARITY,2 STOP BITS MOV R0,#FLAGS1 ;CLR REC ERR FLAG MOV A,@R0 ANL A,#0DFH MOV @R0,A CALL GETK ;GET PARAMETER XRL A,#0EH ;S? JZ TAPE4 ;YES MOV A,R7 XRL A,#07H ;L? JZ TAPE5 ;YES TAPE6 SEL MB0 CALL BEEPLO ;INVALID SEL MB1 JMP TAPE3 ;LOAD MODE TAPE5 MOV A,#7 CALL BAUD ;SET BAUD RATE TO 'TAPE PLAY' MOV R0,#SPCBIT ;ENABLE TAPE REC CKT MOV A,@R0 ANL A,#7FH MOV @R0,A ANL P2,#7FH EN I SEL MB0 TAPE1 CALL KBIN XRL A,#C36 ;USER ABORT? JZ TAPE3 ;YES MOV R6,#0 CALL EOT0 ;DATA RECEPTION STARTED? CPL F1 JF1 TAPE1 ;NO SEL MB1 ;YES CALL INIT50 ;CLEAR BUFFER SEL MB0 SEL RB1 CLR A MOV R0,A MOV R3,A MOV A,R2 ;RECOVER 1ST CHR LOADED AND CALL STOCHR ; PUT IT IN CORRECT BUF LOC MOV R0,#BCE ;INC PTR INC @R0 SEL RB0 TAPE2 CALL KBIN ;USER ABORT? XRL A,#C36 JZ TAPE3 ;YES CALL GETCHR ;NO. GET CHR TO INC PTR SEL MB1 CALL RECERR ;CHK FOR RECEIVE ERRORS SEL MB0 CALL EOT ;DATA RECEPTION STOPPED? JF1 TAPE2 ;NO MOV R0,#FLAGS3 ;YES. WAS ERROR DETECTED? MOV A,@R0 JB5 TAPE6 ;YES ;FINISHED TAPE3 DIS I MOV R0,#SPCBIT ;DISABLE TAPE REC CKT MOV A,@R0 ORL A,#80H MOV @R0,A ORL P2,#80H MOV R0,#BAUDRT MOV A,@R0 ;RESTORE ORIGINAL BAUD RATE SEL MB1 CALL BAUD MOV R0,#USART ;RESTORE ORIGINAL MODE BYTE CALL NEWMOD ; & RESET RECEIVE ERROR BITS CALL SERON ;ENABLE RS232 XMIT SEL MB0 CALL EOTSET ;RESTORE PTRS IN CASE JMP COMAND ; LOAD OR SAVE WAS ABORTED ;SAVE MODE TAPE4 DIS I CALL SEROF1 ;DISABLE RS232 XMIT (BUT DON'T DISABLE MOV A,#6 ; FLAG SO 'SEND' ROUTINE CAN BE USED) CALL BAUD ;SET BAUD RATE TO 'TAPE RECORD' CALL SNDBUF ;SEND BUFFER JMP TAPE3 ;**************************** ;TRANSMIT ENABLE (X-CHORD Y,N) ;THE RS232C TRANSMIT LINE MAY BE ENABLED OR ;DISABLED. Y=YES (ENABLED), N=NO (DISABLED) XMTENB CALL GETK ;Y OR N? JB5 XMTEN1 CALL SEROFF ;NO. DISABLE RS232 XMIT JMP XMTEN2 XMTEN1 CALL SERON ;YES. ENABLE RS232 XMIT XMTEN2 SEL MB0 JMP COMAND END