mirror of
https://github.com/PDP-10/stacken.git
synced 2026-02-18 21:36:58 +00:00
623 lines
22 KiB
Plaintext
623 lines
22 KiB
Plaintext
TITLE FEDSER - FRONT END DEVICE SERVICE ROUTINES V035
|
||
SUBTTL E. SOCCI/EVS/TL 9-JUN-87
|
||
|
||
SEARCH F,S,DTEPRM
|
||
$RELOC
|
||
$HIGH
|
||
|
||
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
|
||
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
|
||
;
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
|
||
; 1976,1977,1978,1979,1980,1982,1984,1986,1988.
|
||
;ALL RIGHTS RESERVED.
|
||
|
||
.CPYRT<1976,1988>
|
||
|
||
|
||
XP VFEDSR,035
|
||
|
||
;NOTE:
|
||
; IF ANY CHANGES ARE MADE TO DTEPRM THAT FEDSER MUST HAVE, UPDATE
|
||
; THE FOLLOWING SYMBOL TO THE VERSION OF DTEPRM THAT MUST BE USED
|
||
PRMMIN==63
|
||
; THIS WAY, ASSEMBLING THIS MODULE WITH WRONG VERSION OF DTEPRM FOR SOME REASON
|
||
; (LIKE FORGETTING TO ASSEMBLE IT) WILL CAUSE ASSEMBLY TO TERMINATE
|
||
; THIS SCHEME DOES NOT CAUSE EXTRA EDITING, SINCE ONLY FILES
|
||
; WHICH NEED THE CHANGES NEED PRMMIN TO BE UPDATED. MODULES
|
||
; THAT DO NOT NEED A NEW VERSION OF DTEPRM NEED NOT DEMAND IT.
|
||
|
||
IFL VDTPRM-PRMMIN,<PRINTX ?PLEASE USE LATEST VERSION OF DTEPRM
|
||
PASS2
|
||
END>
|
||
SALL ;CLEAN MACRO EXPANSIONS
|
||
ENTRY FEDSER
|
||
|
||
FEDSER::
|
||
SUBTTL DTE. UUO FRONT END DEVICE FUNCTIONS -- ASSIGN FED
|
||
|
||
|
||
;FUNCTION TO GET FRONT END DEVICE
|
||
; ADDR/CPU#,,DTE#
|
||
; ADDR+1/FED UNIT # OR -1 TO ASSIGN ANY FREE FED
|
||
;
|
||
|
||
FEDGET::PUSHJ P,GETFEB ;GET FRONT END DEVICE BLOCK IN F FROM USER AREA
|
||
CAIA ;FAILED, SEE WHY
|
||
JRST FEDASG ;SUCCEEDED, ASSIGN THIS FED
|
||
|
||
JUMPL T1,CPOPJ## ;RETURN DTUDCE IF CPU DOESN'T EXIST
|
||
MOVE F,T1 ;SAVE CPU#,,DTE#
|
||
PUSHJ P,GETWDU## ;FAILED, SEE WHAT USER SAID
|
||
CAME T1,[-1] ;REQUEST "ANY FREE FED"?
|
||
PJRST DTUNXF## ;NO, FED DOES NOT EXIST
|
||
PUSHJ P,GETETD## ;FETCH DTE CONTROL BLOCK
|
||
PJRST DTUNXF## ;?HUH
|
||
LOAD. F,ED.FED,(F) ;GET FIRST FEB ADDRESS ON THIS FE
|
||
FEDASW: JUMPE F,DTUNXF## ;RETURN ERROR IF FIND NONE
|
||
LOAD. T1,FE.JCH,(F) ;LOOK FOR FED OWNER
|
||
JUMPN T1,[LOAD. F,FE.LNK,(F) ;ALREADY OWNED, GET NEXT FEB
|
||
JRST FEDASW] ;AND CHECK IT OUT
|
||
LOAD. T1,FE.UNI,(F) ;GET FED NUMBER OF THIS UNIT
|
||
PUSHJ P,STOTAC## ;RETURN FED NUMBER TO USER
|
||
|
||
FEDASG: LOAD. T1,FE.JCH,(F) ;GET JOB OWNING THE FRONT END DEVICE
|
||
JUMPN T1,DTUFDB## ;SOMEONE ALREADY HAS IT
|
||
PUSHJ P,FEDCLR ;CLEAR OUT THE BITS IN FEDSTS FIRST
|
||
PUSHJ P,FEDGTC ;ALLOCATE INPUT AND OUTPUT BUFFERS
|
||
POPJ P, ;OOPS, COULDN'T DO IT
|
||
PUSHJ P,FEDSPT ;INITIALIZE POINTERS TO INPUT BUFFER
|
||
MOVE T1,.CPJCH## ;GET JCH OF NEW OWNER
|
||
STOR. T1,FE.JCH,(F) ;MARK FED IN USE AND AVAIL FOR INPUT
|
||
JRST CPOPJ1## ;RETURN
|
||
SUBTTL DTE. UUO FRONT END DEVICE FUNCTIONS -- RELEASE FED
|
||
|
||
|
||
;FUNCTION TO RETURN A FRONT END DEVICE
|
||
; ADDR/CPU#,,DTE#
|
||
; ADDR+1/FED UNIT #
|
||
;
|
||
|
||
FEDGIV::PUSHJ P,GETFEB ;GET FRONT END DEVICE BLOCK IN F
|
||
JRST DTUNXF## ;DOESN'T EXIST
|
||
JSP T4,FEJCHK ;MAKE SURE WE OWN IT
|
||
PUSHJ P,FEDCLR ;CLEAR OUT THE FRONT END DEVICE
|
||
JRST CPOPJ1## ;AND RETURN
|
||
|
||
|
||
SUBTTL RESET UUO SERVICE
|
||
|
||
;HERE FROM RESET. CHECK TO SEE IF THE JOB OWNS A FRONT END DEVICE,
|
||
; AND GIVE IT UP IF SO.
|
||
|
||
IFE FTMP,< ;SINGLE PROCESSORS DON'T HAVE TO SAVE SO MUCH
|
||
FEDRST::PUSHJ P,SAVE2## ;SAVE P1,P2
|
||
> ;IFE FTMP
|
||
IFN FTMP,< ;MULTI-CPU SYSTEMS DO TRIPLE LOOPS
|
||
FEDRST::PUSHJ P,SAVE3## ;SAVE P1,P2,P3
|
||
MOVEI P3,M.CPU## ;FOR EACH CPU
|
||
FEDRS4: > ;IFN FTMP
|
||
MOVEI P2,3 ;SCAN 4 FRONT ENDS
|
||
FEDRS0: MOVEI P1,.FEMXU ;AND 4 FRONT END DEVICES
|
||
FEDRS1: MOVE F,P2 ;GET CPU#,,DTE# IN F FOR GETETD
|
||
IFN FTMP,<
|
||
HRLI F,-1(P3) ;P3 IS 1 HIGHER THAN CPU NO.
|
||
> ;IFN FTMP
|
||
PUSHJ P,GETETD## ;GET DTE CONTROL BLOCK ADDR FOR GETFE0
|
||
JRST FEDRS3 ;THIS FRONT END DOESN'T EXIST
|
||
MOVE T1,P1 ;GET UNIT NUMBER IN T1
|
||
PUSHJ P,GETFE0 ;GET THAT FRONT END BLOCK
|
||
JRST FEDRS2 ;DOESN'T EXIST
|
||
LOAD. T1,FE.JCH,(F) ;GET JOB OWNING IT
|
||
CAMN T1,.CPJCH## ;SAME AS THIS JOB?
|
||
PUSHJ P,FEDCLR ;YES, RELEASE THIS FRONT END DEVICE
|
||
FEDRS2: SOJGE P1,FEDRS1 ;DO NEXT FRONT END DEVICE ON THIS FE
|
||
FEDRS3: SOJGE P2,FEDRS0 ;DO NEXT FRONT END
|
||
IFN FTMP,<
|
||
SOJG P3,FEDRS4 ;LOOP FOR NEXT CPU
|
||
> ;IFN FTMP
|
||
POPJ P, ;DONE
|
||
;ROUTINE TO DO ACTUAL RELEASE OF FRONT END DEVICE. CALLED FROM DTE.
|
||
; UUO, RESET UUO. CALL WITH FRONT END DEVICE BLOCK IN F.
|
||
|
||
FEDCLR: MOVSI T1,(FE.MIP) ;IS A MESSAGE IN PROGRESS AT INTERRUPT LEVEL
|
||
SYSPIF ;CONSISTENCY (NOT NESC. ON OWNING CPU)
|
||
TDNN T1,FEDSTS(F) ;?? (SO PI.OFF IS NOT SUFFICIENT)
|
||
JRST FEDCLN ;NO, CLEAN OUT THE FED
|
||
SYSPIN ;WAIT
|
||
MOVEI T1,EV.FEI ;YES, WAIT FOR MESSAGE TO FINISH COMING IN
|
||
PUSHJ P,ESLEEP## ;SO WE DON'T RELEASE THE CORE IT WILL WRITE
|
||
JRST FEDCLR ;SEE IF SAFE YET
|
||
|
||
FEDCLN: SETZ T1, ;CLEAR OUT JOB NUMBER
|
||
STOR. T1,FE.JCH,(F) ;IN FED BLOCK
|
||
SYSPIN ;INTERRUPT CODE WON'T TOUCH NOW.
|
||
MOVE T1,[FE.CLR] ;BITS TO CLEAR IN STATUS
|
||
ANDCAM T1,FEDSTS(F) ;CLEAR THEM
|
||
PJRST FEDRLC ;RELEASE BUFFER CORE AND RETURN
|
||
SUBTTL DTE. UUO FRONT END DEVICE FUNCTIONS -- FED DEVICE INPUT
|
||
|
||
|
||
;FUNCTION TO DO INPUT FROM FRONT END DEVICE
|
||
; ADDR/CPU#,,DTE#
|
||
; ADDR+1/FED UNIT #
|
||
; ADDR+2/#16-BIT BYTES TO READ,,BUFFER ADDRESS
|
||
|
||
FEDUIN::PUSHJ P,SAVE4##
|
||
PUSHJ P,GETFEB ;GET FRONT END BLOCK ADDRESS IN F
|
||
JRST DTUNXF## ;DOES NOT EXIST
|
||
JSP T4,FEJCHK ;MAKE SURE WE OWN THIS FRONT END DEVICE
|
||
|
||
PUSHJ P,GETWD1## ;GET BYTE COUNT,,ADDRESS
|
||
HRRI M,-1(T1) ;POINT TO WORD BEFORE THE ADDRESS
|
||
HLRZ P3,T1 ;GET COUNT IN P3
|
||
JUMPE P3,DTUBCE## ;IF ZERO, ERROR IN BYTE COUNT
|
||
MOVE T2,P3 ;GET 16 BIT BYTE COUNT
|
||
ASH T2,-1 ;TURN INTO 36 BIT WORD COUNT
|
||
TLZ T1,-1 ;C(T1) NOW HAS FIRST ADDRESS
|
||
ADDI T2,(T1) ;C(T2) NOW HAS LAST ADDRESS
|
||
PUSHJ P,TRNGE## ;MAKE SURE ITS ALL IN CORE
|
||
MOVSI T1,(FE.EOF) ;CLEAR END OF FILE FLAG
|
||
ANDCAM T1,FEDSTS(F)
|
||
SETZ P1, ;CLEAR COUNT OF BYTES GIVEN TO USER
|
||
|
||
FEDUI1: PUSHJ P,FEDUIB ;GET NEXT INPUT BYTE
|
||
POPJ P, ;ERROR, RETURN IT
|
||
TRNN P1,1 ;GOES IN LH?
|
||
JRST [HRLZ T1,T2 ;YES
|
||
JRST .+2]
|
||
HRR T1,T2 ;NO, PUT IN RH WITH THE OTHER BYTE
|
||
AOS P1 ;ONE MORE BYTE FOR USER
|
||
TRNN P1,1 ;BACK TO A LH BYTE?
|
||
PUSHJ P,PUTWD1## ;YES, GIVE 2 BYTES TO THE USER
|
||
CAMGE P1,P3 ;HAVE WE GIVEN USER ALL HE ASKED FOR?
|
||
JRST FEDUI1 ;NO, KEEP GIVING
|
||
TRNE P1,1 ;YES, STILL KEEPING A LH BYTE IN T1?
|
||
PUSHJ P,PUTWD1## ;YES, STORE THE ODD BYTE
|
||
JRST CPOPJ1## ;RETURN TO USER WITH THE DATA IN HIS BUFFER.
|
||
;READ NEXT (16-BIT) BYTE FROM -11
|
||
;RETURNS BYTE IN T2, MUST PRESERVE T1, P1, P3, & M
|
||
;RETURN: CPOPJ IF ERROR (ERROR ALREADY SET)
|
||
; CPOPJ1 WITH DATA
|
||
|
||
FEDUIB: SKIPG FEDTCT(F) ;IF NO DATA AVAILABLE
|
||
JRST FEDUB2 ;GET SOME MORE
|
||
ILDB T2,FEDTPT(F) ;GET A BYTE
|
||
SOS FEDTCT(F) ;THERE IS ONE LESS BYTE AVAILABLE NOW
|
||
JRST CPOPJ1## ;DONE
|
||
|
||
FEDUB2: PUSH P,T1 ;SAVE POSSIBLE BYTE IN LH(T1)
|
||
SYSPIF ;MUST TURN OFF PI SO WE DON'T GET INPUT
|
||
; DATA FOR FED WHILE UPDATING PUT POINTER
|
||
SKIPG FEDTCT(F) ;OF COURSE, THE DTE COULD HAVE DELIVERED DATA
|
||
JRST FEDUB3 ;SINCE WE LOOKED. JUMP IF IT DID NOT.
|
||
SYSPIN ;IT DID, MUST CONSUME THAT DATA FIRST
|
||
POP P,T1 ;RESTORE POSSIBLE BYTE IN LH
|
||
JRST FEDUIB ;GO TAKE DATA THAT SNUCK IN
|
||
|
||
FEDUB3: MOVSI T1,(FE.MIP) ;IS A MESSAGE ON ITS WAY IN
|
||
TDNN T1,FEDSTS(F) ;(AT INTERRUPT LEVEL)?
|
||
PUSHJ P,FEDSPT ;NO, MAKE THE NEXT ONE START AT TOP OF BUFFER
|
||
SYSPIN ;TURN PI BACK ON.
|
||
; NOTE THAT FRONT END CAN NOW SEND DATA,
|
||
; BEFORE WE SEND ACK THUS WE SEND ACK
|
||
; WHEN LESS THAN WHOLE BUFFER IS AVAILABLE.
|
||
; TO GET AROUND THIS, BUFFER SIZE IS TWICE
|
||
; ALLOCATION
|
||
PUSHJ P,FEDSAK ;SINCE WE EXPECT TO BLOCK, SEND AN ACK TO GET
|
||
PJRST TPOPJ## ;MORE DATA FROM THE -11. (RETURN IF ERROR)
|
||
PUSHJ P,FEDWTI ;WAIT FOR THE BUFFER
|
||
JRST FEDUB4 ;OOPS, FATAL ERROR.
|
||
POP P,T1 ;RESTORE POSSIBLE LH BYTE
|
||
JRST FEDUIB ;GO FETCH THE NEW DATA
|
||
|
||
FEDUB4: POP P,T1 ;GET JUNK OFF STACK
|
||
JRST DTUFER## ;GO GIVE FATAL ERROR
|
||
;ROUTINE TO SEND AN ACK TO -20F
|
||
;-20F DOESN'T REALLY CARE HOW MANY ACKS IT GETS. IT WILL BLOCK FOR AN
|
||
;ACK WHEN SENDING DEVICE DATA (BUT NOT FUNCTION REPLYS). MORE COMPLICATED
|
||
;SCHEMES COULD BE MORE EFFICIENT, BUT SUFFER SYNCHRONIZATION PROBLEMS.
|
||
;
|
||
;CALLED BY FEDUIB, MUST PRESERVE SAME ACS
|
||
|
||
FEDSAK: PUSH P,P1 ;SAVE COUNT OF BYTES GIVEN TO USER
|
||
PUSH P,P3 ;AND COUNT USER WANTS
|
||
LOAD. P1,FE.DTN,(F) ;GET DTE NUMBER OF THIS FE DEVICE
|
||
LOAD. T1,FE.CPN,(F) ;CPU #
|
||
HRL P1,T1 ;CPU#,,DTE# IN P1
|
||
LOAD. T1,FE.UNI,(F) ;GET FRONT END UNIT NUMBER
|
||
LSH T1,^D35-^D15 ;POSITION LINE NUMBER IN 1ST 16 BIT BYTE
|
||
PUSH P,T1 ;SAVE IT SOMEWHERE
|
||
MOVEI P4,(P) ;GET ADDRESS OF DATA TO PUT INTO MSG IN P4
|
||
HRLI P4,(POINT 8,) ;MAKE INTO 8 BIT BYTE POINTER
|
||
MOVEI P3,2 ;2 8 BIT BYTES TO COPY FOR LONG DIRECT MSG
|
||
MOVE P2,[.EMFED,,.EMACK] ;ACK TO FRONT END DEVICE
|
||
MOVSI S,CPOPJ## ;POST ADDRESS,,DATA
|
||
PUSHJ P,DTEQUE## ;ASK FOR DATA
|
||
JRST [ADJSP P,-4 ;POP ALL THAT STUFF OFF STACK
|
||
JRST DTUCSM##] ;AND GIVE CAN'T SEND -11 MESSAGE ERROR
|
||
POP P,T1 ;TAKE TEMPORARY PART OF MSG OFF STACK
|
||
POP P,P3 ;AND USER'S SUPPLIED BYTE COUNT
|
||
POP P,P1 ;AND COUNT GIVEN TO USER SO FAR
|
||
JRST CPOPJ1## ;DONE
|
||
;ROUTINE TO WAIT FOR FRONT END DEVICE INPUT BUFFER TO BECOME
|
||
; AVAILABLE. RETURNS CPOPJ1 IF IT IS, CPOPJ IF A FATAL ERROR
|
||
; HAS OCCURED IN THE FED. (11-RELOAD, DATA OVERRUN)
|
||
|
||
FEDWTI: MOVSI T1,(FE.FER) ;HAS AN ERROR OCCURED?
|
||
TDNE T1,FEDSTS(F)
|
||
POPJ P, ;YES, GIVE THE ERROR RETURN.
|
||
SKIPLE FEDTCT(F) ;NEED TO WAIT?
|
||
JRST CPOPJ1## ;NO, WE HAVE MORE DATA
|
||
MOVEI T1,EV.FEI ;FRONT END INPUT WAIT
|
||
PUSHJ P,ESLEEP## ;GO INTO EVENT WAIT, WAKE UP WHEN DATA IS READY
|
||
JRST FEDWTI ;MAKE SURE ALL IS OK
|
||
|
||
;HERE AT INTERRUPT LEVEL TO TAKE STRING DATA FOR A FRONT END DEVICE.
|
||
;P1-P4 SETUP BY DTESER TO BE THE STANDARD THINGS (SEE DTESER).
|
||
|
||
FEDTKD: PUSHJ P,FDIGET ;GET FED CONTROL BLOCK ADDRESS IN F
|
||
LOAD. T1,FE.JCH,(F) ;GET CONTROLLING JOB NUMBER
|
||
JUMPE T1,EATMSG## ;IF NONE, JUST EAT UP THE DATA
|
||
HRRZ T2,P3 ;GET 8 BIT BYTE COUNT IN T2
|
||
; IT HAD BETTER BE EVEN
|
||
TRNE T2,1 ;BYTE COUNT EVEN? (SHOULD BE 16 BIT BYTES)
|
||
JRST FEDTKE ;NO, GIVE ERROR
|
||
ASH T2,-1 ;CONVERT TO 16 BIT BYTE COUNT
|
||
CAMLE T2,FEDFBI(F) ;ENOUGH ROOM? (HAD BETTER BE OR ELSE
|
||
; FRONT END IS PROBABLY SENDING TOO MUCH)
|
||
JRST FEDTKE ;YES TO EITHER, GIVE FATAL ERROR TO UUO
|
||
|
||
MOVN T3,T2 ;GET COPY OF LENGTH OF MESSAGE
|
||
ADDM T3,FEDFBI(F) ;UPDATE COUNT OF FREE BYTES IN BUFFER
|
||
|
||
HRLM T2,FEDFBI(F) ;SAVE MESSAGE LENGTH FOR POST ROUTINE
|
||
|
||
MOVE P4,FEDPPT(F) ;GET POINTER TO STORE DATA WITH
|
||
|
||
ADJBP T2,P4 ;COMPUTE POINTER TO NEXT PLACE TO STORE DATA
|
||
MOVEM T2,FEDPPT(F) ;UPDATE FOR NEXT MESSAGE
|
||
|
||
MOVSI S,FEDTDD ;THE POST PLACE
|
||
|
||
MOVSI T1,(FE.MIP) ;MESSAGE WILL NOW COME IN
|
||
IORM T1,FEDSTS(F) ;SO MAKE SURE BUFFER POINTERS AREN'T RESET
|
||
POPJ P, ;RETURN TO DTESER, WHO WILL DO INDIRECT
|
||
; XFER.
|
||
|
||
;HERE IF THERE WAS A PROBLEM, GIVE UUO FATAL ERROR RETURN WHEN IT
|
||
; NEXT LOOKS.
|
||
|
||
FEDTKE: MOVSI T1,(FE.FER) ;YES TO EITHER, GIVE FATAL ERROR TO UUO
|
||
IORM T1,FEDSTS(F) ;SET BIT
|
||
PUSHJ P,FEDWKJ ;WAKE UP CORRECT JOB IF WAITING
|
||
PJRST EATMSG## ;EAT REMAINING DATA AND RETURN
|
||
;HERE AT INTERRUPT LEVEL WHEN WE CRASH THE -11 WHILE WAITING FOR INDIRECT DONE
|
||
;DTESER ACS ARE SETUP.
|
||
|
||
FEDLMG: PUSHJ P,FDIGET ;GET FED BLOCK FROM C(P2), C(P3)
|
||
MOVSI T1,(FE.FER) ;FLAG FATAL ERROR STATUS
|
||
IORM T1,FEDSTS(F) ;SO USER WAKES UP NOW
|
||
PJRST FEDTD1 ;CLEAR MESSAGE IN PROGRESS
|
||
|
||
;HERE AT INTERRUPT LEVEL WHEN DATA TRANSFER TO THE TO-10 BUFFER IS COMPLETE.
|
||
;DTESER ACS ARE SETUP.
|
||
|
||
FEDTDD: PUSHJ P,FDIGET ;GET FED BLOCK FROM C(P2), C(P3)
|
||
HLRZ T1,FEDFBI(F) ;FETCH LENGTH OF THIS MESSAGE
|
||
ADDM T1,FEDTCT(F) ;MAKE DATA AVAILABLE TO USER
|
||
FEDTD1: HRRES FEDFBI(F) ;RESTORE BYTES AVAIL FOR NEXT MESSAGE
|
||
MOVSI T1,(FE.MIP) ;MESSAGE IS NO LONGER IN PROGRESS
|
||
ANDCAM T1,FEDSTS(F) ;SO ALLOW BUFFER SWITCHING
|
||
;FALL INTO FEDWKJ
|
||
|
||
|
||
|
||
;HERE TO REMOVE A JOB FROM EVENT WAIT ASSOCIATED WITH A FRONT END DEVICE IF IT
|
||
; EXISTS. CALL WITH FRONT END DEVICE BLOCK ADDRESS IN F.
|
||
; ALWAYS RETURNS CPOPJ.
|
||
|
||
|
||
FEDWKJ: LOAD. T1,FE.JCH,(F) ;GET JOB NUMBER OWNING THIS
|
||
JUMPE T1,CPOPJ## ;DO NOTHING IF THERE IS NONE
|
||
PUSHJ P,CTXEWK## ;THERE IS ONE, WAKE THE JOB UP IF IT'S WAITING
|
||
JFCL ;IT DOESN'T MATTER IF CTX IS NOW GONE
|
||
POPJ P, ;JOB IS AS AWAKE AS IT'LL GET
|
||
SUBTTL DTE. UUO FRONT END DEVICE FUNCTIONS -- FED DEVICE OUTPUT
|
||
|
||
|
||
;FUNCTION TO DO OUTPUT TO FRONT END DEVICE
|
||
; ADDR/CPU#,,DTE#
|
||
; ADDR+1/FED UNIT #
|
||
; ADDR+2/#16-BIT BYTES TO WRITE,,BUFFER ADDRESS
|
||
|
||
FEDUOU::PUSHJ P,SAVE4## ;WE WILL BE CALLING DTEQUE
|
||
PUSHJ P,GETFEB ;SETUP FED BLOCK ADDRESS IN F FROM USER ARGS
|
||
JRST DTUNXF## ;NON-GOOD
|
||
MOVE P1,T1 ;GETFEB RETURNS CPU#,,DTE# IN T1
|
||
; SO SAVE IN P1 FOR MAKING MESSAGE LATER
|
||
JSP T4,FEJCHK ;DOES THIS GUY HAVE THE RIGHT?
|
||
; IF NOT, GO AWAY AND GIVE HIM UUO ERROR RETURN
|
||
|
||
|
||
PUSHJ P,GETWD1## ;GET BYTE COUNT,,ADDRESS
|
||
HLRZ P3,T1 ;GET 16 BIT BYTE COUNT IN P3
|
||
HRRI M,-1(T1) ;ADDRESS-1 IN RH(M) FOR GETWD1
|
||
JUMPE P3,DTUBCE## ;ZERO IS ERROR
|
||
MOVE T2,P3 ;GET 16 BIT COUNT
|
||
ASH T2,-1 ;MAKE 36 BIT COUNT
|
||
TLZ T1,-1 ;FIRST ADDRESS
|
||
ADDI T2,(T1) ;MAKE IT LAST ADDRESS
|
||
PUSHJ P,TRNGE## ;MAKE SURE ALL PAGES ARE THERE
|
||
FEDUO2: PUSHJ P,FEDWTO ;WAIT FOR OUTPUT BUFFER TO BE OURS
|
||
JRST DTUFER## ;SOMETHING HAPPENED . . .
|
||
MOVE P4,FEDOBF(F) ;ADDRESS TO PUT BYTES
|
||
HRLI P4,(POINT 16,) ;MAKE INTO A POINTER
|
||
MOVE P2,P3 ;GET COPY OF COUNT FOR LOOP
|
||
CAILE P2,.FEOSZ ;IS COUNT BIGGER THAN A BUFFER?
|
||
MOVEI P2,.FEOSZ ;YES, JUST DO A BUFFER FULL NOW
|
||
PUSH P,P2 ;SAVE COUNT OF DATA TO SEND OUT NOW
|
||
|
||
FEDUO3: PUSHJ P,GETWD1## ;GET 2 BYTES FROM USER
|
||
HLRZ T2,T1 ;GET FIRST BYTE
|
||
IDPB T2,P4 ;PUT INTO FED BUFFER
|
||
SOJLE P2,FEDU3A ;JUMP IF FINISHED
|
||
IDPB T1,P4 ;PUT SECOND ONE INTO FED OUTPUT BUFFER
|
||
SOJG P2,FEDUO3 ;LOOP UNTIL USER DATA EXHAUSTED
|
||
|
||
FEDU3A: EXCH P3,(P) ;SAVE TOTAL COUNT, GET COUNT FOR THIS OUTPUT
|
||
ASH P3,1 ;MAKE THIS # 8 BIT BYTES FOR DTESER
|
||
LOAD. T1,FE.UNI,(F) ;GET UNIT NUMBER OF THIS FRONT END DEVICE
|
||
HRL P3,T1 ;UNIT,,COUNT
|
||
MOVE P4,FEDOBF(F) ;GET ADDRESS OF BUFFER
|
||
HRLI P4,(POINT 16,) ;MAKE IT BYTE POINTER
|
||
MOVE P2,[.EMFED,,EM.16B+EM.IND+.EMSTR] ;DEVICE,,FN
|
||
;P1 WAS SETUP AT VERY BEGINNING
|
||
MOVSI S,CPOPJ## ;NO POST, WAIT FOR THE ACK THATS COMING
|
||
MOVSI T1,(FE.OAE) ;GIVE UP THE BUFFER, MAKING THE NEXT UUO BLOCK
|
||
IORM T1,FEDSTS(F) ;
|
||
PUSHJ P,DTEQUE## ;SEND THE DATA TO THE -11
|
||
JRST [POP P,P3 ;GET P3 BACK OFF STACK
|
||
JRST DTUCSM##] ;CAN'T SEND -11 MESSAGE
|
||
POP P,P3 ;RESTORE COUNT OF BYTES LEFT TO BE DONE
|
||
SUBI P3,.FEOSZ ;WE'VE JUST DONE LESS THAN OR EQUAL TO A
|
||
; WHOLE BUFFER - ANY BYTES LEFT TO DO?
|
||
JUMPG P3,FEDUO2 ;YES, GO DO THEM
|
||
JRST CPOPJ1## ;NO, RETURN TO USER RIGHT AWAY, LETTING HIM
|
||
; FILL ANOTHER BUFFER
|
||
|
||
|
||
;ROUTINE TO WAIT FOR OUTPUT BUFFER TO FREE UP
|
||
; SKIP RETURN WHEN OUTPUT BUFFER IS READY, NON-SKIP IF FATAL ERROR FLAG
|
||
; IS UP.
|
||
|
||
FEDWTO: MOVSI T1,(FE.FER) ;CHECK FOR FATAL ERROR
|
||
TDNE T1,FEDSTS(F) ;?
|
||
PJRST DTUFER## ;YEAH, GOODBYE.
|
||
MOVSI T1,(FE.OAE) ;CAN WE STUFF OUTPUT BUFFER WITH DATA?
|
||
TDNN T1,FEDSTS(F) ;?
|
||
JRST CPOPJ1## ;YES, GIVE SKIP RETURN
|
||
MOVEI T1,EV.FEO ;NO, GO INTO OUTPUT WAIT
|
||
PUSHJ P,ESLEEP## ;ZZZZ
|
||
JRST FEDWTO ;MAKE SURE EVERYTHING IS OK
|
||
;HERE WHEN THE 11 CAN ACCEPT MORE DATA FOR A FRONT END DEVICE
|
||
; (ACK)
|
||
|
||
FEDACK: ILDB T1,P4 ;GET LINE NUMBER
|
||
IBP P4 ;ADVANCE PAST BLANK BYTE
|
||
SUBI P3,2 ;REMEMBER WE'VE TAKEN 2 BYTES
|
||
PUSHJ P,FDIGT0 ;GET FED BLOCK ADDRESS IN F
|
||
MOVSI T1,(FE.OAE) ;MAKE OUTPUT BUFFER AVAILABLE TO UUO AGAIN
|
||
ANDCAM T1,FEDSTS(F)
|
||
PUSHJ P,FEDWKJ ;AND WAKE UP THE JOB IF IT'S SLEEPING
|
||
JUMPN P3,FEDACK ;LOOP IF MORE ACKS ARE IN THIS MESSAGE
|
||
POPJ P, ;ALL DONE
|
||
SUBTTL DTESER ACK ALL SERVICE
|
||
|
||
|
||
;HERE ON ACK ALL - IF SOMEONE IS USING A FRONT END DEVICE, GIVE HIM
|
||
; AN ERROR, AS THE FE HAS JUST RELOADED.
|
||
|
||
FEDAAL: LOAD. F,ED.FED,(F) ;GET FIRST FRONT END DEVICE ADDRESS
|
||
FEDAA1: JUMPE F,CPOPJ## ;DONE
|
||
LOAD. T1,FE.JCH,(F) ;GET JOB #, IF ANY
|
||
JUMPE T1,FEDAA2 ;NO JOB OWNS IT, GET NEXT FED ON THIS FE
|
||
MOVSI T1,(FE.FER) ;SOMEONE IS USING, GIVE HIM THE FINGER
|
||
IORM T1,FEDSTS(F) ;
|
||
PUSHJ P,FEDWKJ ;RUDE AWAKENING
|
||
FEDAA2: LOAD. F,FE.LNK,(F) ;GET NEXT ADDRESS
|
||
JRST FEDAA1 ;AND LOOP FOR ALL FRONT END DEVICES ON THIS DTE
|
||
SUBTTL DTE. UUO FRONT END DEVICE FUNCTIONS -- GET FED DEVICE STATUS
|
||
|
||
|
||
;FUNCTION TO GET STATUS FROM FRONT END DEVICE
|
||
; ADDR/CPU#,,DTE#
|
||
; ADDR+1/FED UNIT #
|
||
; USER GETS STATUS OF FRONT END DEVICE RETURNED IN HIS AC.
|
||
;
|
||
|
||
FEDUGS::PUSHJ P,GETFEB ;GET FED BLOCK FROM USER ARGS
|
||
JRST DTUNXF## ;SORRY
|
||
JSP T4,FEJCHK ;MAKE SURE HE OWNS THE FE DEVICE
|
||
MOVE T2,FEDSTS(F) ;GET STATUS WORD
|
||
SETZ T1, ;PREPARE RESULT
|
||
|
||
TLNE T2,(FE.EOF) ;EOF?
|
||
TRO T1,EM.EOF ;YES
|
||
TLNE T2,(FE.FER) ;FATAL ERROR?
|
||
TRO T1,EM.FER ;YES
|
||
JRST STOTC1## ;RETURN RESULT IN T1
|
||
;HERE AT INTERRUPT LEVEL TO TAKE STATUS OF A FRONT END DEVICE FROM THE -11
|
||
; (DTESER HAS ALREADY RECEIVED IT)
|
||
;DTESER ACS ARE SETUP.
|
||
|
||
FEDTKS: PUSHJ P,FDIGET ;GET FED BLOCK IN F
|
||
ILDB T1,P4 ;GET GOOD INFO
|
||
MOVSI T2,(FE.EOF) ;EOF BIT WILL BE SET OR CLEARED
|
||
TRNE T1,EM.EOF ;EOF BIT ON?
|
||
IORM T2,FEDSTS(F) ;YES, SET EOF IN THE BLOCK
|
||
MOVSI T2,(FE.FER) ;DO SAME FOR FATAL ERROR BIT
|
||
TRNE T1,EM.FER ;FATAL ERROR?
|
||
IORM T2,FEDSTS(F) ;YES, SET THE FATAL ERROR BIT IN STATUS
|
||
PJRST EATMSG## ;EAT UP REMAINING INDIRECT DATA
|
||
SUBTTL DTE. UUO FRONT END DEVICE FUNCTIONS -- SET FED DEVICE STATUS
|
||
|
||
|
||
;FUNCTION TO SET FRONT END DEVICE STATUS
|
||
; ADDR/CPU#,,DTE#
|
||
; ADDR+1/FED UNIT #
|
||
; ADDR+2/NEW STATUS (16 BITS)
|
||
|
||
FEDUSS::PUSHJ P,SAVE4## ;WE WILL BE CALLING DTEQUE
|
||
PUSHJ P,GETFEB ;GET FRONT END DEVICE BLOCK, AS USUAL
|
||
JRST DTUNXF##
|
||
JSP T4,FEJCHK ;MAKE SURE HE OWNS THE FE DEVICE
|
||
PUSHJ P,GETWD1## ;GET THE STATUS SETTING DESIRED
|
||
DPB T1,[POINT 16,FEDSOB(F),15] ;PUT INTO THE MESSAGE
|
||
MOVEI P4,FEDSOB(F) ;GET ADDRESS OF INDIRECT DATA
|
||
HRLI P4,(POINT 16,) ;MAKE INTO A BYTE POINTER
|
||
LOAD. T1,FE.UNI,(F) ;GET UNIT NUMBER OF FRONT END DEVICE
|
||
HRL P3,T1 ;SETUP UNIT # IN LH(P3)
|
||
HRRI P3,.FESMS*2 ;# 8 BIT BYTES IN THE INDIRECT MESSAGE
|
||
MOVE P2,[.EMFED,,EM.16B+EM.IND+.EMHDS]
|
||
;HERE IS DEVICE STATUS, 16 BIT STYLE
|
||
LOAD. P1,FE.DTN,(F) ;GET DTE #
|
||
LOAD. T1,FE.CPN,(F) ;CPU #
|
||
HRL P1,T1 ;CPU#,,DTE# IN P1
|
||
MOVSI S,CPOPJ## ;FORGET ABOUT POST
|
||
PUSHJ P,DTEQUE## ;SEND THE STATUS
|
||
JRST DTUCSM## ;CAN'T SEND -11 MESSAGE
|
||
JRST CPOPJ1## ;RETURN
|
||
SUBTTL DTE. UUO INTERFACE - READ USER ARGUMENT BLOCK
|
||
|
||
;ROUTINE TO GET FRONT END DEVICE BLOCK IN F FROM USER
|
||
; ARGUMENTS TO DTE. UUO
|
||
;
|
||
; USER ADDR+1/CPU#,,DTE#
|
||
; USER ADDR+2/FE DEVICE UNIT #
|
||
; SKIP RETURN IF OK, NON-SKIP IF SOMETHING WAS WRONG
|
||
; IN ANY CASE WITH CPU#,,DTE# IN T1 (OR -1 IF INVALID)
|
||
|
||
GETFEB: PUSH P,[-1] ;ASSUME CPU OR DTE IS INVALID
|
||
PUSHJ P,[PUSHJ P,DTUGTF## ;CHECK AND GET CPU#,,DTE# IN T1
|
||
JRST CPOPJ1##] ;SKIP FOR SUCCESS
|
||
JRST TPOPJ## ;RETURN BAD CPU/DTE ERROR
|
||
MOVEM T1,(P) ;SAVE CPU#,,DTE#
|
||
PUSHJ P,GETWD1## ;GET FE DEVICE UNIT #
|
||
CAILE T1,.FEMXU ;LEGAL UNIT NUMBER?
|
||
JRST TPOPJ## ;NO, ERROR RETURN
|
||
PUSHJ P,GETFE0 ;YES, GO GET THE BLOCK
|
||
JRST TPOPJ## ;DOESN'T EXIST
|
||
JRST TPOPJ1## ;RETURN WITH CPU#,,DTE# IN T1
|
||
SUBTTL FEB SEARCH ROUTINES
|
||
|
||
|
||
;THIS ROUTINE IS FOR DRIVER INTERRUPT LEVEL TO GET THE FED ADDRESS IN F.
|
||
; CALL WITH CPU#,,DTE# IN P1, FED UNIT NUMBER IN LH(P3)
|
||
; ALWAYS RETURNS CPOPJ, IF FED DOESNT EXIST, STOPCD.
|
||
|
||
FDIGET: HLRZ T1,P3 ;GET FED UNIT
|
||
|
||
|
||
;ENTER HERE WITH UNIT # IN T1, CPU#,,DTE# IN P1
|
||
|
||
FDIGT0: MOVE F,P1 ;GET CPU#,,DTE# IN F
|
||
PUSH P,T1 ;SAVE FED UNIT NUMBER
|
||
PUSHJ P,GTETDS## ;GET DTE CONTROL BLOCK ADDR OR DIE
|
||
POP P,T1 ;RESTORE FED UNIT NUMBER
|
||
PUSHJ P,GETFE0 ;GET THE BLOCK OR
|
||
STOPCD .,STOP,NFB, ;++NO FRONT END DEVICE BLOCK
|
||
SALL
|
||
POPJ P, ;OK, RETURN
|
||
|
||
|
||
|
||
;HERE WITH FED UNIT NUMBER IN T1, DTE CONTROL BLOCK ADDR IN F
|
||
; RETURN CPOPJ1 WITH FED BLOCK ADDRESS IN F, OR CPOPJ IF ERROR.
|
||
|
||
GETFE0: LOAD. F,ED.FED,(F) ;GET FIRST FEB ADDRESS ON THIS FRONT END
|
||
GETFE1: JUMPE F,CPOPJ## ;END OF CHAIN, GIVE ERROR RETURN
|
||
LOAD. T3,FE.UNI,(F) ;GET UNIT NUMBER OF THIS FE DEVICE
|
||
CAMN T1,T3 ;THIS THE ONE?
|
||
JRST CPOPJ1## ;YES, RETURN WITH FEB ADDRESS IN F
|
||
LOAD. F,FE.LNK,(F) ;NO, GET NEXT ADDRESS
|
||
JRST GETFE1 ;AND KEEP LOOKING
|
||
SUBTTL CORE ALLOCATION/DEALLOCATION
|
||
|
||
;ROUTINE TO SETUP INPUT AND OUTPUT BUFFERS FOR FED. CALLED
|
||
; WHEN JOB GETS FED. CALL WITH C(F) = FED BLOCK. NON-SKIP
|
||
; WITH CORRECT ERROR CODE IN T1 IF NO CORE AVAILABLE, SKIP
|
||
; RETURN IF ALL OK.
|
||
|
||
FEDGTC: MOVEI T2,<.FEISZ+<^D36/^D16-1>>/<^D36/^D16>
|
||
;GET NUMBER OF WORDS IN FED BUFFER, ROUNDED UP
|
||
PUSHJ P,GETWDS## ;GET THAT MANY FOR INPUT BUFFER
|
||
PJRST DTUNFC## ;NO FREE CORE, GIVE ERROR RETURN
|
||
MOVEM T1,FEDIBF(F) ;OK, SAVE ADDRESS
|
||
MOVEI T2,<.FEOSZ+<^D36/^D16-1>>/<^D36/^D16>
|
||
;GET NUMBER OF WORDS IN FED BUFFER, ROUNDED UP
|
||
PUSHJ P,GETWDS## ;GET CORE FOR OUTPUT BUFFER NOW
|
||
PJRST [PUSHJ P,FEDRC1 ;NO FREE CORE, RELEASE INPUT BUFFER NOW
|
||
PJRST DTUNFC##] ;LOSE
|
||
MOVEM T1,FEDOBF(F) ;SAVE THAT TOO
|
||
JRST CPOPJ1## ;OK RETURN
|
||
|
||
|
||
;ROUTINE TO GIVE BACK FED BUFFER CORE. ALWAYS NON-SKIP RETURN.
|
||
; IGNORE IF NO BUFFERS TO GIVE BACK.
|
||
|
||
FEDRLC: MOVEI T1,<.FEOSZ+<^D36/^D16-1>>/<^D36/^D16>
|
||
;GET NUMBER OF WORDS IN FED BUFFER, ROUNDED UP
|
||
SKIPE T2,FEDOBF(F) ;GET ADDRESS
|
||
PUSHJ P,GIVWDS## ;GET RID OF OUTPUT BUFFER
|
||
SETZM FEDOBF(F) ;SAY NO MORE BUFFER
|
||
FEDRC1: MOVEI T1,<.FEISZ+<^D36/^D16-1>>/<^D36/^D16>
|
||
;GET NUMBER OF WORDS IN FED BUFFER, ROUNDED UP
|
||
SKIPE T2,FEDIBF(F) ;GET ADDRESS
|
||
PUSHJ P,GIVWDS## ;GIVE BACK THE INPUT BUFFER
|
||
SETZM FEDIBF(F) ;OK, NO MORE INPUT BUFFER
|
||
POPJ P, ;RETURN
|
||
SUBTTL UTILITY ROUTINES
|
||
|
||
|
||
;ROUTINE TO CHECK TO SEE IF A JOB OWNS A FRONT END DEVICE, RETURN
|
||
; TO NEXT LEVEL IF NOT. CALL:
|
||
; ASSUMES JOB IS CURRENT (.CPJCH)
|
||
; MOVE F,<FED BLOCK ADDRESS>
|
||
; JSP T4,FEJCHK
|
||
; <RETURN IF JOB OWNS FRONT END DEVICE>
|
||
|
||
|
||
FEJCHK: LOAD. T1,FE.JCH,(F)
|
||
CAME T1,.CPJCH## ;DOES JOB OWN THIS FRONT END DEVICE?
|
||
JRST DTUDOF## ;NO, GIVE ERROR (AND POPJ BACK TO UPPER LEVEL)
|
||
JRST (T4) ;YES, RETURN TO CALLER
|
||
|
||
|
||
;ROUTINE TO SETUP PUT AND TAKE POINTERS, AND FREE BYTES IN
|
||
; FED INPUT BUFFER. CALLED AT FED INITIALIZATION TIME AFTER
|
||
; BUFFERS HAVE BEEN ALLOCATED, AND JUST BEFORE AN ACK IS SENT TO
|
||
; THE -11. CALL WITH FED BLOCK ADDRESS IN F
|
||
|
||
|
||
FEDSPT: MOVE T1,FEDIBF(F) ;SETUP INITIAL INPUT BUFFER POINTER
|
||
HRLI T1,(POINT 16,) ;MAKE IT A POINTER
|
||
MOVEM T1,FEDTPT(F) ;SETUP TAKE POINTER
|
||
MOVEM T1,FEDPPT(F) ;AND PUT POINTER
|
||
MOVEI T1,.FEISZ ;SETUP NUMBER OF BYTES IN BUFFER FREE
|
||
MOVEM T1,FEDFBI(F) ;FREE BYTES IN INPUT BUFFER
|
||
SETZM FEDTCT(F) ;NO DATA AVAILABLE TO USER
|
||
POPJ P, ;RETURN
|
||
SUBTTL DTESER FUNCTION DISPATCH TABLE FOR THIS DRIVER
|
||
|
||
|
||
IFIW FEDLMG ;(-1) LOST TO-10 INDIRECT MESSAGE
|
||
FEDDSP::DTEFNC ;(??) GENERATE DUMMY TABLE ENTRIES
|
||
DTEFNC (STR,FEDTKD) ;(03) HERE IS STRING DATA
|
||
DTEFNC (HDS,FEDTKS) ;(07) HERE IS DEVICE STATUS
|
||
DTEFNC (ACK,FEDACK) ;(17) ACK
|
||
DTEFNC (AKA,FEDAAL) ;(25) ACK ALL
|
||
|
||
END
|