!%title 'RT11.R16 - RT11 System Interface' ! ! COPYRIGHT (c) 1979, 1980 BY ! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ! ! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ! TRANSFERRED. ! ! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ! CORPORATION. ! ! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ! !++ ! FACILITY: RT11 ! ! ABSTRACT: ! This require file contains Bliss macros which provide the equivalent ! functions to the RT11 system macros. However, there are slight ! differences: no "area" argument is provided, the Bliss macro will ! create its own arg. block; no "pic" argument is provided, there is ! no reason for Bliss to support this; certain other macros (such as ! CHAIN) have had the arg. list modified so that the function may be ! implemented. ! ! Certain RT11 system macros cannot be implemented as Bliss macros. ! These have instead been implemented be creating Bliss macros which ! call MACRO-11 subroutines to perform the required operations. ! See the RTAUX.MAC file for these MACRO-11 functions. ! ! ! ENVIRONMENT: ! This file must be included as a Require file (or its equivalent ! Library file) within any Bliss-16 program desiring to use RT11 ! system macro calls. ! The user program must be linked with the RTAUX.OBJ file if any ! 'extended' macros are used (see description above). ! ! AUTHOR: David Leblang ! ! NOTES: ! Functions which expand to calls on RT$VAL_EMT do not return boolean ! values. On success they return the value of the SUC parameter, which ! is supplied internal macros and correspond to RT-11 directives, it ! is normally R0. On failure they return the value of the ERR parameter. ! Using one of these functions in a flow context (IF func(..) THEN ...) ! is incorrect because the return value is not a boolean. The ERR ! parameter may set a flag if need be, it may RETURN, or could be a ! literal which the function could not return. For example, the ! $LOOKUP function returns the number of blocks in the file looked-up; ! if the look-up fails the user may perform special handling, say SH. ! ! NUM_BLOCKS = $LOOKUP(parameters,LH); ! The error action is LH ! or ! NUM_BLOCKS = $LOOKUP(parameters,-1); ! Can't have -1 blocks ! IF .NUM_BLOCKS EQL -1 THEN LH; ! Check for bad NUM_BLOCKS ! ! ! Other functions return BOOLEAN values and should be used in flow ! context. The functions SHOULD NOT be passed error actions that ! do unconditional RETURNs, the compiler will complain about the code ! in the macro expansion that has become unreachable. Consider the ! $DELETE function which returns TRUE if the file could be deleted, it ! returns FALSE otherwise; special handling will be done on failure. ! ! IF NOT $DELETE(parameters) THEN SH; ! Correct usage. ! or ! $DELETE(parameters,SH); ! Ok if SH does not RETURN ! ! ! ! Versions of RT-11: ! ! A file containing declarations of the RT-11 version and type may be ! written and used as a prefix to the RT11 interface in a library build, ! or required prior to the require of the RT11 interface. In general, ! the default behavior (when no supplemental file is used) will allow ! access to all RT-11 directives. ! ! The user may specify that a particular version of RT is being targeted ! for by declaring a MACRO named RT_VER that expands to the name of the ! version desired. For example: ! MACRO RT_VER = RT_V2 %; ! The currently known versions of RT-11 are RT_V1, RT_V2, and RT_V3; the ! default, if RT_VER is undeclared, is RT_V3. ! ! The user may also specify that a particular type of RT system is being ! targeted for by declaring a MACRO named RT_TYP that expands to the ! name of the type desired. For example: ! MACRO RT_TYP = RT_XM %; ! The currently known types of RT-11 are RT_SJ, RT_FB, and RT_XM; the ! default, if RT_TYP is undeclared, is RT_XM. ! ! MODIFIED BY: ! ! 01 MSC 11-Dec-79 added GTLIN ! 02 TVC 11-Dec-79 corrected spelling ! 03 MSC 28-Dec-79 changed arg.vector to macro ! 04 MSC 28-Dec-79 additional macro calls ! 05 MSC 31-Dec-79 add version and type checking ! 06 MSC 02-Jan-80 added location definitions ! 07 LGD 20-Feb-80 corrections ! 08 DBL 11-Apr-80 Distinguish between boolean valued functions ! and 'R0' valued functions. ! 09 DBL 13-Apr-80 Re-do ARG_BLK macro. Also put R0 = .R0 into ! macros in order to get around a 'quirk' in the ! compiler's register allocation scheme. No code ! is generated & the compiler stops complaining ! about simultaneously allocated registers. ! ! 10 DBL 22-Apr-80 Modify TTINR and TTYIN to deal with null ! parameter passed as CHAR. Also, TTINR ! must use CH$WCHAR to store the character. ! ! 11 DBL 30-Apr-80 Make internal names more unique. ! !-- %IF NOT %BLISS(BLISS16) %THEN %ERROR('RT11 REQUIRES Bliss-16') %FI COMPILETIME ! RT11 VERSION AND TYPE DEFINITIONS RT_V1 = 1, RT_V2 = 2, RT_V3 = 3, %IF NOT %DECLARED(RT_VER) %THEN RT_VER = RT_V3, %FI RT_SJ = 1, RT_FB = 2, RT_XM = 3, %IF NOT %DECLARED(RT_TYP) %THEN RT_TYP = RT_XM, %FI RT_TOT = RT_VER + RT_TYP; %IF RT_VER LSS RT_V1 OR RT_VER GTR RT_V3 %THEN %ERROR('BAD RT VERSION CODE') %FI %IF RT_TYP LSS RT_SJ OR RT_TYP GTR RT_XM %THEN %ERROR('BAD RT TYPE CODE') %FI %IF RT_VER EQL RT_V1 %THEN %ERROR('UNABLE TO HANDLE RT V1 MACROS') %FI %IF RT_VER EQL RT_V1 AND RT_TYP GTR RT_SJ %THEN %ERROR('BAD VERSION/TYPE COMBINATION') %FI %IF RT_VER EQL RT_V2 AND RT_TYP GTR RT_FB %THEN %ERROR('BAD VERSION/TYPE COMBINATION') %FI ! DEFINITIONS OF VARIOUS LOCATIONS WITHIN RT11 WHICH THE USER MAY ACCESS ! (THERE ARE NO STANDARD NAMES FOR THESE IN THE RT11 DOCUMENTATION) ! (THESE NAMES DO NOT CORRESPOND TO ANY STANDARD) MACRO $RT_SYSCOM = ! the RT11 System Communication area ! the user must call this macro in the "own storage" portion ! of the module if any of the other macros in this section ! are to be used BIND RT_SYSCOM = %O'40' : BLOCK[8] VOLATILE; %; MACRO ! locations within SYSCOM RT_JOB = RT_SYSCOM[0,0,16,0] %, RT_ISP = RT_SYSCOM[1,0,16,0] %, RT_JSW = RT_SYSCOM[2,0,16,0] %, RT_JSW_USR = RT_SYSCOM[2,15,1,0] %, RT_JSW_LC = RT_SYSCOM[2,14,1,0] %, RT_JSW_RE = RT_SYSCOM[2,13,1,0] %, RT_JSW_STT = RT_SYSCOM[2,12,1,0] %, RT_JSW_PAS = RT_SYSCOM[2,11,1,0] %, RT_JSW_VIM = RT_SYSCOM[2,10,1,0] %, RT_JSW_OVL = RT_SYSCOM[2,9,1,0] %, RT_JSW_CHN = RT_SYSCOM[2,8,1,0] %, RT_JSW_ERR = RT_SYSCOM[2,7,1,0] %, RT_JSW_ITT = RT_SYSCOM[2,6,1,0] %, RT_JSW_FES = RT_SYSCOM[2,5,1,0] %, RT_JSW_PES = RT_SYSCOM[2,4,1,0] %, RT_USR = RT_SYSCOM[3,0,16,0] %, RT_HMEM = RT_SYSCOM[4,0,16,0] %, RT_ERR = RT_SYSCOM[5,0,16,0] %, RT_ERR_EMT = RT_SYSCOM[5,0,8,0] %, RT_ERR_USR = RT_SYSCOM[5,8,8,0] %, RT_RMON = RT_SYSCOM[6,0,16,0] %, RT_FILL = RT_SYSCOM[7,0,16,0] %, RT_FILL_CHR = RT_SYSCOM[7,0,8,0] %, RT_FILL_CNT = RT_SYSCOM[7,8,8,0] %; MACRO ! locations within RMON ! the preferred method is to use the $GVAL macro ! $RT_RMON(OFFSETT) = (.RT_RMON + OFFSETT) %, RT_SUSR = $RT_RMON(%O'266') %, RT_IOX = $RT_RMON(%O'270') %, RT_SDER = $RT_RMON(%O'272') %, RT_UNIT = $RT_RMON(%O'274')<8,8,0> %, RT_VRSN = $RT_RMON(%O'276')<0,8,0> %, RT_REL = $RT_RMON(%O'276')<0,8,0> %, RT_CNFG = $RT_RMON(%O'300') %, RT_CNFG_TYP = RT_CNFG<0,1,0> %, RT_CNFG_GRF = RT_CNFG<2,1,0> %, RT_CNFG_BAT = RT_CNFG<3,1,0> %, RT_CNFG_CLK = RT_CNFG<5,1,0> %, RT_CNFG_FP = RT_CNFG<6,1,0> %, RT_CNFG_FG = RT_CNFG<7,1,0> %, RT_CNFG_GRAF = RT_CNFG<8,1,0> %, RT_CNFG_USR = RT_CNFG<9,1,0> %, RT_CNFG_1103 = RT_CNFG<11,1,0> %, RT_CNFG_MAP = RT_CNFG<12,1,0> %, RT_CNFG_STCLK = RT_CNFG<13,1,0> %, RT_CNFG_11PCLK = RT_CNFG<14,1,0> %, RT_CNFG_LPCLK = RT_CNFG<15,1,0> %, RT_TIS = $RT_RMON(%O'304') %, RT_TID = $RT_RMON(%O'306') %, RT_TOS = $RT_RMON(%O'310') %, RT_TOD = $RT_RMON(%O'312') %, RT_MFSZ = $RT_RMON(%O'314') %, RT_SYNK = $RT_RMON(%O'324') %, RT_DSTP = $RT_RMON(%O'354') %, RT_MTPS = $RT_RMON(%O'360') %, RT_MFPS = $RT_RMON(%O'362') %, RT_IST = $RT_RMON(%O'366') %, RT_ECFG = $RT_RMON(%O'370') %, RT_ECFG_CACHE = RT_ECFG<0,1,0> %, RT_ECFG_PARITY = RT_ECFG<1,1,0> %, RT_ECFG_SWREG = RT_ECFG<2,1,0> %, RT_ECFG_WCDR = RT_ECFG<3,1,0> %, RT_ECFG_EIS = RT_ECFG<8,1,0> %, RT_ECFG_VTVS = RT_ECFG<9,1,0> %, RT_ECFG_1170 = RT_ECFG<14,1,0> %, RT_ECFG_1160 = RT_ECFG<15,1,0> %, RT_OPT = $RT_RMON(%O'372') %, RT_OPT_ERR = RT_OPT<0,1,0> %, RT_OPT_MMGMT = RT_OPT<1,1,0> %, RT_OPT_IOTO = RT_OPT<2,1,0> %, RT_OPT_MPAR = RT_OPT<9,1,0> %, RT_OPT_SJMT = RT_OPT<10,1,0> %, RT_OPT_ESC = RT_OPT<11,2,0> %, RT_OPT_MT = RT_OPT<13,1,0> %, RT_USZ = $RT_RMON(%O'374') %, RT_NEST = $RT_RMON(%O'376')<8,8,0> %, RT_IBAT = $RT_RMON(%O'400') %, RT_FORK = $RT_RMON(%O'402') %; MACRO ! GENERAL PURPOSE UTILITIES RT$$_ERR_EMT(ERR,EMTNUM) = BEGIN !+ ! RT-11 EMT call interface for boolean valued functions !- LINKAGE $$_RT11=EMT:CLEARSTACK VALUECBIT; IF $$_RT11(EMTNUM,%REMAINING) THEN %IF %NULL(ERR) %THEN 0 ! Failed, no error action, value is FALSE %ELSE (ERR; 0) ! Failed, do error action, value is FALSE %FI ELSE 1 ! Succeeded, value is TRUE END %, RT$$_VAL_EMT(ERR,SUC,EMTNUM) = BEGIN !+ ! RT-11 EMT call interface for valued functions !- LINKAGE $$_RT11=EMT:CLEARSTACK VALUECBIT; IF $$_RT11(EMTNUM,%REMAINING) THEN %IF %NULL(ERR) %THEN 0 ! Failed, no error action, value is 0 %ELSE (ERR) ! Failed, do error action, value is ERR %FI ELSE %IF %NULL(SUC) %THEN 1 ! Succeeded, no SUC action? Value is 1 %ELSE (SUC) ! Succeeded, do success action, value is SUC %FI END %, $RESULT_R0 = (REGISTER R0 = 0; R0 = .R0) %, $ARG_R0(ARG) = (REGISTER R0 = 0; R0 = ARG) %, $ARG_BLK [] = !+ ! Create an argument block on the stack with R0 pointing to the base. ! This macro must be used at the entrance to a block and must not be ! enclosed in an extra block because it allocates local storage. !- LOCAL _$ARGBLOCK : VECTOR[%LENGTH]; ! Allocate storage _$ARG_ITER(%REMAINING); ! Fill in arguments $ARG_R0(_$ARGBLOCK[0]) ! R0 has pointer to base %, _$ARG_ITER (ARG) [] = !+ ! Recursive macro which assigns the Nth argument to _$ARGBLOCK[N]. !- _$ARGBLOCK[%COUNT] = ARG; _$ARG_ITER(%REMAINING) %; MACRO ! RT11 SYSTEM MACROS $CDFN( ADDR, NUM, ERR) = BEGIN $ARG_BLK(%O'15'^8+0,ADDR,NUM); RT$$_ERR_EMT(ERR, %O'375') END %, $CHAIN( PROG, DATA, ERR) = BEGIN %IF NOT %NULL(PROG) %THEN BIND $_P = %O'500' : VECTOR[4]; %FI %IF NOT %NULL(DATA) %THEN BIND $_D = %O'510' : VECTOR[%O'134']; %FI %IF NOT %NULL(PROG) %THEN $_P[0] = .PROG[0]; $_P[1]=.PROG[1]; $_P[2]=.PROG[2]; $_P[3]=.PROG[3]; %FI %IF NOT %NULL(DATA) %THEN $_D[0]=.DATA[0]; $_D[1]=.DATA[1]; $_D[2]=.DATA[2];$_D[3]=.DATA[3]; %FI $ARG_R0(%O'10' ^ 8 + 0); RT$$_ERR_EMT(ERR, %O'374') END %, %IF RT_TYP GTR RT_SJ %THEN $CHCOPY(CHAN, OCHAN, ERR) = BEGIN $ARG_BLK(%O'13'^8+CHAN,OCHAN); RT$$_ERR_EMT(ERR, %O'375') END %, %FI $CLOSE( CHAN, ERR) = BEGIN $ARG_R0(%O'6' ^ 8 + CHAN); RT$$_ERR_EMT(ERR, %O'374') END %, $CMKT( ID, TIME, ERR) = BEGIN $ARG_BLK(%O'23'^8+0,ID,TIME); RT$$_ERR_EMT(ERR, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN $CNTXSW( ADDR, ERR) = BEGIN $ARG_BLK(%O'33'^8+0,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %FI %IF RT_TYP GTR RT_FB %THEN $CRAW( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+2,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, $CRRG( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+0,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %FI $CSIGEN( DEVSPC, DEFEXT, CSTRING, ERR) = BEGIN RT$$_VAL_EMT (ERR,$RESULT_R0, %O'344', CSTRING, DEFEXT, DEVSPC) END %, $CSISPC( OUTSPC, DEFEXT, CSTRING, ERR) = BEGIN RT$$_ERR_EMT(ERR, %O'345', CSTRING, DEFEXT, OUTSPC); END %, %IF RT_TYP GTR RT_SJ %THEN $CSTAT( CHAN, ADDR, ERR) = BEGIN $ARG_BLK(%O'27'^8+CHAN,ADDR); RT$$_ERR_EMT( ERR, %O'375') END %, %FI %IF RT_VER GTR RT_V2 %THEN $CTIMIO (TBK) = BEGIN EXTERNAL ROUTINE %NAME('.CTIMIO.'); %IF %NULL(TBK) %THEN %ERROR('Must Specify TBK') %FI %NAME('.CTIMIO.')(TBK,.$TIMIT); END %, %FI $DATE = BEGIN $ARG_R0(%O'12'^8+0); RT$$_VAL_EMT(,$RESULT_R0, %O'374'); END %, $DELETE( CHAN, DBLK, COUNT, ERR) = BEGIN $ARG_BLK(0+CHAN,DBLK,COUNT); RT$$_ERR_EMT(ERR, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN $DEVICE( ADDR, ERR) = BEGIN ! NON-LINKING FORM $ARG_BLK(%O'14'^8+0,ADDR); RT$$_ERR_EMT( ERR, %O'375') END %, %FI %IF RT_VER GTR RT_V2 %THEN !$DRAST( NAME, PRI, ABT, ERR) !$DRBEG( NAME, VEC, DSIZ, DSTS, VTBL, ERR) !$DREND( NAME, ERR) !$DRFIN( NAME, ERR) %FI $DSTATUS( CBLK, DEVNAM, ERR) = BEGIN $ARG_R0(DEVNAM); RT$$_ERR_EMT( ERR, %O'342', CBLK) END %, %IF RT_TYP GTR RT_FB %THEN $ELAW( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+3,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, $ELRG( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+1,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %FI $ENTER( CHAN, DBLK, LENGTH, COUNT, ERR) = BEGIN $ARG_BLK(2^8+CHAN,DBLK,LENGTH,COUNT); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %, $EXIT( CON) = BEGIN $ARG_R0(%IF %NULL(CON) %THEN 0 %ELSE 1 %FI); RT$$_ERR_EMT(,%O'350') END %, $FETCH( CORADD, DEVNAM, ERR) = BEGIN $ARG_R0(DEVNAM); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'343', CORADD); END %, %IF RT_VER GTR RT_V2 %THEN $FORK (BLK) = BEGIN EXTERNAL ROUTINE %NAME('.FORK.'); %IF %NULL(BLK) %THEN %ERROR('Must specify BLK') %FI %NAME('.FORK.')(BLK,.$FKPTR); END %, %FI %IF RT_TYP GTR RT_FB %THEN $GMCX( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+6,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %FI $GTIM( ADDR,ERR) = BEGIN $ARG_BLK(%O'21'^8+0,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, $GTJB( ADDR, ERR) = BEGIN $ARG_BLK(%O'20'^8+0,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, $GTLIN( LINBUF, PROMPT) = RT$$_ERR_EMT(, %O'345',LINBUF, 1, %IF %NULL(PROMPT) %THEN 0 %ELSE PROMPT %FI, 0) %, $GVAL( OFFSET, ERR) = BEGIN $ARG_BLK(%O'34'^8+0,OFFSET); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %, $HERR = BEGIN $ARG_R0(5 ^ 8); RT$$_ERR_EMT(, %O'374') END % , $SERR = BEGIN $ARG_R0(4 ^ 8); RT$$_ERR_EMT(, %O'374') END %, $HRESET = RT$$_ERR_EMT(, %O'357') %, $INTEN (PRIO) = BEGIN EXTERNAL ROUTINE %NAME('.INTEN.'); %IF %NULL(PRIO) %THEN %ERROR('Must specify PRIORITY') %FI %NAME('.INTEN.')((-(PRIO*32)-1)AND 224); END %, $LOCK = RT$$_ERR_EMT(, %O'346') %, $UNLOCK = RT$$_ERR_EMT(, %O'347') %, $LOOKUP( CHAN, DBLK, COUNT, ERR) = BEGIN $ARG_BLK(1^8+CHAN,DBLK,COUNT); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN $MAP( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+4,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, $UNMAP( ADDR, ERR) = BEGIN $ARG_BLK(%O'36'^8+5,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %FI $MFPS (ADDR) = BEGIN EXTERNAL ROUTINE %NAME('.MFPS.'); %IF %NULL(ADDR) %THEN %NAME('.MFPS.')() %ELSE ADDR = %NAME('.MFPS.')() %FI END %, $MTPS (ADDR) = BEGIN EXTERNAL ROUTINE %NAME('.MTPS.'); %IF %NULL(ADDR) %THEN %ERROR('Must specify ADDR') %FI %NAME('.MTPS.')(ADDR); END %, $MRKT( TIME, CRTN, ID, ERR) = BEGIN $ARG_BLK(%O'22'^8+0,TIME,CRTN,ID); RT$$_ERR_EMT( ERR, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN $MTATCH( ADDR, UNIT, ERR) = BEGIN $ARG_BLK(%O'37'^8+5,ADDR,UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTDTCH( UNIT, ERR) = BEGIN $ARG_BLK(%O'37'^8+6,0,UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTGET( ADDR, UNIT, ERR) = BEGIN $ARG_BLK(%O'37'^8+1,ADDR,UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTIN( ADDR, UNIT, COUNT, ERR) = BEGIN $ARG_BLK(%O'37'+2,ADDR,COUNT^8+UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTOUT( ADDR, UNIT, COUNT, ERR) = BEGIN $ARG_BLK(%O'37'+3,ADDR,COUNT^8+UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTPRNT( ADDR, UNIT, ERR) = BEGIN $ARG_BLK(%O'37'^8+7,ADDR,UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTRCTO( UNIT, ERR) = BEGIN $ARG_BLK(%O'37'^8+4,0,UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, $MTSET( ADDR, UNIT, ERR) = BEGIN $ARG_BLK(%O'37'^8+0,ADDR,UNIT); RT$$_ERR_EMT( ERR, %O'375') END %, %FI %IF RT_TYP GTR RT_SJ %THEN $MWAIT = BEGIN $ARG_R0(%O'11' ^ 8 + 0); RT$$_ERR_EMT(, %O'374') END %, %FI !$PRINT( ADDR) = RT$$_ERR_EMT(, %O'351', ADDR) %, $PRINT( ADDR, ERR) = BEGIN $ARG_R0(ADDR); RT$$_ERR_EMT(ERR, %O'351') END %, %IF RT_TYP GTR RT_SJ %THEN $PROTECT( ADDR, ERR) = BEGIN $ARG_BLK(%O'31'^8+0,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, $UNPROTECT( ADDR, ERR) = BEGIN $ARG_BLK(%O'31'^8+1,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %FI $PURGE( CHAN) = BEGIN $ARG_R0(3 ^ 8 + CHAN); RT$$_ERR_EMT(, %O'374') END %, %IF RT_VER GTR RT_V2 %THEN $QELDF = Q$LINK = 0, Q$CSW = 2, Q$BLKN = 4, Q$FUNC = 6, Q$JNUM = 7, Q$UNIT = 7, Q$BUFF = %O'10', Q$WCNT = %O'12', Q$COMP = %O'14', %IF %DECLARED(MMG$T) %THEN %IF MMG$T EQL 0 %THEN Q$ELGH = %O'16' %ELSE Q$PAR = %O'16', Q$ELGH = %O'24' %FI %ELSE Q$ELGH = %O'16' %FI %, %FI $QSET( ADDR, QLENG) = RT$$_ERR_EMT(, %O'353', QLENG, ADDR) %, $RCTRLO = RT$$_ERR_EMT(, %O'355') %, %IF RT_TYP GTR RT_SJ %THEN $RCVD( BUFF, WCNT, ERR) = BEGIN $ARG_BLK(%O'26'^8+0,0,BUFF,WCNT,1); RT$$_ERR_EMT(ERR, %O'375') END %, $RCVDC( BUFF, WCNT, CRTN, ERR) = BEGIN $ARG_BLK(%O'26'^8+0,0,BUFF,WCNT,CRTN); RT$$_ERR_EMT(ERR, %O'375') END %, $RCVDW( BUFF, WCNT, ERR) = BEGIN $ARG_BLK(%O'26'^8+0,0,BUFF,WCNT,0); RT$$_ERR_EMT(ERR, %O'375') END %, %FI %IF RT_TYP GTR RT_FB %THEN $RDBBK( SIZ) = VECTOR[3] INITIAL(0,SIZ,0) %, $RDBDF = R$GID = 0, R$GSIZ = 2, R$GSTS = 4, R$GLGH = 6, RS$CRR = %O'100000', RS$UNM = %O'40000', RS$NAL = %O'20000' %, %FI $READ( CHAN, BUFF, WCNT, BLK, ERR) = BEGIN $ARG_BLK(%O'10'^8+CHAN,BLK,BUFF,WCNT,1); RT$$_ERR_EMT(ERR, %O'375') END %, $READC( CHAN, BUFF, WCNT, CRTN, BLK, ERR) = BEGIN $ARG_BLK(%O'10'^8+CHAN,BLK,BUFF,WCNT,CRTN); RT$$_ERR_EMT(ERR, %O'375') END %, $READW( CHAN, BUFF, WCNT, BLK, ERR) = BEGIN $ARG_BLK(%O'10'^8+CHAN,BLK,BUFF,WCNT,0); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %, $REGDEF = %, $RELEAS( DEVNAME, ERR) = RT$$_ERR_EMT( ERR, %O'343', DEVNAME) %, $RENAME( CHAN, DBLK, ERR) = BEGIN $ARG_BLK(4^8+CHAN,DBLK); RT$$_ERR_EMT(ERR, %O'375') END %, $REOPEN( CHAN, CBLK, ERR) = BEGIN $ARG_BLK(6^8+CHAN,CBLK); RT$$_ERR_EMT(ERR, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN !$RSUM see $SPND %FI $SAVESTATUS( CHAN, CBLK, ERR) = BEGIN $ARG_BLK(5^8+CHAN,CBLK); RT$$_ERR_EMT(ERR, %O'375') END %, $SCCA( ADDR, ERR) = BEGIN $ARG_BLK(%O'35'^8+0,ADDR); RT$$_ERR_EMT(ERR, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN $SDAT( BUFF, WCNT, ERR) = BEGIN $ARG_BLK(%O'25'^8+0,0,BUFF,WCNT,1); RT$$_ERR_EMT(ERR, %O'375') END %, $SDATC( BUFF, WCNT, CRTN, ERR) = BEGIN $ARG_BLK(%O'25'^8+0,0,BUFF,WCNT,CRTN); RT$$_ERR_EMT(ERR, %O'375') END %, $SDATW( BUFF, WCNT, ERR) = BEGIN $ARG_BLK(%O'25'^8+0,0,BUFF,WCNT,0); RT$$_ERR_EMT(ERR, %O'375') END %, %FI !$SERR see $HERR $SETTOP( ADDR) = BEGIN $ARG_R0(ADDR); RT$$_VAL_EMT(,$RESULT_R0,%O'354') END %, $SFPA( ADDR) = BEGIN $ARG_BLK(%O'30'^8+0,ADDR); RT$$_ERR_EMT(, %O'375') END %, $SPFUN( CHAN, CODE, BUFF, WCNT, BLK, CRTN, ERR) = BEGIN $ARG_BLK(%O'32'^8+CHAN,BLK,BUFF,WCNT,CODE^8+%O'377',CRTN); RT$$_ERR_EMT(ERR, %O'375') END %, %IF RT_TYP GTR RT_SJ %THEN $SPND = BEGIN $ARG_R0(1^8); RT$$_ERR_EMT(, %O'374') END %, $RSUM = BEGIN $ARG_R0(2^8); RT$$_ERR_EMT(, %O'374') END %, %FI $SRESET = RT$$_ERR_EMT(, %O'352') %, $SYNCH = BEGIN EXTERNAL ROUTINE %NAME('.SYNCH.'); %NAME('.SYNCH.')(); END %, %IF RT_VER GTR RT_V2 %THEN $TIMIO (TBK,HI,LO) = BEGIN EXTERNAL ROUTINE %NAME('.TIMIO.'); %IF %NULL(TBK) %THEN %ERROR('Must specify TBK') %FI %IF %NULL(HI) %THEN %ERROR('Must specify HI') %FI %IF %NULL(LO) %THEN %ERROR('Must specify LO') %FI %NAME('.TIMIO.')(TBK,HI,LO,.$TIMIT); END %, %FI %IF RT_TYP GTR RT_SJ %THEN $TLOCK( ERR) = BEGIN $ARG_R0(7 ^ 8); RT$$_ERR_EMT( ERR, %O'374') END %, %FI $TRPSET(ADDR) = BEGIN $ARG_BLK(3^8+0,ADDR); RT$$_ERR_EMT(,%O'375') END %, !+ ! TTYIN can never fail since it waits for a character to be placed into ! the buffer (see RT-11 manual). If CHAR is specified then the character ! input is written to CHAR and this function is NOVALUE; if CHAR is null ! then the value of the function is the character read. !- $TTYIN(CHAR) = BEGIN LINKAGE $$_RT11=EMT:CLEARSTACK VALUECBIT; WHILE $$_RT11(%O'340') DO 0; ! Wait for a character (REGISTER R0=0; R0 = .R0; %IF %NULL(CHAR) %THEN .R0<0,8> %ELSE CH$WCHAR(.R0<0,8>,CHAR) %FI ) END %, !+ ! TTINR is like TTYIN except the function does not loop waiting for a ! character to come in. This function is therefore BOOLEAN valued, that is, ! it returns TRUE if a character was input, FALSE is no character was ! available. If CHAR is specified the character, if any, is written to CHAR; ! the resulting value is a BOOLEAN telling whether a character was read. ! If CHAR is null, then the character input is flushed; the resulting value ! is a BOOLEAN telling whether a character was read. Note that TTYIN is ! a 'R0-valued' function while TTINR is a 'Boolean-valued' function. ! ! Examples: $TTYIN(CH) or CH = $TTYIN() or IF TTINR(CH) THEN process(.CH) !- $TTINR(CHAR) = BEGIN IF RT$$_ERR_EMT(,%O'340') THEN %IF NOT %NULL(CHAR) %THEN (BUILTIN R0; R0=.R0; CH$WCHAR(.R0, CHAR); 1) %ELSE 1 %FI ELSE 0 ! No character read, return FALSE END %, !+ ! According to the RT-11 system macro call manual $TTYOUT takes the ! ADDRESS of a character not the character. The new $TTYOUT macro ! follows this convention; in addition, it allows a quoted string ! character to be passed ( ex. $TTYOUT('>') ). If the buffer is full ! then the $TTYOUT macro waits for the buffer to empty and the character ! to be sent - hence this macro NEVER fails. See $TTOUTR which returns ! TRUE if the character is written, FALSE otherwise. !- $TTYOUT(CHAR) = BEGIN LINKAGE $$_RT11=EMT:CLEARSTACK VALUECBIT; REGISTER R0 = 0; %IF NOT %NULL(CHAR) %THEN %IF %ISSTRING(CHAR) %THEN R0 = %EXACTSTRING(CHAR,1,0) %ELSE R0 = CH$RCHAR(CHAR); %FI %FI WHILE $$_RT11(%O'341') DO 0; END%, $TTOUTR(CHAR) = BEGIN REGISTER R0 = 0; %IF NOT %NULL(CHAR) %THEN %IF %ISSTRING(CHAR) %THEN R0 = %EXACTSTRING(CHAR,1,0) %ELSE R0 = CH$RCHAR(CHAR); %FI %FI RT$$_ERR_EMT(, %O'341') END%, !------ Old versions of TTYOUT and TTOUTR ------! !$TTYOUT( CHAR) = BEGIN ! ! REGISTER R0 = 0; R0 = CHAR; ! ! RT$ERR_EMT(,%O'341') END %, ! ! ! !$TTOUTR = BEGIN ! ! REGISTER R0 = 0; ! ! IF RT$ERR_EMT(, %O'341') THEN -.R0^-1 ! ! ELSE .R0^-1 END %, ! !-----------------------------------------------! %IF RT_TYP GTR RT_SJ %THEN $TWAIT( TIME, ERR) = BEGIN $ARG_BLK(%O'24'^8+0,TIME); RT$$_ERR_EMT( ERR, %O'375') END %, %FI !$UNLOCK see $LOCK %IF RT_TYP GTR RT_SJ %THEN !$UNMAP see $MAP !$UNPROTECT see $PROTECT %FI $WAIT( CHAN, ERR) = BEGIN $ARG_R0(CHAN); RT$$_ERR_EMT( ERR, %O'374') END %, %IF RT_TYP GTR RT_FB %THEN $WDBBK( APR, SIZ, RID, OFF, LEN, STS) = VECTOR[7] INITIAL(APR^8+0,0,SIZ,RID,OFF,LEN,STS) %, $WDBDF = W$NID = 0, W$NAPR = 1, W$NBAS = 2, W$NSIZ = 4, W$NRID = 6, W$NOFF = %O'10', W$NLEN = %O'12', W$NSTS = %O'14', W$NLGH = %O'16', WS$CRW = %O'100000', WS$UNM = %O'40000', WS$ELW = %O'20000', WS$MAP = %O'400' %, %FI $WRITE( CHAN, BUFF, WCNT, BLK, ERR) = BEGIN $ARG_BLK(%O'11'^8+CHAN,BLK,BUFF,WCNT,1); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %, $WRITC( CHAN, BUFF, WCNT, CRTN, BLK, ERR) = BEGIN $ARG_BLK(%O'11'^8+CHAN,BLK,BUFF,WCNT,CRTN); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %, $WRITW( CHAN, BUFF, WCNT, BLK, ERR) = BEGIN $ARG_BLK(%O'11'^8+CHAN,BLK,BUFF,WCNT,0); RT$$_VAL_EMT(ERR,$RESULT_R0, %O'375') END %; !++ ! !Auxiliary definitions for RT11 interface ! !-- !++ !Error codes returned by programmed requests !-- literal ! .MTATCH ERMTATCH$NOLUN = 2, !non-existent lun ERMTATCH$BADREQ = 3, !illegal request, function out of range ERMTATCH$TAKEN = 4, !unit attatched by another job ERMTATCH$BADADR = 5, !status word not in valid addr space END_ERR_CODES = 9999; !no more error codes field !mnemonics for tty status fields tty_status_fld = set ttystat$m_tsts = [0,0,16,0], !terminal congiguration ttystat$tab = [0,0,1,0], !hardware tab if true ttystat$lline = [0,1,1,0], !long output broken into lines ttystat$form = [0,2,1,0], !hardware FF if true ttystat$ctlfb = [0,3,1,0], !^F, ^B normal data if true ttystat$enesc = [0,4,1,0], !enable escape processing ttystat$flesc = [0,5,1,0], !filter esc sequences ttystat$nowait = [0,6,1,0], !inhibit tt wait ttystat$xonoff = [0,7,1,0], !process XON/XOFF ttystat$speed = [0,8,4,0], !tty speed code ttystat$char = [0,12,1,0], !char input mode ttystat$ronly = [0,13,1,0], !terminal is read-only ttystat$upcase = [0,14,1,0], !force input to upper ttystat$bksp = [0,15,1,0], !use backspace for rubout ttystat$m_tst2 = [1,0,16,0], !not now used ttystat$m_tfil = [2,0,8,0], !character requiring fillers ttystat$m_fcnt = [2,8,8,0], !# of fillers ttystat$m_twid = [3,0,8,0], !carriage width ttystat$tstw = [3,8,8,0], !term state byte ttystat$shared = [3,10,1,0], !term is shared console ttystat$hungup = [3,11,1,0], !term hung up ttystat$dz11 = [3,12,1,0], !interface is DZ11 ttystat$2cc = [3,14,1,0], !^C^C was hit ttystat$consol = [3,15,1,0] !term is console tes; macro !+ ! TTY_SPEEDS is a list of the baud rates a terminal can run at. ! This list can be used to initialize a plit or vector. ! NOTES: 134 baud as listed is actually 134.5 baud ! -1 represents an unused baud rate code ! The j is the baud rate code used in TTYSTAT$SPEED, where ! .(UPLIT(TTY_SPEEDS) + %BPVAL*j) is the speed ! desired. !- tty_speeds = 50,75,110,134,150,300,600,1200,1800,2000,2400, 3600,4800,7200,9600,-1 %;