.TITLE PSDRV .IDENT /V002H/ ; EVANS & SUTHERLAND COMPUTER CORPORATION ALL RIGHTS RESERVED ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; THIS MODULE IS THE RSX-11M PICTURE SYSTEM DEVICE DRIVER. ; THIS DRIVER IS A NON-CONVENTIONAL DEVICE DRIVER SIMILAR ; TO THE UDC DEVICE DRIVER IN THAT I/O IS NOT QUEUED FOR ; THE DRIVER; RATHER THE DRIVER IS CALLED WHEN THE I/O OPER- ; ATION IS INITIATED BY THE USER PROGRAM. ; ; ALL DEVICE DEPENDENT PARAMETERS ARE STORED IN THE UNIT ; CONTROL BLOCK AND ARE ACCESSED BY MEANS OF INDEXING INTO ; THE CONTROL BLOCK. IN THIS WAY, THIS DRIVER MAY BE EASILY ; MODIFIED TO BE A MULTIPLE PICTURE SYSTEM DEVICE DRIVER. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;REVISION LIST;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; RV DATE BY REASON FOR CHANGE ; ; -- -------- ---- ------------------------------------------------; ; 2A 10/01/75 MM INITIAL RELEASE OF V002 SOFTWARE ; ; 2B 11/21/75 MM MODIFIED TO USE THE CYCLE BIT TO RESTART DMA ; ; TRANSFERS AS ONE IS ATTEMPTED ACROSS A 32K WORD ; ; BOUNDARY. NECESSARY ONLY IN A MAPPED SYSTEM. ; ; 2C 04/27/76 MM MODIFIED TO CLEAR DRBA BEFORE DMA TRANSFER IS ; ; RESTARTED ACROSS A 32K WORD BOUNDARY. THIS WAS ; ; INADVERTANTLY LEFT OUT OF REV 2B. ; ; 2D 04/28/76 MM MODIFICATION OF RTC INTERRUPT HANDLER AND THE ; ; NUFRAM HANDLER TO SUPPORT SEGMENTATION. ; ; 2E 07/20/76 BSM ADDITION OF DMA INITIATE AND ACTIVITY TEST ; ; 2F 07/29/76 BSM ADDITION OF REFRESH BUFFER WRITE POINTER STORE ; ; AND TABLET READ ROUTINES. ; ; 2G 06/16/77 DPR CHANGE SYMBOLIC OFFSETS FOR RSX-11M V3 ; ; 2H 08/17/77 GAT ADD CANCEL ENTRY CODE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .MCALL DEVDF$,HWDDF$,PKTDF$,TCBDF$ .MCALL FILIO$,IOERR$,CALL,CALLR,RETURN DEVDF$ ;DEFINE DEVICE CONTROL BLOCK OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS FILIO$ ;DEFINE STANDARD I/O FUNCTIONS IOERR$ ;DEFINE STANDARD I/O STATUS CODES ; UNIT CONTROL BLOCK OFFSETS P$$S11 =1 ;ONE PICTURE PROCESSOR U. =U.CNT+2 U.RFV =U.+0 U.RFC =U.+1 U.UDV =U.+2 U.UDC =U.+3 U.BFS =U.+4 U.BWS =U.+5 U.PPST =U.+6 U.SSR =U.+10 U.SRSR =U.+12 U.SRWC =U.+14 U.SRBA =U.+16 U.SRST =U.+20 U.RRTC =U.+22 U.RBWP =U.+24 U.ICL =U.+30 U.IFM =U.+34 U.IX =U.+40 U.IY =U.+44 U.IPN =U.+50 U.IXC =U.+54 U.IYC =U.+60 U.IPNC =U.+64 U.IVW =U.+70 U.PS =U.+74 U.DRWC =U.+76 U.DRBA =U.DRWC+2 U.DRST =U.DRWC+4 U.DRDB =U.DRWC+6 U.RTC =U.DRWC+10 U.SR =U.DRWC+12 U.SRH =U.DRWC+14 U.PSR =U.DRWC+16 U.PSRW =U.DRWC+20 U.RSR =U.DRWC+22 U.TPN =U.DRWC+24 U.TBX =U.DRWC+26 U.TBY =U.DRWC+30 U.TPN2 =U.DRWC+30 U.TBX2 =U.DRWC+34 U.TBY2 =U.DRWC+36 U.ADCS =U.DRWC+40 U.ADDB =U.DRWC+42 U.FL1 =U.DRWC+44 U.FS1 =U.DRWC+46 U.FL2 =U.DRWC+50 U.FS2 =U.DRWC+52 U.LOR =U.DRWC+54 IO.SNF =5*256. ;SET NEW FRAME I/O FUNCTION CODE IO.CTB =6*256. ;CONNECT TABLET BUFFER I/O FUNCTION CODE IO.CCB =7*256. ;CONNECT CURSOR BUFFER I/O FUNCTION CODE IO.DTB =10*256. ;DETACH BUFFER I/O FUNCTION CODE IE.PSC =-30 ;PICTURE SYSTEM BUFFER CONNECT ERROR T.NDSE =2 I.IX =I.PRM ;I/O PACKET OFFSETS I.IY =I.IX+2 I.IPN =I.IX+4 I.IVW =I.IX+6 I.RFRT =I.PRM I.UDRT =I.RFRT+2 I.ICL =I.RFRT+4 I.IFM =I.RFRT+6 I.RBWP =I.RFRT+10 TABMSK =174000 ;TABLET BIT MASK TABADJ =1050 ;TABLET ADJUSTMENT FOR ZERO CENTERING TABMAX =777 ;TABLET MAX (10 BITS) TABRPT =6 ;REPEAT COUNT FOR + OR - 32K CNTBL: .BLKW P$$S11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK .IF GT P$$S11-1 TEMP: .BLKW 1 .IFTF .PAGE .SBTTL DRIVER DISPATCH TABLE $PSTBL:: .WORD PSCHK ;DEVICE INITIATOR ENTRY POINT .WORD PSCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD PSOUT ;DEVICE TIMEOUT ENTRY POINT .WORD PSPWF ;POWERFAIL ENTRY POINT .PAGE .SBTTL I/O PARAMETER CHECK .ENABL LSB ;+ ; **-PSCHK-PICTURE SYSTEM INPUT/OUTPUT PARAMETER CHECKING ROUTINE ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS RECEIVED FOR THE PICTURE SYSTEM. PICTURE SYSTEM ; I/O REQUESTS CONTAIN DEVICE DEPENDENT INFORMATION THAT MUST BE ; CHECKED IN THE CONTEXT OF THE ISSUING TASK. THEREFORE THE I/O ; REQUEST IS NOT QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK (=I/O LISTHEAD ADDRESS). ; R5=ADDRESS OF THE UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; DEPENDENT UPON FUNCTION TO BE PERFORMED. ; ; PICTURE SYSTEM FUNCTION INDEPENDENT I/O PACKET FORMAT: ; ; WD.00 -- I/O QUEUE THREAD WORD. ; WD.01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD.02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD.03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD.04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER. ; WD.05 -- I/O FUNCTION CODE. ; WD.06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD.07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD.10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD.11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ;- PSCHK: MOVB I.FCN+1(R1),R0 ;GET I/O FUNCTION CODE SUB #3,R0 ;ADJUST FOR TABLE INDEX BLT 11$ ;IF LT ILLEGAL FUNCTION CODE ASL R0 ;ADJUST FOR WORD INDEX CMP R0,#12 ;ILLEGAL FUNCTION CODE? BGT 11$ ;IF GT YES MOV R1,R3 ;SET I/O PACKET ADDRESS FOR $IOFIN JMP @10$(R0) ; BRANCH TO SERVICE ROUTINE VIA TABLE 10$: .WORD 20$ ;ATTACH .WORD 40$ ;DETACH .WORD 30$ ;SET NEW FRAME .WORD 50$ ;CONNECT TABLET BUFFER .WORD 60$ ;CONNECT CURSOR BUFFER .WORD 70$ ;DISCONNECT TABLET OR CURSOR BUFFER 11$: MOV #IE.IFC,R0 ;SET ILLEGAL FUNCTION CODE JMP 46$ ;AND CONTINUE .PAGE .SBTTL ATTACH FUNCTION ;+ ; ATTACH FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD.12 -- REFRESH RATE (1-16.) ; WD.13 -- UPDATE RATE (0-256.) ; WD.14 -- VIRTUAL ADDRESS OF USER "ICLOCK". ; WD.15 -- VIRTUAL ADDRESS OF USER "IFRMCT". ; WD.16 -- REFRESH BUFFER SEGMENT START ADDRESS. ; WD.17 -- NOT USED. ; WD.20 -- NOT USED. ;- 20$: TST U.ATT(R5) ;DEVICE ALREADY ATTACHED? BEQ 21$ ;NO CMP U.ATT(R5),I.TCB(R1) ;SAME TASK? BEQ 21$ ;YES, OK MOV #IE.DAA,R0 ;NO, RETURN ERROR JMP 46$ ;AND EXIT 21$: BIS #400,@U.RTC(R5) ;MASTER CLEAR THE P.S. .IFT MOV U.SCB(R5),R0 ;GET SCB ADDRESS MOVB S.STS(R0),R3 ;SET CONTROLLER INDEX .IFF CLR R3 ;INIT CONTROLLER INDEX .IFTF MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB MOVB I.RFRT(R1),U.RFC(R5) ;SET REFRESH RATE MOVB U.RFC(R5),U.RFV(R5) ;AND INIT VARIABLE MOVB I.UDRT(R1),U.UDC(R5) ;SET UPDATE RATE MOVB U.UDC(R5),U.UDV(R5) ;AND INIT VARIABLE MOV I.RBWP(R1),U.RBWP(R5) ;SET INITIAL RBWP CLR U.PSRW(R5) ;INIT PSEUDO SR WORD CLR U.BFS(R5) ;INIT BUFFER STATUS CLR U.PPST(R5) ;INIT PP SAVE STATUS MOVB #77,U.RRTC(R5) ;INIT REFRESH INTERVAL CLR U.ICL+2(R5) ;RESET "ICLOCK" ADDRESS CLR U.IFM+2(R5) ;RESET "IFRMCT" ADDRESS MOV I.TCB(R1),R3 ;GET TCB ADDRESS OF REQUEST TASK MOV R1,-(SP) ;SAVE R1 MOV #PPBF,R2 ;SET ADDRESS OF PP BUFFER WORDS JSR PC,MMAP ;SET THE PHYSICAL ADDRESS OF PPBUF MOV #CSBF,R2 ;SET ADDRESS OF CLIP STORE BUFFER JSR PC,MMAP ;SET THE PHYSICAL ADDRESS OF CSBUF MOV #CURBF,R2 ;SET ADDRESS OF CUR BUFFER WORDS JSR PC,MMAP ;SET THE PHYSICAL ADDRESS OF CURBUF MOV #VWBF,R2 ;SET ADDRESS OF VIEWPORT BUFFER JSR PC,MMAP ;SET THE PHYSICAL ADDRESS OF VWLBH MOV #DRWBF,R2 ;SET ADDRESS OF DRW BUFFER WORDS JSR PC,MMAP ;SET THE PHYSICAL ADDRESS OF DRWBUF BIT #T2.CHK!T2.FXD,T.ST2(R3) ;TASK FIXED OR NOT CHECKPOINTABLE? DPR BEQ 29$ ;IF EQ NO...DON'T CONNECT CLOCKING VARIABLES MOV (SP),R1 ;RESTORE VALUE OF R1 MOV I.TCB(R1),R0 ;GET THE TCB ADDRESS INCB T.IOC(R0) ;BIAS THE I/O COUNT MOV I.ICL(R1),R0 ;SET "ICLOCK" VIRTUAL ADDRESS MOV I.IFM(R1),-(SP) ;SAVE "IFRMCT" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.ICL(R5) ;SAVE "ICLOCK" MOV R2,U.ICL+2(R5) ; PHYSICAL ADDRESS MOV (SP)+,R0 ;SET "IFRMCT" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IFM(R5) ;SAVE "IFRMCT" MOV R2,U.IFM+2(R5) ; PHYSICAL ADDRESS 29$: JSR PC,NULLST ;OUTPUT A NULL STATUS COMMAND MOV (SP)+,R1 ;RESTORE R1 BISB #4,@U.SRH(R5) ;SET TO SWAP BUFFERS BICB #200,@U.SRH(R5) ;AND DO 1 REFRESH MOV #77,@U.RTC(R5) ;START THE RTC ;AND FALL INTO NEW FRAME .PAGE .SBTTL SET NEW FRAME FUNCTION 30$: MOV R4,R0 ;SET ADDRESS OF I/O LISTHEAD ;R1 = ADDRESS OF I/O PACKET CALL $QINSP ;INSERT THE I/O PACKET IN REQUEST QUEUE ;+ ; **-PSINI-PICTURE SYSTEM "NEW FRAME" INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE SET NEW FRAME FUNCTION AFTER THE ; I/O PACKET HAS BEEN INSERTED IN THE I/O QUEUE (BY $QINSP) OR AFTER ; A NEWFRAME I/O OPERATION HAS BEEN COMPLETED TO PROPOGATE THE ; OPERATION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY ; THEN AN ATTEMPT IS MADE TO DEQUE THE NEXT I/O REQUEST, ELSE A ; RETURN TO THE CALLER IS EXECUTED. IF THE DEQUE ATTEMP IS SUCCESS- ; FUL, THEN THE NEXT I/O OPERATION IS INITIATED. A RETURN TO THE ; CALLER IS THEN EXECUTED. ;- PSINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS 31$ ;IF CS CONTROLLER BUSY OR NO REQUEST ;+ ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT ; ; R1=ADDRESS OF THE I/O REQUEST PACKET ; R2=PHYSICAL UNIT # OF THE REQUEST UCB ; R3=CONTROLLER INDEX ; R4=ADDRESS OF THE STATUS CONTROL BLOCK ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ; ; P.S. I/O REQUEST PACKET FORMAT: ; ; WD.00 -- I/O QUEUE THREAD WORD. ; WD.01 -- REQUEST PRIORITY, EVENT FLAG NUMBER ; WD.02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK ; WD.03 -- POINTER TO SECOND LUN WORD IN TASK HEADER ; WD.04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER ; WD.05 -- I/O FUNCTION CODE ; WD.06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD.07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD.10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD.11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ;- ;+ ; SET "NEW FRAME" FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; ; WD.12 -- NOT USED. ; WD.13 -- NOT USED. ; WD.14 -- NOT USED. ; WD.15 -- NOT USED. ; WD.16 -- REFRESH BUFFER SEGMENT START ADDRESS. ; WD.17 -- NOT USED. ; WD.20 -- NOT USED. ;- MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT MOV I.RBWP(R1),U.RBWP(R5) ;INIT THE RB WRITE POINTER INCB U.BFS(R5) ;SET "NEW FRAME" FLAG 31$: RETURN ;AND WAIT FOR I/O TO BE DONE .PAGE .SBTTL DETACH FUNCTION ;+ ; DETACH FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD.12 -- NOT USED. ; WD.13 -- NOT USED. ; WD.14 -- NOT USED. ; WD.15 -- NOT USED. ; WD.16 -- NOT USED. ; WD.17 -- NOT USED. ; WD.20 -- NOT USED. ;- 40$: TST U.ATT(R5) ;DEVICE ALREADY ATTACHED? BEQ 41$ ;IF EQ NO CMP U.ATT(R5),I.TCB(R1) ;SAME TASK? BEQ 41$ ;IF EQ YES MOV #IE.DAA,R0 ;SET DEVICE ALREADY ATTACHED FLAG BR 46$ 41$: CLRB U.RFV(R5) ;CLEAR REFRESH COUNT BISB #40,@U.SRH(R5) ;AND SINGLE STEP REFRESH BUFFER CLRB U.RRTC(R5) ;STOP THE RTC (NEXT REFRESH) TST U.ICL+2(R5) ;I/O COUNT BIASED? BEQ 42$ ;IF EQ NO MOV I.TCB(R1),R0 ;GET THE ADDRESS OF THE TCB DECB T.IOC(R0) ;UNBIAS THE I/O COUNT CLR U.ICL+2(R5) ;RESET POTENTIALLY DAMAGING CONNECTS CLR U.IFM+2(R5) 42$: CLR U.IX+2(R5) CLR U.ATT(R5) ;SET DEVICE NOT ATTACHED 45$: MOV #IS.SUC,R0 ;SIGNIFY I/O SUCCESSFUL 46$: CALLR $IOFIN ;AND EXIT .PAGE .SBTTL CONNECT TABLET FUNCTION ;+ ; CONNECT TABLET BUFFER FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD.12 -- "IX" VIRTUAL ADDRESS. ; WD.13 -- "IY" VIRTUAL ADDRESS. ; WD.14 -- "IPEN" VIRTUAL ADDRESS. ; WD.15 -- NOT USED. ; WD.16 -- NOT USED. ; WD.17 -- NOT USED. ; WD.20 -- NOT USED. ;- 50$: JSR PC,CKFCP ;CHECK TO MAKE SURE TASK CAN CONNECT MOV I.IX(R1),-(SP) ;SAVE IX VIRTUAL ADDRESS MOV I.IY(R1),-(SP) ;SAVE IY VIRTUAL ADDRESS MOV I.IPN(R1),R0 ;SET IPEN VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IPN(R5) ;SAVE "IPEN" MOV R2,U.IPN+2(R5) ; PHYSICAL ADDRESS MOV (SP)+,R0 ;SET "IY" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IY(R5) ;SAVE "IY" MOV R2,U.IY+2(R5) ; PHYSICAL ADDRESS MOV (SP)+,R0 ;SET "IX" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IX(R5) ;SAVE "IX" MOV R2,U.IX+2(R5) ; PHYSICAL ADDRESS BR 45$ ;AND EXIT .PAGE .SBTTL CONNECT CURSOR FUNCTION ;+ ; CONNECT CURSOR BUFFER FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD.12 -- "IX" VIRTUAL ADDRESS. ; WD.13 -- "IY" VIRTUAL ADDRESS. ; WD.14 -- "IPEN" VIRTUAL ADDRESS. ; WD.15 -- "DYNAMIC VIEWPORT" VIRTUAL ADDRESS. ; WD.1 -- NOT USED. ; WD.17 -- NOT USED. ; WD.20 -- NOT USED. ;- 60$: JSR PC,CKFCP ;CHECK TO MAKE SURE TASK CAN CONNECT MOV I.IX(R1),-(SP) ;SAVE "IX" VIRTUAL ADDRESS MOV I.IPN(R1),-(SP) ;SAVE "IPEN" VIRTUAL ADDRESS MOV I.IY(R1),-(SP) ;SAVE "IY" VIRTUAL ADDRESS MOV I.IVW(R1),R0 ;SET VIEWPORT VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IVW(R5) ;SAVE VIEWPORT MOV R2,U.IVW+2(R5) ; PHYSICAL ADDRESS MOV (SP)+,R0 ;SET "IY" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IYC(R5) ;SAVE "IY" MOV R2,U.IYC+2(R5) ; PHYSICAL ADDRESS MOV (SP)+,R0 ;SET "IPEN" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IPNC(R5) ;SAVE "IPEN" MOV R2,U.IPNC+2(R5) ; PHYSICAL ADDRESS MOV (SP)+,R0 ;SET "IX" VIRTUAL ADDRESS CALL $RELOC ;TRANSFORM TO PHYSICAL ADDRESS MOV R1,U.IXC(R5) ;SAVE "IX" MOV R2,U.IXC+2(R5) ; PHYSICAL ADDRESS BR 45$ ;AND EXIT .PAGE .SBTTL DISCONNECT TABLET/CURSOR FUNCTION ;+ ; DISCONNECT BUFFER (TABLET OR CURSOR) FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD.12 -- NOT USED. ; WD.13 -- NOT USED. ; WD.14 -- NOT USED. ; WD.15 -- NOT USED. ; WD.16 -- NOT USED. ; WD.17 -- NOT USED. ; WD.20 -- NOT USED. ;- 70$: TSTB I.FCN(R1) ;TABLET OR CURSOR DISCONNECT? BNE 75$ ;IF NE CURSOR CLR U.IX+2(R5) ;SET TABLET DISCONNECTED BR 45$ ;AND EXIT 75$: CLR U.IXC+2(R5) ;SET CURSOR DISCONNECTED BR 45$ ;AND EXIT .PAGE ;+ ; -CKFCP- THIS ROUTINE VERIFIES THAT THE CALLING TASK IS ; FIXED IN MEMORY OR NOT CHECKPOINTABLE BEFORE A TABLET OR CURSOR ; CONNECT IS ALLOWED. IF A CONNECT IS NOT POSSIBLE THEN AN ERROR ; CODE IS RETURN TO THE CALLING TASK. ;- CKFCP: MOV I.TCB(R1),R0 ;GET TCB ADDRESS OF REQUESTOR TASK BIT #T2.CHK!T2.FXD,T.ST2(R0) ;TASK FIXED OR NOT CHECK- ; POINTABLE? DPR BEQ 79$ ;IF EQ NO...SET ERROR CODE AND RETURN RTS PC ; 79$: MOV #IE.PSC,R0 ;SET BUFFER CONNECT ERROR TST (SP)+ ;CLEAN STACK BR 46$ ;AND EXIT .DSABL LSB .PAGE .SBTTL I/O CANCEL, TIMEOUT, POWER FAIL .ENABL LSB ;+ ; THE FOLLOWING ARGUMENTS ARE ASSUMED UPON ENTRY TO PSCAN: ; ; R0=ADDRESS OF ACTIVE I/O PACKET ; R1=ADDRESS OF TCB OF CURRENT TASK ; R3=CONTROLLER INDEX ; R4=SCB ADDRESS ; R5=UCB ADDRESS ;- PSCAN: TST U.ATT(R5) ;IS PS ATTACHED? BEQ 1010$ ;IF EQ NO CMP U.ATT(R5),R1 ;ATTACHED TO CURRENT TASK? BNE 1030$ ;IF NE NO 1010$: CLRB U.RFV(R5) ;CLEAR REFRESH COUNT BISB #40,@U.SRH(R5) ;AND SINGLE STEP REFRESH BUFFER CLRB U.RRTC(R5) ;STOP THE RTC (NEXT REFRESH) TST U.ICL+2(R5) ;I/O COUNT BIASED? BEQ 1020$ ;IF EQ NO DECB T.IOC(R1) ;UNBIAS THE I/O COUNT CLR U.ICL+2(R5) ;RESET CONNECT STUFF CLR U.IFM+2(R5) ; 1020$: CLR U.IX+2(R5) ; CLR U.ATT(R5) ;SET DEVICE NOT ATTACHED 1030$: RETURN ;DONE ;+ ; THE FOLLOWING ARGUMENTS ARE ASSUMED UPON ENTRY TO PSOUT: ; ; R0=I/O STATUS CODE IE.DNR (DEVICE NOT READY) ; R3=CONTROLLER INDEX ; R4=SCB ADDRESS ; R5=UCB ADDRESS ;- PSOUT: CALL $DVMSG RETURN ;+ ; THE FOLLOWING ARGUMENTS ARE ASSUMED UPON ENTRY TO PSPWF: ; ; R3=CONTROLLER INDEX ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; THIS ROUTINE SETS THE ILLEGAL INSTRUCTION TRAP INTERCEPT MECHANISM ;- PSPWF: MOV R5,CNTBL(R3) ;SET ADDRESS OF UCB CMP @#10,#TRPINT ;ILLEGAL INSTRUCTION INTERCEPT ALREADY SET UP? BEQ 10$ ;IF EQ YES MOV @#10,TRPVEC ;ELSE SAVE THE TRAP HANDLER ADDRESS MOV #TRPINT,@#10 ;AND SET TO INTERCEPT TRAPS BR 20$ ;AND JUST RETURN 10$: MOV #CURBF,R2 ;SET ADDRESS OF CURBF JUST IN CASE JSR PC,MMAP ;AND MAP TO AN NPR ADDRESS JSR PC,NULLST ;OUTPUT A NULL STATUS WORD BISB #4,@U.SRH(R5) ;SET FOR A NEW FRAME BICB #200,@U.SRH(R5) ;AND START THE RB MOVB #77,@U.RTC(R5) ;RESTART THE RTC 20$: RETURN .DSABL LSB .PAGE .SBTTL MISCELLANEOUS ROUTINES .ENABL LSB MMAP: MOV R2,R0 ;SET BUFFER ADDRESS ADD #4,R2 ;ADJUST FOR DATA BUFFER .IF DF M$$MGE MOV R2,R1 ;COPY ADDRESSS BIC #177700,R2 ;ISOLATE DISPLACEMENT IN BLOCK BIC R2,R1 ;CLEAR DISPLACEMENT BITS ASL R1 ;ISOLATE APR AND BLOCK ROL R1 ROL R1 ROLB R1 ASLB R1 ;CONVERT APR TO WORD INDEX CLR -(SP) ;PICK UP APR NUMBER BISB R1,(SP) ADD #KISAR0,(SP) ;POINT TO PROPER RELOCATION REGISTER CLRB R1 ;CLEAR APR NUMBER SWAB R1 ;BLOCK NUMBER TO RIGHT HALF ASR R1 ;RIGHT JUSTIFY BLOCK NUMBER ADD @(SP)+,R1 ;ADD IN RELOCATION BASE BIS #140000,R2 ;SET APR6 BIAS CALL $MPPHY ;MAP TO NPR ADDRESS .IFF CLR R1 ;RESET DRST WORD .ENDC INC R1 ;SET THE GO BIT MOV R1,(R0)+ ;SET DRST VALUE MOV R2,(R0) ;SET DRBA VALUE RTS PC ;AND RETURN DMAOUT: BIT #200,@U.DRST(R5) ;DMA READY? BEQ DMAOUT ;IF EQ NO MOV R1,@U.DRWC(R5) ;SET THE WORD COUNT MOV 2(R2),@U.DRBA(R5) ;SET THE BASE ADDRESS 1$: BITB #1,@U.SR(R5) ;MAP DONE? BEQ 1$ ;IF EQ NO MOV R0,@U.RSR(R5) ;SET THE RSR MOV (R2),@U.DRST(R5) ;AND START THE DMA RTS PC ; NULLST: BIT #200,@U.DRST(R5) ;DMA READY? BEQ NULLST ;IF EQ NO MOV #-3,@U.DRWC(R5) ;SET THE WORD COUNT MOV CURBF+2,@U.DRBA(R5) ;SET THE BASE ADDRESS 2$: BITB #1,@U.SR(R5) ;MAP DONE? BEQ 2$ ;IF EQ NO MOV #32000,@U.RSR(R5) ;SET THE RSR MOV CURBF,@U.DRST(R5) ;AND START THE DMA RTS PC ; TABS: BIC #TABMSK,R0 ;MASK OFF NON-SIGNIFICANT BITS SUB #TABADJ,R0 ;ADJUST FOR ZERO CENTER MOV #TABMAX,-(SP) ;SET VALUE CMP R0,(SP) ;VALUE TOO GREAT? BGT 3$ ;IF GT YES NEG (SP) CMP R0,(SP) ;VALUE TO LITTLE? BGE 4$ ;IF GE NO 3$: MOV (SP),R0 ;SET DEFAULT 4$: TST (SP)+ .REPT TABRPT ASL R0 ;SCALE THE VALUE UP .ENDR RTS PC ;AND RETURN RTC300: TSTB U.PPST(R5) ;DEJA VU? BNE 13$ ;IF NE YES...JUST RETURN BIT #200,@U.DRST(R5) ;DMA BUSY? BNE 12$ ;IF NE NO CMP #-200,@U.DRWC(R5) ;YES...ABOUT DONE? BGT 14$ ;IF GT NO 10$: BIT #200,@U.DRST(R5) ;WAIT FOR DMA DONE BEQ 10$ 11$: BITB #1,@U.SR(R5) ;WAIT FOR MAP DONE BEQ 11$ 12$: INCB U.PPST(R5) ;SET PP STATUS SAVED FLAG MOVB @U.SR(R5),U.SSR(R5) ;SAVE SR BICB #1,U.SSR(R5) ;SAVE CURRENT 1,2,3 & 4 BITS BICB #36,@U.SR(R5) ;AND CLEAR THEM IN THE SR MOV @U.DRST(R5),U.SRST(R5) ;SAVE DRST CLR @U.DRST(R5) ;RESET DRST BITS MOV @U.DRBA(R5),U.SRBA(R5) ;SAVE DRBA MOV @U.DRWC(R5),U.SRWC(R5) ;SAVE DRWC MOV @U.RSR(R5),U.SRSR(R5) ;SAVE RSR 13$: TST (R4)+ ;BUMP PAST BRANCH 14$: RTS R4 ;AND RETURN .DSABL LSB .PAGE .SBTTL RTC INTERRUPT HANDELER .ENABL LSB ;+ ; PICTURE SYSTEM REAL-TIME CLOCK INTERRUPT HANDLER ; ;- $RTINT:: ;;;REF LABEL .IFT MOV PS,TEMP ;;;SAVE CONTROLLER NUMBER .IFTF CALL $INTSV,PR5 ;;;SAVE REGISTERS AND SET PRIORITY .IFT MOV TEMP,R4 ;;;RETRIEVE CONTROLLER NUMBER BIC #177760,R4 ;;;CLEAR ALL BUT CONTROLLER NUMBER ASL R4 ;;;CONVERT TO CONTROLLER INDEX .IFF CLR R4 ;;;SET CONTROLLER INDEX TO ZERO .IFTF MOVB #PR4,PS ;;;LOWER PRIORITY MOV CNTBL(R4),R5 ;;;RETRIEVE ADDRESS OF UCB MOVB U.RRTC(R5),@U.RTC(R5) ;;;RESTART THE RTC TST U.IFM+2(R5) ;;;USER CONNECTED TO "IFRMCT"? BEQ 10$ ;;;IF EQ NO .IF DF M$$MGE MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.IFM(R5),KISAR6 ;;;MAP TO USER BUFFER INC @U.IFM+2(R5) ;;;INCREMENT USER "IFRMCT" MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFF INC @U.IFM+2(R5) ;;;INCREMENT USER "IFRMCT" .ENDC 10$: DECB U.RFV(R5) ;;;TIME FOR ANOTHER REFRESH? BGT 11$ ;;;IF GT NO ;DETERMINE WHETHER THE RB HAS STOPPED BITB #200,@U.SRH(R5) ;;;CHECK FOR RB STOPPED BNE 12$ ;;;IF NE RB STOPPED 11$: JMP $INTXT ;;;EXIT FROM INTERRUPT ; RB STOPPED...PREPARE FOR ANOTHER REFRESH 12$: BICB #6,@U.SRH(R5) ;;;CLEAR THE ND AND NC BITS ; TIME FOR A NEW FRAME? MOVB U.RFC(R5),U.RFV(R5) ;;;SET COUNT FOR NEXT REFRESH DECB U.UDV(R5) ;;;READY FOR A NEW FRAME? BVC 13$ ;;;IF VC NO UNDERFLOW CLRB U.UDV(R5) ;;;ADJUST FOR UNDERFLOW 13$: BGT 20$ ;;;IF GT NOT TIME FOR A NEW FRAME TSTB U.BFS(R5) ;;;IS A NEW FRAME WANTED? BEQ 20$ ;;;IF EQ NO JSR R4,RTC300 ;;;SAVE AWAY PP STATUS (IF POSSIBLE) BR 20$ ;;;BRANCH IF NOT ABLE TO SAVE STATUS ;;;RTC300 RETURN HERE IF STATUS SAVED MOVB U.UDC(R5),U.UDV(R5) ;;;SET UPDATE COUNT TSTB U.PSRW(R5) ;;;CURSOR IN PROGRESS? BNE 14$ ;;;IF NE YES BICB #1,@U.SRH(R5) ;;;CLEAR DC BIT 14$: BISB #4,@U.SRH(R5) ;;;SET ND BIT (NEW FRAME) CLRB U.PSRW(R5) ;;;RESET THE CURSOR IN PROGRESS BIT SWAB U.BFS(R5) ;;;RESET BFS AND SET BWS JSR PC,NULLST ;;;OUTPUT A NULL STATUS ; RESTART THE RB 20$: BISB U.PSRW+1(R5),@U.SRH(R5) ;;;SET THE PSEUDO SR BITS FOR THIS REFRE CLRB U.PSRW+1(R5) ;;;AND RESET THE PSEUDO SR BICB #200,@U.SRH(R5) ;;;CLEAR RB STOPPED TSTB U.BWS(R5) ;;;WAS A NEW FRAME INITIATED? BEQ 25$ ;;;IF EQ NO...SKIP THE SEGMENTATION CODE CMP #4,U.RBWP(R5) ;;;SEGMENTATION BEING USED? BGE 25$ ;;;NO, SKIP THE CODE ; A NEW FRAME HAS BEEN INITIATED...RESET THE RB WRITE POINTER 21$: BIT #200,@U.DRST(R5) ;;;DMA DONE? BEQ 21$ ;;;IF EQ NO...WAIT FOR IT BITB #20,@U.SRH(R5) ;;;SINGLE BUFFER MODE? BNE 22$ ;IF NE YES...JUST WRITE U.RBWP MOV #146400,@U.RSR(R5) ;;;STORE P.P. REGISTER 15 MOV @U.DRDB(R5),-(SP) ;;;GET THE CURRENT WRITE POINTER BIC #157777,(SP) ;;;CLEAR ALL BUT THE BUFFER POINTER BIT BIS (SP)+,U.RBWP(R5) ;;;AND SET IT IN THE NEXT ADDDRESS 22$: MOV U.RBWP(R5),@U.DRDB(R5) ;;;SET THE WRITE POINTER MOV #176000,@U.RSR(R5) ;;;SET A RSR NO-OP COMMAND BIS #4,@U.DRST(R5) ;;;SET THE FNCT2 BIT MOV #5,@U.DRST(R5) ;;;AND GO 23$: BIT #200,@U.DRST(R5) ;;;DMA DONE? BEQ 23$ ;;;IF EQ NO...WAIT BIC #4,@U.DRST(R5) ;;;RESET FNCT2 25$: TST U.ICL+2(R5) ;;;USER CONNECTED TO "ICLOCK"? BEQ 30$ ;;;IF EQ NO .IF DF M$$MGE MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.ICL(R5),KISAR6 ;;;MAP TO USER BUFFER INC @U.ICL+2(R5) ;;;INCREMENT USER "ICLOCK" MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFF INC @U.ICL+2(R5) ;;;INCREMENT USER "ICLOCK" ; TEST FOR AUTOMATIC TABLET MODE .IFTF 30$: TST U.IX+2(R5) ;;;CONNECTED TO USER BUFFER? BEQ 39$ ;;;IF EQ NO .IFT MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.IPN(R5),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV R0,-(SP) ;;;SAVE R0 BIT #2,@U.IPN+2(R5) ;;;IS THE PEN DOWN? BNE 31$ ;;;IF NE YES...UPDATE REGARDLESS BIT #2,@U.IPN+2(R5) ;;;HAS THE LAST INFORMATION BEEN READ? BNE 38$ ;;;IF NE NO...DON'T UPDATE VALUES 31$: BIT #1,@U.TPN(R5) ;;;IS THE PEN IN BOUNDS? BEQ 33$ ;;;IF EQ NO.. DON'T UPDATE X&Y VALUES MOVB PS,-(SP) ;;;SAVE CURRENT PRIORITY MOVB #PR7,PS ;;;MASK OFF ALL INTERRUPTS MOV @U.TBX(R5),R0 ;;;GET X MOV @U.TBY(R5),R4 ;;;GET Y MOV @U.TBX(R5),-(SP) ;;;GET X' MOV @U.TBY(R5),-(SP) ;;;GET Y' CMP R0,2(SP) ;;;X = X' ? BEQ 32$ ;;;IF EQ YES...DON'T USE X' & Y' MOV (SP),R4 ;;;Y <= Y' MOV 2(SP),R0 ;;;X <= X' 32$: CMP (SP)+,(SP)+ ;;;ADJUST THE STACK MOVB (SP)+,PS ;;;UNMASK INTERRUPTS JSR PC,TABS ;;;ADJUST FOR TABLET ODDITIES .IFT MOV U.IX(R5),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV R0,@U.IX+2(R5) ;;;PUT X IN USER BUFFER MOV R4,R0 ;;;SET Y VALUE JSR PC,TABS ;;;ADJUST FOR TABLET ODDITIES .IFT MOV U.IY(R5),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV R0,@U.IY+2(R5) ;;;PUT Y IN USER BUFFER 33$: .IFT MOV U.IPN(R5),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV @U.TPN(R5),@U.IPN+2(R5) ;;;PUT PEN INFO IN USER BUFFER 38$: MOV (SP)+,R0 ;;;RESTORE R0 .IFT MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFTF 39$: TST U.IXC+2(R5) ;;;CONNECTED TO USER CURSOR BUFFER? BNE 40$ ;;;IF NE YES...BETTER DO IT TSTB U.BWS(R5) ;;;WAS BUFFER SWAPPED? BNE 40$ ;;;IF NE YES...BETTER DO A FORK JMP $INTXT ;;;OTHERWISE JUST EXIT ;;;(NOTHING WAS DISTURBED!) 40$: CALL $FORK ;;;CREATE A SYSTEM PROCESS .PAGE ; TEST FOR AUTOMATIC CURSOR MODE .IFT MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV U.IPNC(R5),KISAR6 ;MAP TO USER BUFFER .IFTF TST U.IXC+2(R5) ;CONNECTED TO USER CURSOR BUFFER? BNE 42$ ;IF NE YES 41$: JMP 50$ ;FORGET THE CURSOR 42$: BIT #1,@U.IPNC+2(R5) ;IS THE PEN IN BOUNDS? BEQ 41$ ;IF EQ NO...FORGET THE CURSOR JSR R4,RTC300 ;SAVE AWAY THE PP STATUS (IF POSSIBLE) BR 41$ ;BRANCH IF NOT ABLE TO SAVE STATUS MOV #377,R0 ;ASSUME THE PEN IS DOWN (MAX INTENSITY) BIT #2,@U.IPNC+2(R5) ;IS THE PEN DOWN? BNE 43$ ;IF NE YES MOV #300,R0 ;SET LOWER INTENSITY 43$: MOV R0,VWLBH+4 ;SET HITHER INTENSITY MOV #140374,R0 ;SET TO STORE PP REGS 0-3 MOV #-16.,R1 ;16 WORDS MOV #PPBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ; MOV #150370,R0 ;SET TO STORE PP REGS 20-27 MOV #-32.,R1 ;32 WORDS MOV #CSBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ; MOV U.IVW(R5),U.BUF(R5) ;SET VIEWPORT ADDRESS MOV U.IVW+2(R5),U.BUF+2(R5) ;FOR $GTWRD CALL $GTWRD MOV (SP)+,VWLBH ;SET IVL CALL $GTWRD MOV (SP)+,VWRTY ;SET IVR CALL $GTWRD MOV (SP)+,VWLBH+2 ;SET IVB CALL $GTWRD MOV (SP)+,VWRTY+2 ;SET IVT MOV #120374,R0 ;SET TO LOAD PP REGS 0-3 MOV #-16.,R1 ;16 WORDS MOV #CURBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ; MOV #130372,R0 ;SET TO LOAD PP REGS 20-25 MOV #-24.,R1 ;24 WORDS MOV #VWBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ;LOAD CURSOR VIEWPORT .IFT MOV U.IXC(R5),KISAR6 ;MAP TO USER BUFFER .IFTF MOV @U.IXC+2(R5),R0 ;GET CURRENT X VALUE ASR R0 ;DIVIDE BY 2 TO COMPENSATE FOR W=40000 ADD #1000,R0 ;POSITION IT MOV R0,DRWBUF ;SET CURRENT X VALUE .IFT MOV U.IYC(R5),KISAR6 ;MAP TO USER BUFFER .IFTF MOV @U.IYC+2(R5),R0 ;GET CURRENT Y VALUE ASR R0 ;DIVIDE BY 2 TO COMPENSATE FOR W=40000 ADD #1000,R0 MOV R0,DRWBUF+2 ;SET CURRENT Y VALUE BISB #20,@U.SR(R5) ;SET CURSOR OUTPUT BIT MOV #32374,R0 ;SET TO OUTPUT 4 STATUS NULLS MOV #-12.,R1 ;12 WORDS MOV #CURBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ; MOV #000374,R0 ;SET TO DRAW CURSOR (2DDRAW) MOV #-8.,R1 ;8 WORDS MOV #DRWBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ; MOV #120374,R0 ;SET TO RESTORE PP REGS 0-3 MOV #-16.,R1 ;16 WORDS MOV #PPBF,R2 ;ADDRESS OF DRST & DRBA JSR PC,DMAOUT ; MOV #130370,R0 ;SET TO LOAD PP REGS 20-27 MOV #-32.,R1 ;32 WORDS MOV #CSBF,R2 ;ADDRESS OF DRST & DRBA BIC #2,@R2 ;RESET FUNCTION 1 BIT BIT #3000,U.SRST(R5) ;WERE THE "HIT BITS" SET? BNE 44$ ;IF NE YES BIS #2,@R2 ;ELSE SET THE FUNCTION 1 BIT 44$: JSR PC,DMAOUT ; BIS #1400,U.PSRW(R5) ;SET THE PSEUDO NC & DC BITS 50$: .IFT MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .ENDC TSTB U.PPST(R5) ;WAS THE PP STATUS CHANGED? BEQ 52$ ;IF EQ NO (AND BF WASN'T SWITCHED EITHER) 51$: BIT #200,@U.DRST(R5) ;DMA DONE? BEQ 51$ ;IF EQ NO MOV U.SRSR(R5),@U.RSR(R5) ;RESTORE RSR MOV U.SRWC(R5),@U.DRWC(R5) ;RESTORE DRWC MOV U.SRBA(R5),@U.DRBA(R5) ;RESTORE DRBA MOV U.SRST(R5),@U.DRST(R5) ;RESTORE DRST MOVB U.SSR(R5),@U.SR(R5) ;RESTORE PREVIOUSLY SET SR BITS CLRB U.PPST(R5) ;RESET PPSTATUS CHANGED FLAG 52$: TSTB U.BWS(R5) ;WAS BF SWITCH SET? BNE 53$ ;IF NE YES RETURN ;ELSE JUST RETURN FROM FORK PROCESS 53$: CLRB U.BWS(R5) ;RESET BF SWITCH WAS SET FLAG MOV #IS.SUC&377,R0 ;SET SUCCESS CODE FOR I/O STATUS BLOCK CALL $IOALT ;FINISH I/O OPERATION JMP PSINI ;AND SEE IF ANOTHER IS QUEUED .DSABL LSB .PAGE .SBTTL DR11-B INTERRUPT HANDLER .ENABL LSB ; $PSINT: DR11-B DMA INTERRUPTS $PSINT:: .IFT MOV PS,TEMP ;;;SAVE DR11-B CONTROLLER NUMBER .IFTF CALL $INTSV,PR5 ;;;SAVE REGISTER & SET PRIORITY .IFT MOV TEMP,R4 ;;;RETREIVE CONTROLLER NUMBER BIC #177760,R4 ;;;CLEAR ALL BUT CONTROLLER NUMBER ASL R4 ;;;CONVERT TO CONTROLLER INDEX .IFF CLR R4 ;;;SET CONTROLLER INDEX TO ZERO .ENDC MOV CNTBL(R4),R5 ;;;RETREIVE ADDRESS OF UCB MOV U.DRST(R5),R4 ;;;GET DRST ADDRESS BIT #100000,@R4 ;;;"ERROR" SET? BEQ 50$ ;;;IF EQ NO ERROR BIT #20000,@R4 ;;;"ATT" SET? BNE 50$ ;;;IF NE ATT SET...NO PROBLEM BIT #40000,@R4 ;;;"NEX" SET? BNE 30$ ;;;IF NE "NEX" ERROR TST -2(R4) ;;;DRBA = 0? BEQ 40$ ;;;IF EQ OK...ELSE MUST BE THE DR11-B 30$: MOV #T.NDSE,R0 ;;;SET DEVICE SELECT ERROR CALL $DVMSG ;;;OUTPUT MESSAGE BR 50$ ;;;AND EXIT 40$: TST -4(R4) ;;;DRWC = 0? BGE 50$ ;;;IF GE THEN NO MORE TO DO CLR -2(R4) ;;;RESET DRBA TO CLEAR ERROR CONDITION MOV @R4,-(SP) ;;;GET CURRENT DRST ADD #421,(SP) ;;;INC BA<17:16> AND SET CYCLE AND GO MOV (SP)+,@R4 ;;;RESTART THE DMA 50$: JMP $INTXT ;;;EXIT FROM INTERRUPT .DSABL LSB .PAGE .SBTTL ILLEGAL INSTRUCTION TRAP HANDLER ; ILLEGAL INSTRUCTION TRAP HANDLER TRPINT: MOV R5,-(SP) ;;;SAVE R5 MOV R4,-(SP) ;;;SAVE R4 MOV 4(SP),R5 ;;;GET ADDRESS OF ILLEGAL INSTRUCTION .IF DF M$$MGE MFPI -2(R5) ;;;GET TRAP INSTRUCTION .IFF MOV -2(R5),-(SP) ;;;GET ILLEGAL INSTRUCTION .IFTF MOV (SP)+,R4 ;;;GET OPCODE CMP R4,#7000 ;;;IS IT WITHIN RANGE? BLT 1$ ;;;NO CMP R4,#7005 BGT 1$ ;;;NO BIC #7000,R4 ;;;CLEAR THE OP-CODE ASL R4 ;;;SHIFT THE SUB-OP MOV 2$(R4),R4 ;;;GET ADDRESS OF ROUTINE RTS R4 ;DISPATCH AND RESTORE R4 2$: DEVO DEVI DMAS ;DMA START DMAI ;DMA IDLE TEST WRBP ;WRITE REFRESH BUFFER POINTER RTAB ;READ TABLET REGISTERS 1$: MOV (SP)+,R4 ;;;RESTORE R4 MOV (SP)+,R5 ;;;RESTORE R5 JMP @TRPVEC ;;;JUMP TO THE REAL TRAP HANDLER .PAGE .SBTTL DEVO ;+ ; DEVO - PUT VALUE TO DEVICE ;- DEVO: .IFT MFPI (R5)+ ;;;GET INSTRUCTION MFPI (R5)+ ;;;GET IMMEDIATE VALUE MOV (SP)+,EX1 ;;;SET INTO BUFFER MFPI (R5)+ ;;;GET INDEX .IFF MOV (R5)+,-(SP) ;;;GET INSTRUCTION MOV (R5)+,EX1 ;;;SET IMMEDIATE VALUE INTO BUFFER MOV (R5)+,-(SP) ;;;GET INDEX .IFTF MOV R5,6(SP) ;;;SET RETURN ADDRESS MOV CNTBL,R5 ;;;GET ADDRESS OF UCB CMP (SP),#U.DRBA ;;;DRBA SETUP? BNE 10$ ;;;IF NE NO .IFT MOV R0,-(SP) ;;;SAVE R0 MOV R1,-(SP) ;;;SAVE R1 MOV R2,-(SP) ;;;SAVE R2 MOV EX1,R0 ;;;SET VIRTUAL ADDRESS CALL $RELOC ;;;CONVERT TO BLOCK # AND BIAS CALL $MPPHY ;;;CONVERT TO 18-BIT PHYSICAL ADDRESS BIS #100,R1 ;;;SET IE BIT BIC #60,@U.DRST(R5) ;;;RESET THE BA<17:16> BITS BIS R1,@U.DRST(R5) ;;;SET THE BITS IN THE DRST MOV R2,EX1 ;;;SET THE BASE ADDRESS OPERAND MOV (SP)+,R2 ;;;RESTORE R2 MOV (SP)+,R1 ;;;RESTORE R1 MOV (SP)+,R0 ;;;RESTORE R0 .IFF BIS #100,@U.DRST(R5) ;;;SET IE IN THE DRST .IFTF 10$: MOV (SP)+,EX2 ;;;SET INDEX INTO BUFFER BIC #7777,(SP) ;;;CLEAR DESTINATION BITS BIS #2775,(SP) ;;;SET PROPER MODE & REGISTER BITS MOV (SP)+,EX0 ;;;SET INSTRUCTION INTO BUFFER EX0: .BLKW 1 EX1: .BLKW 1 EX2: .BLKW 1 MOV PS,R5 ;;;SAVE PROCESSOR STATUS BIC #177760,R5 ;;;CLEAR ALL BUT CONDITION BITS BIC #17,4(SP) ;;;CLEAR USER CONDITION BITS BIS R5,4(SP) ;;;SET USER CONDITION BITS BR DEVEXT ;;;RETURN .PAGE .SBTTL DEVI ;+ ; DEVI - GET INPUT FROM DEVICE ;- DEVI: .IFT MFPI (R5)+ ;;;GET INSTRUCTION MFPI (R5)+ ;;;GET INDEX MOV (SP)+,EXI1 ;;;SET INDEX .IFF MOV (R5)+,-(SP) ;;;GET INSTRUCTION MOV (R5)+,EXI1 ;;;GET AND SET INDEX .IFTF BIC #7777,(SP) ;;;CLEAR SRC & DST BITS BIS #7446,(SP) ;;;SET PROPER MODE & REGISTER BITS MOV (SP)+,EXI0 ;;;SET INSTRUCTION MOV R4,-(SP) ;;;SAVE R4 MOV CNTBL,R4 ;;;GET ADDRESS OF UCB MOV SP,U.PS(R4) ;;;SET ADDRESS OF "PROCESSOR STATUS" ADD #6,U.PS(R4) ;;;ADJUST FOR STACK ENTRIES EXI0: .BLKW 1 EXI1: .BLKW 1 .IFT MTPI (R5)+ ;;;SET VALUE INTO USER WORD .IFF MOV (SP)+,(R5)+ ;;;SET VALUE INTO WORD .IFTF MOV (SP)+,R4 ;;;RESTORE R4 MOV R5,2(SP) ;;;SET RETURN ADDRESS BR DEVEXT ;;;AND EXIT .ENDC .PAGE .SBTTL DMA START ;+ ; DMA START ROUTINE ; ; THIS ROUTINE WILL START A DR11B TRANSFER ; (EVEN IF ITS RUNNING!) SO WAIT BEFORE CALLING ; ;INPUTS: ; R0 USER ADDRESS ; R1 DMA WORD COUNT ; R2 RSR VALUE ; ;OUTPUTS: ; NONE ;- DMAS: MOV CNTBL,R5 ;;;GET UCB ADDRESS MOV R2,@U.RSR(R5) ;;;SET RSR MOV R1,@U.DRWC(R5) ;;;SET WORD COUNT BEQ 1$ ;;;WORD COUNT ZERO, JUST SEND RSR MOV R1,-(SP) ;;;SAVE REGISTERS MOV R2,-(SP) CALL $RELOC ;;;CONVERT TO PHYSICAL CALL $MPPHY ;;;CONVERT TO 18 BIT MOV R2,@U.DRBA(R5) ;;;STORE ADDRESS BIS #101,R1 ;;;INT ENABLE AND GO BIC #60,@U.DRST(R5) ;;;CLEAR ANY LEFT OVER EXTENSION BIS R1,@U.DRST(R5) ;;;START THE TRANSFER MOV (SP)+,R2 ;;;RESTORE REGISTERS MOV (SP)+,R1 BR DEVEXT ;;;RETURN 1$: BIS #101,@U.DRST(R5) ;;;INT ENABLE AND GO BR DEVEXT ;;;RETURN .PAGE .SBTTL DMA IDLE TEST ;+ ; DMA IDLE TEST ; ; THIS ROUTINE RETURNS THE DMA STATE IN THE CARRY BIT ; ;INPUTS: ; NONE ; ;OUTPUTS: ; CARRY SET IF BUSY, CLEAR IF IDLE ;- DMAI: MOV CNTBL,R5 ;;;GET UCB ADDRESS BIC #17,4(SP) ;;;CLEAR USER CONDITION CODES TSTB @U.DRST(R5) ;;;DMA IDLE? BPL 1$ ;;;NO TST @U.DRWC(R5) ;;;WORD COUNT ZERO? BNE 1$ ;;;NO, SO RETURN CARRY SET BITB #1,@U.SR(R5) ;;;MAP BUSY? BNE DEVEXT ;;;NO 1$: INC 4(SP) ;;;BUSY, SET CARRY DEVEXT: MOV (SP)+,R5 ;;;RESTORE R5 RTI ;;;AND RETURN FROM INTERRUPT .PAGE .SBTTL WRITE REFRESH BUFFER POINTER ;+ ; WRITE REFRESH BUFFER POINTER ; ; THIS ROUTINE WRITES THE RBWP ; ;INPUTS: ; R0 VALUE TO WRITE ; ;OUTPUTS: ; NONE ;- WRBP: MOV CNTBL,R5 ;;;GET UCB ADDRESS MOV R0,@U.DRDB(R5) ;;;STORE THE VALUE MOV #176000,@U.RSR(R5) ;;;NOP COMMAND BIS #4,@U.DRST(R5) ;;;SET FUNCT2 BIS #5,@U.DRST(R5) ;;;SET FUNCT2 AND GO 1$: BIT #200,@U.DRST(R5) ;;;WAIT FOR DMA TO COMPLETE BEQ 1$ BIC #4,@U.DRST(R5) ;;;CLEAR FUNCT2 BR DEVEXT ;;;AND RETURN .PAGE .SBTTL TABLET READ ROUTINE ;+ ; TABLET READ ROUTINE ; ; THIS ROUTINE RETURNS THE VALUES OF THE TABLET REGISTERS ; PROPERLY READ TO AVOID SPLIT DATA ; ;INPUTS: ; NONE ; ;OUTPUTS: ; R0 TABLET X ; R1 TABLET Y ; R2 TABLET STATUS ;- RTAB: MOV CNTBL,R5 ;;;GET UCB ADDRESS MOV @U.TBX(R5),R0 ;;;GET X MOV @U.TBY(R5),R1 ;;;GET Y MOV @U.TBX(R5),-(SP) ;;;GET ANOTHER X MOV @U.TBY(R5),-(SP) ;;;GET ANOTHER Y CMP R0,2(SP) ;;; X'S EQUAL BEQ 1$ ;;;YES, FIRST X,Y ARE RIGHT MOV (SP),R1 ;;;NO, USE SECOND VALUES MOV 2(SP),R0 ;;;GET SECOND X 1$: CMP (SP)+,(SP)+ ;;;CLEAN UP THE STACK MOV @U.TPN(R5),R2 ;;;GET STATUS BR DEVEXT ;;;AND RETURN .PAGE ;STORAGE AREA TRPVEC: .BLKW 1 PPBF: .BLKW 2 PPBUF: .BLKW 16. ;PP REGS 0-3 CSBF: .BLKW 2 CSBUF: .BLKW 16. ;PP REGS 20-23 .BLKW 16. ;PP REGS 24-27 CURBF: .BLKW 2 CURBUF: .WORD 40000,0,0,0 ;PP REGS 0-3 .WORD 0,40000,0,0 .WORD 0,0,40000,0 .WORD 0,0,0,40000 VWBF: .BLKW 2 VWLBH: .WORD 0,0,377,0 ;PP REG 20 .BLKW 12. ;PP REGS 21-23 VWRTY: .WORD 0,0,300,0 ;PP REG 24 .WORD 0,0,0,40000 ;PP REG 25 DRWBF: .BLKW 2 DRWBUF: .WORD 0,0 ;CURSOR (ABS) .WORD -2000,-2000 ;(REL) .WORD 2000,0 ;(REL) .WORD -2000,2000 ;(REL) ; ; PATCH AREA ; PSPAT:: .BLKW 20 ;PATCH AREA .END