M.MMP=0;THIS IS A MULTIPROCESSOR MONITOR! .MCALL TCBDF$ TCBDF$ ;DEFINE TCB OFFSETS .TITLE MXINT ;MSX INTERRUPT CONTROL LOGIC FOR DEVICE .IDENT /GCE001/ ;V001 G. EVERHART ; .MCALL DSAR$S ; ; THESE ROUTINES ARE SAMPLES TO DEMONSTRATE THE GENERAL METHOD ;FOR ALLOWING MSX SYSTEMS RUNNING UNDER RSX-11 TO HANDLE INTERRUPTS ;FROM DEVICES. A ROUTINE IS PROVIDED WHICH IS CALLED FROM THE INTERRUPT ;ROUTINE AT HIGH HARD PRIORITY TO PERFORM ANY TIME-CRITICAL FUNCTIONS. ;THE REMAINING INTERRUPT HANDLING IS CARRIED OUT AT A LATER POINT ;AT WHICH CONTROL IS MERGED WHETHER THE MSX SYSTEM OR SOMETHING ;ELSE WAS INTERRUPTED. ; THERE IS AN ATTEMPT TO SEE IF THE MSX SYSTEM WAS THE INTERRUPTED ;TASK UNDER RSX AND IF SO TO AVOID THE COMPLETE CONTEXT SWITCH THAT ;RSX WOULD OTHERWISE BE OBLIGED TO CARRY OUT. THE IDEA IS THAT A HIGH ;RATE DEVICE CAN USUALLY INTERRUPT MSX AND MOST OF THE RSX OVERHEAD ;CAN BE AVOIDED. (THE MSX OVERHEAD IS JUST TOOO BAD; MSX HAS SO MUCH ;INTER-CPU CHECKING TO DO THAT IT WILL NECESSARILY BE MUCH SLOWER THAN ;THE OLD BSX EXECUTIVE (FOR EXAMPLE) WAS.) ; ; THIS SET OF ROUTINES PRESUMES THE WNDMNG SUBROUTINES HAVE ; DEFINED "MYHDR" AND LOADED IT WITH THE CONTENTS OF $HEADR AT ; THE START OF THE TASK. THIS WILL BE COMPARED WITH THE ACTUAL ; CONTENTS OF $HEADR TO FIND OUT WHETHER THE RUNNING TASK WAS THE ; MSX SYSTEM AT THE TIME OF THE INTERRUPT. SEVERAL ROUTINES WILL BE ; DEFINED HERE. SPRING WILL BE THE ROUTINE TO CONNECT THE DEVICE INTERRUPT ; TO THE ILSR HERE; UNSPRING WILL DISCONNECT IT AGAIN. ; ; .GLOBL SPRING,UNSPRG .MCALL CINT$C ;CONNECT TO INTERRUPT DIRECTIVE VEC=200 DEVCSR=177570 ;DEV CSR (DUMMIES FOR NOW...) EDIR: BCS 1$ CLR @#DEVCSR ;TURN OFF DEV INTERRUPTS RTS PC ;THAT'S ALL 1$: BIS #100,@#DEVCSR ;TURN ON DEV INTERRUPTS RTS PC SPRING: CINT$C VEC,0,MX.CEI,EDIR,340,MX.CAS RTS PC ;INTERRUPT NOW CONNECTED. PAR 0 MAPPED. UNSPRG: CINT$C VEC,0,0,EDIR,340,MX.CAS RTS PC ;INTERRUPT NOW DISCONNECTED ; ;ROUTINE MX.CEI IS THE ENTRY FOR DEV INTERRUPTS (IN THE REAL WORLD ; THERE MAY BE MORE THAN 1 ON THIS MODEL...) ; IT WILL PERFORM REAL WORK TO BE DONE IN ROUTINE DEVHDL ; WHICH WILL BE DUMMIED HERE BUT CAN HAVE ACTUAL WORK PUT ; IN AS APPROPRIATE. THE MSX SYSTEM WILL BE NOTIFIED EITHER ; BY A SIMULATED INTERRUPT VIA LOCAL STACK JUGGLING, OR ; BY AN AST AT MX.CAS DOING THE JUGGLING WITH THE BASE LEVEL. ; MX.CEI: ; ; FIRST BE SURE THE MSX TASK IS NOT SUSPENDED. R5, R4 FREE HERE. MOV MYHDR,R4 ;GET MY TASK HEADER BIC #TS.EXE,T.STAT(R4) ;CLEAR EXECUTION BLOCKED BIC #,T.ST2(R4) ;CLEAR SUSPENDED ; OR WAITING STATUSES JSR R5,S.RSAV ;SAVE ALL REGS ON STACK OF THE MOMENT JSR PC,DEVHDL ;DO INTERRUPT LEVEL WORK JSR R5,S.RRES ;RESTORE REGS FROM CURRENT STACK CMP R4,$HEADR ;NOW IS MSX THE ACTIVE TASK AT INTERRUPT? BNE 1$ ;NO, HAVE TO USE AST ;MSX WAS INTERRUPTED. HENCE USER STACK IS NOW MSX SYSTEM, SO GO BACK DIRECTLY. ;STACK NOW CONTAINS THE FOLLOWING: ; INTERRUPT PS ; INTERRUPT PC ; OLD R5 (FROM JSR R5...) ; OLD R4 (FROM EXPLICIT PUSH) ; OLD PC FROM TRANSFER NODE JSR PC... ; MODIFY BY PUTTING DUMMY RETURN ABOVE IT ON STACK... BIT #30000,@#PS ; WAS PREV. MODE USER? BEQ 1$ ; NO, MUST HAVE INTERRUPTED A FORK OR SOMETHING MFPI SP ;GET USER STACK ONTO STACK MOV (SP)+,R4 ;POINT AT IT WITH R4 MOV 10(SP),-(SP) ;COPY OLD STATUS TO STACK MTPI -(R4) ;USE R4 AS "USER SP" MOV 6(SP),-(SP) ;COPY OLD PC NOW FROM INT. MTPI -(R4) ;AND BASH USER STACK AGAIN MOV R4,-(SP) ;GET READY AND... MTPI SP ;...DECREMENT USER STACK AGAIN MOV #MX.XVC,6(SP) ;SET TO RETURN TO MX.XVC NOW ON RETURN FROM INT. BR 2$ ;BACK TO CALLER DIRECT FROM PRIO 7 1$: ;MSX WAS NOT THE ACTIVE TASK, SO QUEUE AN AST TO MSX. JSR PC,@#$FORK2 ;CALL FORKING PROCESS CLR @R3 ;FREE FORK BLOCK FOR NEXT TIME JSR PC,@#$QASTC ;QUEUE AN AST TO MSX SYSTEM 2$: RTS PC ; GO BACK TO CALLER AND SCRAM FROM HERE... .MCALL ASTX$S .GLOBL MX.CAS ;MAKE AST ENTRY GLOBAL FOR EASY USE... MX.CAS: ; AST ENTRY FOR DEV INTERRUPT MOV 2(SP),-(SP) ;PUSH $DSW DOWN AGAIN MOV 6(SP),2(SP) ;OLD PC SAVE MOV 10(SP),4(SP) ;MOVE UP AST PS MOV 12(SP),6(SP) ;MOVE UP 1ST EF MSK MOV 14(SP),10(SP) ;MOVE UP 2ND EF MSK MOV 16(SP),12(SP) ;MOVE UP 3RD EF MSK MOV 20(SP),14(SP) ;MOVE UP 4TH EF MSK WORD (=LAST) MOV 2(SP),16(SP) ;NOW MOVE AST PS,PC UP. PC HERE MOV 4(SP),20(SP) ;AND THE PS ; NOTE THAT VECTOR ADDRESS CAME IN ON TOP OF STACK AND HAS BEEN ;OVERWRITTEN... CLR 4(SP) ;STATUS=0 MOV #MX.XVC,2(SP) ;RETURN TO MX.XVC AT TASK LEVEL MOV #1,MX.ARC ;FLAG AST RECOGNITION DISABLED... DSAR$S ;AND DISABLE IT (FOR SCHED...) ASTX$S ;EXIT THE AST FINALLY. ;MX.XVC IS THE GENERAL ENTRY. WE ARE GUARANTEED TO GET HERE WITH MSX ;AS THE ACTIVE TASK, EITHER FROM AN AST ENTRY FAKED-UP RTI, OR FROM THE ;INTERRUPT HANDLER'S JIGGERY-POKERY DIRECTLY. WE DO NOT KNOW THE STATE ;OF THE MSX STACK AT THIS POINT, BUT CAN OTHERWISE DO PRETTY MUCH AS ;WE PLEASE, JUST SO WE SAVE AND RESTORE REGS, APR'S, ETC. AROUND ;OUR USE. MX.XVC: INCB MX.SEV ;DECLARE SIG EVENT (ONCE HPS IS DONE) MOV R0,-(SP) ;SAVE R0 AT CALL ;FOR STARTERS, SUPPOSE WE ARE RUNNING A TASK FROM WITHIN AN INTERRUPT... ;SUPPOSE FURTHER IT IS TASK NO. 3 IN THIS CPU... TSK=3 ;TASK NUMBER OF TSK ; QRUN TSK ;CALL TSK ; INSERT WHATEVER CODE IS DESIRED HERE TO START TASKS, ETC. FROM ;INTERRUPT LEVEL. THE QRUN SEQUENCE IS DESIGNED TO WORK FROM INTERRUPT ;LEVEL. MOV (SP)+,R0 ;RESTORE R0 TO LOOK TRANSPARENT RTI ;RETURN TO WHATEVER WAS INTERRUPTED ; ; DUMMY DEVHDL ROUTINE ;THIS ROUTINE IS CALLED TO DO TIME-CRITICAL THINGS AT INTERRUPT LEVEL. ; DEVHDL: RTS PC ;DO NOTHING, JUST RETURN .END