.TITLE ADMIO .IDENT /1501.1/ ; ; ; ; ; ADAPTED BY GRAEME WIGHTMAN (FROM TVIIO.MAC) ; 15-JAN-82 ; ; ; ; VERSION 150182/01. ; ; ;-------------------------------------------------------------------- ; ; ; THIS MODULE CONTAINS THE ROUTINES NEEDED TO DO I/O TO AND FROM THE ; CONSOLE. THE ROUTINES AVAILABLE ARE- ; ; ADM.CI INPUT ONE CHRACTER FROM THE CONSOLE ; ADM.CO OUTPUT ONE CHRACTER TO THE CONSOLE ; ADM.LI INPUT A LINE FROM THE CONSOLE ; ADM.LO OUTPUT A LINE TO THE CONSOLE ; ADM.ES ERASE THE CONSOLE SCREEN ; ADM.EL ERASE A LINE ON THE CONSOLE SCREEN ; ADM.XY POSITION THE CUSOR ON THE SCREEN ; ; ; ; ; .SBTTL MODIFICATIONS ; ; ; ; ; ; .SBTTL DOCUMENTATION - REGISTERS USAGE AND ARGUMENT PASSING ; ; ; ALL THE ROUTINES IN THE MODULE PRESERVE ALL REGISTERS. THE ARGUMENTS ARE ; PASSED VIA THE REGISTERS AS FOLLOWS- ; ; ADM.CO CHARACTER IS PASSED IN 'R0' ; ADM.CI CHARACTER IS RETURNED IN 'R0' ; ADM.LO ADDRESS OF ASCII STRING IS PASSED OVER IN 'R0' ; ADM.LI ADDRESS OF BUFFER IS PASSED OVER IN 'R0' ; ADM.ES .... NO ARGUMENT ... ; ADM.EL ADDRESS OF LINE IS PASSED OVER IN LOB OF R0. ; ADM.XY COORDINATES ARE PASSED OVER IN 'R0' (X=LOB,Y=HOB) ; ; ; .SBTTL DOCUMENTATION - NOTES ; ; ; THE MODULE SETS THE SPECIAL INPUT MODE BIT IN THE 'JSW' TO STOP THE ; MONITOR ECHOING THE INPUT. ; ; IF A CHARACTER IS INPUT IT IS DISCARDED AND ANOTHER CHARACTER IS ; INPUT. ; ; THE MAXIMUM INPUT LINE SIZE IS 78 CHARACTERS. THIS IS DETERMINED BY ; THE 'LINSIZ' CONSTANT. ; ; ; ; ; ; .SBTTL DECLARATIONS ; ; .MCALL .TTYOUT,.TTYIN,.TTINR ; I/O MACROS .MCALL .PUSH,.POP ; STACKING ; .GLOBL ADM.CI,ADM.CO ; CHARACTER IN/OUT .GLOBL ADM.LI,ADM.LO ; LINE IN/OUT .GLOBL ADM.ES,ADM.EL ; ERASE SCREEN/LINE .GLOBL ADM.XY ; POSITION CUSOR ; ; TTY.NE = 10000 ; SPECIAL TTY MODE - NO ECHO JSW = 44 ; JSW FOR RT11 LINSIZ = 78. ; INPUT LINE SIZE ; ; ; .SBTTL DEFINITIONS - CHARATER CODES ; ; .IIF NDF,BELL, BELL = 'G-'@ ; BELL .IIF NDF,BS, BS = 'H-'@ ; BACKSPACE .IIF NDF,TAB, TAB = 'I-'@ ; TAB .IIF NDF,LF, LF = 'J-'@ ; LINEFEED .IIF NDF,CR, CR = 'M-'@ ; CARRIAGE RETURN .IIF NDF,HOMECR, HOMECR = '^-'@ ; HOME CURSOR .IIF NDF,ESC, ESC = 33 ; CHARACTER 'ESCAPE' .IIF NDF,CLRSCN, CLRSCN = 32 ; CNTRL Z .IIF NDF,SPACE, SPACE = 40 ; SPACE .IIF NDF,ESCOUT, ESCOUT = 233 ; CHARACTER 'ESCAPE' .IIF NDF,DELETE, DELETE = 177 ; DELETE CHARACTER ; ; ; .PSECT CODE ; OPEN CODE SECTION ; ------ ---- ; ; ; .SBTTL DEFINITION - MACRO '.OUT' ; ; ; THIS ROUTINE CAUSES A NUMBER OF CHARCATERS TO BE OUTPUT TO ; THE CONSOLE. ; ; .MACRO .OUT CHAR .IF B, CALL ADM.CO .MEXIT .ENDC MOV R0,-(SP) .IRP X, MOVB X,R0 CALL ADM.CO .ENDR MOV (SP)+,R0 .ENDM .OUT ; ; ; ; ; .SBTTL INITIALIZATION CODE ; ; ; ; HERE WE ENTER SPECIAL TTY MODE. THIS IS DONE BY SETTING A BIT IN ; THE JSW. AS A RESULT OF THIS THE MONITOR WILL NOT ECHO CHARACTERS. ; ; .PSECT INITLZ ; OPEN SECTION ; ------ ------ ; ; BIS #TTY.NE,@#JSW ; DISABLE MONITOR ECHO ; ; .PSECT CODE ; OPEN CODE SECTION ; ------ ---- ; ; ; ; ; ; .SBTTL ROUTINE - 'ADM.CI' ... INPUT A CHARACTER FROM TERMINAL ; ; ; WE INPUT A CHARACTER AND RETURN IT IN R0. ; ; ADM.CI: .TTYIN ; GET A CHARACTER (-> R0) BIC #^C377,R0 ; LEAVE LOB ONLY CMPB R0,#40 ; SPECIAL CHARACTER? BLO 100$ ; YES -> SKIP RETURN ; EXIT ; 100$: CMPB R0,#CR ; WAS IT A ? BNE 200$ ; NO -> 200$ .TTINR ; STRIP OF MOV #CR,R0 ; RETURN A .. RETURN ; ... ; 200$: CMPB R0,#ESC ; ESCAPE CHAR? BNE 400$ ; NO -> SKIP .TTYIN ; INPUT ANOTHER CHAR BIC #^C377,R0 ; STRIP BIS #200,R0 ; SET BIT RETURN ; HOME ; 400$: .PUSH R1 ; SAVE R1 MOV #1000$,R1 ; R1 -> TRANSLATION TABLE 410$: ADD #4,R1 ; POINT NEXT ENTRY CMP R0,(R1) ; AT EOT? BHI 410$ ; LOOP BNE 470$ ; NO MATCH -> EXIT MOV 2(R1),R0 ; TRANSLATE 470$: .POP R1 ; RESTORE RETURN ; BYE ; ; 1000$: .WORD 0,0 ; START OF TABLE .WORD 8.,304 ; -> LEFT CURSOR .WORD 10.,302 ; -> BOTTOM FIELD .WORD 11.,301 ; -> TOP FIELD .WORD 12.,303 ; -> RIGHT CURSOR .WORD 377,377 ; EOT ; ; ; ; .SBTTL ROUTINE - 'ADM.CO' ... OUTPUT A CHARACTER TO CONSOLE ; ; ; ADM.CO: .TTYOUT ; CHARACTER (R0) --> CONSOLE RETURN ; HOME ; ; .SBTTL ROUTINE - 'ADM.LO' ... OUTPUT A LINE TO CONSOLE ; ; ADM.LO: .PUSH ; SAVE MOV R0,R1 ; STR ADD -> R1 10$: MOVB (R1)+,R0 ; GET CHAR BLE 100$ ; EOS -> SKIP CALL ADM.CO ; SEND IT TO TTY BR 10$ ; LOOP ; 100$: BLT 200$ ; EXIT .OUT <#CR,#LF> ; 200$: .POP ; RESTORE RETURN ; EXIT ; ; ; ; ; .SBTTL ROUTINE - 'ADM.LI' ... INPUT A LINE FROM CONSOLE ; ; ; SET UP REGISTERS (AFTER SAVING THEM) AS FOLLOWS- ; ; R2 COUNT OF CHARACTERS IN BUFFER ; R1 STORE POINTER ; R0 HOLDS INPUT CHRACTER ; ; ADM.LI: .PUSH ; SAVE MOV R0,R1 ; BUFFER ADDRESS -> R1 CLR R2 ; NO CHARACTERS IN BUFFER ; ; ; MAIN LOOP. INPUT A CHARACTER. IF IT IS A , <^U> OR ; TAKE APPROPRIATE ACTION. IF IT IS NOT A LEGAL CHARACTER IGNORE ; IT. IF BUFFER IS FULL RING BELL AND IGNORE IT. IF CHARACTER ; IS LEGAL ECHO IT AND STORE IT IN BUFFER. ; ; 10$: CALL ADM.CI ; GET A CHARACTER CMPB R0,#CR ; A ? BEQ 100$ ; YES -> 100$ CMPB R0,#<'U-'@> ; A ^U? BEQ 200$ ; YES -> 200$ CMPB R0,#<'K-'@> ; A ^K BEQ 200$ ; YES -> 200$ CMPB R0,#DELETE ; A DELETE? BEQ 300$ ; YES -> 300$ CMPB R0,#BS ; BACKSPACE ? BEQ 300$ ; YES -> 300$ CMPB R0,#40 ; >= SPACE? BLO 10$ ; NO -> IGNORE -> 10$ CMP R2,#LINSIZ ; BUFFER FULL? BHIS 400$ ; YES -> 400$ CALL ADM.CO ; ECHO MOVB R0,(R1)+ ; SAVE CHARACTER INC R2 ; UP COUNT BR 10$ ; LOOP ; ; ; ; ; ; DETECTED , WHICH MEANS THAT INPUT MODE IS TERMINATED. WE ; PLACE A NULL AT THE END OF THE BUFFER AND EXIT. ; 100$: CALL ADM.CO ; OUTPUT A CHARACTER CLRB (R1) ; NULL AT EOL .POP ; RESTORE RETURN ; HOME ; ; ; ; DETECTED A <^U>, WHICH MEANS LINE IS THE BE DISCARDED. CARRY OUT ; MULTIPLE DELETE OPERATIONS TILL ALL CHARACTERS IN BUFFER ARE ; DISCARDED. ; 200$: TST R2 ; ANY CHARACTERS IN BUFFER? BEQ 10$ ; NO -> EXIT LOOP CALL 1000$ ; DELETE CHARACTER BR 200$ ; LOOP ; ; ; ; WE ARE DELETING A CHARACTER. ; 300$: CALL 1000$ ; DELETE A CHARACTER BR 10$ ; EXIT SUBMODE ; ; ; ; BUFFER IS FULL - CANNOT ACCEPT CHARACTER - THERE RING BELL. ; 400$: .OUT #BELL ; TELL BUFFER FULL BR 100$ ; EXIT SUBMODE ; ; ; ; THIS ROUTINE CAUSES THE LAST CHARACTER TO BE TYPED IN TO BE DISCARDED ; FROM THE INPUT BUFFER AND DELETED FROM THE SCREEN. ; ; 1000$: TST R2 ; ANY CHARACTERS TO DELETE? BEQ 1010$ ; NO -> EXIT .OUT <#BS,#SPACE,#BS> ; DEC R1 ; DOWN POINTER DEC R2 ; DOWN COUNTER 1010$: RETURN ; DONE ; ; ; ; .SBTTL LINE ERASE PRIMITIVE - 'ADM.EL' ; ; ; ; THIS ROUTINE CLEARS A LINE ON THE SCREEN. ALL REGISTERS ARE ; PRESERVED THROUGH THE ROUTINE. ; ; ADM.EL: CALL ADM.XY ; GET THE RIGHT LINE .OUT #CR ; START OF LINE MOV #11$,R0 CALL ADM.LO ; FILL WITH SPACES .OUT #CR RETURN ; 11$: .REPT LINSIZ - 7 .ASCII /./ .ENDR .BYTE 200 .EVEN ; ; ; ; .SBTTL SCREEN ERASE PRIMITIVE - 'ADM.ES' ; ; ; ADM.ES: .OUT #CLRSCN ; CLEAR SCREEN RETURN ; ; ; ; ; .SBTTL ROUTINE - 'ADM.XY' ... POSITION CUSOR ON SCREEN ; ; ; ; THIS ROUTINE CUASES THE CUSOR TO BE POSITIONED AT X,Y. THE COORDINATES ; ARE PASSED AS FOLLOWS- ; ; X == LOB OF R0 ; Y == HOB OF R0 ; ; ; ALL REGISTERS ARE PRESERVED THROUGH THE ROUTINE. ; ; ADM.XY: SWAB R0 ; SWAP X/Y .PUSH R0 ; SAVE COORDINATES .OUT <#ESCOUT,#'=> ; TELL WISH TO POSITION MOVB (SP),R0 ; GET X COORDINATE ADD #40,R0 ; ADJUST TO ALPHA BIC #^C177,R0 ; ENSURE IN RANGE .OUT ; SEND OUT X COORDINATE ; MOV (SP),R0 ; GET COORDINATES SWAB R0 ; Y -> LOB ADD #40,R0 ; ADJUST TO ALPHA BIC #^C177,R0 ; ENSURE IN RANGE .OUT ; SEND OUT Y COORDINATE ; .POP R0 ; RESTORE SWAB R0 ; SWAP X/Y ; RETURN ; ALL DONE ; ; ; .END *