.TITLE VC4IO .IDENT /0383.1/ ; ; ; AUTHOR: N.A. HIGGINS ; DATE: 170383 ; ; ;THIS MODULE CONTAINS ROUTINES TO INTERFACE 'DBSMNG' TO A VOLKER-CRAIG VC404 ;VIDEO TERMINAL. THE FOLLOWING ROUTINES ARE PROVIDED: ; ; VC4.CI CHARACTER INPUT PRIMITIVE ; VC4.CO CHARACTER OUTPUT PRIMITIVE ; VC4.LI LINE INPUT ROUTINE ; VC4.LO LINE OUTPUT ROUTINE ; VC4.XY CURSOR GOTO XY PRIMITIVE ; VC4.EL ERASE LINE ROUTINE ; VC4.ES ERASE SCREEN PRIMITIVE ; ; .SBTTL REGISTER USAGE AND ARGUMENT PASSING ; ; ;ALL ROUTINES IN THE MODULE PRESERVE ALL REGISTERS. ARGUMENTS ARE PASSED IN ;THE REGISTERS AS FOLLOWS: ; ; VC4.CI CHARACTER IS RETURNED IN R0 ; VC4.CO CHARACTER IS PASSED IN R0 ; VC4.LI ADDRESS OF BUFFER IS PASSED IN R0 ; VC4.LO ADDRESS OF STRING IS PASSED IN R0 ; VC4.XY CO-ORDINATES ARE PASSED IN R0 ( X=LOB, Y=HOB ) ; VC4.EL ADDRESS OF LINE IS PASSED IN R0 ( Y=HOB ) ; VC4.ES - NO ARGUMENT - ; ; .SBTTL NOTES ; ; ;THIS MODULE SETS THE SPECIAL INPUT MODE BIT OF THE JSW ( LOCATION 44 ) THUS ;INHIBITING MONITOR ECHO. ALL ECHO IS PERFORMED EXPLICITLY BY THESE ROUTINES. ; ;THE MAXIMUM INPUT LINE SIZE IS 78 CHARACTERS ( SEE DEFINITION OF 'LINSIZ' ;CONSTANT LATER IN MODULE ). ; ;THE CHARACTER INPUT ROUTINE ( VC4.CI ) REJECTS ALL CODES ABOVE 177 OCTAL. ; ;THE CHARACTER OUTPUT ROUTINE ( VC4.CO ) REJECTS ALL CODES ABOVE 177 OCTAL ;WITH THE EXCEPTION OF 233. THIS LATTER CODE IS REQUIRED FOR OUTPUTTING ESC ;CHARACTERS UNDER THE RSTS/E RT-11 EMULATOR. ; ; .SBTTL VC404 QUIRKS ; ; ;THE FOLLOWING TABLE SUMMARIZES THE PERFORMANCE OF THIS MODULE AS REQUIRED ;TO MAKE A VC404 LOOK AT LEAST PARTIALLY CIVILIZED ( IN FACT, IT'S A BLOODY ;AWFUL TERMINAL ). THE 'FUNCTIONS' REFERRED TO IN THE TABLE ARE THOSE INVOKED ;WHILE IN THE DATABASE FULL SCREEN EDITOR. THE 'STANDARD KEYSTROKES' ARE THE ;KEYSTROKES WHICH ARE USED TO INVOKE THOSE FUNCTIONS ON A VT100. THE 'VC404 ;KEYSTROKES' ARE THE KEYSTROKES USED ON A VC404 TO ACHIEVE THE SAME RESULT. ;NOTE THAT THE 'VC404 KEYSTROKES' REFER TO KEYS ON THE 'NATIVE' VC404 BOARD. ;AS SOME OF THESE ARE PRETTY ILLOGICAL, THE OFFENDING KEYS MUST BE RELABELLED ;AS SHOWN IN THE 'RELABELLED AS' COLUMN. THE 'CODES GENERATED BY VC404' ARE ;THE ASCII CODES WHICH RESULT WITH EACH CORRESPONDING KEYSTROKE, AND THE ;'STANDARD CODES' ARE THE CODES WHICH MUST BE RETURNED ( VIA A TRANSLATION ;PROCESS ) BY THE ROUTINES SO AS TO CORRECTLY INVOKE THE REQUIRED FUNCTIONS. ;SIMPLE, AIN'T IT! ; ; FUNCTION STANDARD VC404 RELABELLED CODE STANDARD ; KEYSTROKE KEYSTROKE AS GENERATED CODE ; BY VC404 ; ; COMMAND MODE ; ------------ ; ; DELETE DEL RUBOUT - DEL DEL ; CHARACTER ; ; DELETE ^U ^U - ^U ^U ; LINE ; ; ENTER CMD RETURN RETURN - ^M ^M ; ; ; EDIT MODE ; --------- ; ; TOP OF UP UP - ^Z 200+A ; FIELD ; ; BOTTOM OF DOWN LINE FEED - ^J 200+B ; FIELD ; ; CURSOR LEFT LEFT - ^H 200+D ; LEFT ; ; CURSOR RIGHT HOME RIGHT ^Y 200+C ; RIGHT ; ; DELETE PF1 CLEAR DEL CHAR ^X 200+P ; UNDER ; CURSOR ; ; INSERT PF2 ESC,I - ESC,I 200+Q ; MODE ; ; BACKUP PF3 ESC,B - ESC,B 200+R ; ONE FIELD ; ; BACKUP BACKSPACE ESC,B - ESC,B 200+R ; ONE FIELD ; ; ADVANCE PF4 ESC,A - ESC,A 200+S ; ONE FIELD ; ; ADVANCE TAB TAB - ^I ^I ; ONE FIELD ; ; DELETE DEL RUBOUT - DEL DEL ; LEFT OF ; CURSOR ; ; DELETE ^U ^U - ^U ^U ; FIELD ; ; ; NON-STANDARD VC404 KEYS ; ----------------------- ; ; - BACKSPACE BLANK ^H ** USE ESC,B KEYS ** ; ; - RIGHT BLANK ^U ** DISABLE !!!!!! ** ; ; .SBTTL OPERATING SYSTEMS ; ; ;THIS MODULE WILL OPERATE UNDER RT-11, TSX PLUS AND RSTS/E ( UNDER THE RT-11 ;EMULATOR ) AS LONG AS IT IS MANAGED BY THE CONIO MODULE WHICH CARRIES OUT ;OPERATING SYSTEM SPECIFIC INITIALIZATONS. RSTS/E USERS MUST ENSURE THAT THE ;FOLLOWING TERMINAL CHARACTERISTICS ARE IN FORCE: ; ; NO FORM ; NO TAB ; NO UPARROW ; SCOPE ; STALL ; ; .SBTTL DECLARATIONS ; ; .MCALL .TTYIN,.TTYOUT ;RT11 I/O .MCALL .PUSH,.POP ;STACK OPS ; .GLOBL VC4.CI,VC4.CO ;CHARACTER I/O ENTRY POINTS .GLOBL VC4.LI,VC4.LO ;LINE I/O ENTRY POINTS .GLOBL VC4.XY ;XY ENTRY POINT .GLOBL VC4.EL ;ERASE LINE ENTRY POINT .GLOBL VC4.ES ;ERASE SCREEN ENTRY POINT ; ; .IIF NDF,JSW JSW = 44 ;JOB STATUS WORD .IIF NDF,JSW.NE JSW.NE = 10000 ;NO ECHO BIT IN JSW .IIF NDF,LINSIZ LINSIZ = 78. ;MAX CHARACTERS PER INPUT LINE ; .IIF NDF,ESC ESC = 33 ;ESC CHARACTER .IIF NDF,ESCOUT ESCOUT = 233 ;RSTS/E ESC OUTPUT CHARACTER ; .IIF NDF,BELL BELL = 'G-'@ ;BELL CHARACTER .IIF NDF,BS BS = 'H-'@ ;BACKSPACE CHARACTER .IIF NDF,CTRLH CTRLH = 'H-'@ ;CONTROL-H CHARACTER .IIF NDF,LF LF = 'J-'@ ;LINE FEED CHARACTER .IIF NDF,CTRLJ CTRLJ = 'J-'@ ;CONTROL-J CHARACTER .IIF NDF,CR CR = 'M-'@ ;CARRIAGE RETURN CHARACTER .IIF NDF,GOTOYX GOTOYX = 'P-'@ ;VC404 GO TO ( Y, X ) CODE .IIF NDF,CTRLU CTRLU = 'U-'@ ;CONTROL-U CHARACTER .IIF NDF,CL2EOL CL2EOL = 'V-'@ ;VC404 CLEAR TO EOL CHARACTER .IIF NDF,CLEARS CLEARS = 'X-'@ ;VC404 CLEAR SCREEN CHARACTER .IIF NDF,CTRLX CTRLX = 'X-'@ ;CONTROL-X CHARACTER .IIF NDF,CTRLY CTRLY = 'Y-'@ ;CONTROL-Y CHARACTER .IIF NDF,CTRLZ CTRLZ = 'Z-'@ ;CONTROL-Z CHARACTER .IIF NDF,SPACE SPACE = 40 ;SPACE CHARACTER .IIF NDF,DEL DEL = 177 ;DEL CHARACTER ; ; .SBTTL ".OUT" MACRO ; ; .MACRO .OUT CHAR .IF B, CALL VC4.CO .IFF .PUSH R0 .IRP X, MOVB X,R0 CALL VC4.CO .ENDR .POP R0 .ENDC .ENDM .OUT ; ; .SBTTL INITIALIZATION CODE ; ; .PSECT INITLZ ;INITIALIZATION SECTION ; ----- ------ ; BIS #JSW.NE,@#JSW ;SET NO ECHO BIT IN JSW ; ; .PSECT CODE ;REST OF MODULE GOES IN CODE SECTION ; ----- ---- ; ; .SBTTL "VC4.CI" PRIMITIVE ; ; VC4.CI: .TTYIN ;GRAB A CHARACTER FROM INPUT DEV BIC #<^C377>,R0 ;CLEAR GARBAGE FROM HIGH BYTE TSTB R0 ;CHECK BIT 7 BMI VC4.CI ;REJECT CODES 200 AND ABOVE ; CMP R0,#SPACE ;PRINTABLE CHARACTER? BLO 100$ ;SKIP IF NOT RETURN ;ELSE RETURN WITH THE GOODIES ; 100$: CMP R0,#ESC ;ESCAPE SEQUENCE INCOMING? BNE 200$ ;SKIP IF NOT .TTYIN ;GRAB NEXT CHARACTER IN SEQUENCE BIC #<^C377>,R0 ;CLEAR GARBAGE FROM HIGH BYTE .PUSH R1 ;SAVE R1 ON STACK MOV #ESCTAB,R1 ;R1 <-- ADDRESS OF TRANSLATION TABLE 120$: TSTB (R1) ;END OF TABLE? BEQ 140$ ;SKIP IF NO MATCH FOUND CMPB R0,(R1)+ ;CHECK FOR MATCH BEQ 160$ ;SKIP OUT IF MATCH FOUND INC R1 ;BUMP POINTER BR 120$ ;ONCE MORE INTO THE ABYSS! 140$: .POP R1 ;RESTORE R1 BR VC4.CI ;BAD ESCAPE SEQUENCE. RETURN TO START 160$: MOVB (R1),R0 ;TRANSLATE .POP R1 ;RESTORE R1 RETURN ;RETURN WITH THE GOODIES ; 200$: .PUSH R1 ;SAVE R1 ON STACK MOV #CTLTAB,R1 ;R1 <-- ADDRESS OF TRANSLATION TABLE 220$: TSTB (R1) ;END OF TABLE? BEQ 260$ ;NO MATCH FOUND - THAT'S OK CMPB R0,(R1)+ ;CHECK FOR MATCH BEQ 240$ ;SKIP OUT IF MATCH FOUND INC R1 ;BUMP POINTER BR 220$ ;ONCE MORE INTO THE ABYSS! 240$: MOVB (R1),R0 ;TRANSLATE 260$: .POP R1 ;RESTORE R1 RETURN ;RETURN WITH THE GOODIES ; ;TRANSLATION TABLES MADE UP AS ORDERED PAIRS OF BYTES ( SUBJECT, OBJECT ), AND ;TERMINATED BY A ( 0, 0 ) PAIR. ; ESCTAB: .BYTE 'A,<200+'S> .BYTE 'B,<200+'R> .BYTE 'I,<200+'Q> .BYTE 0,0 ; CTLTAB: .BYTE CTRLH,<200+'D> .BYTE CTRLJ,<200+'B> .BYTE CTRLX,<200+'P> .BYTE CTRLY,<200+'C> .BYTE CTRLZ,<200+'A> .BYTE 0,0 ; ; .SBTTL "VC4.CO" PRIMITIVE ; ; VC4.CO: TSTB R0 ;CHECK BIT 7 OF CHARACTER BPL 100$ ;SKIP IF CODE LESS THAN 200 CMPB R0,#ESCOUT ;RSTS/E ESCAPE CHARACTER? BEQ 100$ ;OK IF IT IS RETURN ;OTHERWISE CHUCK IT AND RETURN ; 100$: .TTYOUT ;PUT CHARACTER OUT TO I/O DEV RETURN ;ALL FINISHED. RETURN ; ; .SBTTL "VC4.LI" ROUTINE ; ; VC4.LI: .PUSH ;PRESERVE REGISTERS MOV R0,R1 ;R1 POINTS TO BUFFER CLR R2 ;INITIALIZE CHARACTER COUNT ; ;NORMAL CHARACTERS GO DIRECTLY INTO BUFFER UNLESS THE MAX ALLOWABLE NUMBER OF ;CHARACTERS HAS ALREADY BEEN RECEIVED ( IN WHICH CASE THEY ARE CHUCKED AND THE ;BELL IS RUNG ). CONTROL CHARACTERS, DELETE AND SPECIALS ( 200 UP ) GENERATED ;BY THE INPUT PRIMITIVE ARE HANDLED IN SEPARATE SUBROUTINES. THE SPECIALS AND ;ANY UNRECOGNIZED CONTROL CHARACTERS ARE CHUCKED ( INCLUDED AMONG THE SPECIALS ;THAT ARE CHUCKED ARE THE 302 CODES ORIGINATING FROM RT-11'S GRATUITOUS LINE ;FEEDS ). ; 100$: CALL VC4.CI ;GET A CHARACTER CMPB R0,#DEL ;DEL CODE OR GREATER? BHIS 200$ ;SKIP IF IT IS CMPB R0,#SPACE ;IS IT PRINTABLE? BLO 200$ ;SKIP IF NOT CMP R2,#LINSIZ ;ALREADY GOT OUR QUOTA? BHIS 120$ ;SKIP IF SO MOVB R0,(R1)+ ;TRANSFER CHARACTER TO BUFFER INC R2 ;BUMP UP CHARACTER COUNT .OUT ;ECHO CHARACTER TO SCREEN BR 100$ ;GO BACK FOR NEXT CHARACTER 120$: .OUT <#BELL> ;TELL HIM TO GET LOST BR 100$ ;GO BACK FOR NEXT CHARACTER ; 200$: MOV #ADRTAB,R3 ;R3 <-- ADDRESS OF JUMP TABLE 220$: TST (R3) ;END OF TABLE? BEQ 240$ ;SKIP OUT IF NO MATCH FOUND CMPB R0,(R3) ;CHECK FOR MATCH BEQ 240$ ;SKIP OUT IF MATCH FOUND ADD #4,R3 ;BUMP POINTER BR 220$ ;TRY NEXT ELEMENT IN TABLE 240$: CALL @2(R3) ;DESPATCH TO APPROPRIATE SUBROUTINE BR 100$ ;GO BACK FOR NEXT CHARACTER ( MAYBE ) ; ;JUMP TABLE ORGANIZED AS ORDERED PAIRS OF THE FORM ( SUBJECT, SUBROUTINE ), ;AND TERMINATED BY A ( 0, NOMATCH ) PAIR ( CORRESPONDING WITH THE CHUCKING OF ;UNRECOGNIZED CONTROL CHARACTERS ). ; ADRTAB: .WORD CR,1100$ ;CR --> EXIT .WORD CTRLU,1200$ ;CTRLU --> DELETE LINE .WORD DEL,1300$ ;DEL --> DELETE CHARACTER .WORD 0,NOMAT ;NO MATCH --> CHUCK IT ; ; ;CARRIAGE RETURN HANDLER - TERMINATE BUFFER AND SCRAM ; 1100$: CLRB (R1) ;TERMINATE BUFFER WITH A NULL .OUT <#CR,#LF> ;MOVE CURSOR TO NEW LINE ADD #2,SP ;DISCARD SUBROUTINE CALL ADDRESS .POP ;RESTORE REGISTERS RETURN ;RETURN WITH INPUT LINE IN BUFFER ; ; ;CONTROL-U HANDLER - DELETE ENTIRE LINE ; 1200$: TST R2 ;ANY CHARACTERS IN BUFFER? BEQ 1220$ ;SKIP OUT IF NOT CALL 1300$ ;GO DELETE A CHARACTER BR 1200$ ;LOOP UNTIL NO CHARACTERS LEFT 1220$: RETURN ;ALL DONE ; ; ;DEL HANDLER - DELETE ONE CHARACTER ; 1300$: TST R2 ;ANY CHARACTERS IN BUFFER? BEQ 1320$ ;SKIP IF NOT DEC R1 ;BUMP POINTER BACK DEC R2 ;DECREMENT CHARACTER COUNT .OUT <#BS,#SPACE,#BS> ;ERASE CHARACTER FROM SCREEN 1320$: RETURN ;ALL DONE ; ; ;NO MATCH FOR CONTROL CHARACTER - POLITELY IGNORE IT ; NOMAT: RETURN ;ALL DONE ; ; .SBTTL "VC4.LO" ROUTINE ; ; ;IF THE BUFFER IS TERMINATED WITH A NULL, THIS ROUTINE APPENDS CR, LF TO END ;THE CURRENT LINE. IF THE BUFFER IS TERMINATED WITH A 200 CODE, IT IS ASSUMED ;THAT FURTHER OUTPUT WILL BE APPENDED TO THE CURRENT LINE ( A LA RT-11 ). ; VC4.LO: .PUSH ;SAVE REGISTERS MOV R0,R1 ;R1 POINTS TO BUFFER ; 100$: MOVB (R1)+,R0 ;GET NEXT BYTE FROM BUFFER BEQ 200$ ;SKIP OUT IF NULL FOUND CMPB R0,#200 ;LINE CONTINUATION CODE? BEQ 220$ ;SKIP IF SO .OUT ;PUT CHARACTER OUT TO I/O DEV BR 100$ ;LOOP BACK FOR NEXT CHARACTER ; 200$: .OUT <#CR,#LF> ;MOVE CURSOR TO NEW LINE 220$: .POP ;RESTORE REGISTERS RETURN ;ALL DONE ; ; .SBTTL "VC4.XY" PRIMITIVE ; ; ;SEE VC404 MANUAL. TO POSITION THE CURSOR, IT IS NECESSARY TO SEND A CONTROL-P ;CODE, THEN THE Y CO-ORDINATE ( OFFSET BY ^O40 ), THEN THE X CO-ORDINATE ( ALSO ;OFFSET BY ^O40 ). ; VC4.XY: .OUT <#GOTOYX> ;PUT OUT GO TO ( Y, X ) CODE .PUSH R0 ;SAVE ARGUMENT ON STACK ; SWAB R0 ;SWAP Y CO-ORD TO LOB CMPB R0,#23. ;SEE IF CO-ORD IS IN BOUNDS BLOS 20$ ;SKIP IF IT IS MOVB #23.,R0 ;OTHERWISE CHOP TO UPPER BOUND 20$: ADD #SPACE,R0 ;TRANSLATE CO-ORD TO PRINTABLE CHAR .OUT ;PUT OUT Y CO-ORD ; MOV (SP),R0 ;COPY ARG FROM STACK CMPB R0,#79. ;SEE IF CO-ORD IS IN BOUNDS BLOS 40$ ;SKIP IF IT IS MOVB #79.,R0 ;OTHERWISE CHOP TO UPPER BOUND 40$: ADD #SPACE,R0 ;TRANSLATE CO-ORD TO PRINTABLE CHAR .OUT ;PUT OUT X CO-ORD ; .POP R0 ;RESTORE ARGUMENT RETURN ;ALL DONE ; ; .SBTTL "VC4.EL" ROUTINE ; ; ;POSITIONS THE CURSOR AT THE START OF THE SELECTED LINE, THEN SENDS AN ERASE ;TO EOL CODE. ; VC4.EL: .PUSH R0 ;SAVE ARGUMENT ON STACK BIC #377,R0 ;CLEAR X CO-ORDINATE TO ZERO CALL VC4.XY ;GO POSITION CURSOR .OUT <#CL2EOL> ;PUT OUT CLEAR TO EOL CODE .POP R0 ;RESTORE ARGUMENT RETURN ;ALL DONE ; ; .SBTTL "VC4.ES" PRIMITIVE ( *** NASTY *** ) ; ; ;THIS IS THE ONLY REALLY NASTY BIT. THE VC404 REQUIRES 40MS ( ON RECEIPT OF ;THE CLEAR SCREEN CODE ) TO PERFORM THE FUNCTION. HENCE THE INCLUSION OF A ;GIANT DO-NOTHING LOOP AFTER THE CODE IS SENT. THIS LOOP GIVES ABOUT 300MS ;DELAY ON A KD11-HA PROCESSOR AND SHOULD GIVE AT LEAST 40MS ( REALISTICALLY ) ;ON ANY OTHER PROCESSOR. HOWEVER IF YOU HAVE ANY PROBLEMS, THIS IS THE FIRST ;PLACE TO LOOK. ; VC4.ES: .OUT <#CLEARS> ;PUT OUT CLEAR SCREEN CODE ; .PUSH R0 ;SAVE R0 ON STACK CLR R0 ;R0 = 0 --> MAXIMUM COUNT 20$: SOB R0,20$ ;OH DEAR! .POP R0 ;RESTORE R0 ; RETURN ;ALL DONE ( WHEW! ) ; ; .END