! !*********************************************************************** ! !*********************************************************************** !* !* DIRECTOR ROUTINES DCONNECT & DDISCONNECT REPLACED BY SUBSYSTEM !* ROUTINES CONNECT & DISCONNECT !* 14/11/78 -- L.A.B. !* !********************************************************************** ! ! !* !* EMAS 2900 INTERFACE FOR KENT BASIC !* !********************************************************************** ! ! !********************************************************************** !* !* CONSTANTS !* !********************************************************************** ! %CONSTSTRING(4) VERSION = "1.5" %CONSTINTEGER SEG SHIFT = 18 %CONSTINTEGER NO = 0, %C YES = 1, %C FALSE = 0, %C TRUE = 1 %CONSTINTEGER CODE DESC = X'E1000000' %CONSTINTEGER NIL = 0 %CONSTINTEGER NOT IMPLEMENTED = X'8000' !?1; %CONSTINTEGER JS VAR LIMIT = 7 ;! SET TO 7 FOR TEST PURPOSES %C %CONSTINTEGER JS VAR LIMIT = 30 %CONSTINTEGER FILE LIMIT = 20 %CONSTINTEGER FOREGROUND = 1 %CONSTINTEGER BACKGROUND = 2 %CONSTSTRING(8) SOURCE = E"SOURCE" %CONSTBYTEINTEGERARRAY CONTINGENCY MAP (0:79) = %C 1,2,3,4,5,6,7,8,9,10,11,12,13,14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,64,51,66, 0,0,0,0,0,0,0,0,0,0,0,0,0 %CONSTINTEGERARRAY VALID ACTION (0:5) = %C 0,X'00000003',X'000000A1',X'00000081',X'00000020',X'00008000' %CONSTINTEGERARRAY VALID ACTION ID (0:5) = %C 0, 1 , 0 , 2 , 3 , 4 %CONSTINTEGER VA COUNT = 5 %CONSTINTEGERARRAY DML DECODE(0:14,0:1) = %C 0, 2, 0, 0, 0, 2, 2, 0, 0, 2, 1, 1, 1, 0, 0, 0,11, 0, 0, 0, 0, 2, 0, 0, 4, 6, 7, 9, 0, 0 %CONSTBYTEINTEGERARRAY RAF SWITCH (0:4,0:4) = %C 0,0,0,0,0, 0,1,3,6,7, 0,1,3,6,7, 0,2,5,8,7, 0,1,0,0,7 ! THE DIMENSIONS FOR RAF SWITCH CORRESPOND TO VALID ACTION ID ! AND DATA FORMAT VALUES %CONSTINTEGERARRAY FCR DML INFO DEFAULTS (0:12) = %C 0,0,0,0,0,0,2,1,-1,-1,-1,0,0 %CONSTSTRING(1)%ARRAY HEX TAB(0:15)="0","1","2","3","4","5","6","7", %C "8","9","A","B","C","D","E","F" ! ! ! !********************************************************************** !* !* GLOBALS !* !********************************************************************** ! %RECORDFORMAT JS VAR RF (%STRING(8) NAME,%STRING(80) VALUE, %C %INTEGER MAX LEN) !?2; %OWNINTEGER TRACE COUNT %OWNRECORDARRAY JS VAR (0:29) (JS VAR RF) %RECORDFORMAT FHDR FORMAT %C (%INTEGER DATA END,DATA START,FILE SIZE,FILE TYPE, %C CHECK SUM,DANDT,FORMAT,RECORD COUNT) %RECORDFORMAT FCR FORMAT %C (%INTEGER EP,PC,LNB, %C ROUTE,RAF SWITCH,CON ADDR,DATA FORMAT, %C %RECORDNAME FHDR, %C %INTEGER DATA LIMIT,RMIN,RMAX,CUR PTR,CUR LEN, %C BUFF DR0,BUFF DR1,XFER DR0,XFER DR1,KEY DR0,KEY DR1, %C POSITION,DISPLCMNT,ALL ACTIONS,NEW ACTIONS, %C ACC ACTIONS,CURR DR0,CURR DR1, %C %STRING(32) NAME,%STRING(6) OWNER) %RECORDSPEC FCR FORMAT_FHDR (FHDR FORMAT) %OWNRECORDARRAY FCT (0:20) (FCR FORMAT);! FILE CONTROL TABLE BEING A ! TABLE OF FILE CONTROL RECORDS %RECORDFORMAT CONNECTFORM(%INTEGER CONAD,FILETYPR,DATASTART,DATAEND) %OWNINTEGERARRAYFORMAT FDI FORMAT (0:12) ;! FCR DML INFORMATION %OWNINTEGER ENTRY LNB %OWNINTEGER RAM PC %OWNINTEGER RAM LNB %OWNINTEGER EXEC MODE %OWNINTEGER JS VAR COUNT %OWNLONGREAL INITIAL CPU TIME !?2; %OWNINTEGER TRACE STREAM %OWNINTEGER LOG STREAM !?3; %OWNINTEGER DIAG STREAM %OWNINTEGER IT PROMPT FLAG ! %OWNINTEGER INT DATA FLAG %OWNINTEGERARRAY INT DATA (0:17) %OWNLONGINTEGERARRAY CONT RTN DESC (0:63) %OWNSTRING(6) USER NAME ! !********************************************************************** !* !* EXTERNAL REFERENCES - SUBSYSTEM !* !********************************************************************** ! !?1; %EXTERNALINTEGERFNSPEC RETURN CODE %EXTERNALINTEGERFNSPEC OUT STREAM %EXTERNALROUTINESPEC DEFINE (%STRING(255) PARMS) %EXTERNALROUTINESPEC PROMPT(%STRING(15) NEW PROMPT) %EXTERNALLONGREALFNSPEC CPU TIME %EXTERNALSTRINGFNSPEC DATE %EXTERNALSTRINGFNSPEC TIME %SYSTEMROUTINESPEC DESTROY (%STRING(31) FILE NAME, %C %INTEGERNAME FLAG) %SYSTEMSTRINGFNSPEC CONFILE (%INTEGER ADDRESS) %SYSTEMROUTINESPEC CONNECT(%STRING(31) FILENAME, %C %INTEGER MODE,HOLE,PROTECT, %C %RECORDNAME R, %INTEGERNAME FLAG) %SYSTEMROUTINESPEC CHANGE ACCESS (%STRING(31) FILE NAME, %C %INTEGER NEW ACCESS, %C %INTEGERNAME FLAG) %SYSTEMROUTINESPEC CHANGE FILE SIZE (%STRING(31) FILENAME, %C %INTEGER NEW SIZE, %C %INTEGERNAME FLAG) %SYSTEMROUTINESPEC DISCONNECT(%STRING(31) FILENAME, %INTEGERNAME FLAG) %SYSTEMROUTINESPEC OUTFILE (%STRING(31) FILE NAME, %C %INTEGER SIZE,GAP,PROTECTION, %C %INTEGERNAME CONNECTED ADDR,FLAG) %SYSTEMSTRINGFNSPEC NEXT TEMP %SYSTEMROUTINESPEC MOVE (%INTEGER LENGTH,FROM ADDR,TO ADDR) %SYSTEMROUTINESPEC ITOE (%INTEGER ADDRESS,LENGTH) %SYSTEMROUTINESPEC ETOI (%INTEGER ADDRESS,LENGTH) %SYSTEMROUTINESPEC FILL (%INTEGER LENGTH,ADDRESS,FILLER) %EXTERNALROUTINESPEC SET RETURN CODE (%INTEGER RES) %EXTERNALINTEGERFNSPEC UINFI (%INTEGER ENTRY) %EXTERNALSTRINGFNSPEC UINFS (%INTEGER ENTRY) ! !********************************************************************** !* !* EXTERNAL REFERENCES - DIRECTOR !* !********************************************************************** ! %EXTERNALINTEGERFNSPEC DCREATE (%STRING(6) USER, %C %STRING(15) FILE, %C %INTEGER FSYS,FILE SIZE,X) %EXTERNALROUTINESPEC DRESUME (%INTEGER LNB,PC,ADDRESS) %EXTERNALINTEGERFNSPEC PRIME CONTINGENCY (%ROUTINE ONTRAP) %EXTERNALROUTINESPEC DRESET CONTINGENCY %EXTERNALINTEGERFNSPEC READ ID (%INTEGER ADDRESS) %EXTERNALINTEGERFNSPEC DISC ID !%EXTERNALINTEGERFNSPEC DCONNECT (%STRING(6) USER, %C ! %STRING(15) FILE,%INTEGER FSYS,MODE,APF, %C ! %INTEGERNAME SEG,GAP) !%EXTERNALINTEGERFNSPEC DDISCONNECT (%STRING(6) USER, %C ! %STRING(15) FILE,%INTEGER FSYS,DSTRY) ! DDISCONNECT PARAMETER DSTRY-- 0 FILE NOT DESTROYED -- 1 FILE DESTROYED ! !********************************************************************** !* !* MISCELLANEOUS DECLARATIONS !* !********************************************************************** %EXTERNALROUTINESPEC KBASC(%INTEGER DR0,DR1) !?3; %EXTERNALROUTINESPEC XDUMP (%STRING(120) COMMENT,%INTEGER A,L) !%EXTERNALINTEGERFNSPEC OMF LOAD (%STRING(63) FILE NAME) !%EXTERNALROUTINESPEC FIND OMF ENTRY(%STRING(32) NAME, %C ! %INTEGERNAME DR0,DR1) %INTEGERFNSPEC ASSIGN FILE (%INTEGER ROUTE DR0,ROUTE DR1, %C NIL0,NAME DR0,NAME DR1,GENERATION,NIL1, %C DESC DR0,DESC DR1) %INTEGERFNSPEC LOG MESSAGE (%INTEGER NIL0,NIL1,DR0,DR1) %INTEGERFNSPEC DE ASSIGN FILE (%INTEGER ROUTE,ST DR0,ST DR1) %ROUTINESPEC ABANDON(%INTEGER I,%STRING(120) COMMENT) ! ! !********************************************************************** !* !* SERVICE ROUTINES !* !********************************************************************** ! %INTEGERFN I2(%INTEGER AD) !AD POINTS TO THE FIRST OF A PAIR OF DECIMAL CHARACTERS. THE RESULT !IS THE NUMERIC VALUE OF THE CHAS %RESULT = 10*(BYTEINTEGER(AD)&X'F')+(BYTEINTEGER(AD+1)&X'F') %END; !OF I2 %INTEGERFN PACKDATE(%STRING (8) DATE) %INTEGER AD AD = ADDR(DATE) %RESULT = ((I2(AD+7)-70)<<26)!(I2(AD+4)<<22)!(I2(AD+1)<<17) %END; !OF PACKDATE %INTEGERFN PACKDATEANDTIME(%STRING (8) DATE, TIME) %INTEGER AT AT = ADDR(TIME) %RESULT = PACKDATE(DATE)!(I2(AT+1)<<12)!(I2(AT+4)<<6)!(I2( %C AT+7)) %END; !OF PACKDATEANDTIME ! %INTEGERFN FILE TIME STAMP %RESULT = PACK DATE AND TIME(DATE,TIME) %END ;! OF FILE TIME STAMP ! %ROUTINE DECODE PPLIST (%INTEGER PP DR0,PP DR1, %C %INTEGERARRAYNAME DECODE,ENCODE) ! ! THIS ROUTINE DECODES A LIST OF PARAMETER PAIRS ( DEFINED BY ! THE DESCRIPTOR PP DR0,PP DR1) INTO AN ARRAY, ENCODE, BY A MAPPING ! DEFINED BY THE ARRAY DECODE. NOTE THAT THE DESCRIPTOR ! IS A WORD TYPE DESCRIPTOR, IE SCALED TO 4 BYTES. ! ! THE LIST OF PARAMETER PAIRS CONSISTS OF CONSECUTIVE TRIPLETS ! OF WORDS, EACH TRIPLET CONSTITUTING A PARAMETER PAIR. ! THE FIRST WORD IS ITS IDENTIFIER AND THE OTHER ! TWO BEING THE CORRESPONDING VALUE. THE LAST WORD NEED ! NOT NECESSARILY BE USED. ! THE 'ENCODE' ARRAY IS A SINGLE DIMENSION ARRAY (WHOSE LOWER ! BOUND IS ZERO) INTO WHICH THE VALUES FROM THE PARM PAIR ! LIST ARE COPIED ! THE 'DECODE' ARRAY IS TWO DIMENSIONAL (0:N,0:1) WHERE N IS ! THE HIGHEST VALUE OF PARM PAIR IDENTIFIER EXPECTED. FOR EACH ! IDENTIFIER VALUE THERE ARE TWO ELEMENTS IN THIS ARRAY: ! ! DECODE(N,0) - THE NUMBER OF WORDS TO BE COPIED FROM THE ! PARM PAIR WITH IDENTIFIER N. IF ZERO, THIS ! PARM PAIR NOT OF INTEREST. ! DECODE(N,1) - AN INDEX INTO THE 'ENCODE' ARRAY POINTING TO ! ELEMENT(S) TO RECEIVE THE PARM PAIR VALUE. ! %INTEGER I,ID %SWITCH S (0:2) ! %CYCLE I =PPDR1,12,(PPDR1+(PP DR0&X'00FFFFFF')*4)-12 ID = INTEGER(I) -> S(DECODE(ID,0)) S(2): ENCODE(DECODE(ID,1)+1) = INTEGER (I+8) S(1): ENCODE(DECODE(ID,1)) = INTEGER (I+4) S(0): %REPEAT %RETURN %END ;! OF DECODE PP LIST ! %INTEGERFN CREATE JS VAR (%STRING(8) NAME,%STRING(80) VALUE, %C %INTEGER MAX LEN) JS VAR COUNT = JS VAR COUNT + 1 %IF JS VAR COUNT = JS VAR LIMIT %THEN %RESULT = X'B01' JS VAR(JS VAR COUNT)_NAME = NAME JS VAR(JS VAR COUNT)_VALUE = VALUE %IF MAX LEN < 0 %THEN JS VAR(JS VAR COUNT)_MAX LEN = LENGTH(VALUE) %C %ELSE JS VAR(JS VAR COUNT)_MAX LEN = MAX LEN %RESULT = -2 %END ;! OF CREATE JS VAR ! !?1; %STRING(255)%FN ISOF(%STRING(255) ESTRING) !?1; ETOI(ADDR(ESTRING)+1,LENGTH(ESTRING)) !?1; %RESULT = ESTRING !?1; %END ;! OF ISOF ! %STRING(8)%FN BIN STRING(%INTEGER M,N) %STRING(8) WORK LENGTH(WORK) = 8 MOVE(4,ADDR(M),ADDR(WORK)+1) MOVE(4,ADDR(N),ADDR(WORK)+5) %RESULT = WORK %END ;! OF BIN STRING ! %SYSTEMSTRING(15)%FN SFROMI (%INTEGER X) %INTEGER REM,NUMB,NF %STRING(15) ANS ANS = '' %IF X < 0 %THEN %START NF = YES X = X*(-1) %FINISH %ELSE NF = NO %CYCLE NUMB = X X = X//10 REM = NUMB - X*10 ANS = TOSTRING(REM+'0').ANS %EXIT %IF X = 0 %REPEAT %IF NF = YES %THEN ANS = "-".ANS %RESULT = ANS %END ;! OF SFROMI ! %INTEGERFN IFROMS (%STRING(20) NUMBER) %INTEGER I,J,K,L K=ADDR(NUMBER) J=0 %CYCLE I=1,1,20 L = BYTEINTEGER(K+I) %IF L<'0' %OR L>'9' %THEN %RESULT = J J=(J*10)+L-'0' %REPEAT %END ;! OF IFROMS ! %ROUTINE LOG (%STRING(120) MSG) %INTEGER CURRENT STREAM CURRENT STREAM = OUTSTREAM SELECT OUTPUT (LOG STREAM) SPACES(9) PRINTSTRING(MSG) ; NEWLINE SELECT OUTPUT(CURRENT STREAM) %RETURN %END ;! OF LOG ! !?3; %ROUTINE LOG DIAG (%STRING(120) MSG) !?3; %INTEGER CURRENT STREAM !?3; CURRENT STREAM = OUT STREAM !?3; SELECT OUTPUT (DIAG STREAM) !?3; NEWLINE !?3; PRINTSTRING('KBB DIAG:'.MSG) !?3; NEWLINE !?3; SELECT OUTPUT(CURRENT STREAM) !?3; %RETURN !?3; %END ;! OF LOG DIAG ! !?1; %STRING(8)%FN HEXOF (%INTEGER X) !?1; %STRING(8) ANS !?1; %INTEGER I !?1; ANS = '' !?1; %CYCLE I=0,4,28 !?1; ANS = HEXTAB((X>>I)&X'0000000F').ANS !?1; %REPEAT !?1; %RESULT = ANS !?1; %END ;! OF HEXOF ! ! %LONGINTEGERFN LONG INT (%LONGREAL X) *LSQ _X *RAD _R'40800000000000000000000000000000' *RSC _47 *RSC _-47 *FIX _%B *MYB _4 *CPB _-64 *JCC _10,
  • *LB _-64 LI: *ISH _%B *EXIT _-64 %END ;! OF LONG INT ! %STRING(255)%FN STRING FROM (%INTEGER LENGTH,ADDRESS) %STRING(255) S *LB _LENGTH *LDA _ADDRESS *LDTB _X'18000000' *LDB _%B *CYD _0 *LD _S *MVL _%L=1 *MV _%L=%DR,0,129 %RESULT = S %END ;! OF STRING FROM ! %ROUTINE FIND JS VAR (%STRING(8) NAME,%INTEGERNAME POINTER) %INTEGER I %CYCLE I=0,1,JS VAR COUNT %IF NAME = JS VAR(I)_NAME %THEN POINTER = I %AND %RETURN %REPEAT POINTER = -1 %RETURN %END ;! OF FIND JS VAR ! !?1; %STRING(80)%FN NEXT LINE !?1; %INTEGER I !?1; %BYTEINTEGERARRAY LINE (0:80) !?1; %WHILE NEXT SYMBOL = NL %THEN SKIP SYMBOL !?1; %CYCLE I=1,1,80 !?1; READ SYMBOL(LINE(I)) !?1; %IF LINE(I) = NL %THEN %EXIT !?1; %REPEAT !?1; LINE(0) = I-1 !?1; %RESULT = STRING(ADDR(LINE(0))) !?1; %END ;! OF NEXT LINE ! %STRING(255)%FN DE SPACED (%STRING(255) S) %STRING(255) B,A %WHILE S -> B.(" ").A %THEN S = B.A %RESULT = S %END ;! OF DE SPACED ! !?1; %ROUTINE ASK FOR STREAM(%INTEGERNAME STREAM,%STRING(15) P) !?1; %INTEGER X,RC !?1; %STRING(80) REPLY !?1; ! !?1; RC = 1 !?1; PROMPT(P) !?1; %WHILE RC > 0 %THEN %CYCLE !?1; REPLY = DESPACED(NEXT LINE) !?1; %IF REPLY = "" %THEN %RETURN !?1; X = IFROMS(REPLY) !?1; %IF X>0 %AND X<80 %THEN STREAM = X %AND %RETURN !?1; DEFINE(SFROMI(STREAM).",".REPLY) !?1; X = RETURN CODE !?1; %IF X = 0 %THEN %RETURN !?1; PRINTSTRING("REPLY NOT VALID") !?1; NEWLINE !?1; %REPEAT !?1; %RETURN !?1; %END ;! OF ASK FOR STREAM ! !?2; %ROUTINE TRACE (%STRING(40) RTN,MSG,%INTEGER LNB,N,PPO) !?2; %STRING (132) WORKA,WORKB !?2; %INTEGER PPDESC ADDR,PPADDR,PPLEN,CURRENT STREAM !?2; TRACE COUNT = TRACE COUNT + 1 !?2; WORKA="TRACE CALL >>".SFROMI(TRACE COUNT)."<< ".RTN." ".MSG !?2; CURRENT STREAM = OUT STREAM !?2; SELECT OUTPUT (TRACE STREAM) !?2; NEWLINES(2) !?2; PRINTSTRING(WORKA) !?2; NEWLINE !?2; WORKB="STACK DUMP STARTING FROM LNB, ".SFROMI(N)." WORDS OF PARMS" !?2; XDUMP(WORKB,LNB,(10+N)*4) !?2; %IF PPO > -1 %THEN %START !?2; NEWLINE !?2; PPDESC ADDR = LNB + 20 +(PPO*4) !?2; PPLEN = INTEGER(PPDESC ADDR)&X'0000FFFF' !?2; PPADDR = INTEGER(PPDESC ADDR+4) !?2; %UNLESS PPADDR = NIL %OR PPLEN = NIL %THEN %START !?2; WORKB="PARAMETER PAIR LIST DUMP FOLLOWS ," !?2; WORKB=WORKB.SFROMI(PPLEN)." WORDS IN LIST" !?2; XDUMP(WORKB,PPADDR,PPLEN*4) !?2; %FINISH %ELSE %START !?2; PRINTSTRING("PARAMETER PAIR LIST IS NIL") ; NEWLINE !?2; %FINISH !?2; %FINISH !?2; NEWLINE !?2; SELECT OUTPUT(CURRENT STREAM) !?2; !?3; LOG DIAG(WORKA) !?2; %RETURN !?2; %END ;! OF TRACE ! !?2; %ROUTINE RESULT TRACE (%STRING(32) RTN NAME,%INTEGER RC) !?2; %STRING(132) S !?2; %INTEGER CURRENT STREAM !?2; S = " RESULT = ".SFROMI(RC) !?2; S = S." FROM ".RTN NAME !?2; CURRENT STREAM=OUT STREAM !?2; SELECT OUTPUT(TRACE STREAM) !?2; PRINTSTRING(S) !?2; SELECT OUTPUT(CURRENT STREAM) !?2; !?3; LOG DIAG(S) !?2; %RETURN !?2; %END ;! OF RESULT TRACE ! !?3; %ROUTINE PRINT FCT !?3; %INTEGER I !?3; %RECORDNAME FCR (FCR FORMAT) !?3; ! !?3; NEWLINE !?3; PRINTSTRING("FILE CONTROL TABLE, FILE LIMIT = ".SFROMI(FILE LIMIT)) !?3; NEWLINE !?3; PRINTSTRING(" FILE NAME") ; SPACES(22) !?3; PRINTSTRING(" ROUTE RAFS FORMAT ALL ACTS") !?3; NEWLINE !?3; %CYCLE I=0,1,FILE LIMIT !?3; FCR == FCT(I) !?3; %IF FCR_PC=0 %THEN -> REP !?3; NEWLINE !?3; WRITE(I,2) ; SPACES(4) !?3; PRINTSTRING(FCR_OWNER.".".FCR_NAME) !?3; SPACES(31-LENGTH(FCR_OWNER)-LENGTH(FCR_NAME)) !?3; WRITE(FCR_ROUTE,3) !?3; WRITE(FCR_RAF SWITCH,5) !?3; WRITE(FCR_DATA FORMAT,5) !?3; PRINTSTRING(" ".HEXOF(FCR_ALL ACTIONS)) !?3; REP: !?3; %REPEAT !?3; NEWLINE !?3; %RETURN !?3; %END ;! OF PRINT FCT !?3; ! !?3; %ROUTINE PRINT JSV TABLE !?3; %INTEGER I,J,K !?3; %RECORDNAME VAR (JS VAR RF) !?3; ! !?3; NEWLINES(2) !?3; PRINTSTRING("TABLE OF JOB SPACE VARIABLES, JS VAR LIMIT =") !?3; WRITE(JS VAR LIMIT,0) !?3; NEWLINE !?3; %CYCLE I = 0,1,JS VAR COUNT !?3; VAR == JS VAR(I) !?3; NEWLINE !?3; WRITE(I,3) ; SPACES(4) !?3; PRINTSTRING(ISOF(VAR_NAME)) !?3; SPACES(8-LENGTH(VAR_NAME)) !?3; WRITE(VAR_MAX LEN,6) !?3; WRITE(LENGTH(VAR_VALUE),4) !?3; PRINTSTRING(" ".ISOF(VAR_VALUE)) !?3; %IF CHARNO(VAR_VALUE,1) < X'C1' %THEN %START !?3; SPACES(4) !?3; MOVE(4,ADDR(VAR_VALUE)+1,ADDR(J)) !?3; MOVE(4,ADDR(VAR_VALUE)+5,ADDR(K)) !?3; PRINTSTRING("X(".HEXOF(J).HEXOF(K).")") !?3; %FINISH !?3; %REPEAT !?3; NEWLINES(2) !?3; %RETURN !?3; %END ;! OF PRINT JSV TABLE ! !********************************************************************** ! !* RECORD ACCESS SERVICE ROUTINES !* !********************************************************************** ! %ROUTINE DERIVE RAF SWITCH (%INTEGER ACTION,DATA FORMAT, %C %INTEGERNAME VALUE) %INTEGER I,J %CYCLE I = 1,1, VA COUNT %IF ACTION = VALID ACTION(I) %THEN J = I %AND -> AF %REPEAT VALUE = -1 %AND %RETURN ;! NOT A VALID ACTION AF: VALUE = RAF SWITCH(VALID ACTION ID(J),DATA FORMAT) %RETURN %END ;! OF DERIVE RAF SWITCH ! %INTEGERFN DERIVE CUR LEN (%RECORDNAME FCR) ! ! THIS ROUTINE DERIVES THE LENGTH OF THE RECORD POINTED TO BY ! CUR PTR. WHEN THE LENGTH OF THE RECORD HAS BEEN ! WRITTEN INTO FCR_CUR LEN, THE RECORD, IN THE TERMS OF ! THIS INTERFACE, IS SAID TO BE SELECTED. ! %RECORDSPEC FCR (FCR FORMAT) %INTEGER I,J %SWITCH DFP(0:4) %INTEGER RC ! RC = 0 FCR_CUR LEN = 0 -> DFP(FCR_DATA FORMAT) DFP(1): ! FIXED FORMAT RECORDS IN FILE FCR_CUR LEN = FCR_RMIN -> OUT DFP(2): ! VARIABLE LENGTH RECORDS, TWO BYTE LENGTH FIELD MOVE(2,FCR_CON ADDR + FCR_CUR PTR,ADDR(FCR_CUR LEN)+2) -> OUT DFP(3): !NOT RELEVANT, INTERACTIVE TERMINAL I/0 !HANDLED INDEPENTANTLY OF THIS ROUTINE %RESULT = X'8000' DFP(4): ! TEXT OR CHARACTER FILE, MUST FIND NEXT NEWLINE %CYCLE I=FCR_CON ADDR + FCR_CUR PTR,1,FCR_CON ADDR + FCR_DATA LIMIT-1 %IF BYTEINTEGER(I) = X'0A' %THEN J = I %AND -> NF %REPEAT J = FCR_CON ADDR + FCR_DATA LIMIT - 1 NF: FCR_CUR LEN = J - FCR_CON ADDR - FCR_CUR PTR + 1 -> OUT OUT: %IF FCR_CUR LEN > FCR_RMAX %THEN RC = X'0541' %RESULT = RC %END ;! OF DERIVE CUR LEN ! %INTEGERFN SERIAL SELECT (%RECORDNAME FCR) ! ! ON ENTRY CUR PTR AND CUR LEN ARE SET TO POINT AT THE CURRENTLY ! 'SELECTED' RECORD AND ITS LENGTH. FOR SELECTING THE FIRST ! RECORD IN A FILE, CUR PTR IS SET TO POINT ! TO THE START OF DATA (OR FIRST RECORD) ! AND CUR LEN IS SET TO ZERO. THE OFFSET OF THE NEXT RECORD IS ! CALCULATED (FROM CUR PTR AND CUR LEN) ! AND ITS LENGTH DERIVED TO MAKE IT THE CURRENTLY ! SELECTED RECORD. ! %RECORDSPEC FCR (FCR FORMAT) FCR_CUR PTR = FCR_CUR PTR + FCR_CUR LEN %IF FCR_CUR PTR < FCR_DATA LIMIT %THEN %RESULT = DERIVE CUR LEN %C (FCR) ! READING OFF END OF DATA IF REACHED HERE ! FCR_CUR PTR = FCR_DATA LIMIT FCR_CUR LEN = 0 %RESULT = X'0603' %END ;! OF SERIAL SELECT ! %ROUTINE CLEAR FILES %INTEGER I,X,Y,RC ! X = NIL ; Y = NIL %CYCLE I=2,1,FILE LIMIT ! FCT ENTRIES 0&1 CONTAIN TERMINAL I/O ENTRIES -> REP %UNLESS FCT(I)_PC > 0 RC = DE ASSIGN FILE(I,X,Y) REP: %REPEAT %END ;! OF CLEAR FILES ! !********************************************************************** !* !* RECORD ACCESS FUNCTIONS !* !********************************************************************** ! ! %ROUTINE SERIAL REWIND (%RECORDNAME FCR) ! ! THIS ROUTINE SETS THE RELEVANT FIELDS IN THE CURRENT FCR ! SUCH THAT THE NEXT CALL ON SERIAL SELECT WILL SELECT THE ! FIRST RECORD IN THE FILE. ! %RECORDSPEC FCR (FCR FORMAT) FCR_CUR PTR = FCR_FHDR_DATA START FCR_CUR LEN = 0 FCR_DATA LIMIT = FCR_FHDR_DATA END %RETURN %END ;! OF SERIAL REWIND ! %ROUTINE SERIAL UNWIND (%RECORDNAME FCR) ! ! THIS ROUTINE SETS THE RELEVANT ENTRIES IN THE FCR SUCH ! THAT THE NEXT RECORD WRITTEN WILL BE ADDED TO THE END ! OF THE FILE. ! %RECORDSPEC FCR (FCR FORMAT) FCR_CUR PTR = FCR_FHDR_DATA END %RETURN %END ;! OF SERIAL UNWIND ! %ROUTINE TRUNCATE (%RECORDNAME FCR) ! ! THIS ROUTINE SETS ENTRIES IN THE CURRENT FCR SUCH THAT ALL RECORDS ! FROM AND INCLUDING THAT CURRENTLY SELECTED ARE DELETED. ! %RECORDSPEC FCR (FCR FORMAT) FCR_FHDR_DATA END = FCR_CUR PTR FCR_CUR LEN = 0 FCR_FHDR_RECORD COUNT = -1 %IF FCR_FHDR_DATA END=FCR_FHDR_DATA START %THEN %C FCR_FHDR_RECORD COUNT = 0 ;!IE TRUNCATED AT START OF FILE %RETURN %END ;! OF TRUNCATE ! %ROUTINE DESELECT (%RECORDNAME FCR) ! ! THIS ROUTINE EFFECTIVLY STOPS ALL FURTHER TANSFERS VIA THE ! CURRENT FILE ROUTE (FCR) UNTIL A FURTHER CALL IS MADE ON ! SELECT RAM FOR THIS FILE ROUTE. THE ROUTE IS MARKED ! AS 'UNSELECTED' BY SETTING THE RAF SWITCH ENTRY T0 -1. ! %RECORDSPEC FCR (FCR FORMAT) FCR_RAF SWITCH = -1 %RETURN %END ;! OF DESELECT ! %INTEGERFN SERIAL READ (%RECORDNAME FCR) %INTEGER RC,POS,LEN %RECORDSPEC FCR(FCR FORMAT) ! ! ON ENTRY CUR PTR AND CUR LEN IDENTIFY THE PREVIOUSLY ! SELECTED RECORD. THEREFORE MUST CALL SERIAL SELECT TO IDENTIFY ! THE NEXT RECORD AND THEN MOVE IT INTO THE USERS BUFFER. ! RC = 0 RC = SERIAL SELECT (FCR) %IF RC > 0 %THEN %RESULT = RC POS = FCR_CUR PTR LEN = FCR_CUR LEN %IF FCR_DATA FORMAT = 2 %THEN %START ! VARIABLE LENGTH RECORDS WITH 2 BYTE HEADERS POS = POS + 2 LEN = LEN -2 %FINISH MOVE(LEN,FCR_CON ADDR+POS,FCR_BUFF DR1) %IF FCR_DATA FORMAT = 4 %THEN %START ! CHARACTER FILE, MUST TRANSLATE ITOE(FCR_BUFF DR1,LEN) BYTEINTEGER(FCR_BUFF DR1+LEN-1)=X'15' %FINISH %IF FCR_XFER DR0 # NIL %THEN INTEGER(FCR_XFER DR1)=LEN %RESULT = RC %END ;! OF SERIAL READ ! %INTEGERFN IT READ (%RECORDNAME FCR) %RECORDSPEC FCR(FCR FORMAT) !?3;%INTEGER X %INTEGER I,J,LINE LENGTH,PROMPT LENGTH %BYTEINTEGERARRAY LINE BUFFER (0:FCR_RMAX) %STRING(15) NEW PROMPT ! %IF FCR_KEY DR0 # 0 %THEN %START ! USER HAS SPECIFIED A PROMPT PROMPT LENGTH = FCR_KEY DR0 & X'0000000F' ! ONLY TAKE FIRST 15 CHARS OF PROMPT NEW PROMPT = STRING FROM (PROMPT LENGTH,FCR_KEY DR1) ETOI(ADDR(NEW PROMPT)+1,PROMPT LENGTH) PROMPT(NEW PROMPT) IT PROMPT FLAG = YES %FINISH %ELSE %START %IF IT PROMPT FLAG = YES %THEN PROMPT("BASIC INPUT: ") %C %AND IT PROMPT FLAG = NO %FINISH %CYCLE I=1,1,FCR_RMAX READ SYMBOL(LINE BUFFER(I)) %IF LINE BUFFER(I) = NL %THEN J=I %AND -> EOL %REPEAT ! LINE TOO LONG, TRUNCATE J = FCR_RMAX EOL: !?3;X=OUTSTREAM !?3;SELECTOUTPUT(DIAGSTREAM) %IF J>(FCR_BUFF DR0&X'00FFFFFF') %THEN LINE LENGTH %C = FCR_BUFF DR0&X'00FFFFFF' %ELSE LINE LENGTH = J !?3;XDUMP("LINEBUFFER",ADDR(LINEBUFFER(0)),30) ITOE(ADDR(LINE BUFFER(1)),LINE LENGTH) LINEBUFFER(LINELENGTH)=X'15' MOVE(LINE LENGTH,ADDR(LINE BUFFER(1)),FCR_BUFF DR1) !?3;XDUMP("USERBUFF",FCR_BUFF DR1,30) !?3;NEWLINE;WRITE(LINELENGTH,1) !?3;SELECTOUTPUT(X) INTEGER(FCR_XFER DR1) = LINE LENGTH %RESULT = 0 %END ;! OF IT READ ! %INTEGERFN IT WRITE (%RECORDNAME FCR) %INTEGER LINE LENGTH %RECORDSPEC FCR(FCR FORMAT) %BYTEINTEGERARRAY LINE BUFFER (0:FCR_RMAX) ! LINE LENGTH = FCR_BUFF DR0&X'00FFFFFF' %IF LINE LENGTH > FCR_RMAX %THEN LINE LENGTH = FCR_RMAX MOVE(LINE LENGTH,FCR_BUFF DR1,ADDR(LINE BUFFER(1))) ETOI(ADDR(LINE BUFFER(1)),LINE LENGTH) LINE BUFFER(0) = LINE LENGTH PRINTSTRING (STRING(ADDR(LINE BUFFER(0)))) NEWLINE %RESULT = 0 %END ;! OF IT WRITE ! %INTEGERFN SERIAL APPEND (%RECORDNAME FCR) %INTEGER RECORD LENGTH,XL,XP %RECORDSPEC FCR(FCR FORMAT) %SWITCH S(0:5) ! RECORD LENGTH = FCR_BUFF DR0 & X'00FFFFFF' %IF RECORD LENGTH > FCR_RMAX %THEN %RESULT = X'0541' SERIAL UNWIND(FCR) XL = RECORD LENGTH -> S(FCR_DATA FORMAT) ! S(1): ! FIXED LENGTH RECORDS %IF FCR_CUR PTR + RECORD LENGTH > FCR_FHDR_FILE SIZE %THEN %C %RESULT = X'0506' XP = FCR_CUR PTR -> XFER S(2): ! VARIABLE LENGTH RECORDS WITH 2 BYTE HEADER RECORD LENGTH = RECORD LENGTH + 2 %IF FCR_CUR PTR + RECORD LENGTH > FCR_FHDR_FILE SIZE %THEN %C %RESULT = X'0506' MOVE(2,ADDR(RECORD LENGTH)+2,FCR_CON ADDR + FCR_CUR PTR) XP = FCR_CUR PTR + 2 -> XFER ! XFER: MOVE(XL,FCR_BUFF DR1,FCR_CON ADDR + XP) ! NEW RECORD BECOMES CURRENTLY SELECTED RECORD ! FCR_CUR PTR REMAINS UNCHANGED FCR_CUR LEN = RECORD LENGTH FCR_FHDR_DATA END = FCR_CUR PTR + RECORD LENGTH FCR_FHDR_RECORD COUNT = FCR_FHDR_RECORD COUNT + 1 %RESULT = 0 %END ;! OF SERIAL APPEND ! ! !*********************************************************************** !* !* QUIT !* !********************************************************************** ! ! THIS ROUTINE IS CALLED TO FORCE A RETURN TO COMMAND LEVEL. ! THE RETURN IS MADE VIA THE LNB SAVED ON INITIAL ENTRY (BASICBASE) ! FOR THE PURPOSE. ! %EXTERNALROUTINE SSQT (%INTEGER RESULT CODE) %INTEGER X,RC !?2; *STLN _X !?2; TRACE("QUIT","",X,1,-1) CLEAR FILES SET RETURN CODE (RESULT CODE) ! ! JUST IN CASE THERE ARE ANY REMAINING QUEUED INTERRUPTS ! DO A DDISC ID TO CLEAR THEM. IF THERE ARE ANY THE ! CALL ON DISC WILL HAVE HE EFFECT OF INVOKING ANOTHER ENTRY ! INTO THE "BBONTRAP" ROUTINE. HIS SHOULD ENABLE ALL QUEUED ! INTERRUPTS TO BE CLEARED BEFORE RETURN TO COMMAND ! LEVEL. ! RC = DISC ID DRESET CONTINGENCY X = ENTRY LNB *LLN_X ;! RESTORE LNB AND RETURN AS IF *EXIT_-64 ;! FROM ENTRY ROUTINE, BASICBASE %END ;! OF QUIT ! !********************************************************************** !* !* ABANDON !* !********************************************************************** ! %ROUTINE ABANDON (%INTEGER OPTIONS,%STRING(120) COMMENT) ! RETURN TO COMMAND LEVEL ! OPTION 1 => RETURN WITHOUT DIAGS ! 2 => LANGUAGE DIAGS ! 3 => STACK DUMP ! 4 => TOTAL DUMP ! %UNLESS COMMENT = '' %THEN LOG(COMMENT.' - ABANDONING') ! ! OTHER DUMPING CODE IN HERE ! SSQT(1000) %END ;! OF ABANDON ! !********************************************************************** !* !* SET CONTINGENCY !* !********************************************************************** ! %EXTERNALINTEGERFN SET CONTINGENCY (%LONGINTEGER DESC,MASK) %INTEGER I %LONGINTEGER X !?2; *STLN _I !?2; TRACE("SET CONTINGENCY","",I,4,-1) X=MASK %CYCLE I = 0,1,63 %IF X&X'0000000000000001' = 0 %THEN CONT RTN DESC(I) = DESC X = X>>1 %REPEAT %RESULT = 0 %END ;! OF SET CONTINGENCY ! !********************************************************************** !* !* READ INTERRUPT DATA !* !********************************************************************** ! %EXTERNALINTEGERFN READ INTERRUPT DATA (%INTEGER ID DR0,ID DR1) %INTEGER L,RC !?2; *STLN _L !?2; TRACE("READ INTERRUPT DATA","",L,2,-1) %IF INT DATA FLAG = NO %THEN %RESULT = X'F02' RC = 0 L= ID DR0 & X'00FFFFFF' %IF L < 18 %THEN RC = -1 %IF L > 18 %THEN L = 18 MOVE (L * 4,ADDR(INT DATA(0)),ID DR1) %RESULT = RC %END ;! OF READ INTERRUPT DATA ! !********************************************************************** !* !* DISCARD INTERRUPT DATA !* !********************************************************************** ! %EXTERNALINTEGERFN DISCARD INTERRUPT DATA !?2; %INTEGER X !?2; *STLN _X !?2; TRACE("DISCARD INTERRUPT DATA","",X,0,-1) ! ! SINCE A CALL ON DIRECTOR'S DISC ID INTERFACE IS MADE ! IMMEDIATELY ON RECEIVING AN INTERRUPT (SEE BBONTRAP) ! THERE IS NO NEED TO DO ANYTHING HERE EXCEPT TO SET A ! FLAG TO INDICATE WHETHER OR NOT BASIC HAS "DISCARDED". ! THIS IS THE SAME AS A CHECK ON WHETHER THERE SHOULD BE ! MEANINGFULL INTERRUPT DATA AVAILABLE. ! %IF INT DATA FLAG = NO %THEN %RESULT = X'F02' INT DATA FLAG = NO %RESULT = 0 %END ;! OF DISCARD INTERUPT DATA ! !********************************************************************** !* !* BBONTRAP !* !********************************************************************** ! %EXTERNALROUTINE BBONTRAP (%INTEGER CLASS,SUBCLASS) %INTEGER KCLASS,RC,X !?2; %INTEGER CURRENT STREAM ! %LONGINTEGER DESC ! !?2; *STLN _X !?2; TRACE("BBONTRAP","",X,2,-1) KCLASS = CONTINGENCY MAP(CLASS) - 1 %IF KCLASS < 0 %THEN %START ABANDON(0,'CONTINGENCY CLASS '.SFROMI(CLASS).', SUBCLASS '. %C SFROMI(SUBCLASS)) %FINISH %IF INT DATA FLAG = YES %THEN %START ABANDON(2,'ERROR ON ERROR') %FINISH RC = READ ID (ADDR(INT DATA(0))) %IF RC # 0 %THEN ABANDON(1,'NO INT DATA AFTER INTERRUPT') INT DATA FLAG = YES !?2; CURRENT STREAM = OUT STREAM !?2; SELECT OUTPUT (TRACE STREAM) !?2; XDUMP ("INTERRUPT DATA",ADDR(INT DATA(0)),18*4) !?2; %MONITOR !?2; SELECT OUTPUT (CURRENT STREAM) ! ! THE FOLLOWING CALL ON DISC ID EFFECTIVELY INFORMS ! DIRECTOR THAT THE CURRENT INTERRUPT HAS BEEN DEALT WITH. ! ALTHOUGH THIS IS NOT STRICTLY TRUE UNTIL BASIC'S ! CONTINGENCY ROUTINE HAS PROCESSED IT, IT MUST BE POSSIBLE FOR ! FURTHER ASYNCRONOUS INTERRUPTS TO GET THROUGH, TO KILL ! DIAGNOSTIC OUTPUT, SAY. ! RC = DISC ID DESC = CONT RTN DESC(KCLASS) %IF DESC = 0 %THEN ABANDON(1,'NO RTN TO HANDLE CLASS '.SFROMI(KCLASS) %C .'CONTINGENCY') ! ! ENTER MACHINE CODE SEQUENCE TO CALL THE CONTINGENCY ROUTINE ! SPECIFIED BY THE CONTENTS OF 'DESC' ! *LD _DESC *STLN _%TOS *ASF _4 *LSS _SUBCLASS *SLSS _KCLASS *ST _%TOS *RALN _7 *CALL _(%DR) ! ! IF BASIC RETURNS TO HERE THEN A NORMAL RETURN HAS BEEN ! MADE FROM BASIC'S CONTINGENCY HANDLING ROUTINE WHICH ! IMPLIES A NEED TO RESUME AT THE POINT OF INTERRUPTION. ! CHECK TO SEE IF INT DATA HAS ! BEEN DISCARDED. IF YES THEN DUMP. IF NOT RESUME AT ! ENVIRONMENT DESCRIBED BY INT DATA ! %IF INT DATA FLAG = NO %THEN %C ABANDON(1,'NO INT DATA FOR NORMAL RETURN') INT DATA FLAG = NO DRESUME(0,0,ADDR(INT DATA(0))) %END ;! OF BBONTRAP ! ! !********************************************************************** !* !* ENTRY ROUTINE FOR KENT BASIC INTERFACE !* !********************************************************************** ! %EXTERNALROUTINE BASIC(%STRING(255) PARMS) %INTEGER X,Y,RC,RAM USER LNB,RAM RC,I,CURRENT STREAM %INTEGER BP DR0,BP DR1,APP DR0,APP DR1 %INTEGERARRAY ENTRY DESC (0:1) %LONGINTEGER FCR DESC,EX DESC %STRING(32) LOAD FILE %SWITCH RAF (0:10) ;! RECORD ACCESS FUNCTION SWITCH %RECORDNAME FCR (FCR FORMAT) %INTEGERARRAYNAME FCR DML INFO *STLN_X ;! ( SAVE LNB AT ENTRY FOR USE IN ENTRY LNB = X ;! ( EXIT FROM QUIT !?2; TRACE COUNT = 0 LOG("EMAS 2900 - KENT BASIC INTERFACE, VERSION ".VERSION) !?3; DIAG STREAM = 60 LOG STREAM = 61 !?2; TRACE STREAM = 62 !?3 %C DEFINE("61,.OUT") !?3; ASK FOR STREAM (DIAG STREAM,"DIAG STREAM? ") !?3; ASK FOR STREAM (LOG STREAM,"LOG STREAM? ") !?2; ASK FOR STREAM (TRACE STREAM,"TRACE STREAM? ") FILL(64*8,ADDR(CONT RTN DESC(0)),X'00') INT DATA FLAG = NO INITIAL CPU TIME = CPU TIME IT PROMPT FLAG = YES ;! IE REQUIRING PROMPT TO BE REFRESHED ! ! JS VAR(0)_NAME = E"RESULT" ;!) SET UP FIRST JS VAR JS VAR(0)_VALUE = BIN STRING(0,0) ;!) IN JS VAR LIST ;!) SUCH THAT THE JS VAR(0)_MAX LEN = 8 ;!) POINTERS IN THE ROUTINE JS VAR COUNT = 0 ;!) 'CREATE JS VAR' WORK PROPERLY %CYCLE I=0,1,FILE LIMIT - 1 FCT(I)_PC = 0 FCT(I)_RAF SWITCH = -1 %REPEAT USER NAME = UINFS (1) *JLK _ ;! JUMP AROUND RECMAN RAM PROCESSING ! !*********************************************************************** ! RECORD ACCESS HANDLING !********************************************************************** ! *STLN _%B ;! SAVE LNB TEMPORARILY IN B REGISTER *LDTB _X'29000003' ;! LOAD TYPE & BOUND FOR A WORD DESC *LLN _(%DR+2) ;! DR AFTER ESCAPE POINTS TO ESCAPE DESCRIPTOR ! TARGET SET UP AT ASSIGN TIME. DR IS UNSCALED ! WORD DESCRIPTOR. LOAD LNB FOR THIS ! FOR THIS ENVIRONMENT AS SAVED AT RI. *STD _FCR DESC ;! STORE DESCRIPTOR REGISTER *STB _RAM USER LNB ;! STORE CALLER'S LNB FOR RETURN ! ! FOR EXPLANATION OF ESCAPE MECHANISM SEE 2.5.1 PP 48,53,74,102 ! ! CODE FOR HANDLING CALLS ON RECORD CURRENCIES OR RECORD ! ACCESS METHODS, IE. RAMS. THESE ARE IN FACT THE ESCAPE ! DESCRIPTORS SET UP WHEN A CALL IS MADE ON ASSIGNFILE. ! FCR == RECORD(INTEGER(ADDR(FCR DESC)+4)) !?2; TRACE("ACCESS","ROUTE - ".SFROMI(FCR_ROUTE),RAMUSERLNB,2,0) %IF FCR_RAF SWITCH < 0 %THEN RAM RC = X'0530' %AND -> RAM RETURN APP DR0 = INTEGER(RAM USER LNB+20) APP DR1 = INTEGER(RAM USER LNB+24) %UNLESS APP DR0 = NIL %THEN %START ! DECODE PARM PAIR LIST FCRDMLINFO==ARRAY(ADDR(FCR_BUFF DR0),FDI FORMAT) DECODE PPLIST(APP DR0,APP DR1,DML DECODE,FCR DML INFO) %UNLESS FCR_NEW ACTIONS=-1 %THEN %START !ACTION APPEARED IN PARM PAIR LIST DERIVE RAF SWITCH(FCR_NEW ACTIONS,FCR_DATA FORMAT,X) %IF X<1 %THEN RAM RC = X'0902' %AND -> RAM RETURN FCR_RAF SWITCH = X FCR_ACC ACTIONS=FCR_NEW ACTIONS FCR_NEW ACTIONS = -1 %FINISH %FINISH %IF FCR_RAF SWITCH<1 %THEN RAM RC = X'0902' %AND -> RAM RETURN RAM RC = 0 -> RAF(FCR_RAF SWITCH) ! RAF(1): ! SERIAL READ ! RAM RC = SERIAL READ (FCR) -> RAM RETURN ! RAF(2): ! INTERACTIVE TERMINAL READ RAM RC = IT READ(FCR) -> RAM RETURN ! RAF(3): ! SERIAL APPEND ! RAM RC = SERIAL APPEND (FCR) -> RAM RETURN ! RAF(5): ! INTERACTIVE TERMINAL WRITE RAM RC = IT WRITE(FCR) -> RAM RETURN ! RAF(6): ! TRUNCATE TRUNCATE(FCR) RAM RC = 0 -> RAM RETURN ! RAF(7): ! DESELECT RAM DESELECT(FCR) RAM RC = 0 -> RAM RETURN ! ! RAF(8): ;! DUMMY I/O OPERATION RAM RETURN: *LSS _RAM RC *LLN _RAM USER LNB *EXIT _-40 ! !********************************************************************* ! END OF RECORD ACCESS PROCESSING !********************************************************************** ! ! RI: !RAM INIT SEQUENCE ! STORE REGISTERS TO ENABLE RE-ESTABLISHMENT OF ENVIRONMENT ! FOR HANDLING RAM CALLS *LSS _%TOS ;! LOAD PC AS STACKED BY JLK INSTRUCTION *ST _X ;! STORE PC TO BE USED BY ESCAPE RAM PC = X *STLN _X ;! STORE LNB TO BE USED BY ESCAPE RAM LNB = X ! ! THESE TWO VALUES ARE COPIED INTO THE FILE CONTROL RECORD ! FOR EACH FILE AS IT IS ASSIGNED. THE ESCAPE DESCRIPTOR ! THAT IS RETURNED BY SELECT RAM AS THE RECORD CURRENCY POINTS ! TO THE PC ENTRY IN THAT FILE CONTROL RECORD. ! ! THIS NEXT BIT MUST COME AFTER SAVING RAM PC & RAM LNB ! EXEC MODE = UINFI(2) %IF EXEC MODE = FOREGROUND %THEN %START X = CREATE JS VAR (E"ICL9XJST",BIN STRING(0,0),-1) FIND JS VAR (E"ICL9XJST",X) LENGTH(JS VAR(X)_VALUE) = 4 X = CREATE JS VAR (E"INPUT",BIN STRING(0,0),-1) X = CREATE JS VAR (E"OUTPUT",BIN STRING(0,1),-1) RC = ASSIGN FILE(X'28000001',ADDR(X), %C NIL,X'18000006',ADDR(SOURCE)+1, %C NIL,NIL,NIL,NIL) %IF RC # 0 %THEN ABANDON(1,"FAILED TO ASSIGN TERMINAL") %IF X # 0 %THEN ABANDON(1,"TERMINAL INCORRECTLY ASSIGNED") RC = ASSIGN FILE (X'28000001',ADDR(X), %C NIL,X'18000006',ADDR(SOURCE)+1, %C NIL,NIL,NIL,NIL) %IF RC # 0 %THEN ABANDON(1,"FAILED TO ASSIGN TERMINAL - OUTPUT") %IF X # 1 %THEN ABANDON(1,"TERMINAL OUTPUT INCORRECTLY ASSIGNED") %FINISH ! ! NOW FOR SEQUENCE TO SET UP ENTRY FOR BASIC PROPER ! CURRENT STREAM = OUT STREAM !?3; -> BYPASS DEFINE("20,.NULL") SELECT OUTPUT(20) !?3; BYPASS: SELECT OUTPUT(CURRENT STREAM) ! ! NOW SET UP CONTINGENCY HANDLIG ! !?3; PROMPT("CONTINGENCIES?") !?3; %IF DE SPACED(NEXTLINE)="NO" %THEN ->LAB2 RC = PRIME CONTINGENCY (BBONTRAP) %IF RC # 0 %THEN ABANDON(0,"FAILED TO PRIME CONTINGENCIES") !?3; LAB2: ! KBASC(NIL,NIL) ! ! SHOULD RETURN TO HERE FROM BASIC ! %RETURN %END ;! OF BASICBASE ! !********************************************************************** !* !* JS WRITE !* !********************************************************************** ! %EXTERNALINTEGERFN JS WRITE (%INTEGER NAME DR0,NAME DR1, %C NIL0,NIL1, %C VAL DR0,VAL DR1) %INTEGER RC,POINTER %STRING(80) VALUE !?2; %STRING(80) TTWORK %STRING(8) NAME ! ! NOTE THAT ALL JS VARS ARE STORED IN EBCDIC ! ! !?2; *STLN _RC !?2; TTWORK=STRINGFROM(NAME DR0,NAME DR1) !?2; ETOI(ADDR(TTWORK)+1,LENGTH(TTWORK)) !?2; TRACE("JS WRITE",TTWORK,RC,6,-1) %IF NAME DR0&X'000000FF' > 8 %THEN %RESULT = X'401' %IF VAL DR0 & X'000000FF' > 80 %THEN %RESULT = X'403' RC = 0 NAME = STRING FROM (NAME DR0,NAME DR1) VALUE = STRING FROM (VAL DR0,VAL DR1) FIND JS VAR (NAME,POINTER) %IF POINTER = -1 %THEN %RESULT = CREATE JS VAR (NAME,VALUE,-1) ! JS VAR FOUND, NEED TO UPDATE VALUE %IF LENGTH(VALUE) > JS VAR(POINTER)_MAX LEN %THEN %C LENGTH(VALUE) = JS VAR(POINTER)_MAX LEN %AND RC = -1 JS VAR(POINTER)_VALUE = VALUE %RESULT = RC %END ;! OF JS WRITE ! ! !********************************************************************** !* !* JS READ !* !********************************************************************** ! %EXTERNALINTEGERFN JS READ (%INTEGER NAME DR0,NAME DR1, %C NIL0,NIL1, %C VAL DR0,VAL DR1) %INTEGER POINTER,VAL LEN,RC %STRING(80) VALUE !?2; %STRING(80) NAME ! !?2; *STLN _RC !?2; NAME = STRING FROM (NAME DR0,NAME DR1) !?2; ETOI(ADDR(NAME)+1,LENGTH(NAME)) !?2; TRACE("JS READ",NAME,RC,6,-1) RC = 0 VAL LEN = VAL DR0 & X'0000FFFF' %IF NAME DR0 & X'000000FF' > 8 %THEN RC = X'401' %AND -> OUT VALUE = STRING FROM(NAME DR0,NAME DR1) ;! USE VALUE TEMPORARILY %WHILE CHARNO(VALUE,LENGTH(VALUE)) = X'40' %THEN %C LENGTH(VALUE)=LENGTH(VALUE)-1 FIND JSVAR(VALUE,POINTER) %IF POINTER = -1 %THEN RC = X'B03' %AND -> OUT VALUE = JS VAR(POINTER)_VALUE FILL(VAL LEN,VAL DR1,64) ;! SPACE FILL AREA FOR RETURN VALUE %IF VAL LEN < LENGTH(VALUE) %THEN LENGTH(VALUE) = VAL LEN %AND RC=-1 MOVE(LENGTH(VALUE),ADDR(VALUE)+1,VAL DR1) OUT: !?2; RESULT TRACE("JS READ",RC) %RESULT = RC %END ;! OF JS READ ! ! !********************************************************************** !* !* LOG MESSAGE !* !********************************************************************** ! %EXTERNALINTEGERFN LOG MESSAGE (%INTEGER NIL0,NIL1, %C MSG DR0,MSG DR1) %INTEGER RC,L,DSTREAM,CURRENT STREAM %STRING(138) S DSTREAM = LOG STREAM RC = 0 L = MSG DR0&X'000000FF' %IF L > 108 %THEN L = 108 %AND RC = -1 CURRENT STREAM = OUTSTREAM SELECT OUTPUT(LOG STREAM) S = STRING FROM (L,MSG DR1) ETOI(ADDR(S)+1,L) PRINTSTRING(TIME." ".S) NEWLINE SELECT OUTPUT(CURRENT STREAM) %RESULT = RC %END ;! OF LOG MESSAGE ! ! !* !********************************************************************** !* !* GIVE PROCESS TIME !* !********************************************************************** ! ! %EXTERNALINTEGERFN GIVE PROCESS TIME (%INTEGER TOTAL, %C PT DR0,PT DR1) %LONGINTEGER ANSWER %LONGREAL REQUIRED CPU TIME !?2; %INTEGER X !?2; *STLN _X !?2; TRACE("GIVE PROCESS TIME","",X,3,-1) REQUIRED CPU TIME = CPU TIME %IF TOTAL = 1 %THEN %C REQUIRED CPU TIME = REQUIRED CPU TIME - INITIAL CPU TIME ANSWER = LONGINT(REQUIRED CPU TIME * 1000) LONGINTEGER(PT DR1) = ANSWER %RESULT = 0 %END ;! OF GIVE PROCESS TIME ! ! !********************************************************************** !* !* GIVE DATE AND TIME !* !********************************************************************** ! %EXTERNALINTEGERFN GIVE DATE AND TIME (%INTEGER %C DATE DR0,DATE DR1, %C TIME DR0,TIME DR1, %C DATE FORMAT) %CONSTINTEGERARRAY MD MAP (1:12) = 0,31,59,90,120,154, %C 181,212,243,273,304,334 %CONSTSTRING(3)%ARRAY MONTH NAME (1:12) = 'JAN','FEB','MAR', 'APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC' %STRING(8) WORK %STRING(2) DAY,MONTH,YEAR %INTEGER NMONTH,NDAYS,NYEAR,L,RC %SWITCH FORMAT (0:2) ! !?2; *STLN _RC !?2; TRACE("GIVE DATE AND TIME","",RC,5,-1) RC = 0 %IF TIME DR1 # NIL %THEN %START WORK = TIME L = TIME DR0 & X'000000FF' ITOE(ADDR(WORK)+1,8) %IF L > 8 %THEN L = 8 %IF L < 8 %THEN RC = -2 MOVE(L,ADDR(WORK)+1,TIME DR1) %FINISH %IF DATE DR1 # NIL %THEN %START L = DATE DR0 & X'000000FF' WORK = DATE DAY = FROM STRING (WORK,7,8) MONTH = FROM STRING (WORK,4,5) YEAR = FROM STRING (WORK,1,2) NMONTH = IFROMS(MONTH) -> FORMAT ( DATE FORMAT) FORMAT(0): ;! DDMMMYY , EG. 05SEP77 WORK = DAY.MONTH NAME(NMONTH).YEAR -> OUT FORMAT(2): ;! DDD/77 , EG. 248/77 NDAYS = MD MAP(NMONTH) + IFROMS(DAY) NYEAR = IFROMS(YEAR) %IF NMONTH > 2 %AND NYEAR-((NYEAR//4)*4) = 0 %THEN %C NDAYS = NDAYS + 1 WORK = SFROMI(NDAYS)."/".YEAR FORMAT(1): ;! YY/MM/DD EG. 77/09/05 OUT: ITOE(ADDR(WORK)+1,8) %IF L > 8 %THEN L = 8 %IF L < 8 %THEN RC = RC + 1 MOVE(L,ADDR(WORK)+1,DATE DR1) %FINISH %RESULT = RC %END ;! OF GIVE DATE AND TIME ! ! !********************************************************************** !* !* CREATE FILE !* !********************************************************************** ! %EXTERNALINTEGERFN CREATE FILE (%INTEGER %C ROUTE DR0,ROUTE DR1, %C NIL0, %C NAME DR0,NAME DR1, %C GENERATION,NIL1, %C DESC DR0,DESC DR1) ! %INTEGER RC,I,X,CON SEG %INTEGER RECORD TYPE,RECORD SIZE,FILE SIZE %RECORDNAME FILE HEADER (FHDR FORMAT) %RECORD R(CONNECTFORM) %STRING(32) FILE NAME %SWITCH S(104:118) ! !?2; %STRING(80) TTWORK !?2; *STLN _RC !?2; TTWORK=STRING FROM (NAME DR0,NAME DR1) !?2; ETOI(ADDR(TTWORK)+1,LENGTH(TTWORK)) !?2; TRACE("CREATE FILE",TTWORK,RC,9,7) RECORD TYPE = 2 ; RECORD SIZE = 132 ; FILE SIZE = X'7880' ! THIS LOOP A BIT GROTTY, MUST TIDY IT UP SOME TIME %CYCLE I = DESC DR1,12,(DESC DR1 + (DESC DR0&X'00FFFFFF')*4)-12 -> S(INTEGER(I)) S(104): RECORD TYPE = INTEGER(I+4) -> REP S(105): RECORD SIZE = INTEGER(I+4) -> REP S(118): FILE SIZE = INTEGER(I+4) REP: %REPEAT ! FILE NAME = STRING FROM (NAME DR0,NAME DR1) ETOI(ADDR(FILE NAME)+1,LENGTH(FILE NAME)) FILE NAME = DE SPACED (FILE NAME) RC = DCREATE (USER NAME,FILE NAME,-1,FILE SIZE >> 10,0) %IF RC > 0 %THEN %START LOG("FAILED TO CREATE FILE ".FILE NAME." - ".SFROMI(RC)) %RESULT = X'8000' %FINISH ! ! NOW TO CONSTRUCT A HEADER FOR THE FILE TO CONFORM TO ! TO STANDARD SUBSYSTEM DISCRETE RECORD(VARIABLE) FILES ! ! ROUND UP FILE SIZE TO NEXT UNIT OF ALLOCATION, IE 4K ! X = FILE SIZE >> 12 %IF X << 12 < FILE SIZE %THEN FILE SIZE = (X+1)<<12 CON SEG = 0 ; X = 0 CONNECT(USERNAME.".".FILENAME,2,0,0,R,RC) %IF RC > 0 %THEN %START LOG("FAILED TO CONNECT FILE ".FILE NAME." - ".SFROMI(RC)) %RESULT = X'8000' %FINISH FILE HEADER == RECORD(R_CONAD) FILE HEADER_DATA END = 32 ;! ALLOW FOR HEADER FILE HEADER_DATA START = 32 ;! FILE EMPTY FILE HEADER_FILE SIZE = FILE SIZE ;! PHYSICAL FILE SIZE FILE HEADER_FILE TYPE = 4 ;! DISCRETE RECORDS FILE HEADER_CHECK SUM = 0 ;! NOT YET USED FILE HEADER_DANDT = FILE TIME STAMP ;! TIME LAST WRITTEN TO FILE HEADER_FORMAT = (RECORD SIZE<<16)!2 ;! ALWAYS VARIABLE FILE HEADER_RECORD COUNT = 0 ;! FILE EMPTY DISCONNECT(USERNAME.".".FILENAME,RC) %IF RC > 0 %THEN %START LOG("CF - DDISCON FAILS, FILE ".FILE NAME." - ".SFROMI(RC)) %RESULT = X'8000' %FINISH ! ITOE(ADDR(FILE NAME)+1,LENGTH(FILE NAME)) RC = ASSIGN FILE (ROUTE DR0,ROUTE DR1, %C NIL,X'18000000'!LENGTH(FILE NAME),ADDR(FILE NAME)+1, %C NIL,NIL,NIL,NIL) %RESULT = RC %END ;! OF CREATE FILE ! !********************************************************************** !* !* DE ASSIGN FILE !* !********************************************************************** ! %EXTERNALINTEGERFN DE ASSIGN FILE (%INTEGER ROUTE,ST DR0,ST DR1) ! %INTEGER RC %RECORDNAME FCR(FCR FORMAT) ! !?2; *STLN _RC !?2; TRACE("DE ASSIGN FILE","",RC,2,-1) FCR ==FCT(ROUTE) %IF FCR_PC = 0 %THEN %START ! FILE ROUTE NOT ASSIGNED LOG ('ATTEMPT TO DE-ASSIGN NON-ASSIGNED FILE ROUTE') %RESULT = X'0C07' %FINISH %IF FCR_RAF SWITCH # -1 %THEN %START ! FILE STILL OPEN, RAM NOT DESELECTED DESELECT(FCR) %FINISH FCR_PC = 0 ! NOW CALL DIRECTOR TO DISCONNECT FILE DISCONNECT(FCR_OWNER.".".FCR_NAME,RC) %IF RC > 0 %THEN %RESULT = X'0C07' %RESULT = 0 %END ;! OF DE ASSIGN FILE ! ! !********************************************************************** !* !* ASSIGN FILE !* !********************************************************************** ! ! %EXTERNALINTEGERFN ASSIGN FILE (%INTEGER %C ROUTE DR0,ROUTE DR1, %C NIL0, %C NAME DR0,NAME DR1, %C GENERATION,NIL1, %C DESC DR0,DESC DR1) ! %INTEGER I,ROUTE,CON SEG,CON GAP,CON ADDR,RC,RECTYPE,X %INTEGER ST DR0,ST DR1 !?2; %STRING(80) TTWORK %SWITCH S(0:7) %CONSTINTEGER RM LIMIT = 5 %CONSTINTEGERARRAY RESULT MAP (0:4,0:1) = %C 5, 6, 32, 34, 37, X'0811',X'0C03',X'0C02',X'0C06',X'0C02' %RECORDNAME FILE HEADER (FHDR FORMAT) %RECORDNAME FCR (FCR FORMAT) %RECORD R(CONNECTFORM) %ROUTINE FILL COMMON FCR FIELDS FCR_CONADDR = CONADDR FCR_FHDR == RECORD(CON ADDR) FCR_CUR PTR = FCR_FHDR_DATA START FCR_DATA LIMIT = FCR_FHDR_DATA END FCR_CUR LEN = 0 FCR_RAF SWITCH = -1 %END ! !?2; *STLN _RC !?2; TTWORK = STRING FROM(NAME DR0,NAME DR1) !?2; ETOI(ADDR(TTWORK)+1,LENGTH(TTWORK)) !?2; TTWORK = "- ".TTWORK !?2; TRACE("ASSIGN FILE",TTWORK,RC,9,7) ! ST DR0 = NIL ; ST DR1 = NIL ;! STATS DESC USED IN CALLS ON DEASSIGN ! ! MUST LOOK TO WHETHER THE REQUESTED FILE IS ALREADY ASSIGNED ! AND USE THE EXISTING ENTRY IF IT IS NOT CONNECTED, IE. IF ! THE ROUTE IS NOT ALREADY IN USE. ! ! FIND NEXT VACANT ROUTE (IE ENTRY) IN FILE CONTROL TABLE, FCT %CYCLE I = 0,1,FILE LIMIT - 1 %IF FCT(I)_PC = 0 %THEN ROUTE = I %AND -> RF %REPEAT ! FILE LIMIT REACHED, NO MORE SLOTS FOR FILE CURRENCIES %RESULT = X'0903' RF: ! VACANT ROUTE FOUND IN FCT FCR == FCT(ROUTE) FCR_PC = 1 ;! ) ROUTE NOMINALLY FCR_RAF SWITCH = -1 ;! ) OCCUPIED FCR_ROUTE = ROUTE FCR_ALL ACTIONS = 0 FCR_NAME = STRING FROM (NAME DR0,NAME DR1) ETOI(ADDR(FCR_NAME)+1,LENGTH(FCR_NAME)) FCR_NAME = DE SPACED (FCR_NAME) %IF FCR_NAME = 'SOURCE' %THEN -> S(6) %IF DESC DR0 # NIL %AND INTEGER(DESC DR1) = 40 %THEN %START ! PARMS SPECIFIED AND ONLY TYPE 40 EXPECTED FCR_OWNER = STRING FROM (INTEGER(DESC DR1+4),INTEGER(DESC DR1+8)) ETOI(ADDR(FCR_OWNER)+1,LENGTH(FCR_OWNER)) %FINISH %ELSE FCR_OWNER = USER NAME FCR_OWNER = DE SPACED(FCR_OWNER) CON SEG = 0 ; CON GAP = 0 CONNECT(FCR_OWNER.".".FCR_NAME,1,0,0,R,RC); ! READ ONLY ACCESS %IF RC > 0 %THEN %START !?3; LOG ("AF - RESULT CODE FROM DCONNECT = ".SFROMI(RC)) X = DE ASSIGN FILE(ROUTE,ST DR0,ST DR1) %CYCLE I = 0,1,RM LIMIT - 1 %IF RC = RESULT MAP (I,0) %THEN %RESULT = RESULT MAP (I,1) %REPEAT %RESULT = X'8000' %FINISH CONADDR = R_CONAD ST DR0 = NIL ; ST DR1 = NIL ! MAP FILE HEADER TEMPORARILY TO INVESTIGATE FILE FILE HEADER == RECORD(CONADDR) %IF FILE HEADER_FILE TYPE < 0 %OR FILE HEADER_FILE TYPE > 5 %C %THEN %START LOG('FILE '.FCR_OWNER.".".FCR_NAME.' HAS CORRUPT HEADER, FILE TYPE') RC = DE ASSIGN FILE (ROUTE,ST DR0,ST DR1) %RESULT = X'0C16' %FINISH -> S(FILE HEADER_FILE TYPE) ! S(0):S(1):S(2):S(5): ! FILE TYPES NOT SUITABLE FOR DATA FOR BASIC LOG('FILE '.FCR_NAME.' NOT VALID FOR CURRENT ACCESS') RC = DE ASSIGN FILE (ROUTE,ST DR0,ST DR1) %RESULT = X'0C15' S(3): ! CHARACTER FILE FCR_RMIN = 1 FCR_RMAX = 255 FCR_DATA FORMAT = 4 FILL COMMON FCR FIELDS ->FINAL S(4): ! DATA FILE - DISCRETE RECORDS REC TYPE = FILE HEADER_FORMAT & X'0000FFFF' FCR_RMAX = FILE HEADER_FORMAT >> 16 %IF REC TYPE = 1 %THEN %START ! FIXED LENGTH RECORDS FCR_RMIN = FCR_RMAX FCR_DATA FORMAT = 1 -> DFF %FINISH %IF REC TYPE = 2 %THEN %START ! VARIABLE LENGTH RECORDS FCR_RMIN = 1 FCR_DATA FORMAT = 2 -> DFF %FINISH LOG ('FILE '.FCR_NAME.' HAS CORRUPT HEADER WORD 6') RC = DE ASSIGN FILE (ROUTE,ST DR0,ST DR1) %RESULT = X'0C16' DFF: FILL COMMON FCR FIELDS -> FINAL S(6): ! INTERACTIVE TERMINAL FCR_CON ADDR = -1 FCR_OWNER = "" FCR_DATA FORMAT = 3 FCR_RMIN = 0 FCR_RMAX = 255 ->FINAL ! FINAL: FCR_LNB = RAM LNB FCR_PC = RAM PC FCR_EP=X'E1000000' INTEGER(ROUTE DR1) = ROUTE %RESULT = 0 %END ;! OF ASSIGN FILE %EXTERNALINTEGERFN INTERROGATE FILE DESCRIPTION (%INTEGER %C ROUTE, %C DESC DR0,DESC DR1) %RESULT = NOT IMPLEMENTED %END ;! OF INTERROGATE FILE DESCRIPTION ! ! %EXTERNALINTEGERFN LIST FILE (%INTEGER %C DN DR0,DN DR1, %C FN DR0,FN DR1) %RESULT = NOT IMPLEMENTED %END ;! OF LIST FILE ! ! !********************************************************************** !* !* SELECT RECORD ACCESS METHOD !* !********************************************************************** ! %EXTERNALINTEGERFN SELECT RECORD ACCESS METHOD (%INTEGER %C ROUTE , %C PP DR0,PP DR1) ! %INTEGER X,RC,Y %INTEGERARRAYNAME FCR DML INFO %RECORDNAME FCR(FCR FORMAT) %RECORD R(CONNECTFORM) !?3; %INTEGER CURRENT STREAM !?3; %STRING(100) DWORK ! !?2; *STLN _X !?2; TRACE("SELECT RAM","",X,3,1) FCR == FCT(ROUTE) %IF FCR_PC = 0 %THEN %RESULT = X'8000' ;! ROUTE NOT ASSIGNED %IF FCR_RAF SWITCH # -1 %THEN %RESULT = X'0901' ;! THIS ROUTE IN USE FCR DML INFO == ARRAY(ADDR(FCR_BUFF DR0),FDI FORMAT) MOVE (13*4,ADDR(FCR DML INFO DEFAULTS(0)),ADDR(FCR_BUFF DR0)) DECODE PP LIST (PP DR0,PP DR1,DML DECODE,FCR DML INFO) DERIVE RAF SWITCH (FCR_NEW ACTIONS,FCR_DATA FORMAT,X) %IF X < 0 %THEN %RESULT = X'0902' ;! NO SUITABLE ALGORITHM FCR_RAF SWITCH = X FCR_ALL ACTIONS = FCR_NEW ACTIONS %IF X > 0 %THEN FCR_ACC ACTIONS = FCR_NEW ACTIONS FCR_NEW ACTIONS = -1 ! %UNLESS FCR_DATA FORMAT = 3 %THEN %START ! IE FOR ALL FILES OTHER THAN INTERACTIVE TERMINAL STREAM SERIAL REWIND (FCR) ;! OK FOR KENT BASIC FILES %IF FCR_ALL ACTIONS&X'B8' > 0 %THEN %START ! WRITE ACCESS REQUIRED DISCONNECT(FCR_OWNER.".".FCR_NAME,RC) %IF RC > 0 %THEN %START ABANDON(1,"DDISCON FAILS ON ".FCR_NAME." - ".SFROMI(RC)) %FINISH Y = FCR_CON ADDR << SEG SHIFT X = 0 CONNECT(FCR_OWNER.".".FCR_NAME,3,0,0,R,RC) %IF RC > 0 %THEN %START ABANDON(1,"FAILED TO CONNECT ".FCR_NAME." - ".SFROMI(RC)) %FINISH FCR_FHDR_DANDT = FILE TIME STAMP %FINISH %FINISH !?3;NEWLINE;WRITE(FCR_CURR DR1,10);NEWLINE INTEGER(FCR_CURR DR1)=X'B1000000' ;! RETURN RECORD CURRENCY VIA DESC INTEGER(FCR_CURR DR1+4) = ADDR(FCR_EP) ;! GIVEN IN PARM PAIR LIST !?3; CURRENT STREAM = OUT STREAM !?3; SELECT OUTPUT(DIAG STREAM) !?3; DWORK = "FILE ".FCR_OWNER.".".FCR_NAME." SELECTED, FCR FOLLOWS" !?3; XDUMP(DWORK,ADDR(FCR_EP),120) !?3; %IF FCR_CON ADDR > 0 %THEN %START !?3; XDUMP("FIRST 100 BYTES OF FILE",FCR_CON ADDR,100) !?3; %FINISH !?3; SELECT OUTPUT(CURRENT STREAM) %RESULT = 0 %END ;! OF SELECT RECORD ACCESS METHOD ! !********************************************************************** !* !* CREATE AREA !* !********************************************************************** ! ! %EXTERNALINTEGERFN CREATE AREA (%INTEGER %C NAME DR0,NAME DR1, %C P DR0,P DR1, %C A DR0,A DR1) ! ! THE ROW OF WORDS PASSED AS THE PARAMETER PAIR LIST IS MAPPED ! ONTO AN INTEGER ARRAY, PPLIST, USING AN INTEGER ARRAY ! FORMAT, PPF, WITH DYNAMIC BOUNDS, THE BOUNDS BEING ! BEING CALCULATED FROM THE LENGTH FIELD OF THE DESCRIPTOR ! FOR THE PARAMETER PAIRS. AN ARRAY OF POINTERS, IDPTR, EACH ! ELEMENT OF WHICH CORRESPONDS TO A PARM PAIR IDENTIFIER, IS ! INITIALISED SUCH THAT THE NTH ELEMENT POINTS TO THE ! FIRST WORD (IDENTIFIER) OF THE PARM PAIR WITH IDENTIFIER N. ! THE LENGTH OF THE ARRAY IDPTR IS DETERMINED BY THE ! LOWEST AND HIGHEST NUMERICAL VALUES OF THE PARM PAIR ! IDENTIFIERS EXPECTED. ! SEE K-SV9 BUPI MANUAL FOR FULL EXPLANATION OF THE PARM ! MECHANISM. ! ! THE ONLY TWO PARM PAIRS OF INTEREST TO EMAS WRT THIS ! INTERFACE ARE SIZE AND MAXSIZE, IDENTIFIERS 1 AND 7 ! RESPECTIVLY. THE ACCESS PERMISSION IS SET TO WRITE ! AS THERE IS LITTLE POINT IN CONNECTING TO A NEW AREA IN OTHER ! THAN WRITE MODE. ! ! THIS LAST POINT MAY HAVE TO BE REVISED TO TAKE ACCOUNT OF ! THINGS LIKE READ AND WRITE INITIAL PERMISSION. ! %INTEGERARRAYFORMAT PPF (0:(P DR0 & X'00FFFFFF') - 1) %INTEGERARRAYNAME PP LIST %INTEGERARRAY IDPTR (0:14) %INTEGER I,SIZE,MAX SIZE,FLAG,AREA ADDR,PPLIST LENGTH !?2; %STRING(80) TTWORK !?2; %INTEGER X %STRING(30) FILE NAME ! !?2; *STLN _X !?2; TRACE("CREATE AREA","",X,6,2) PPLIST LENGTH = P DR0 & X'00FFFFFF' PP LIST == ARRAY(P DR1,PPF) FILL (15*4,ADDR(IDPTR(0)),X'FF') %CYCLE I = 0,2,PPLIST LENGTH - 2 IDPTR(PPLIST(I))=I %REPEAT %IF IDPTR(1) > -1 %THEN SIZE = PPLIST(IDPTR(1)+1) %C %ELSE %RESULT = X'101' %IF IDPTR(7) > -1 %THEN %START MAX SIZE = PPLIST(IDPTR(7)+1) %IF MAX SIZE < SIZE %THEN %RESULT = X'E03' %FINISH %ELSE MAX SIZE = SIZE FILE NAME = "T#".NEXT TEMP OUT FILE (FILENAME,SIZE,MAX SIZE,0,AREA ADDR,FLAG) %IF FLAG # 0 %THEN %START LOG ('FAILURE FROM EMAS ''OUTFILE'' = ' %C .SFROMI(FLAG)) %RESULT = X'E08' %FINISH INTEGER(A DR1) = X'18000000' ! SIZE INTEGER(ADR1+4) = AREA ADDR !?2; TTWORK=STRINGFROM(NAMEDR0,NAMEDR1) !?2; ETOI(ADDR(TTWORK)+1,LENGTH(TTWORK)) !?2; TTWORK="-".TTWORK !?2; LOG("CREATE AREA- NAME IS >>".TTWORK."<<") !?2; LOG("TEMPAREA FILENAME IS >>".FILENAME."<<") !?2; TTWORK=HEXOF(INTEGER(ADR1)).HEXOF(INTEGER(ADR1+4)) !?2; LOG(">>".SFROMI(TRACECOUNT)."<< CREATE AREA DESCRIPTOR IS".TTWORK) %RESULT = 0 %END ;! OF CREATE AREA ! !********************************************************************** !* !* DELETE AREA !* !********************************************************************** ! ! %EXTERNALINTEGERFN DELETE AREA (%INTEGER A DR0,A DR1) %STRING(31) FILE NAME %INTEGER RC ! !?2; *STLN _RC !?2; TRACE("DELETE AREA","",RC,2,-1) FILE NAME = CONFILE(ADR1) %IF FILE NAME = '.NULL' %THEN %RESULT = X'401' DESTROY(FILE NAME,RC) %IF RC # 0 %THEN %RESULT = X'E0B' %RESULT = 0 %END ;! OF DELETE AREA ! !********************************************************************** !* !* UPDATE AREA LOCAL PROPERTIES !* !********************************************************************** ! ! %EXTERNALINTEGERFN UPDATE AREA LOCAL PROPERTIES (%INTEGER %C A DR0,A DR1, %C P DR0,P DR1) ! ! SEE CREATE AREA FOR DETAILS OF HANDLING OF PARAMETER PAIRS ! ! THE ONLY PROPERTIES OF INTEREST HERE ARE THOSE WHICH IMPLY ! A CHANGE IN AREA SIZE OR A CHANGE IN ACCESS PERMISSION TO THE ! THE AREA SPECIFIED. THE PARM PAIR ID'S OF INTEREST ARE ! AS FOLLOWS: ! 1 AREA SIZE ! 2 READ ACCESS ! 3 WRITE ACCESS ! 4 EXECUTE ACCESS %INTEGERARRAYFORMAT PPF (0:(P DR0 & X'00FFFFFF') - 1) %INTEGERARRAYNAME PPLIST %INTEGERARRAY IDPTR (0:14) %STRING(15) FILE NAME %INTEGER RC,NA,I,PPLIST LENGTH !?3; %INTEGER CURRENT STREAM !?3; %STRING(100) DWORK ! !?2; *STLN _RC !?2; TRACE("UPDATE ALP","",RC,4,2) PPLIST LENGTH = P DR0 & X'00FFFFF' PP LIST == ARRAY(P DR1,PPF) FILL(15*4,ADDR(IDPTR(0)),X'FF') %CYCLE I = 0,2,PPLIST LENGTH - 2 IDPTR(PPLIST(I)) = I %REPEAT ! !?3; CURRENT STREAM=OUTSTREAM !?3; SELECTOUTPUT(DIAGSTREAM) !?3; DWORK="ENTERED UALP---FCR FOLLOWS" !?3; XDUMP(DWORK,ADR1,120) !?3; SELECTOUTPUT(CURRENTSTREAM) FILE NAME = CONFILE(A DR1) %IF FILE NAME = '.NULL' %THEN %RESULT = X'401' %IF IDPTR(1) > -1 %THEN %START ! CHANGE FILE SIZE CHANGE FILE SIZE(FILE NAME,PPLIST(IDPTR(1)+1),RC) %IF RC # 0 %THEN %RESULT = X'E03' %FINISH NA = 0 %IF IDPTR(2) > -1 %THEN NA = 1 %IF IDPTR(3) > -1 %THEN NA = NA + 2 %IF IDPTR(4) > -1 %THEN NA = NA + 4 %IF NA > 0 %THEN %START CHANGE ACCESS (FILE NAME,NA,RC) %IF RC # 0 %THEN %RESULT = X'E03' %FINISH %RESULT = 0 %END ;! OF UPDATE AREA LOCAL PROPERTIES ! %EXTERNALINTEGERFN DELETEFILE %RESULT=0 %END ! %ENDOFFILE BP DR0 = NIL ; BP DR1 = NIL