;;; Copyright (c) 1999 Massachusetts Institute of Technology ;;; ;;; This program is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ;DEVICE CODES DIS==130 ;DISPLAY PROCESSOR DISMAP==134 ;MEM PROT & REL LIPSH==(040000) NWSTK==LIPSH 3, ADSTAR: CONO PI,CLKOFF ;TURN OFF CLOCK TO PREVENT POSSIBLE GOBBLING BY ANOTHER USER PUSHJ P,DISCHK ;CHECK IF THIS USER OWNS THE DISPLAY JRST CLKONJ ;RESTART THE CLOCK SETZM E.SPGH ; QSWI1 switch SETZM E.SCLS ; clear clobber switch SKIPL DISUSR ; no user CAMN U,DISUSR ; skips if different index JRST NOCLBR ; dont untie pages MOVEM U,E.SCLS ; else remember to untie SKIPA ; and dont hack disusr NOCLBR: MOVEM U,DISUSR ;GIVE IT TO HIM IF NO ONE ELSE OWNS IT CONO PI,CLKON ;RESTORE THE CLOCK CONO DIS,5010 ;SET STOP, CLEAR PIA XCTR XR,[HRRZ A,(C)] ; causes pg ld, fetches droot HRRM A,DSTADD ; remember for restarts XCTR XR,[MOVE B,(A)] ; load display page PUSHJ P,SWTL ; circular switch gobble CIRPSW LSH A,-10. ; page number SKIPN E.SCLS ; clobbering old user index ? JRST RDSCLB ; if not, skip it MOVE U,DISUSR ; old useri PUSHJ P,E.SCLB ; untie pages MOVEI U,0 EXCH U,E.SCLS ; clear switch, fetch new usri MOVEM U,DISUSR RDSCLB: PUSHJ P,UPLC ; users pg n into circular pointer PUSHJ P,CHACK ; go in circles SKIPL C ; 4.9 implies real core in loop JRST NOTIED ; if not, dont tie down -- still swapped out MOVE T,J ; MEMPNT INDEX MOVE E,D ; MMP INDEX PUSHJ P,E.SPG1 ; go tie it down NOTIED: PUSHJ P,LSWPOP ; clear switch ; now set up E&S dbrs MOVEI T,UDBR1A(U) HRLI T,_1 ;DBL left 1 relative to 10 MOVEM T,E.SPM+2 HRRI T,UDBR2A(U) MOVEM T,E.SPM+3 ; now start (or restart if from E.SPGI) E&S RDSTAR: CONO DIS,515330 ;RESET THE WORLD SETOM E.SSYS ;FLAG=MAP ON (USER MODE) CONO DIS,515330 ;CLEAR 3D CLIPPER MOVEI I,1000 ;SET COUNT FOR TIMEOUT MOVE H,DSTADD ; fetch c(0) MOVEM H,E.SPM ; store in status block MOVSI H,140000 ; status bits -- map high and low MOVEM H,E.SPM+1 ; set status SKIPA H,[-ADSTN,,ADSTL-1] BLKO DIS,H CONSO DIS,604000 ;SKIP IF DONE OR ERROR SOJG I,.-1 JUMPL H,.-3 JUMPE I,CPOPJ ;FAIL IF TIME OUT ON START CONSZ DIS,600000 ;CHECK FOR EXECUTIVE ERRORS JRST ADXIT ;GIVE INTERRUPT, NO SKIP AOS (P) ADCON1: CONO DIS,400 ;RUN ADXIT: CONO DIS,222010+DISCHN ;ALARM+MPV+STOP+PIA POPJ P, ADSTPX: CONSZ DIS,1040 ;FAIL TO SKIP IF MEM OR SEL STOP JRST ILUUO ;ERROR IF STOP ADSTOP: CAME U,DISUSR ;SKIP IF USER OF SCOPE JRST URET ;EXIT IF NOT SCOPE USER ADSTPY: CONO DIS,5000 ; IOSTOP+STOP.INT.OFF CONO DIS,300 ;LR.PROG+CLR.HIT CONSO DIS,640000 ;SKIP IF PARITY, NXM, MPV ON JRST E.SUSM ;MAP IS STILL ON CONO DIS,400000 ;CLEAR MASTER STUFF (TURNS OFF MAP) CONO DIS,400000 ;CLEAR 3D CLIPPER AOS E.SSYS ;REMEMBER PAGING IS OFF E.SUSM: CONSO DIS,4000 ;SKIP IF STOPPED AND READY PUSHJ P,UFLS ;ELSE WAIT UNTIL READY POPJ P, ADCONT: PUSHJ P,ADSTPX ;ILLEGAL IF MEM OR SEL STOP PUSHJ P,E.SFU ; force user mode if necessary POPJ P,0 ; gross lossage (hardware) JRST ADCON1 ADSTEP: PUSHJ P,ADSTPX ;ILLEGAL IF MEM OR SEL STOP PUSHJ P,E.SFU ; Force User mode (reloads map and skips) POPJ P,0 ; lossage if here CONO DIS,40 POPJ P, ADWORD: XCTR XR,[MOVE J,(J)] ; fetch c(AC) PUSHJ P,ADSTOP ;MAKE SURE IT IS STOPPED PUSHJ P,E.SFU ;RELOAD MAP IF NECESSARY POPJ P,0 ;MAP NOT IN USER MODE DATAO DIS,J POPJ P, ADCLOS: CAME U,DISUSR POPJ P, CONO DIS,5010 ;STOP, PI OFF SETZM E.SPGW ;CLEAR PAGE WAIT PUSHJ P,SWTL ;LOCK CIRCULAR SWITCH CIRPSW PUSHJ P,E.SCLB PUSHJ P,LSWPOP ;RESTORE SWITCH SETOM DISUSR POPJ P, DISCHK: MOVE B,UNAME(U) SKIPL T,DISUSR CAMN B,UNAME(T) AOS (P) ADRSTA: ;READ STATE, WRITE STATE NOT IN. ADSSTA: POPJ P, ;E&S PAGER HAS TO REFERENCE 0 TO INITIALLIZE MAP. ;E&S FORCE USER MODE E.SFU: SKIPGE E.SSYS JRST POPJ1 ;SKIP IF MAP OFF E.SFU2: MOVSI T,140000 ;ENTRY FOR DCRRST MOVEM T,E.SPM+1 ;RESETS STATUS DATAO DIS,[NWSTK 1] ;STORE SP AT 0 PUSHJ P,E.SWT ;CANNOT UFLS -- NWSTK MIGHT BE REISSUED POPJ P,0 ;HARDWARE LOSSAGE DATAO DIS,E.SPM ;OUTPUTS C(0) (RELOADS SP) PUSHJ P,E.SWT POPJ P,0 ;LOST SETOM E.SSYS ;REMEMBER MAP ON JRST POPJ1 E.SWT: PUSH P,J MOVEI J,100 ;COUNT FOR TIMEOUT CONSZ DIS,4000 ;STOPPED AND READY? ELSE SKIP JRST POPJJ1 ;SKIP RET IF READY CONSO DIS,640000 ;OTHER FLAVORS OF LOSSAGE SOJG J,E.SWT+2 ;COUNT IF STILL OK CONO DIS,10 ;STOP FOR GOOD JRST POPJJ ;LOSES, NO SKIP RETURN ADSTL: 000501052405 ;LI DIR,052405(PROGM) 300541,,[-1,,] ;LOCLA SELINT,[-1,,](1) 300441,,[102521,,] ;LOCLA CDIR,[102521,,](1) 302641,,[3777,,3777] ;LOCLSA VIEW,[3777,,3777](1) 302701,,[377777377777] ;LOCLSA WIND,[377777377777](1) 100,,0 ; (JMP 0) load page map and go ADSTN==.-ADSTL EBLK DSTADD: 000100,, ;JMP TO CODE (FILL IN ADDRESS) ; E&S PAGE MAP STATUS BLOCK E.SPM: 0 ; c(0) 0 ; status word 0 ; dbr low 0 ; dbr high MXDISP==16. ; maximum number of tied pages DISPGP: -MXDISP,,0 ; page pointer for mmp pages DISSWP: BLOCK MXDISP ; MMSWP INDICES TIED E.SPGW: 0 ; if non zero, E&S page wait page E.SPGH: 0 ; flag for QSWI1 E.SCLS: 0 ; if non zero, new userI flushing disusr E.SSYS: 0 ; flag for pager on/off E.SIST: 0 ; ststus word at last interrupt ; counts for debugging E.SNTI: 0 ; # pages tied down (total during system run) E.SNUT: 0 ; # pages untied (should = .-1 after dclose) E.SREL: 0 ; # times pages in DISSWP table were relocated ; end of debug counts DSTPCT: -1 ; STOP COUNT TO HANDLE REDUNDANT STOPS DSCONI: 0 ;LAST CONI FROM DISPLAY EBRKA: 0 ;INTERRUPT SAVE AC EBRKU: 0 ; DITTO ESBRK: 0 ;HANDLE E&S INTERRUPT BBLK CONSO DIS,7 ;PI CHAN ASSIGNED? JRST 12,@ESBRK ;NO, CANNOT INTERRUPT CONI DIS,DSCONI CONO DIS,10 ;DEASSIGN PI CHANNEL MOVEM U,EBRKU ;SAVE AC'S MOVEM A,EBRKA MOVEI A,%PILTP ;GIVE "LTPEN" INT (CLASS 3) CONSZ DIS,640040 ;PAR, NXM, MPV, SELECT JRST E.SFLT ; check page fault E.SUIN: SKIPL U,DISUSR IORM A,PIRQC(U) E.SPFR: MOVE A,EBRKA ;UNSAVE AC'S MOVE U,EBRKU JRST 12,@ESBRK ;RETURN E.SFLT: CONSZ DIS,200000 ; skip if not NXM (ie not fault) SKIPL E.SPM+1 ; error bit set in status word ? JRST E.SILM ; if not, real illegal mem LDB U,[121000,,E.SPM+1] ; get page # HRROM U,E.SPGW ; save for loading (LH is flag) MOVE U,E.SPM+1 ; get status MOVEM U,E.SIST ; save status for later (debugging) LDB U,[330300,,U] ; access and pgerr CAIE U,2 ; read write/first error SKIPN U ; no access -- page fault JRST E.SPFR ; gives a page fault E.SILM: SETZM E.SPGW ; if not page fault, don't rq load MOVEI A,%PIDIS; mem fault bits JRST E.SUINT ; give user interrupt DCRSTP: CAMN U,DISUSR ;IS THIS U ON DIS AOSE DSTPCT ; HERE IF THIS USER, SKIP IF FIRST CALL TO STOP POPJ P, ;RETURN IF NOT CONSO DIS,7 ; SKIP IF CURRENTLY RUNNING POPJ P, ; RETURN IF NOT RUNNING NOW CONI DIS,DSCONI ;SAVE STATE FOR RESTART CONO DIS,5000 ;OTHERWISE STOP IT DISSTQ: MOVEI TT,100 CONSO DIS,4000 ;SKIP IF STOP ACTUALLY TAKES HOLD SOJG TT,.-1 ;TIME-OUT LOOP JUMPG TT,CPOPJ ;DID NOT TIME OUT, OK CONO DIS,10 ;DISABLE DISPLAY (CLEAR PIA) AOS DISSTQ ;CAUSE "SYSTEM CLOBBERED" ... ON SYS CONSOLE POPJ P, E.SLPM: PUSHJ P,DCRSTP ; stop before loading page map DCRRST: CAMN U,DISUSR ;IS THE CURRENT U ON DISPLAY? SOSL T,DSTPCT ; SKIP IF LAST START CALL, (FROM MORE THAN 1 STOP) POPJ P, ;NO AOSE T ;SKIP IF ONLY ONE STOP JRST 4,. ;SOME ONE IS OUT OF PHASE! MOVE T,DSCONI CONSZ DIS,7 ;SKIP IF NOT RUNNABLE TRNE T,4000 ;1=> WAS STOPPED POPJ P, ;SO QUIT PUSHJ P,E.SFU2 ; load E&S page map POPJ P,0 ; lost somehow CONO DIS,400 ;ELSE SET RUN CONO DIS,2000 ;THEN ALLOW STOP INT POPJ P, ; tie down hacks ;E.SPCH checks MMSWP ind in T against DISSWP ; R0 if already there, R1 if not. ret index in H E.SPCH: MOVSI H,-MXDISP CAMN T,DISSWP(H) POPJ P,0 ; found AOBJN H,.-2 ; look some more JRST POPJ1 ; not found, skip E.SCLB: MOVSI H,-MXDISP SKIPE T,DISSWP(H) ; VALID IF NON-ZERO PUSHJ P,UNTIE ; UNTIE PAGE IN T (MMSWP INDEX) AOBJN H,E.SCLB+1 POPJ P,0 ; UNTIE PG T/ MMSWP index ; H/ display table index UNTIE: AOS E.SNUT ; count unties PUSH P,H MOVSI H,-1 ADDB H,MMSWP(T) ; sos # exec pgs SKIPGE H ; if less than zero, untied an untied page JRST 4,. ; exec pg count < 0 POP P,H SETZM DISSWP(H) ; clear table entries POPJ P,0 ; ties down page. T/ MMSWP ind. E.SPG1: SKIPL MEMBLT(T) ; frozen, so dont tie PUSHJ P,E.SPCH ; skips if not there POPJ P,0 ; dont tie AOS E.SNTI ; count number of ties. MOVSI H,1 ADDM H,MMSWP(T) ; aos # exec pgs MOVE H,DISPGP ; fetch dis pg pointer AOBJN H,.+2 MOVSI H,-MXDISP ; reset pointer if table full MOVEM H,DISPGP ; update pointer PUSH P,T ; now checks if slot in use SKIPE T,DISSWP(H) PUSHJ P,UNTIE ; untie page in T POP P,T MOVEM T,DISSWP(H) ; remember mmswp ind POPJ P,0 ; E.SPGI called from CFHPI on page in core after fault E.SPGI: SKIPGE U,DISUSR JRST 4,. ; why here ? HRRO I,CFHUVP ; user virtul page from CFH... CAME I,E.SPGW ; is the sam as E&S rq ? POPJ P,0 ; no, return SETOM E.SPGH ; set flag for QSWI1 (read/write/first hack) PUSHJ P,E.SPG1 ; tie down SETZM E.SPGW ; clear page wait PUSHJ P,RDSTART ; restart display POPJ P,0 POPJ P,0 ; skip return from rdstart if wins