Trailing-Edge
-
PDP-10 Archives
-
BB-K911B-SM
-
sources/fesrv.mac
There are 48 other files named fesrv.mac in the archive. Click here to see a list.
;<4.MONITOR>FESRV.MAC.4, 3-Jan-80 08:08:40, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<OSMAN.MON>FESRV.MAC.1, 10-Sep-79 15:28:23, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>FESRV.MAC.2, 4-Mar-79 16:40:07, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>FESRV.MAC.1, 8-Dec-78 17:26:37, EDIT BY MILLER
;USE HLDF TO REQUEST HOLD IN BALSET
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG
TTITLE FESRV
IFN KLFLG,<
SEARCH PROKL>
;DEVICE CODE FOR FE DEVICES. THIS CODE CONTAINS THE DEVICE
;DEPENDENT ROUTINES FOR THE FE PSEUDO DEVICES. THE DEVICE NAMES
;ARE FEN: WHERE 0<=N<=3
;REGISTERS USED HEREIN
DEFAC (STS,P1) ;GTJFN,ETC BITS
DEFAC (JFN,P2) ;THE JFN FOR THE OPERATION
DEFAC (DEV,P4)
;STORAGE DEFINED IN STG FOR FE'S
EXTN<FELOCK,FEUDB0,FEUDB1,FEUDB5,FEUDB6,FEUDB7,FEUDB3,FEUDB4,FEN>
BLKSIZ==^D64 ;SIZE OF A BUFFER
;DATA DEFINITIONS FOR UNIT DATA BLOCKS
DEFSTR (FEACT,FEUDB0,0,1) ;OUTPUT ACTIVE BIT
DEFSTR (FEDTE,FEUDB0,2,2) ;FIELD FOR WHICH DTE OWNS THIS DEVICE
DEFSTR (FEFRK,FEUDB0,35,18) ;FORK NUMBER OWNING DEVICE
DEFSTR (FEBLK,FEUDB0,3,1) ;UNIT IS BLOCKED
DEFSTR (FEEOF,FEUDB0,4,1) ;INPUT EOF DECLARED BY FE
DEFSTR (FEVDT,FEUDB0,5,1) ;FE ASSIGNMENT IS VALID
DEFSTR (FEFEM,FEUDB0,17,12) ;FE ALLOCATION
DEFSTR (FEICT,FEUDB1,11,12) ;CURRENT INPUT COUNT IN BYTES
;DEFSTR (FEICM,FEUDB1,23,12) ;UNUSED
DEFSTR (FEFEI,FEUDB1,35,12) ;BYTES NOW IN FE
DEFSTR (FEIBF,FEUDB3,17,18) ;BUFFER ADDRESS
DEFSTR (FEOCT,FEUDB3,35,12) ;OUTPUT COUNT
DEFSTR (FEBSZ,FEUDB3,23,6) ;BYTE SIZE OF OPENING
FEBPI==FEUDB4 ;INPUT INPUT POINTER
DEFSTR (FEHNG,FEUDB5,0,1) ;HUNG BIT
DEFSTR (FEPRO,FEUDB5,11,11) ;COUNT OF INPUT SINCE LAST ACK
DEFSTR (FEIBC,FEUDB5,23,12) ;COUNT OF BYTES IN INTERRUPT BUFFER
DEFSTR (FEOE1,FEUDB5,35,12) ;BYTES REMAINING FOR OUTPUT LEVEL
FEBPO==FEUDB6 ;OUTPUT OUTPUT POINTER
DEFSTR (FEIE1,FEUDB7,11,12) ;BYTES REMAINING FOR INPUT LEVEL
DEFSTR (FEOEB,FEUDB7,23,12) ;BYTES REMAINING FOR OUTPUT INT LEVEL
DEFSTR (FEIEB,FEUDB7,35,12) ;BYTES REMAINING FOR INPUT IN LEVEL
;DEVICE TRANSFER VECTOR
;FIRST THE PROTOCOL VECTOR
RESCD
FEDTV::FEHSD ;STRING DATA
FEDON ;ACK
FESSTS ;STATUS
FESLA ;SET LINE ALLOCATION
0 ;NO SYSERR
FERLD ;RELOAD ACTION
SWAPCD
FEDTB:: DTBBAD (GJFX32) ;SET DIRECTORY
DTBBAD (DESX9) ;NAME LOOKUP
DTBBAD (DESX9) ;EXTENSION LOOKUP
DTBBAD (DESX9) ;VERSION LOOKUP
DTBBAD (DESX9) ;PROTECTION INSERTION
DTBBAD (DESX9) ;ACCOUNT INSERTION
DTBBAD (DESX9) ;STATUS INSERTION
DTBDSP (FEOPN) ;OPEN
DTBDSP (FEBIN) ;BIN
DTBDSP (FEBOUT) ;BOUT
DTBDSP (FECLZ) ;CLOSE
DTBBAD (DESX9) ;RENAME
DTBBAD (DESX9) ;DELD
DTBBAD (DUMPX6) ;DUMPI
DTBBAD (DUMPX6) ;DUMPO
DTBBAD (DESX9) ;MOUNT
DTBBAD (DESX9) ;DISMOUNT
DTBBAD (DESX9) ;INIT DIRECTORY
DTBDSP (FEMTO) ;MTOPR
DTBBAD (DESX9) ;GETSTS
DTBBAD (DESX9) ;SETSTS
DTBSKP ;RECORD OUT
DTBDSP (RFTADN) ; READ TAD
DTBDSP (SFTADN) ; SET TAD
DTBDSP (FESETI) ;SET JFN FOR INPUT
DTBDSP (FESETO) ;SET JFN FOR OUTPUT
DTBBAD (GJFX49) ;CHECK ATTRIBUTE
DTBLEN==:.-FEDTB ;GLOBAL LENGTH OF DISPATCH TABLE
SWAPCD
;FEINI IS CALLED AT SYSTEM STARTUP TO INITIALIZE THE FE DATA
;BASE.
FEINI:: MOVSI A,-FEN ;NUMBER OF FE'S IN CONFIGURATION
SETOM FELOCK ;INIT LOCK TO AVAILABLE
FECLR: SETZM FEUDB0(A) ;CLEAR UDB0
SETZM FEUDB1(A) ;UDB1
AOBJN A,FECLR ;DO ALL DEVICES
RET ;AND DONE
;ROUTINE TO OPEN AN FE DEVICE. ACCEPTS:
; DEV/ UNIT,,DTB ADDRESS
; STS/ BITS AND BYTE SIZE
SWAPCD ;IS SWAPPABLE
FEOPN: ACVAR <W1>
STKVAR <<BTARG,2>> ;ARGS FOR BOOT JSYS
SKIPN PROFLG ;EVER GOING TO USE PRIMARY PROTOCOL ?
RETBAD (OPNX18) ;NO, ISSUE ERROR
MOVE A,CAPENB ;GET ENABLED CAPABILITIES
TXNN A,SC%WHL!SC%OPR ;MUST BE WHEEL OR OPERATOR
RETBAD (CAPX1) ;IF NOT, RETURN WITH ERROR
LDB W1,PBYTSZ ;GET DEISRED BYTE SIZE OF OPEN
CAIE W1,10 ;8 BITS
CAIN W1,20 ;OR 16 BITS?
JRST FEOPN2 ;YES. ALLOW IT
CAIE W1,7 ;OR 7 BITS?
RETBAD (SFBSX2) ;NO. CAN'T DO IT THEN
FEOPN2: LOCK FELOCK,<CALL LCKTST> ;LOCK UP THE DATA BASE
HLRZ D,DEV ;GET PROPER UNIT
JN FEFRK,(D),[ UNLOCK FELOCK ;ALREADY ASSIGNED?
RETBAD (OPNX9)] ;YES. GIVE ERROR
TRNE STS,17 ;NORMAL MODE?
RETBAD (OPNX14,<UNLOCK FELOCK>) ;NO. BOMB HIM
JUMPN D,FEOPN1 ;IF NOT FE0, DON'T SET DTE ASSIGNMENT
JN FEVDT,(D),FEOPN1 ;IF ALREADY ASSIGNED ,SKIP THIS
MOVEI A,.BTSTS ;READ DTE STATUS
MOVEI B,BTARG ;WHERE ARG IS
MOVEM D,.BTDTE(B) ;SET UP ARG
BOOT ;READ PROTOCOL STATUS
ERJMP FEOPN1 ;IF NON-EX DTE, GO ON
MOVE B,.BTCOD(B) ;GET PROTOCOL STATE
CAIE B,.VN20F ;DOING 20F PROTOCOL?
JRST FEOPN1 ;NO
STOR D,FEDTE,(D) ;MAKE THIS ON THE DEFAULT FE
SETONE FEVDT,(D) ;SAY ASSIGNMENT IS NOW VALID
; ..
;FEOPN CONTINUED
;ASSIGN BUFFERS TO THIS FE
FEOPN1: TQZE <RNDF> ;WANT APPEND?
TQO <WRTF> ;YES. GIVE WRITE THEN
MOVE A,[.RESP3,,BLKSIZ*2] ;GET BUFFER SPACE FOR THIS FE
MOVE B,[RS%SE0!.RESNP] ;FROM THE NETWORK POOL
CALL ASGRES ;GO GET THE FREE SPACE
JRST [ UNLOCK FELOCK ;FAILED. FREE THE LOCK
RETBAD()] ;AND DON'T DO THE OPEN
HLRZ D,DEV ;GET BACK UNIT NUMBER
STOR A,FEIBF,(D) ;STORE BUFFER ADDRESS
;BUFFERS ARE ASSIGNED
MOVEI A,^D36 ;BITS PER WORD
IDIV A,W1 ;COMPUTE BYTES PER WORD
IMULI A,BLKSIZ ;BYTES PER BUFFER
STOR W1,FEBSZ,(D) ;REMEMBER BYTE SIZE OF OPENING
CAIN W1,20 ;WORD MODE?
MOVEI A,BLKSIZ*4 ;YES. INT BUFFER HAS THIS SIZE THEN
STOR A,FEIBC,(D) ;STORE BYTES IN INTERRUPT BUFFER
SETZRO <FEICT,FEOCT,FEACT,FEFEI,FEPRO>,(D) ;CLEAR COUNTS
JN FEFEM,(D),FEOPN3 ;HAVE AN ALLOCATION YET?
STOR A,FEFEM,(D) ;NO. ASSUME A WHOLE BUFFER
FEOPN3: CALL SETINB
CALL SETINI
CALL SETOPB
CALL SETOBI ;GO INIT ALL BUFFER POINTERS
MOVE A,FORKX ;OWNING FORK
STOR A,FEFRK,(D) ;REMEMBER THIS
OPSTR <SKIPE>,FEVDT,(D) ;HAVE VALID ASSIGNMENT?
CALL SETALC ;YES, GO DECLARE LINE ALLOCATION
UNLOCK FELOCK ;FREE THE LOCK
TQO <SIZEF> ;CAN'T CHANGE FILE BYTE SIZE
RETSKP ;AND DONE
;ROUTINES TO INIT POINTERS AND COUNTS
;ROUTINE TO SET UP FILBYT FOR FILE
;ACCEPTS: D/ FE UNIT NUMBER
; JFN/ THE JFN FOR THE FILE
SETOPB: LOAD A,FEIBC,(D) ;GET MAX COUNT
STOR A,FEOE1,(D) ;SET THIS UP AS CURRENT
CALL FRMINP ;GET POINTER
ADDI A,BLKSIZ ;MOVE IT TO THE OUTPUT BUFFER
MOVEM A,FILMS2(JFN) ;SAVE IT
RET ;AND DONE
;SET UP POINTER AND COUNT FOR OUTPUT INTERRUPT LEVEL
RESCD ;CALLED FROM INT LEVEL
SETOBI: LOAD A,FEIBC,(D) ;GET MAX COUNT OF INT BUFFER
STOR A,FEOEB,(D) ;SAVE IT
CALL FRMINP ;GET POINTER
TLZE A,2000 ;WORD MODE?
TLO A,1000 ;YES. CHANGE TO BYTES
ADDI A,BLKSIZ ;POINT TO OUTPUT BUFFER
MOVEM A,FEBPO(D) ;SAVE IT
RET ;AND DONE
;ROUTINE TO SET UP INPUT POINTER AND COUNT
SWAPCD
SETINB: LOAD A,FEIBC,(D) ;GET MAX COUNT
STOR A,FEIE1,(D) ;SAVE IT
CALL FRMINP ;GET POINTER
MOVEM A,FILOFN(JFN) ;SAVE IT
RET ;AND DONE
;ROUTINE TO SET UP INPUT INT POINTER AND COUNT
RESCD ;CALLED FROM INT LEVEL
SETINI: LOAD A,FEIBC,(D) ;GET MAX COUNT OF INT BUFFER
STOR A,FEIEB,(D) ;SAVE IT
CALL FRMINP ;GET POINTER
TLZE A,2000 ;WORD MODE?
TLO A,1000 ;YES. MAKE IT BYTE MODE
MOVEM A,FEBPI(D) ;SAVE IT
RET ;AND DONE
;ROUTINE TO FORM A BYTE POINTER
FRMINP: LOAD A,FEIBF,(D) ;GET BUFFER ADDRESS
LOAD B,FEBSZ,(D) ;GET BYTE SIZE OF OPENING
IORI B,4400 ;MAKE PROPER BYTE POINTER
DPB B,[POINT 12,A,11] ;COMBINE HALVES
RET ;DONE
;ROUTINE TO OUTPUT A BYTE TO AN FE. ACCEPTS:
; A/THE BYTE
; JFN/ THE JFN FOR THE OPERATION
; DEV/ UNIT,,DTB
SWAPCD ;IS SWAPPABLE
FEBOUT: HLRZ D,DEV ;GET UNIT
JE FEVDT,(D),[ TQO <ERRF> ;OF NO VAILD ASSIGNMENT,
RET] ;THIS IS AN ERROR
STKVAR <SAVCHR>
MOVEM A,SAVCHR ;SAVE THE BYTE
CALL FESETO ;AND GO SET UP OUTPUT
SOSGE FILCNT(JFN) ;ROOM?
JRST [ CALL STRTFE ;GO START UP THE DEVICE
MOVSI A,0(D)
HRRI A,FEFULL
TQO <BLKF> ;NEED TO BLOCK
RET]
MOVE A,SAVCHR ;GET BACK BYTE
IDPB A,FILBYT(JFN) ;STORE IT
RET ;AND DONE
;SCHEDULER TEST ROUTINES
RESCD
FEFULL: JE FEVDT,(A),1(4) ;MAKE SURE STILL HAS AN ASSIGNMENT
LOAD B,FEOCT,(A) ;GET CURRENT COUNT
OPSTR <CAML B,>,FEIBC,(A) ;ROOM YET?
JRST 0(4) ;NO.
JRST 1(4) ;YES
FEDOBE::JE FEVDT,(A),1(4) ;MAKE SURE STILL HAS ASSIGNMENT
OPSTR <SKIPE>,FEOCT,(A) ;IS OUTPUT BUFFER EMPTY?
JRST 0(4) ;NO. CAN'T WAKE YET
OPSTR <SKIPE>,FEFEI,(A) ;HAS FE ACKED ALL BYTES?
JRST 0(4) ;NO. CAN'T WAKE YET
JRST 1(4) ;YES. TIME TO AWAKEN
;ROUTINE CALLED FROM DETSRV AT SCHEDULER LEVEL TO SEE IF ANY
;FE'S NEED ATTENTION
FEPOLL: MOVEI D,-FEN ;POLL ALL DEVICES
FEPOL2: JE FEHNG,(D),FEPOL1 ;IS ATTENTION BIT UP?
SETZRO FEHNG,(D) ;YES. CLEAR IT
CALL STRTF1 ;AND GO START UP THE DEVICE
FEPOL1: AOBJN D,FEPOL2 ;DO ALL OF THEM
RET ;AND DONE
;-11 RELOAD ACTION
FERLD: MOVSI D,-FEN ;SCAN ALL FE'S
FERLD1: JE FEVDT,(D),FERLD2 ;DON'T LOOK AT INACTIVE FE'S
LOAD B,FEDTE,(D) ;GET ITS ASSIGNMENT
CAIE B,0(A) ;SAME AS RELOADING -11?
JRST FERLD2 ;NO. SKIP IT
SETZRO FEVDT,(D) ;YES. CLEAR ASSIGNMENT AND GIVE
; PROGRAM ERROR NEXT I/O ATTEMPT
FERLD2: AOBJN D,FERLD1 ;SCAN THEM ALL
RET ;AND DONE
;DTE STARTUP AND INTERRUPT CODE
STRTFE: JN FEACT,(D),R ;IS IT ACITVE YET?
SETONE FEACT,(D) ;NO. START IT UP THEN
STRTF1: NOSKD1
CHNOFF DLSCHN ;AND THE DTE
CALL FEINT1 ;AND GO START A TRANSFER
CHNON DLSCHN ;TURN ON THE DTE
OKSKD1 ;AND THE SCHEDULER
RET ;AND DONE
;DTE POST ROUTINE
; A/ UNIQUE CODE
; B/ FE UNIT NUMBER
RESCD ;MUST BE RESIDENT
FEINT: CALL CHKFE
RET ;BAD DTE
MOVE D,B ;MOVE DTE NUMBER
LOAD C,FEOCT,(D) ;GET CURRENT COUNT
SUBI C,0(A) ;ACCOUNT FOR BYTES JUST SENT
STOR C,FEOCT,(D) ;AND UPDATE THE COUNT
OPSTRM <ADDM A,>,FEFEI,(D) ;AND INCREMENT BYTES IN THE FE
LOAD C,FEOEB,(D) ;GET BYTES IN PHYSICAL BUFFER
SUBI C,0(A) ;ACCOUNT FOR THE ONES SENT
JUMPLE C,[CALL SETOBI ;INIT NEW VALUES
JRST FEINT1] ;AND PROCEED
STOR C,FEOEB,(D) ;NEW COUNT
ADJBP A,FEBPO(D) ;UPDATE THE BYTE POINTER
MOVEM A,FEBPO(D) ;AND SAVE NEW VALUE
; ..
;DTE POST AND STARTUP CODE (STRTFE) JOIN HERE
FEINT1: JE FEOCT,(D),[SETZRO FEACT,(D)
RET] ;ALL DONE IF NO MORE BYTES
LOAD A,FEOCT,(D) ;GET CURRENT OUTPUT COUNT
LOAD C,FEFEM,(D) ;GET MAX BYTES ALLOWED IN FE
OPSTR <SUB C,>,FEFEI,(D) ;NUMBER REMAINING IN QUOTA
JUMPLE C,[SETONE FEBLK,(D) ;IF NO MORE ROOM, SAY WE ARE BLOCKED
RET] ;AND GIVE UP FOR NOW
CAILE A,0(C) ;ROOM FOR ALL BYTES?
MOVEI A,0(C) ;NO. TAKE SMALLER NUMBER THEN
LOAD C,FEOEB,(D) ;GET ROOM LEFT IN PHYSICAL BUFFER
CAILE A,0(C) ;DO WE NEED WRAP TO HANDLE ALL OF THEM?
MOVEI A,0(C) ;YES. DO AS MANY AS POSSIBLE THEN
LOAD B,FEBSZ,(D) ;GET BYTE SIZE OF OPENING
CAIN B,20 ;WORD MODE?
JRST [ TRZN A,1 ;YES. MUST BE EVEN COUNT THEN
JRST .+1 ;ALREADY IS
JUMPN A,.+1 ;WASN'T. IS IT NOW NON-ZERO?
SETONE FEBLK,(D) ;NO. SAY WE ARE BLOCKED
RET] ;AND GIVE UP
MOVEI C,0(A) ;COUNT
HRLI C,0(D) ;UNIT
PUSH P,D ;SAVE UNIT NUMBER
PUSH P,F ;SAVE FLAGS
MOVEI F,0(A) ;SAVE COUNT AS UNIQUE CODE
CAIE B,20 ;WORD MODE?
TXO C,DTBYTM ;NO. FORCE BYE-MODE TRANSFER
LOAD A,FEDTE,(D) ;DTE NUMBER
HRLI A,FEINT ;WHERE TO POST TO
MOVE B,[.DFHSD,,.FEFE]
MOVE D,FEBPO(D) ;BYTE POINTER
CALL DTEQ ;GO SEND DATA
JRST [ POP P,F ;FAILED.
POP P,D ;GET BACK UNIT NUMBER
SETONE FEHNG,(D) ;TELL SCHEDULER TO TRY AGAIN
RET] ;AND DONE
POP P,F ;RESTORE F
POP P,D ;AND UNIT NUMBER
RET ;AND DONE
;MTOPR FUNCTIONS FOR THE FE DEVICES.
;ACCEPTS: 2/FUNCTION
; USER 3/DATUM
;VALID FUNCTIONS:
; .MODTE ASSIGN FE TO SPECIFIED DTE
; .MOEOF EOF ON OUTPUT SIDE OF FE
SWAPCD ;ALL SWAPPABLE
FEMTO: STKVAR <<BTARGM,2>> ;SPACE FOR BOOT ARGS
TQNN <OPNF> ;ILLEGAL IF OPENED
RETBAD (CLSX1) ;JFN NOT OPENED ERROR
UMOVE C,C ;GET DATUM
HRRZS C ;RIGHT HALF ONLY
HLRZ D,DEV ;GET FE UNIT
CAIN B,.MOEOF ;SETTING OUTPUT EOF?
JRST CLZIT ;YES. GO DO IT
CAIE B,.MODTE ;SETING DTE ASSIGNMENT?
RETBAD (MTOX1) ;NO. UNKNOWN CODE
JN FEVDT,(D),[ ;NOW HAVE A VALID ASSIGNMEMT?
OPSTR <CAME C,>,FEDTE,(D) ;YES.IS IT THE SAME ONE?
JRST .+1 ;NO. DO ASSIGNMENT
RETSKP] ;YES. ALL DONE THEN
MOVEI A,.BTSTS ;SET UP TO VERIFY THIS DTE
MOVEI B,BTARGM ;ARG BLOCK
MOVEM C,.BTDTE(B) ;INTO ARG BLOCK
BOOT ;GET STATE
ERJMP [RETBAD (ASNDX3)] ;INVALID DTE
MOVE B,.BTCOD(B) ;GET PROTOCOL
CAIE B,.VN20F ;PROPER?
RETBAD (ASNDX3) ;NO
SETONE FEVDT,(D) ;REMEMBER IT HAS BEEN ASSIGNED
STOR C,FEDTE,(D) ;SET ASSIGNMENT
CALL SETALC ;GO SET DEVICE ALLOCATION
RETSKP ;DONE SUCCESSFULLY
;GENERATE DEVICE EOF TO THE FE
CLZIT: JE FEVDT,(D),[ RETBAD (ASNDX3)] ;IF NO VALID ASSIGNMENT
CALL FEIUND ;UNDO INPUT TO GET AN ACK (FOR THE DN64)
CALL FEOUND ;UNDO OUTPUT
JE FEOCT,(D),CLZIT1 ;ANY BYTES TO GO?
CLZIT2: CALL STRTFE ;YES. MAKE THEM GO NOW
MOVSI A,0(D) ;UNIT #
HRRI A,FEDOBE ;TEST ROUTINE
TQO <BLKF,HLDF> ;REQUEST BLOCK AND HOLD
RET
CLZIT1: CALL SETOPB ;INIT OUTPUT POINTERS
CALL SETOBI ;""
UMOVE C,C ;GET IT AGAIN
SKIPE C ;SEND EOF
RETSKP ;NO. JUST RETURN
HLRZ D,DEV ;GET UNIT AGAIN
LOAD A,FEDTE,(D)
MOVE B,[.DFSTS,,.FEFE] ;SET DEVICE STATUS
MOVSI C,0(D) ;UNIT
HRRI C,2 ;COUNT OF BYTES
MOVE D,[POINT 8,[BYTE (16) .DVFEF]]
CALL DTEQ ;DO IT
JFCL ;WILL GO
RETSKP ;AND DONE
;ROUTINE TO DECLARE ALLOCATION OF THIS LINE
; D/ UNIT NUMBER
SETALC: LOAD A,FEDTE,(D) ;GET DTE ASSIGNMENT
MOVE B,[.DFHLA,,.FEFE] ;FUNCTION,,DEVICE
MOVSI C,0(D) ;UNIT
LOAD D,FEIBC,(D) ;GET MAX BUFFER SIZE
LSH D,-1 ;HALVE IT
CALL DTEQ ;DO IT
JFCL
RET ;AND DONE
;ROUTINE TO SET EOF IN INPUT STREAM
;CALLED FROM DTESRV AT DTE PI LEVEL
; B/UNIT
; C/COUNT
; D/BYTE POINTER
RESCD
FESSTS::CAIGE C,2 ;ENOUGH BYTES LEFT?
RET ;NO ALL DONE
CALL CHKFE
RET ;ABD UNIT
ILDB A,D ;GET THE STATUS
ILDB A,D ;GET LOW EIGHT BITS
TXNN A,.DVFEF ;END OF FILE?
JRST [ BUG(FEUSTS)
JRST FESST1]
SETONE FEEOF,(B) ;AND IS AT EOF
FESST1: SUBI C,2 ;TOOK 2 BYTES
RET ;AND DONE
;ROUTINE TO COMPLETE LINE BUFFER EMPTY MESSAGE FROM DTE
;ACCEPTS: B/UNIT
FEDON:: JUMPL B,DONALL ;IF NEG, HE WANTS TO ACK THEM ALL
CALL CHKFE
RET ;BAD FE UNIT
SETZRO FEFEI,(B) ;NO BYTES IN FE -11 NOW
JN FEBLK,(B),[ ;IS IT NOW BLOCKED?
MOVE D,B ;YES
SETZRO FEBLK,(D) ;CLEAR BLOCKED INDICATOR
CALLRET FEINT1] ;AND GO START IT UP AGAIN
RET ;AND DONE
;HERE TO ACK ALL UNITS
DONALL: STKVAR <SAVEE>
MOVSI C,-FEN ;TO DO THEM ALL
DONAL1: MOVEM C,SAVEE
MOVEI B,0(C) ;SET UP ARG
LOAD C,FEDTE,(B) ;GET DTE ASSIGMENT
CAMN C,MSTRDT ;IS THIS ON THE MASTER?
CALL FEDON ;GO ACK IT
MOVE C,SAVEE ;THE WORD
AOBJN C,DONAL1 ;GO DO IT
RET ;AND DONE
;ROUTINE TO SET DEVICE ALLOCATION
;ACCEPTS: A/DEVICE CODE
; B/ALLOCATION
; C/UNIT
FESLA:: CALL CHKFE
RET ;BAD UNIT
LOAD D,FEIBC,(C) ;GET OUR MAX INT COUNT
CAILE B,0(D) ;DOES IT FIT IN OUR BUFFER?
MOVEI B,0(D) ;NO. USE OUR MAX SIZE THEN
STOR B,FEFEM,(C) ;SET IT
RET ;AND DONE
;ROUTINE TO CHECK AND VERIFY UNIT NUMBER
;WITH: B/ UNIT NUMBER
CHKFE: CAIL B,FEN ;VALID UNIT?
RET ;NO
JE FEVDT,(B),R ;MUST HAVE AN ASSIGNMENT
RETSKP ;ALL IS WELL
;ROUTINE CALLED FROM DTE INTERRUPT LEVEL TO PASS STRING DATA TO
;AN FE DEVICE. ACCEPTS:
; A/DTE#,,BYTE COUNT
; B/UNIT #
; C/DEVICE CODE
; D/BYTE POINTER TO THE DATA
RESCD ;MUST BE RESIDENT
FEHSD:: CALL CHKFE
RET ;BAD FE UNIT
EXCH B,D ;GET UNIT IN D
JE FEFRK,(D),R ;IF UNASSIGNED, FORGET IT
PUSH P,A ;SAVE COUNT
HLRZS A ;GET DTE
LOAD C,FEDTE,(D) ;GET ASSIGNED DTE
CAIE A,0(C) ;SAME?
JRST [ BUG(FEBAD) ;NO
JRST PA1] ;DONE
LOAD C,FEIBC,(D) ;GET MAX ALLOCATION
LOAD A,FEICT,(D) ;GET CURRENT COUNT
SUBI C,0(A) ;GET CURRENT ROOM LEFT
POP P,A
MOVEI A,0(A) ;ISOLATE BYTE COUNT
CAILE A,0(C) ;CAN PUT THEM IN?
JRST [ BUG(FEBFOV,<<A,D>,<C,D>>) ;NO
MOVE A,C ;ONLY DO THOSE THAT WILL FIT
JRST .+1]
OPSTRM <ADDM A,>,FEICT,(D) ;NEW COUNT OF BYTES IN FE
OPSTRM <ADDM A,>,FEPRO,(D) ;INPUT RECEIVED SINCE LAST ACK
ACVAR <W1,W2> ;GET SOME WORK REGISTERS
LOAD W2,FEIEB,(D) ;GET INT COUNT
FEHS1: ILDB W1,B ;GET NEXT BYTE
IDPB W1,FEBPI(D) ;INTO THE BUFFER
SOSG W2 ;ONE LESS INT LEVEL BYTE
CALL [ SAVET ;SAVE ALL TEMPS
CALL SETINI ;GO INIT BUFFERS
LOAD W2,FEIEB,(D) ;GET BACK THE COUNT
RET] ;AND PROCEED
SOJG A,FEHS1 ;DO ALL BYTES
STOR W2,FEIEB,(D) ;PUT BACK FINAL COUNT
RET ;AND DONE
;ROUTINE TO DO SEQUENTIAL INPUT ON AN FE.
;ACCEPTS: DEV/UNIT,,CODE
; JFN/THE JFN FOR THE OPERATION
SWAPCD ;IS SWAPABLE
FEBIN: HLRZ D,DEV ;GET UNIT
JE FEVDT,(D),[ TQO <ERRF> ;MAKE SURE ASSIGNMENT IS VALID
RET] ;ITS NOT
TQNE <EOFF> ;EOF ON DEVICE?
RET ;YES. FORGET IT
FEBIN1: CALL FESETI ;GO SET UP FOR INPUT
SOSL FILCNT(JFN) ;HAVE A BYTE TO FETCH?
JRST ABYTE ;YES. GO GET IT
JN FEEOF,(D),[ ;NO. HAVE AN EOF?
TQO <EOFF> ;YES. SET EOF IN STATUS
SETZRO FEEOF,(D) ;CLEAR LOCAL EOF
SETZ A, ;RETURN A NULL
RET] ;AND DONE
FEBIN2: MOVSI A,0(D) ;NO. MUST WAIT THEN
HRRI A,FEBWT
TQO <BLKF,HLDF> ;REQUEST BLOCK AND HOLD
RET ;AND RETURN
;HAVE SOME BYTES TO READ
ABYTE: ILDB A,FILBYT(JFN) ;GET A BYTE
RET ;AND DONE
;ROUTINES TO SET UP JFN FOR INPUT/OUTPUT.
FESETI: TQOE <FILINP> ;NOW SET UP FOR INPUT?
JRST [ SKIPLE FILCNT(JFN) ;YES. HAVE ANY INPUT?
RET ;YES. ALL READY THEN
CALL FEIUND ;NO. GO ACK AND RECOMPUTE COUNTS
JRST FESETI] ;AND TRY AGAIN
CALL FEOUND ;GO UNDO OUTPUT
HLRZ D,DEV ;GET UNIT NUMBER
LOAD B,FEICT,(D) ;GET COUNT OF BYTES
LOAD C,FEIE1,(D) ;GET BYTES LEFT IN RING
CAILE B,0(C) ;RING BIGGER THAN BUFFER?
MOVEI B,0(C) ;NO. USE RING THEN
MOVE C,FILOFN(JFN) ;GET CURRENT BYTE POINTER
FEXSET: MOVEM C,FILBYT(JFN) ;STASH IT
LOAD C,FEBSZ,(D) ;GET OPEN BYTE SIZE
CAIN C,20 ;WORD MODE?
LSH B,-1 ;YES. HALVE THE COUNT THEN
MOVEM B,FILCNT(JFN) ;SET UP THE COUNT
MOVEM B,FILMS1(JFN) ;SAVE INITIAL SIZE
MOVEM B,FILLEN(JFN) ;FAKE THE LENGTH
SETZM FILBYN(JFN) ;AND SAY WE ARE AT TOP OF FILE
RET ;AND DONE
;ROUTINE TO UNDO INPUT
FEIUND: HLRZ D,DEV ;GET UNIT NUMBER
TQZN <FILINP> ;NOW DOING INPUT?
RET ;NO. FALSE ALARM
SKIPGE FILCNT(JFN) ;HAVE A GOOD COUNT?
SETZM FILCNT(JFN) ;NO
MOVE B,FILMS1(JFN) ;START OFF COUNT
SUB B,FILCNT(JFN) ;COMPUTE USED BYTES
JUMPE B,R ;IF NONE USED, ALL DONE
LOAD C,FEBSZ,(D) ;GET BYTE SIZE
CAIN C,20 ;WORD MODE?
LSH B,1 ;YES. COMPUTE CORRECT COUNT
NOSKED
CHNOFF DLSCHN
LOAD C,FEICT,(D) ;GET CURRENT IN COUNT
SUBI C,0(B) ;NEW COUNT
STOR C,FEICT,(D) ;STASH IT
OPSTR <SUB C,>,FEPRO,(D) ;COMPUTE FEICT-FEPRO
CHNON DLSCHN
OKSKED
SKIPGE C ;CAN WE SEND AN ACK NOW?
CALL CLRALC ;YES. SO DO IT
LOAD C,FEIE1,(D) ;GET RING COUNT
SUBI C,0(B) ;NEW RING COUNT
SETZM FILCNT(JFN) ;NO COUNT
JUMPLE C,[CALLRET SETINB] ;IF ALL GONE, GET NEW COUNT
STOR C,FEIE1,(D) ;UPDATE COUNT
MOVE C,FILBYT(JFN) ;GET CURRENT BYTE POINTER
MOVEM C,FILOFN(JFN) ;AND REMEMBER IT
RET ;AND DONE
;ROUTINES TO SET UP AND MANAGE OUTPUT BUFFERS
;ENTRY TO SET UP FOR OUTPUT
FESETO: TQOE <FILOUP> ;NOW DOING OUTPUT?
JRST [ SKIPLE FILCNT(JFN) ;YES. ANY COUNT?
RET ;YES ALL DONE
CALL FEOUND ;NO. RECOMPUTE COUNTS
JRST FESETO] ;AND PROCEED
CALL FEIUND ;UNDO INPUT
HLRZ D,DEV ;GET UNIT NUMBER
LOAD B,FEIBC,(D) ;GET MAX COUNT OF OUTPUT BUFFER
OPSTR <SUB B,>,FEOCT,(D) ;GET ROOM LEFT
LOAD C,FEOE1,(D) ;GET ROOM LEFT IN RING
CAILE B,0(C)
MOVEI B,0(C) ;USE MINIMUM OF NUMBERS
MOVE C,FILMS2(JFN) ;GET BYTE POINTER
JRST FEXSET ;AND GO DO COMMON JFN SET UP
;ROUTINE TO UNDO OUTPUT
FEOUND: TQZN <FILOUP> ;NOW DOING OUTPUT?
RET ;NO. FALSE ALARM
HLRZ D,DEV ;GET UNIT NUMBER
SKIPGE FILCNT(JFN) ;HAVE A GOOD COUNT
SETZM FILCNT(JFN) ;NO. MAKE IT GOOD
MOVE B,FILMS1(JFN) ;GET STARTING COUNT
SUB B,FILCNT(JFN) ;GET ENDING COUNT
LOAD C,FEBSZ,(D) ;GET PREVAILING BYTE SIZE
CAIN C,20 ;WORD MODE?
LSH B,1 ;YES. COMPUTE BYTES
NOSKED ;PREVENT INTERRUPTION
CHNOFF DLSCHN
OPSTRM <ADDM B,>,FEOCT,(D) ;NEW OUTPTU COUNT
CHNON DLSCHN
OKSKED
LOAD C,FEOE1,(D) ;GET RING COUNT
SUBI C,0(B) ;COMPUTE BYTES LEFT IN THE RING
SETZM FILCNT(JFN) ;CLEAR COUNT
JUMPLE C,[CALLRET SETOPB] ;SET UP NEW RING QUANTITIES
STOR C,FEOE1,(D) ;NEW COUNT
MOVE C,FILBYT(JFN) ;GET FINAL BYTE POINTER
MOVEM C,FILMS2(JFN) ;AND REMEMBER IT
RET ;AND DONE
;ROUTINE TO SEND -11 LINE ALLOCATION EMPTY MESSAGE
;ACCEPTS D/UNIT
;PRESEVES ALL REGS
CLRALC: SAVET ;SAVE REGISTERS
SETZRO FEPRO,(D) ;CLEAR COUNT OF BYTES SINCE ACK
LOAD A,FEDTE,(D) ;GET DTE
MOVE B,[.DFLBE,,.FEFE] ;LINE BUFFER EMPTY
SETZ C,
CALL DTEQ ;SEND IT
JFCL
RET ;RETURN WITH BYTE
;SCHEDULER WAIT TEST FOR INPUT
RESCD
FEBWT:: JE FEVDT,(A),1(4) ;IF NOT VALID ASSIGNMENT, WAKE UP
JN FEEOF,(A),1(4) ;IF EOF UP, HAVE DATA
JE FEICT,(A),0(4) ;IF NOT AND NO DATA, REBLOCK
JRST 1(4) ;MUST HAVE DATA
;ROUTINE TO CLOSE AN FE DEVICE.
SWAPCD
FECLZ: HLRZ D,DEV ;GET UNIT
TXNE A,CZ%ABT ;WANT ABORT?
JRST FECLZ1 ;YES. GO IT NOW THEN
JE FEVDT,(D),[ RETBAD (ASNDX3)] ;NO. MUST HAVE AN ASSIGNMENT THEN
CALL FEOUND ;UNDO OUTPUT
JE FEOCT,(D),FECLZ1 ;ANY BYTES TO GO?
CALLRET CLZIT2 ;GO START FE AND BLOCK
FECLZ1: LOCK FELOCK,<CALL LCKTST>
SETZRO FEVDT,(D) ;NO DTEASSIGNED
SETZRO <FEFRK,FEBLK,FEEOF>,(D) ;CLEAR FIELDS
CALL CLRALC ;CLEAR FE'S BUFFERS
LOAD A,FEIBF,(D) ;GET BUFFER ADDRESS
CALL RELRES ;AND RELEASE IT
UNLOCK FELOCK
SETZM FILMS1(JFN)
SETZM FILMS2(JFN) ;CLEAN UP JFN BLOCK
RETSKP ;AND DONE
TNXEND ;END OF CODE
END ;END OF ASSEMBLY