; FOR STANDAONE MSX IN DUAL MODE USE... .TITLE KBIOHT KB HANDLER FOR MSX .PSECT ;----- ; THIS IS A SPECIAL IO HANDLER TASK IN THAT IT DOES NOT USE ; THE STANDARD DOS DRIVER, BUT RATHER INCLUDES ITS OWN ; BASIC DRIVER. IN ADDITION, IT INCLUDES A SPECIAL ; LISTENER TO LOOK AT KEYBOARD INTERRUPTS BEFORE GIVING ; THEM UP TO THE DRIVER. THIS IS TO ALLOW CONTROL C KEYINS ; TO CLEAN UP AND GO BACK TO DOS. ;------ .GLOBL MX.IVS,MX.IOH,S.RRES,MX.PST ; DEFINE REGS R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; TTY CSR AND DBR ADDRESSES TKS=177560 TKB=177562 TPS=177564 TPB=177566 ; NOTE: WE TREAT KB AS TWO INDEPENDENT DEVICES. HENCE, EACH ; HAS ITS OWN LINK-BLOCK AND HANDLER TASK ENTRIES. ; KBI HANDLER TASK ; INCLUDES ITS OWN LINK BLOCK AND INITIALIZATION CODE.. .GLOBL KBIHT,KBIN ; LINK BLOCK + 0 KBIN: + KBIDDB ; POINT TO DRIVER TABLE .RAD50 / / .BYTE 1,0 .RAD50 /KBI/ ; AREA USED BY MXIOHT .=.+20 ; INTERNAL DDB CAUSE WE DON'T WANT TO USE SYSTEMS + 0,0,0,KBI ; DRIVER PTR KBIDDB: + 0 ; CALL ADDRESS + 0,0,0,0,0,0,0,0,0,0,0 + 0,0,0,0,0,0,0,0,0,0,0 ; STACK SPACE .=.+100 ; ---- CODE KBIHT: ;--- ENTRY FROM SCANNEER ON STARTUP .IF NDF,NODOS MOV #60,R1 ; IV ADDRESS MOV #MX.KBL,R2 ; ADDRES OF LISTNER JSR PC,MX.IVS ; SWAP IV STUFF MOV #KBIN,R0 ; SET UP CALL ON MXIOHT JSR PC,MX.IOH ; AND CALL UPON MXIOHT .ENDC .GLOBL MX.KBL,KBOINT ; KBO OUTPUT HANDLER TASK ENTRY ; INCLUDES MY OWN LINK-BLOCK .GLOBL KBOHT,KBOT ; LINK BLOCK +0 KBOT: + KBODDB ; POINTER TO DDB .RAD50 / / .BYTE 1,0 .RAD50 /KBO/ ; SPACE FOR MXIOHT .=.+20 ; INTERNAL DDB + 0,0,0,KBO KBODDB: + 0 + 0,0,0,0,0,0,0,0,0,0,0 + 0,0,0,0,0,0,0,0,0,0,0 ; STACK SPACE .=.+100 ;---- CODE FOLLOWS KBOHT: ; ENTRY POINT FROM SCANNER .IF NDF,NODOS MOV #64,R1 ; SET IV ADR MOV #KBOINT,R2 ; SET M]Y POINTER JSR PC,MX.IVS ; AND SWAP IVS STUFF MOV #KBOT,R0 ; SET LINK POINTER FOR MSX JSR PC,MX.IOH ; AND USE COMMON CODE .ENDC ; KEYBOARD LISTENER AND KBO INTERUPTS ; THIS CODE LOOKS AT INPUT INTERRUPTS AND DETERMINES ; IF ANY INPUT ACTIVIT] IS PRESENT. IF NOT, THE CHARAC]TER ; IS IGNORED WITH OUT ECHO. IF SO, IT IS SENT TO THE ; DRIVER. A SPECIAL CHECK IS MADE FOR THE CASE OF CONTROL-C ; WHICH WILL CASE A CLEANUP OF MSX AND GO TO DOS STUFF.. .GLOBL MX.KBL,MX.KIL ;---- MX.KBL: ; ENTRY ON INPUT INTERRUPT JSR R5,MX.PST ; POST THE INT .BYTE 200,1 ; WITH REG SAVES MOV @#TKB,R0 ; FETCH THE BYTE BIC #177600,R0 ; MASK JUNK BEQ KBLXIT ; IGNORE NULLS CMP #003,R0 ; IS IT CTRL-C ? BEQ CRASH ; YES, SKIP .IF NDF,NOCTLS ;IF NOT EXCLUDED... CMP #1,R0 ;CTRL A = ATTENTION!! ;(ACTIVATE TASK #N FOR INPUT!) BNE 1$ ;ELSE SKIP OVER IT INCB MX.SEV ;SET SIG EVENT INC ATTNEV ;AND SET EVENT VARIABLE FOR TASK TO AWAIT 1$: CMP #'T-100,R0 ;CONTROL-T MEANS START UP DEBUGGER. BNE 2$ ;ELSE SKIP ;FOR DDT STARTUP, RECALL THAT DDT IS NOT A TASK BUT PART OF ;THE EXECUTIVE. JUST JUMP TO IT TO START UP. ;FAKE IT UP TO APPEAR THAT NO KB INT. HAPPENED... JSR R5,S.RRES ;GET BACK REGS JSR PC,U.RSAV ;SAVE ANY CURRENT TASK CONTEXT CMP @#14,#D.BRK ;IS BPT LOCATION LOADED? BEQ 11$ ;YES, JUMP THERE JMP DDT ;NO, START AT HARD ENTRY OF DDT 11$: MOV #1,D.S ;YES, SET SINGLE STEP FLAG MOV #1,D.CT ;SET PROCEED COUNT TO 1 INC D.FFPC ;FLAG HARD INT. MODE ALSO JMP D.BRK ;AND MAKE DDT THINK IT GOT STEP STOP. ;(REQUIRES RESET LATER BUT WHO CARES?) 2$: .GLOBL ATTNEV .ENDC TST KI.BSY ; IS INPUT BUSY? BEQ KBLXIT ; NO, FORGET THIS ONE ; HERE WE POST THE INTERRUPT AND USE COMMON CODE IN DRIVER JMP KI.INT ; AND MERGE WITH MODIFIED DRIVER ; IGNORE THIS INTERRUPT KBLXIT: JSR R5,S.RRES ; RESTORE SAVED REGS RTI ; AND EXIT ; CRASH THE SYSTEM HERE CRASH: RESET ; THIS SHOULD DO IT FOLKS. ; HALT JMP MX.KIL ; OFF TO DOS VESTORATION ; INTERRUPT ROUTINE FOR OUTPUT KBOINT: ; GET HERE ON INTERRUPT JSR R5,MX.PST ; POST THE THING .BYTE 200,1 JMP KO.INT ; AND USER DRIVER ; KBIO BISON MSX DRIVER (AS MODIFIED FOR MSX ) ; PN-23 KEITH RICH ; 12-JUL-72 ORIGINAL .GLOBL KBI .GLOBL KBO PS = -2 CR = 15 ;CARRIAGE RETURN LF = 12 ;LINE FEED FF = 14 ;FORM FEED VT = 13 ;VERTICAL TAB BS = 134 ;BACK SLASH UA = 136 ;UP ARROW RO = 177 ;RUBOUT CU = 25 ;CONTROL-U CZ = 32 ;CONTROL-Z KBI: .WORD 0 .BYTE 024 ;ASCII,INPUT .BYTE 0 .BYTE 2 ;STD BUF = 32 WRDS .BYTE 0 ; NOTE: WE DON'T USE INIT .BYTE 200 ;INP INT PRTY = 4 .BYTE 0 ;NO OPEN .BYTE KI.TFR-KBI ;INPUT TRANSFER .BYTE 0 ;NO CLOSE .BYTE 0 ;NO SPECIAL FUNCTIONS .BYTE 0 .RAD50 /KBI/ KBO: .WORD 0 .BYTE 022 ; ASCII.OUTPUT .BYTE 0 .BYTE 2 ;STD BUF = 32 WRDS .BYTE 0 ; WE DON'T USE INTERRUPT OFFSET .BYTE 200 ;OUT INT PRTY = 4 .BYTE 0 ;NO OPEN .BYTE KO.TFR-KBO ;OUTPUT TRANSFER .BYTE 0 ;NO CLOSE .BYTE 0 ;NO SPECIAL FUNCTIONS .BYTE 0 .RAD50 /KBO/ ; CODE FOLLOWS KI.TFR: BIS #240,@#PS ;SET PRI5 IN CASE SOME CLOWN SET KB THAT HIGH ADD #6,R0 MOV PC,R1 ADD #KI.BFP-.,R1 MOV (R0)+,R2 ;SAVE MOV R2,(R1)+ ; BUF PTR MOV (R0)+,R3 ;GET NEG WRD CNT .IIF DF,IO$WDS, ASL R3 ; NEG BYTE CNT NEG R3 ; POS BYTE CNT MOV R3,(R1)+ ; SAVE IT BIC #140000,(R0)+ ;CLR ERR,EOF MOV (R0)+,(R1)+ ;SAVE DONE RTN ADR MOV R0,(R1)+ ;SAVE PTR TO WRDS NOT XFERRED CLR (R1)+ ;CLR CUR BYTE CNT .IF DF,PRMT.. ;IF "PRMT.." IS DEFINED, FIRST CHARACTER IN THE USER'S INPUT BUFFER ;AT THE QTRAN BECOMES AN INPUT PROMPT SENT OUT BY THE HANDLER. THIS ;MAY BE HELPFUL WHERE THE CONSOLE IS BEING SHARED BY SEVERAL ;PROCESSES. MOV R0,-(SP) MOV KI.BFP,-(SP) ;GET PROMPT CHARACTER OUT OF USER BUFFER MOV R2,KI.BFP ;R2 POINTS AT IT... JSR PC,KI.GET ;LOAD CHAR INTO R0 FROM WHEREVER IT IS MOVB R0,@R1 ;SAVE THE PROMPT CHARACTER (1ST CHAR IN BUFFER) MOV (SP)+,KI.BFP ;RESTORE THINGS AGAIN NEXT MOV (SP)+,R0 ; MOVB (R2),(R1) ;SAVE INPUT FLAG CHR .ENDC ; CLRB (R2)+ ;CLEAR ; DEC R3 ; THE ; BLT .-4 ; BUFFER MOV KI.BFP,-(SP) MOV R0,-(SP) 1$: MOV R2,KI.BFP INC R2 CLR R0 JSR PC,KI.PUT DEC R3 ;CLEAR ALL BUFFER BGT 1$ ;TILL DONE MOV (SP)+,R0 MOV (SP)+,KI.BFP MOV @#PS,-(SP) ;SAVE PRTY BIS #340,@#PS ;PRTY = 7 TST KO.BSY ;IF OUTPUT BUSY BNE KI.TFW ; THEN JUMP INC KI.BSY ;SET INPUT BUSY MOV (SP)+,@#PS ;RESTORE PRIORITY BIS #100,@#TKS ;ENABLE INPUT INTERRUPT RTS PC ;EXIT TO CALLER KI.TFW: INC KI.REQ ;SET INPUT REQUEST MOV (SP)+,@#PS ;RESTORE PRIORITY RTS PC ;EXIT TO CALLER KO.TFR: BIS #240,@#PS ;SET PRI5 IN CASE SOME CLOWN SET KB THAT HIGH ADD #6,R0 MOV PC,R1 ADD #KO.BFP-.,R1 MOV (R0)+,(R1)+ ;SAVE BUFFER POINTER MOV (R0)+,(R1) ;GET NEG WRD CNT .IIF DF,IO$WDS, ASL (R1) ; NEG BYTE CNT NEG (R1)+ ; POS BYTE CNT BIC #140000,(R0)+ ;CLR ERR,EOF MOV (R0)+,(R1)+ ;SAVE DONE RTN ADR MOV @#PS,-(SP) ;SAVE PRTY BIS #340,@#PS ;PRTY = 7 TST KI.BSY ;IF INPUT BUSY BNE KO.TFW ; THEN JUMP KO.OAW: INC KO.BSY ;SET OUTPUT BUSY MOV (SP)+,@#PS ;RESTORE PRIORITY BIS #100,@#TPS ;ENABLE OUTPUT INTERRUPT RTS PC ;EXIT TO CALLER KO.TFW: TST KI.ABC ;IF NO INP CHARS YET BEQ KO.OOK ; THEN JUMP INC KO.REQ ;SET OUTPUT REQUEST MOV (SP)+,@#PS ;RESTORE PRIORITY RTS PC ;EXIT TO CALLER KO.OOK: BIC #100,@#TKS ;DISABLE INPUT INTERRUPT CLR KI.BSY ;CLR INP BSY INC KI.REQ ;SET INP REQ BR KO.OAW ;GO START OUTPUT ;---- INTERRUPTS GET HERE (AFTER POSTING) KI.INT: ; BIC #100,@#TKS ;DISABLE INP INT CMPB R0,#RO ;JUMP BEQ KI.IRO ; IF RUBOUT TST KI.ROS ;JUMP IF PREV CHAR BEQ KI.NBS ; NOT RUBOUT MOV R0,KI.ECH ;SAVE CHAR MOV #BS,R0 ;ECHO JSR PC,KI.PCH ; BACK SLASH MOV KI.ECH,R0 ;RSTR CHAR CLR KI.ROS ;CLR RUBOUT SWITCH KI.NBS: CMPB R0,#CZ ;JUMP IF BEQ KI.ICZ ; CONTROL-Z TST KI.ABC ;JUMP IF NOT BNE KI.NPE ; FIRST CHARACTER INC KI.ABC ;BUMP BYTE CNT MOV R0,KI.ECH ;SAVE CHAR .IF DF,PRMT.. ;(IF USING PROMPT FEATURE... MOV KI.PMT,R0 ;GET INPUT FLAG CHAR BEQ .+6 ;JUMP IF NUL JSR PC,KI.PCH ;ECHO FLAG CHAR .ENDC MOV KI.ECH,R0 ;RSTR CHAR KI.NPE: JSR PC,KI.PCH ;ECHO CHAR CMPB R0,#CU ;JUMP IF BEQ KI.ICU ; CONTROL-U ; MOVB R0,@KI.BFP ;STORE CHAR IN BUF MOV R0,-(SP) JSR PC,KI.PUT ;STORE CHAR IN BUF MOV (SP)+,R0 INC KI.BFP ;BUMP BUF PTR INC KI.ABC ;BUMP BYTE CNT CMP KI.ABC,KI.BBC ;JUMP IF BGT KI.IDN ; BUF OVFL CMPB R0,#CR ;JUMP IF BEQ KI.ICR ; CARRIAGE RETURN CMPB R0,#LF ;JUMP IF BEQ KI.ILF ; LINE FEED CMPB R0,#FF ;JUMP IF BEQ KI.ICL ; FORM FEED CMPB R0,#VT ;JUMP IF BEQ KI.ICL ; VERTICAL TAB KI.INX: BIS #101,@#TKS ;ENABLE INPUT INTERRUPT JSR R5,S.RRES ; RESTORE USERS REGS RTI ;EXIT KI.IDN: MOV #CR,R0 ;ECHO JSR PC,KI.PCH ; CARRIAGE RETURN MOV #LF,R0 ;ECHO JSR PC,KI.PCH ; LINE FEED KI.IEX: MOV KI.RTN,R1 ;GET DONE RTN ADR CLR KI.BSY ;CLR INP BSY TST KO.REQ ;JUMP IF BEQ KI.IXT ; NO OUTPUT REQ CLR KO.REQ ;CLR OUT REQ INC KO.BSY ;SET OUT BSY BIS #100,@#TPS ;ENABLE OUTPUT INTERRUPT KI.IXT: MOV KBI,R0 ; SET ADDRESS OF DDB MOV R1,PC ; AND OFF TO HANDLER KI.ICZ: MOV KI.WNT,R0 ;SET TST -(R0) ; EOF BIS #040000,-(R0) ; BIT KI.ICL: MOV #LF,R0 ;ECHO JSR PC,KI.PCH ; LINE FEED KI.ILF: MOV #CR,R0 ;ECHO JSR PC,KI.PCH ; CARRIAGE RETURN MOV KI.ABC,R0 ;CURRENT BYTE CNT SUB KI.BBC,R0 ;MAXIMUM BYTE CNT .IIF DF,IO$WDS, ASR R0 ;NEG CNT OF MOV R0,@KI.WNT ; WRDS NOT XFERRED BR KI.IEX ;GET OUT OF HERE KI.ICR: MOVB #LF,R0 ;CARRIAGE RETURN BR KI.NBS ; IMPLIES LINE FEED KI.IRO: TST KI.ABC ;IF BUFFER BNE KI.INU ; IS EMPTY INC KI.ABC ; THEN ECHO BR KI.ICU ; CR,LF KI.INU: TST KI.ROS ;IF THIS BNE KI.INF ; IS FIRST INC KI.ROS ; RUBOUT MOV #BS,R0 ; THEN ECHO JSR PC,KI.PCH ; BACK SLASH KI.INF: DEC KI.ABC ;BUMP BYTE CNT DOWN DEC KI.BFP ;BUMP BUF PTR DOWN JSR PC,KI.GET ;GET CHAR FOR ECHO ; MOVB @KI.BFP,R0 ;ECHO JSR PC,KI.PCH ; DELETED CHAR ; CLRB @KI.BFP ;PUT NUL IN BUF MOV R0,-(SP) CLR R0 JSR PC,KI.PUT ;PUT NULL IN BUFFER MOV (SP)+,R0 CMP KI.ABC,#1 ;IF BUF BNE KI.INX ; NOW EMPTY MOV #BS,R0 ; THEN ECHO JSR PC,KI.PCH ; BACK SLASH CLR KI.ROS ;CLR RUBOUT SWITCH KI.ICU: MOV #CR,R0 ;ECHO JSR PC,KI.PCH ; CARRIAGE RETURN MOV #LF,R0 ;ECHO JSR PC,KI.PCH ; LINE FEED DEC KI.ABC ;JUMP IF BEQ KI.ICX ; BUF ALREADY EMPTY MOV KI.BFP,R0 ;CUR BUF PTR MOV KI.ABC,R1 ;CUR BYTE CNT 1$: DEC R0 MOV KI.BFP,-(SP) MOV R0,KI.BFP MOV R0,-(SP) CLR R0 JSR PC,KI.PUT ;CLEAR BUFFER MOV (SP)+,R0 MOV (SP)+,KI.BFP ; CLRB -(R0) ;CLEAR DEC R1 ; THE BGT 1$ ; BUFFER MOV R0,KI.BFP ;SET BUF PTR BACK AT START CLR KI.ABC ;SET CUR BYTE CNT TO ZERO KI.ICX: TST KO.REQ ;JUMP IF ; BEQ KI.INX ; NO OUTPUT REQUEST BNE 1$ JMP KI.INX 1$: CLR KI.BSY ;CLR INP BSY INC KI.REQ ;SET INP REQ CLR KO.REQ ;CLR OUT REQ INC KO.BSY ;SET OUT BSY BR KO.INX ; EXIT KI.PCH: MOV R0,KI.NCH ;SAVE CHAR TO BE ECHOED MOV (SP)+,KI.RAD ;SAVE TEMP RTN ADR INC KI.EFL ;SET ECHO FLAG BR KO.INX ;AWAIT RDY TO OUTPUT KI.EDN: CLR KI.EFL ;CLR ECHO FLAG MOV KI.NCH,R0 ;RSTR CHAR JSR PC,KO.PCH ;OUTPUT CHAR MOV KI.RAD,PC ;RETURN ;------ INTERRUPTS GET HERE (AFTER POSINT) KO.INT: ; BIC #100,@#TPS ;DISABLE OUTPUT INTERRUPT TST KO.EFL ;JUMP IF WE'VE JUST DONE BNE KO.EDN ; THE UP ARROW OF A CTL CHAR TST KI.EFL ;JUMP IF BNE KI.EDN ; INPUT ECHO ; MOVB @KO.BFP,R0 ;FETCH NEXT OUTPUT CHAR FROM OUT BUF JSR PC,KO.GET ;R0 GETS CHAR AT KO.BFP JSR PC,KO.PCH ; AND PRINT IT INC KO.BFP ;BUMP BUF PTR DEC KO.BBC ;BUMP BYTE CNT BLE KO.IDN ;JUMP IF DONE KO.INX: BIS #100,@#TPS ;ENABLE OUTPUT INTERRUPT JSR R5,S.RRES ; RESTORE USER REGS RTI ;EXIT KO.IDN: MOV KO.RTN,R1 ;GET DONE RTN ADR CLR KO.BSY ;CLR OUT BSY TST KI.REQ ;JUMP IF BEQ KO.IXT ; NO INPUT REQ CLR KI.REQ ;CLR INP REQ INC KI.BSY ;SET INP BSY BIS #101,@#TKS ;ENABLE INP INT KO.IXT: MOV KBO,R0 ; SE DDB ADDRESS MOV R1,PC ; AND OFF TO HANDLER KO.PCH: MOV R0,-(SP) ;SAVE OUTPUT CHAR BEQ KO.OEX ;EXIT IF NUL CMPB R0,#CR ;PRINT IT IF BEQ KO.OCH ; CARRIAGE RETURN CMPB R0,#LF ;PRINT IT IF BEQ KO.OCH ; LINE FEED CMPB R0,#032 ;PRINT IT BGT KO.OCH ; IF NOT CTL CHAR MOV (SP)+,KO.NCH ;SAVE CTL CHAR MOV (SP)+,KO.RAD ;SAVE TEMP RTN ADR MOV #UA,R0 ;ECHO JSR PC,KO.PCH ; UP ARROW INC KO.EFL ;SET UP ARROW FLAG BR KO.INX ;AWAIT RDY TO OUTPUT KO.EDN: CLR KO.EFL ;CLR UP ARROW FLAG MOV KO.NCH,R0 ;RSTR CTL CHR MOV KO.RAD,-(SP) ;RSTR TEMP RTN ADR MOV R0,-(SP) ;SAVE CTL CHAR ADD #100,R0 ;COMPUTE CORRESPONDING CHAR KO.OCH: INC @#TPS MOVB R0,@#TPB ;WRITE THE CHARACTER KO.OEX: MOV (SP)+,R0 ;RSTR THE ORIGINAL CHARACTER RTS PC ;RETURN KO.MAP: JSR R5,S.RSAV MOV KBO,R0 ;DDB ADDR MOV KO.BFP,R1 ;OUTPUT BUFFER ADDR BR KB.CMM ;DO COMMON MAP OF APR6 ;KI.MAP -- MAP KERNEL APR6 TO AREA ADDRESSED BY BUFFER POINTED TO BY R1 ;WITH DDB IN R0. PRESUMES MSX SAVED TCB ADDR IN DDB. KI.MAP: JSR R5,S.RSAV ;SAVE USER REGS FOR MAPPING MOV KBI,R0 ;GET DDB MOV KI.BFP,R1 ;AND ADDR KB.CMM: MOV 20(R0),R2 ;GET TCB ADDR OF TASK MOV R1,R3 ;SAVE ADDR ASH #-12.,R1 ;MASK OFF APR BITS BIC #^C16,R1 ;MAKE A WORD OFFSET ADD #TCBAPR,R2 ;POINT AT SAVED APRS TCBAPR=34 ADD R1,R2 ;POINT AT CORRECT USER APR MOV R3,R1 ;GET BACK ADDR ASH #-6,R1 ;REMOVE OFFSET BITS IN BLOCK BIC #176000,R1 ;ALSO REMOVE ANY SIGN EXTENSIONS! ADD @R2,R1 ;ADD USER'S APR BASE MOV R1,@#KAPR6 ;BASH KERNEL APR6 JSR R5,S.RRES ;GET BACK REGS WE STARTED WITH RTS PC ;GO TO CALLER ; ;KI.GET -- LOAD R0 WITH VALUE AT KI.BFP ; KI.GET: MOV @#PS,-(SP) ;SAVE OLD PSW MOVB #340,@#PS ;DISALLOW INTS MOV @#KAPR6,-(SP) ;SAVE KNL APR6 TST KBIDDB+20 ;SEE IF THERE WAS A TASK BEQ 1$ ;IF NOT, SKIP MAPPING JSR PC,KI.MAP ;MAP IT TO INPUT BUFFER MOV KI.BFP,R0 ;GET THE ADDRESS BIC #^C77,R0 ;MASK OFFSET BIS #140000,R0 ;PUT IN APR6 BITS BR 2$ 1$: MOV KI.BFP,R0 ;GET UNMAPPED POINTER 2$: MOVB @R0,R0 ;GET THE BYTE MOV (SP)+,@#KAPR6 ;RESTORE KNL APR6 MOV (SP)+,@#PS ;RESTORE PSW RTS PC ; ;KI.PUT -- PUT R0 INTO BYTE AT KI.BFP KI.PUT: MOV @#PS,-(SP) ;SAVE OLD PSW MOVB #340,@#PS ;DISALLOW INTS MOV @#KAPR6,-(SP) ;SAVE KNL APR6 TST KBIDDB+20 ;TEST IF TSK THERE BEQ 1$ ;IF NOT SKIP MAP JSR PC,KI.MAP ;MAP IT TO INPUT BUFFER 1$: MOV R0,-(SP) ;SAVE R0 MOV KI.BFP,R0 ;GET THE ADDRESS TST KBIDDB+20 BEQ 2$ ;SKIP IF NO MAP BIC #^C77,R0 ;MASK OFFSET BIS #140000,R0 ;PUT IN APR6 BITS 2$: MOVB (SP)+,@R0 ;STASH THE BYTE MOV (SP)+,@#KAPR6 ;RESTORE KNL APR6 MOV (SP)+,@#PS ;RESTORE PSW RTS PC ; ;KO.GET -- GET BYTE TO R0 THAT IS IN KO.BFP KO.GET: MOV @#PS,-(SP) ;SAVE OLD PSW MOVB #340,@#PS ;DISALLOW INTS MOV @#KAPR6,-(SP) ;SAVE KNL APR6 TST KBODDB+20 ;SEE IF TSK THERE BEQ 1$ ;NO, KNL MODE JSR PC,KO.MAP ;MAP IT TO OUTPUT BUFFER 1$: MOV KO.BFP,R0 ;GET THE ADDRESS TST KBODDB+20 BEQ 2$ BIC #^C77,R0 ;MASK OFFSET BIS #140000,R0 ;PUT IN APR6 BITS 2$: MOVB @R0,R0 ;GET THE BYTE MOV (SP)+,@#KAPR6 ;RESTORE KNL APR6 MOV (SP)+,@#PS ;RESTORE PSW RTS PC ; ;KO.PUT -- PUT R0 INTO BYTE AT KO.BFP KO.PUT: MOV @#PS,-(SP) ;SAVE OLD PSW MOVB #340,@#PS ;DISALLOW INTS MOV @#KAPR6,-(SP) ;SAVE KNL APR6 TST KBODDB+20 ;TEST TSK BEQ 1$ ;SKIP IF NONE JSR PC,KO.MAP ;MAP IT TO OUTPUT BUFFER 1$: MOV R0,-(SP) ;SAVE R0 MOV KO.BFP,R0 ;GET THE ADDRESS TST KBODDB+20 BEQ 2$ ;SKIP IF NO TSK BIC #^C77,R0 ;MASK OFFSET BIS #140000,R0 ;PUT IN APR6 BITS 2$: MOVB (SP)+,@R0 ;STASH THE BYTE MOV (SP)+,@#KAPR6 ;RESTORE KNL APR6 MOV (SP)+,@#PS ;RESTORE PSW RTS PC ; DATA AND FLAG AREAS KI.BFP: .WORD 0 ;INPUT BUFFER POINTER KI.BBC: .WORD 0 ;INPUT MAXIMUM BYTE COUNT KI.RTN: .WORD 0 ;INPUT DONE RETURN ADDRESS KI.WNT: .WORD 0 ;INPUT PTR TO WRDS NOT XFERRED WRD KI.ABC: .WORD 0 ;INPUT CURRENT BYTE COUNT KI.PMT: .WORD 0 ;INPUT FLAG CHARACTER KI.BSY: .WORD 0 ;INPUT BUSY FLAG KI.REQ: .WORD 0 ;INPUT REQUEST FLAG KI.ECH: .WORD 0 ;INPUT ECHO CHARACTER KI.NCH: .WORD 0 ;INPUT TEMPORARY CHARACTER KI.RAD: .WORD 0 ; INPUT TEMP RETURN ADDRESS KI.EFL: .WORD 0 ;INPUT ECHO FLAG KI.ROS: .WORD 0 ;INPUT RUBOUT SWITCH KO.BFP: .WORD 0 ;OUTPUT BUFFER POINTER KO.BBC: .WORD 0 ;OUTPUT BYTE COUNT KO.RTN: .WORD 0 ;OUTPUT DONE RETURN ADDRESS KO.BSY: .WORD 0 ;OUTPUT BUSY FLAG KO.REQ: .WORD 0 ;OUTPUT REQUEST FLAG KO.NCH: .WORD 0 ;OUTPUT TEMPORARY CHARACTER KO.RAD: .WORD 0 ;OUTPUT TEMP RETURN ADDRESS KO.EFL: .WORD 0 ; OUTPUT UP ARROW FLAG .END