<< LINES .001/.009 ARE RESERVED FOR SYSTEMS INTEGRATION>>               00000001
$CONTROL MAP,CODE,USLINIT                                               00010000
<<NRIO - MODULE 62>>                                                    00012000
<< HP32002C MPE SOURCE C.00.00 >>                                       00014000
$COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980. ",            & 00016000
$     "THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A ",      & 00018000
$     "TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR ",    & 00020000
$     "STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION ",& 00022000
$     "OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED ",  & 00024000
$     "WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY."   00026000
                                                                        00028000
                                                                        00030000
$CONTROL PRIVILEGED, MAIN = NRIO ,SEGMENT = NRIO                        00032000
$THIRTY                                                                 00034000
                                                                        00036000
BEGIN    << NON CORE RESIDENT I/O  ROUTINES >>                          00038000
                                                                        00040000
EQUATE                                                                  00042000
    ABORT'    =  0,        << ABORT THIS I/O REQUEST >>                 00044000
    ABORT'IO  = 66,      << SCCP ABORTIO AND PROCIO FUNCTION >><<00.TE>>00046000
    BREAK'    = 10,        << BREAK IS ALLOWED AND HAS BEEN DETECTED >> 00048000
    CCE       = 2,                                                      00050000
    CCG       = 0,                                                      00052000
    CCL       = 1,                                                      00054000
    CPCB      = 4,         << CURRENT PCB INDEX >>                      00056000
    CR        =%15,                                                     00058000
    DCNTRL    =10,         << MULTIPLEXOR CONTROL WORD AND NEXT DSTATE>>00060000
    DDLTP     = 4,         << DLT POINTER >>                            00062000
    DELECHO'  = 2,         << CHARACTER DELETION ECHO CODE >>           00064000
    DILTP     = 5,         << ILT POINTER >>                            00066000
    DIOQP     = 2,         << IOQ POINTER TO FIRST REQUEST >>           00068000
    DISC'     =  1,        << DEVICE IS A DISC (DIT) >>                 00070000
    DLAST     =23,                                             <<00.06>>00072000
    DLDEV     = 3,         << LOGICAL DEVICE AND UNIT NUMBERS >>        00074000
    DMODEM    = 8,         << MODEM TYPE AND STATE  >>                  00076000
    DSPEED    = 9,         << MULTIPLEXOR SPEED AND OTHER FLAGS >>      00078000
    DSTATE'   =12,         << DEVICE STATE                              00080000
                               0 - NULL         %10 - EOR SYNC          00082000
                               1 - WRITING      %11 - WRITE BUF FILL    00084000
                               2 - READING      %12 - DELETE LF OR CHAR 00086000
                               3 - XON WRITE    %13 - DELETE CR         00088000
                               4 - READ TURN    %14 - DELETE !'S        00090000
                               5 - BAND WAIT    %15 - WRT TURN DONE     00092000
                               6 - EOR LF       %16 - START READ        00094000
                               7 - EOR CR       %17 - FINISH READ  >>   00096000
    DSTAT     = 6,         << LAST HARDWARE INTERRUPT STATUS >>         00098000
    DSIZE     = 5,         << DEVICE TYPE >>                            00100000
    DSYNC     =29,         << CR,LF SYNC DATA AND SYNC COUNTER >>       00102000
    DTYPE     = 7,         << STOP FLAGS, TERMTYPE, HSTATE,TIMER FLAGS>>00104000
    ECHOOFF   = 0,         << TURN ECHO OFF CODE TO MPXCONTROL >>       00106000
    FIRSTINDEX= 8,         << INDEX TO FIRST BUFFER OF TABLE >>         00108000
    GOODIO    = 1,         << SUCCESSFUL I/O STATUS RETURN >>           00110000
    HP2631B    = 19,         << TERM TYPE FOR 2631B >>         <<01466>>00112000
    HP2645K  = 12,         <<HP2645K 8-BIT TTYPE>>             <<AMS00>>00114000
    HSI       = 19,        << HSI DEVICE TYPE >>               <<00.TE>>00116000
    IAK'      = 8,         << DEVICE HAS INTERRUPTED (DIT) >>           00118000
    ICNTRL    = 7,         << CONTROLLER INFO IN ILT >>        <<01300>>00120000
    IFLAG     = 13,        << FLAGS WORD OF ILT >>             <<01300>>00122000
    ISIOP     = 8,         << SIOP POINTER IN ILT >>           <<01300>>00124000
    IDITP     = 14,        << DITP POINTER IN ILT >>           <<01300>>00126000
    IMPEDABLE = 4,         << AWAKEIO CALLER MAY BE IMPEDED >>          00128000
    INITDSET  = 0,         << INITIALIZE DATA SET CONTROL CODE >>       00130000
    IOQSIZE   =11,         << IOQ ELEMENT SIZE >>                       00132000
    JUNKWAIT  = %20,                                                    00134000
    LIM       = 0,         << LIMIT WORD OF TABLE ALLOCATION >>         00136000
    MHDISC    = 1,         << MOVING HEAD DISC TYPE >>         <<00.TE>>00138000
    NOPCB     = %13,       << NO PCB I/O REQUEST >>            <<00.TE>>00140000
    NOIMPEDE  = 0,         << AWAKEIO CALLER MAY NOT BE IMPEDED >>      00142000
    NOPTY'    = 2,         <<8-BIT DATA  FLAG-->>              <<AMS00>>00144000
                           <<SET IN 8TH BIT>>                  <<AMS00>>00146000
    NULL      = 0,                                                      00148000
    PARITYBITS'=7,     <<1ST PRTY CNTRL BIT IN DCNTRL>>        <<+1.M3>>00150000
    PCBB      = 3,         << BASE OF PCB TABLE >>                      00152000
    PCBSIZE   =16,                                                      00154000
    QLINK     = 1,         << NEXT IOQ POINTER >>                       00156000
    QLDEV     = 2,        << LDEV INDEX IN IOQ >>              <<00.05>>00158000
    QSTAT     =10,         << REQUEST STATUS AND PCB NUMBER >>          00160000
    READFUNC  = 0,         << READ FUNCTION CODE >>                     00162000
    READING   = 2,         << DSTATE- READ IN PROGRESS >>      <<00.03>>00164000
    SSBREAK'  = 4,         << SUB SYS BRK IS ALLOWED &  HAS BEEN DET. >>00166000
    SSLC      = 18,        << SSLC DEVICE TYPE >>              <<00.TE>>00168000
    SYSDB     =%1000,                                                   00170000
    SYNCCHAR  =%47777,     << SYNC CHARACTER  >>                        00172000
    SYSDISK   = 1,         << SYSTEM DISK LOGICAL DEVICE # >>           00174000
    SYSCST    = 1,                                                      00176000
    SYSDST    = 2,                                                      00178000
    SYSIOQ    = 5,        << IOQ TABLE PTR SYSDB INDEX >>      <<00.05>>00180000
    SYSLPDT   =%10,        << LOGICAL PHYSICAL DEVICE TABLE >>          00182000
    SYSSBUF   = 6,                                                      00184000
    TELENET   = 13,        << TELENET TERMINAL TYPE >>                  00186000
    TERMINAL' = 0,         << DEVICE IS A TERMINAL >>                   00188000
    THEAD     = 2,         << HEAD INDEX  >>                            00190000
    TOVRFL    = 5,         << OVERFLOW OF PRIMARY TABLE COUNTER >>      00192000
    TRQSTS    = 3,         << REQUEST FOR ELEMENTS COUNTER, DOUBLE >>   00194000
    TR1       = TRQSTS*2,  << MSW OF REQUEST CNTR >>                    00196000
    TR2       = TR1+1,     << LSW OF REQUEST CNTR >>                    00198000
    TSIZE     = 1,         << ELEMENT SIZE AND IMPEDED PCB >>           00200000
    TTAIL     = 3,         << INDEX OF LAST ELEMENT  >>                 00202000
    TUSE      = 4,         << MAX IN USE AND CURRENT IN USE >>          00204000
    UNDEFINED =%37,        << UNDEFINED TERMINAL TYPE >>                00206000
    WRTCHAN   =-1,         << FLAG TO INDICATE WRITE CHANNEL MPXCNTRL >>00208000
    Y'C       =%31,        << CONTROL Y >>                              00210000
  ENDEQ       = 0;                                                      00212000
                                                                        00214000
  DEFINE                                                                00216000
    ABORT     =(ABORT':1)#,<< QFLAG, REQUEST IS TO BE ABORTED >>        00218000
    ABS       = ABSOLUTE#,                                              00220000
    ASMB      = ASSEMBLE#,                                              00222000
    CC        =( 6:2)#,    << CONDITION CODE FIELD IN STATUS >>         00224000
    COMPLETED = (6:1)#,    << REQUEST COMPLETED BY DRIVER >>   <<00.TE>>00226000
    CHARMASK  =( 8:8)#,                                                 00228000
    CRSYNCS   =( 4:6)#,    << NUMBER OF SYNC'S AFTER A CR >>   <<00.02>>00230000
    CRSYNC    =( 4:4)#,    << NUMBER OF SYNC'S AFTER A CR >>   <<00.02>>00232000
    DEVTYPE   =(8:8)#,     << DEVICE TYPE OF DLT >>                     00234000
    DISABLE   = ASSEMBLE( SED 0 )#,                                     00236000
    DSTATE    =(DSTATE'  :4)#,                                          00238000
    DUPLICATE =ASSEMBLE( DUP     )#,                                    00240000
    ENABLE    = ASSEMBLE( SED 1 )#,                                     00242000
    ECHO      =( 3:1)#,    << INPUT IS TO BE ECHOED TO OUTPUT CHANNEL >>00244000
    ESIZE     =(8:8)#,     << TABLE ENTRY SIZE >>                       00246000
    HCUNIT    =(11:5)#,  << HIGHEST CONF. UNIT IN ILT FLAGS W>><<01300>>00248000
    IAK       =(IAK':1)#,                                               00250000
    INSPEED   =(12:4)#,    << INPUT SPEED AND CHARACTER SIZE >>         00252000
                           <<  0 - NOT DETERMINED  4 - 30 CPS           00254000
                               1 - 240 CPS         5 - 15 CPS           00256000
                               2 - 120 CPS         6 - 10 CPS           00258000
                               3 -  60 CPS         7 - 14 CPS  >>       00260000
    INUSE     =(8:8)#,     << NUMBER OF ELEMENTS CURRENTY IN USE >>     00262000
    IOSTAT    =( 8:8)#,    << TOTAL REQUEST STATUS RETURNED >>          00264000
    LDEVN     =( 8:8)#,    << DLDEV, LOGICAL DEVICE NUMBER >>           00266000
    LIMIT1    =(8:8)#,     << PRIMARY TABLE SIZE  >>                    00268000
    LIMIT2    =(0:8)#,     << TOTAL TABLE SIZE >>                       00270000
    MAXENTRY  =( 0:8)#,    << ENTRIES IN LPDT >>                        00272000
    MAXUSE    =( 0:8)#,    << MAXIMUM TABLE ENTRIES USED >>             00274000
    MSGREPLY  =(15:1)#,  << MESSAGE REPLY BIT OF IOQ >>                 00276000
    MTYPE     =( 1:3)#,    << MODEM TYPE                                00278000
                                0 - HARDWIRED   2 - 202C                00280000
                                1 - 103         3 - 2002   >>           00282000
    NOPTY     =(NOPTY':1)#,<<8-BIT DATA FLAG-->>               <<AMS00>>00284000
                           <<NO PARITY SET IN 8TH BIT>>        <<AMS00>>00286000
    NOSYNC    =( 7:1)#,    << NO SYNC TERMINAL, USES ENQ AND ACK >>     00288000
    OUTSPEED  =( 6:4)#,    << OUTPUT SPEED AND CHARACTER SIZE CODE      00290000
                               SEE INSPEED FOR MEANING >>               00292000
    PARITYBITS=(PARITYBITS':2)#,<<PRTY CNTRL BITS>>            <<+1.M3>>00294000
    PCBIO    =IOQP(QSTAT).PCBN<>0#,<<TRUE IF PROC. RELATED IO>><<00.TE>>00296000
    PCBN      =( 0:8)#,    << QSTAT, PCB NUMBER >>                      00298000
    PDISABLE  = ASMB(PSDB)#,                                   <<00.05>>00300000
    PENABLE   = ASMB(PSEB)#,                                   <<00.05>>00302000
    QABORTS   = (11:1)#,   << Q ABORTS RATHER THAN SET BITS >> <<00.TE>>00304000
    QLDEVN    =(8:8)#,     << LOGICAL DEVICE # FIELD OF I/O REQ >>      00306000
    RBYTE     =(8:8)#,                                                  00308000
    SCOUNT    =( 8:8)#,    << SYNC'S REMAINING TO DO AFTER THIS<<00.02>>00310000
    SPDSENSING = (4:1)#,   << DEVICE IS IN SPEED SENSING MODE    01.01>>00312000
    SPEEDF    =(10:6)#,    << SPEED INDEX FIELD IN TERM TABLE >>        00314000
    STATUS    =(13:3)#,    << QSTAT, GENERAL STATUS >>                  00316000
    TFIELD    =(11:5)#,    << TERM TYPE FIELD IN TERMTABLE >>           00318000
    TERMSPEED =(12:4)#,    << PRECONFIGURED TERMINAL SPEED >>  <<00.06>>00320000
    TERMINALTYPE=( 0:7)#,  << DEFAULT TERMINAL TYPE >>         <<00.06>>00322000
    TTYPE     =( 5:5)#,    << TERMINAL TYPE AS IN MPE ERS >>            00324000
    UNIT      =( 3:5)#,    << DLDEV, UNIT NUMBER >>                     00326000
    UP        =( 1:1)#,    <<ONLINE, SPEED SENSED, CAN DO I/O >>        00328000
    ENDDEF    = 0#;                                                     00330000
                                                                        00332000
                                                                        00334000
                                                                        00336000
                                                                        00338000
    INTEGER POINTER PS0 = S-0,  PS1 = S-1;                              00340000
    POINTER LPS0 = S-0;                                                 00342000
    INTEGER S0 = S-0, S1 = S-1, X = X;                                  00344000
                                                                        00346000
    INTEGER RSTATUS = Q -1;   << PCAL RETURN STATUS >>                  00348000
                                                                        00350000
    INTEGER ARRAY WA0(*) = DB + 0;                                      00352000
    BYTE ARRAY BA0(*) = DB + 0;  << TO BYTE ADDRESS DIT AND TBUFS >>    00354000
     INTEGER ARRAY IOQ(@) = DB + SYSIOQ;                       <<00.05>>00356000
    INTEGER ARRAY LPDT(@) = DB + SYSLPDT;                               00358000
    DOUBLE ARRAY LPDTD(@) = DB + SYSLPDT;                               00360000
    INTEGER POINTER LPDTP = 8;<<LOAD/STORE LPDT SYSTEM TABLE >><<00.TE>>00362000
    INTEGER ARRAY SBUF(@) = DB + SYSSBUF;                               00364000
                                                                        00366000
    INTEGER ARRAY DST (@) = DB + SYSDST;                                00368000
                                                                        00370000
    INTEGER DSETB = DB+%66;                                             00372000
$PAGE " EXTERNAL PROCEDURE DECLARATIONS    JUNE 28, 1974"               00374000
                                                                        00376000
DOUBLE PROCEDURE ATTACHIO(LDEV,QMISC,DSTX,ADR,FNCT,CNT,P1,P2,FLAGS);    00378000
  VALUE LDEV,QMISC,DSTX,ADR,FNCT,CNT,P1,P2,FLAGS;                       00380000
  INTEGER LDEV,QMISC,DSTX,ADR,FNCT,CNT,P1,P2,FLAGS;                     00382000
  OPTION EXTERNAL;                                                      00384000
                                                                        00386000
PROCEDURE AWAKE(PCBPT, N, WAITF);                                       00388000
  VALUE PCBPT, N, WAITF;                                                00390000
  INTEGER PCBPT, N, WAITF;                                              00392000
  OPTION EXTERNAL;                                                      00394000
                                                                        00396000
PROCEDURE AWAKEIO(DITP,IMPDFLAG);                                       00398000
  VALUE DITP, IMPDFLAG;  INTEGER IMPDFLAG;                              00400000
  INTEGER POINTER DITP;                                                 00402000
  OPTION EXTERNAL;                                                      00404000
                                                                        00406000
PROCEDURE CHECKLDEV(LDEV);                                              00408000
  VALUE LDEV;  INTEGER LDEV;                                            00410000
  OPTION EXTERNAL;                                                      00412000
  <<                                                                    00414000
     RETURN:  CCE - SIO DEVICE                                          00416000
              CCG - TERMINAL                                            00418000
              CCL - INVALID DEVICE                                      00420000
  >>                                                                    00422000
                                                                        00424000
PROCEDURE DSETCONTROL(CONTROL,DITP);                                    00426000
  VALUE CONTROL;    INTEGER CONTROL;                                    00428000
  ARRAY DITP;    OPTION EXTERNAL;                                       00430000
                                                                        00432000
INTEGER PROCEDURE EXCHANGEDB(DST);                             <<01221>>00434000
  VALUE DST;                                                   <<01221>>00436000
  INTEGER DST;                                                 <<01221>>00438000
  OPTION EXTERNAL;                                             <<01221>>00440000
                                                               <<01221>>00442000
INTEGER PROCEDURE GENMSG(A,B,C,D,E,F,G,H,I,J,K,L,M);           <<0U.EB>>00444000
   VALUE A,B,C,D,E,F,G,H,I,J,K,L,M;                            <<0U.EB>>00446000
   INTEGER A,B,C,D,E,F,G,H,I,J,K,L,M;                          <<0U.EB>>00448000
   OPTION EXTERNAL,VARIABLE;                                   <<0U.EB>>00450000
                                                               <<0U.EB>>00452000
INTEGER PROCEDURE GETDEVINFO(DEVICE,DEVINFO);                  <<00177>>00454000
   BYTE ARRAY DEVICE;                                          <<00177>>00456000
   INTEGER ARRAY DEVINFO;                                      <<00177>>00458000
   OPTION EXTERNAL;                                            <<00177>>00460000
                                                               <<00177>>00462000
PROCEDURE HELP;   OPTION EXTERNAL;                                      00464000
                                                                        00466000
PROCEDURE IOFAILURE(DRTN,DITP);                                         00468000
  VALUE DRTN;    INTEGER DRTN;                                          00470000
  ARRAY DITP;    OPTION  EXTERNAL;                                      00472000
                                                                        00474000
PROCEDURE IOIMPEDE(TBASE);                                              00476000
  VALUE TBASE;  INTEGER TBASE;                                          00478000
  OPTION EXTERNAL;                                                      00480000
                                                                        00482000
PROCEDURE LOG; OPTION EXTERNAL;                                         00484000
                                                                        00486000
PROCEDURE MPXCONTROL(FUNCTION,DITP);                                    00488000
  VALUE FUNCTION;   INTEGER FUNCTION;                                   00490000
  ARRAY DITP;    OPTION EXTERNAL;                                       00492000
                                                                        00494000
PROCEDURE MPXWRITE(DATA,DITP);                                          00496000
  VALUE DATA;   INTEGER DATA;                                           00498000
  ARRAY DITP;   OPTION EXTERNAL;                                        00500000
                                                                        00502000
PROCEDURE RESETDB(OLDDB);                                               00504000
  VALUE OLDDB;  INTEGER OLDDB;                                          00506000
  OPTION EXTERNAL;                                                      00508000
                                                                        00510000
PROCEDURE RETURNIOQ(PNTR);                                              00512000
  VALUE PNTR;   INTEGER POINTER PNTR;                                   00514000
  OPTION EXTERNAL;                                                      00516000
                                                                        00518000
PROCEDURE RETURNTBUF(BPTR);                                             00520000
  VALUE BPTR;                                                           00522000
  POINTER BPTR;                                                         00524000
  OPTION EXTERNAL;                                                      00526000
                                                                        00528000
INTEGER PROCEDURE SETSYSDB;  OPTION EXTERNAL;                           00530000
                                                                        00532000
PROCEDURE SUDDENDEATH(NUMBER);                                          00534000
  VALUE NUMBER;  INTEGER NUMBER;                                        00536000
  OPTION EXTERNAL;                                                      00538000
                                                               <<01370>>00540000
                                                                        00542000
PROCEDURE WAIT(WAITFIELD,WAITTYPE);                                     00544000
  VALUE WAITFIELD, WAITTYPE;                                            00546000
  INTEGER WAITFIELD, WAITTYPE;                                          00548000
  OPTION EXTERNAL;                                                      00550000
                                                               <<00.05>>00552000
DOUBLE PROCEDURE WAITFORIO(IOQX);                              <<00.05>>00554000
   VALUE IOQX; INTEGER IOQX;                                   <<00.05>>00556000
   OPTION EXTERNAL;                                            <<00.05>>00558000
                                                               <<00177>>00560000
procedure SENDMSG(DESTPIN,DESTPORT,MSGLEN,FLAGS);              <<02806>>00562000
value DESTPIN,DESTPORT,MSGLEN,FLAGS;                           <<02806>>00564000
integer DESTPIN,DESTPORT,MSGLEN;                               <<02806>>00566000
logical FLAGS;                                                 <<02806>>00568000
option external;                                               <<02806>>00570000
                                                               <<02806>>00572000
logical procedure PORTSTATUS(PORTNUMBER);                      <<02806>>00574000
value PORTNUMBER;                                              <<02806>>00576000
integer PORTNUMBER;                                            <<02806>>00578000
option external;                                               <<02806>>00580000
                                                               <<02806>>00582000
procedure RECEIVEMSG(PORTNUM,MSGLEN,FLAGS);                    <<02806>>00584000
value PORTNUM,MSGLEN,FLAGS;                                    <<02806>>00586000
integer PORTNUM,MSGLEN;                                        <<02806>>00588000
logical FLAGS;                                                 <<02806>>00590000
option external;                                               <<02806>>00592000
                                                               <<02806>>00594000
procedure RETURNSBUF(IX);                                      <<02806>>00596000
value IX; integer IX;                                          <<02806>>00598000
option external;                                               <<02806>>00600000
                                                               <<02806>>00602000
integer procedure GETDATASEG(SIZE,VMALLOC);                    <<02806>>00604000
value SIZE,VMALLOC;                                            <<02806>>00606000
integer SIZE,VMALLOC;                                          <<02806>>00608000
option external;                                               <<02806>>00610000
                                                               <<02806>>00612000
procedure RETURNSYSBUF(INDEX);                                 <<02806>>00614000
value INDEX;                                                   <<02806>>00616000
integer INDEX;                                                 <<02806>>00618000
option external;                                               <<02806>>00620000
                                                               <<02806>>00622000
double procedure IOSTATUS(IOQX);                               <<02806>>00624000
value IOQX;                                                    <<02806>>00626000
integer IOQX;                                                  <<02806>>00628000
option external;                                               <<02806>>00630000
                                                               <<02806>>00632000
procedure RELDATASEG(INDEX);                                   <<02806>>00634000
value INDEX;                                                   <<02806>>00636000
integer INDEX;                                                 <<02806>>00638000
option external;                                               <<02806>>00640000
                                                               <<02806>>00642000
integer procedure GETSIR(SIRNUM);                              <<02806>>00644000
value SIRNUM;  logical SIRNUM;                                 <<02806>>00646000
option external;                                               <<02806>>00648000
                                                               <<02806>>00650000
procedure RELSIR(SIRNUM,A);                                    <<02806>>00652000
value SIRNUM,A;  logical SIRNUM,A;                             <<02806>>00654000
option external;                                               <<02806>>00656000
                                                               <<02806>>00658000
procedure UNIMPEDE(PCBPT);                                     <<02806>>00660000
value PCBPT;  integer PCBPT;                                   <<02806>>00662000
option external;                                               <<02806>>00664000
                                                               <<02806>>00666000
integer procedure GETSBUF(TYPE);                               <<02806>>00668000
value TYPE;  integer TYPE;                                     <<02806>>00670000
option external;                                               <<02806>>00672000
                                                               <<02806>>00674000
double procedure TIMER;                                        <<02806>>00676000
option external;                                               <<02806>>00678000
                                                               <<02806>>00680000
procedure ABORTTIMEREQ(TRLX);                                  <<02806>>00682000
value TRLX;  integer TRLX;                                     <<02806>>00684000
option external;                                               <<02806>>00686000
                                                               <<02806>>00688000
integer procedure TIMEREQ(CODE,REQ,TIME);                      <<02806>>00690000
value CODE, REQ, TIME;                                         <<02806>>00692000
double TIME;                                                   <<02806>>00694000
integer CODE, REQ;                                             <<02806>>00696000
option external;                                               <<02806>>00698000
                                                               <<02806>>00700000
procedure MPE'TABLE'FULL(INX);                                 <<02806>>00702000
value INX;  integer INX;                                       <<02806>>00704000
option external;                                               <<02806>>00706000
                                                               <<02806>>00708000
procedure LOG15(I,J,K,L);                                      <<02806>>00710000
value I,J,K,L;                                                 <<02806>>00712000
logical I,J,K,L;                                               <<02806>>00714000
option external;                                               <<02806>>00716000
                                                               <<02806>>00718000
procedure LOG46(I,J,K,L,M,N,O,P,Q,R,S);                        <<03102>>00720000
value I,J,K,L,M,N,O,P,Q,R,S;                                   <<03102>>00722000
logical I,J,K,L,M,N,O,P,Q,R,S;                                 <<03102>>00724000
option external;                                               <<03102>>00726000
                                                               <<03102>>00728000
procedure LOG47(I,J,K,L,M,N);                                  <<03102>>00730000
value I,J,K,L,M,N;                                             <<03102>>00732000
logical I,J,K,L,M,N;                                           <<03102>>00734000
option external;                                               <<03102>>00736000
                                                               <<03102>>00738000
INTRINSIC ASCII;                                               <<00177>>00740000
                                                               <<00177>>00742000
$PAGE  "NON CORE RESIDENT I/O SERVICE ROUTINES"                         00744000
                                                               <<01221>>00746000
                                                               <<01221>>00748000
LOGICAL PROCEDURE DEVICESTATUS(LDEV);                          <<01221>>00750000
  VALUE  LDEV;   INTEGER LDEV;                                 <<01221>>00752000
  OPTION UNCALLABLE, PRIVILEGED;                               <<01221>>00754000
                                                                        00756000
<< THIS PROCEDURE RETURNS THE HARDWARE INTERRUPT STATUS                 00758000
   FOR DEVICES OTHER THAN TERMINALS. FOR SERIES 2/3 I/O                 00760000
   TYPE, STATUS IS GOTTEN FROM THE DIT TABLE, WORD 6.                   00762000
   FOR HPIB I/O TYPE, STATUS IS RETURNED BY USING AN                    00764000
   ATTACHIO CALL WITH A FUNCTION CODE OF 15.                            00766000
                                                                        00768000
     RETURNS:  CCE - DEVICE STATUS RETURNED                             00770000
               CCL - INVALID LDEV OR A TERMINAL      >>                 00772000
                                                                        00774000
  BEGIN                                                        <<01221>>00776000
    INTEGER SAVST;  << STATUS REGISTER >>                      <<01221>>00778000
    INTEGER CCODE;  << CONDITION CODE >>                       <<01221>>00780000
    INTEGER DBSAVE;  << DB SAVED >>                            <<01221>>00782000
    DOUBLE LPDTENTRY;  << LOGICAL DEV LPTD ENTRY >>            <<01221>>00784000
    INTEGER POINTER DITP = LPDTENTRY;  << DITP >>              <<01221>>00786000
    INTEGER DEVST;  << STATUS RETURN >>                        <<01221>>00788000
                                                               <<01221>>00790000
    <<  NOTE:  PROCEDURE ENTERED IN SPLIT STACK MODE >>        <<01221>>00792000
                                                               <<01221>>00794000
    SAVST := RSTATUS;  << SAVE STATUS REGISTER >>              <<01221>>00796000
    CCODE := 1;  << INIT TO CONDITION CODE CCL >>              <<01221>>00798000
    DBSAVE := SETSYSDB;  << SET DB TO SYSDB >>                 <<01221>>00800000
    CHECKLDEV(LDEV);                                           <<01221>>00802000
    IF = THEN    << VALID LDEV, NOT A TERMINAL >>              <<01221>>00804000
      BEGIN  << GET STATUS >>                                  <<01221>>00806000
      LPDTENTRY := LPDTD(LDEV);  << GET DITP >>                <<01221>>00808000
      IF DITP(DLDEV).(0:2)=0 THEN  << CHECK I/O TYPE >>        <<01370>>00810000
        BEGIN  << SERIES 2/3 SYSTEM >>                         <<01248>>00812000
        IF WA0(DITP(DDLTP)+DSIZE).DEVTYPE = 23 THEN            <<01221>>00814000
          << IF PGM CNTRLER, PUT STATUS IN DIT >>              <<01221>>00816000
          ATTACHIO(LDEV,0,0,0,28,0,1,0,1);                     <<01221>>00818000
        DEVICESTATUS := DITP(DSTAT);  << RET. STATUS >>        <<01221>>00820000
        RESETDB(DBSAVE);  << RESET TO SPLIT STACK >>           <<01221>>00822000
        END                                                    <<01221>>00824000
      ELSE                                                     <<01221>>00826000
        BEGIN  << SERIES 33/HPIB >>                            <<01221>>00828000
        RESETDB(DBSAVE);  << RESET TO SPLIT STACK >>           <<01221>>00830000
        DBSAVE := EXCHANGEDB(0);  << SET TO USER DB >>         <<01221>>00832000
        DEVST := 0;  << CLEAR STATUS >>                        <<01221>>00834000
        ATTACHIO(LDEV,0,0,@DEVST,15,1,0,0,1);                  <<01221>>00836000
        DEVICESTATUS := DEVST; << RET.SINGLE STATUS >>         <<01221>>00838000
        EXCHANGEDB(DBSAVE);  << RESET TO SPLIT STACK >>        <<01221>>00840000
        END;                                                   <<01221>>00842000
      CCODE := CCODE + 1;  << SET CCE >>                       <<01221>>00844000
      END ELSE                                                 <<01248>>00846000
      RESETDB(DBSAVE);  << RESET TO SPLIT STACK >>             <<01248>>00848000
    RSTATUS := SAVST;  << RESTORE STATUS >>                    <<01221>>00850000
    RSTATUS.CC := CCODE;  << SET CC IN STAT REG FOR RET >>     <<01221>>00852000
    END;                                                       <<01221>>00854000
                                                               <<01221>>00856000
$PAGE                                                                   00858000
                                                                        00860000
LOGICAL PROCEDURE IOCONTROL(LDEV,FUNCTION);                             00862000
  VALUE   LDEV, FUNCTION;                                               00864000
  INTEGER LDEV, FUNCTION;                                               00866000
  OPTION PRIVILEGED, UNCALLABLE;                                        00868000
                                                                        00870000
  << THIS PROCEDURE GENERATES A BLOCKED CONTROL REQUEST.                00872000
                                                                        00874000
     RETURN: TRUE  - SUCCESSFULLY COMPLETED                             00876000
             FALSE - ERROR OCCURED IN PERFORMING REQUEST                00878000
  >>                                                                    00880000
  BEGIN                                                                 00882000
    TOS := ATTACHIO(LDEV, 0, 0, 0, FUNCTION, 0, 0, 0, 1 );              00884000
    DEL;     << DELETE TRANSFER COUNT >>                                00886000
    IF TOS.STATUS = GOODIO THEN                                         00888000
      IOCONTROL := 1;     << SET TRUE RETURN >>                         00890000
  END;                                                                  00892000
$PAGE   "NON RESIDENT TERMINAL SERVICE ROUTINES"                        00894000
                                                                        00896000
LOGICAL PROCEDURE RESETBREAKBITS(LDEV,BFLAG);                           00898000
  VALUE  LDEV, BFLAG;                                                   00900000
  INTEGER LDEV;  LOGICAL BFLAG;                                         00902000
  OPTION UNCALLABLE, PRIVILEGED;                                        00904000
                                                                        00906000
  <<                                                                    00908000
    THIS PROCEDURE RESETS THE BREAK OR CONTROL Y OCCURED BITS IN        00910000
    THE LPDT AND RETURNS THE PREVIOUS SETTING.                          00912000
                                                                        00914000
    BFLAG:  TRUE  - RESET BREAK BIT                                     00916000
            FALSE - RESET CONTROL Y BIT                                 00918000
                                                                        00920000
    RETURN: TRUE  - BIT WAS SET BEFORE BEING CLEARED                    00922000
            FALSE - BIT WAS CLEAR                                       00924000
  >>                                                                    00926000
  BEGIN                                                                 00928000
    TOS := SETSYSDB;                                                    00930000
                                                                        00932000
    CHECKLDEV(LDEV);                                                    00934000
    IF > THEN    << A TERMINAL >>                                       00936000
      BEGIN                                                             00938000
        DISABLE;                                                        00940000
        TOS := LPDTD(LDEV);                                             00942000
        IF BFLAG THEN TOS.(BREAK':1) := 0                               00944000
          ELSE TOS.(SSBREAK':1) := 0;                                   00946000
        IF <> THEN RESETBREAKBITS := 1;                                 00948000
        LPDTD(X) := TOS;                                                00950000
      END;                                                              00952000
                                                                        00954000
    RESETDB( * );                                                       00956000
  END;   <<  RESET BREAK BITS >>                                        00958000
$PAGE                                                                   00960000
                                                                        00962000
                                                                        00964000
PROCEDURE SETTERMTYPE(TYPE,INSPD,OUTSPD,DITP);                          00966000
  VALUE TYPE, INSPD, OUTSPD;                                            00968000
  INTEGER TYPE, INSPD, OUTSPD;                                          00970000
  INTEGER ARRAY DITP;                                                   00972000
  option privileged,uncallable;                                <<02638>>00974000
  <<                                                                    00976000
    THIS PROCEDURE CHECKS FOR VALID TYPE SPECIFICATION AND CHECKS       00978000
    THAT THE SPEEDS ARE ALLOWED FOR THE TYPE SPECIFIED                  00980000
                                                                        00982000
    TYPE   - TERMINAL TYPE AS SPECIFIED IN THE MPE ERS                  00984000
    INSPD  - INPUT SPEED NUMBER                                         00986000
              0 - 240                   4 - 30 CPS                      00988000
              1 - 240 CPS               5 - 15 CPS                      00990000
              2 - 120 CPS               6 - 10 CPS                      00992000
              3 -  60 CPS               7 - 14 CPS                      00994000
    OUTSPD - OUTPUT SPEED NUMBER                                        00996000
                                                                        00998000
    RETURN - CCL:  IF SPEED OR TYPE INCORRECT                           01000000
             CCE:  NEW TYPE AND/OR SPEEDS SET                           01002000
  >>                                                                    01004000
  BEGIN                                                                 01006000
    INTEGER  TTBASE,  << INDEX IN TERMTABLE TO BASE OF TYPE ENTRY >>    01008000
             NSPEEDS, << NUMBER OF SPEEDS ALLOWED FOR TYPE >>           01010000
             I;                                                         01012000
                                                                        01014000
  <<------- TERMINAL SPEED & CAPABILITY DATA ---------->>               01016000
                                                                        01018000
  <<                                                                    01020000
    EACH ENTRY IN THE TERM TYPE TABLE BELOW CONSISTS OF A ONE WORD      01022000
    HEADER FOLLOWED BY ONE TO SIX WORDS, ONE FOR EACH SPEED THAT THE    01024000
    TERMINAL IS CAPABILE OF OPERATING AT.                               01026000
                                                                        01028000
    HEADER.( 0:4) = NUMBER OF DIFFERENT SPEEDS                          01030000
           .(4:2)  = NOT USED                                  <<AMS00  01032000
           .(6:1)  = 8-BIT DATA FLAG SET 2635/45K              <<AMS00  01034000
           .(7:1)  = NO  SYNC FLAG,SET FOR 2635/40/44/45K      <<AMS00  01036000
          .( 8:2) = DELETE RESPONSE CODE                                01038000
                     0 - NULL, 1 - \, 2 - LF, 3 - CNTRL Y               01040000
          .(10:1) = SET IF RESPONDS TO A FORM FEED                      01042000
          .(11:5) = TERM TYPE NUMBER                                    01044000
                                                                        01046000
    SPEEDS.( 0:4) = NUMBER OF LINE FEED SYNCS REQUIRED                  01048000
          .( 4:6) = NUMBER OF CARRIAGE RETURN SYNCS REQUIRED            01050000
          .(10:6) = SPEED NUMBER                                        01052000
                                                                        01054000
    NUMBER OF SYNCS = IF GREATER THAN 7 THEN (N-6)*5           <<00.02  01056000
  >>                                                                    01058000
                                                                        01060000
                                                                        01062000
    INTEGER ARRAY TERMTABLE(0: 6) = PB := <<ASR 33>>           <<04246>>01064000
      %060100,%000106,%000205,%000304,%000603,                 <<04246>>01066000
      %001402,%003001;                                         <<04246>>01068000
                                                                        01070000
    ARRAY TT1(0: 6) = PB :=    <<ASR 37>>                      <<04246>>01072000
      %060241,%000106,%000205,%000304,%000603,                 <<04246>>01074000
      %001402,%003001;                                         <<04246>>01076000
                                                                        01078000
    INTEGER ARRAY TT2(0: 6) = PB :=  <<ASR 35>>                <<04246>>01080000
      %060142,%000106,%000205,%000304,%000603,                 <<04246>>01082000
      %001402,%003001;                                         <<04246>>01084000
                                                                        01086000
    ARRAY TT3(0: 6) = PB :=   <<EXECUPORT>>                    <<04246>>01088000
      %060243,%000106,%000305,%000504,%000703,                 <<04246>>01090000
      %001102,%001301;                                         <<04246>>01092000
                                                                        01094000
    ARRAY TT4(0: 6) = PB :=   << DATAPOINT >>                           01096000
      %060304,%000006,%040005,%040004,%040003,%040002,%040001;          01098000
                                                                        01100000
    ARRAY TT5(0: 6) = PB :=  <<MEMOREX 1240>>                  <<04246>>01102000
      %060245,%011006,%011005,%011304,%031703,                 <<04246>>01104000
      %072502,%173701;                                         <<04246>>01106000
                                                                        01108000
    ARRAY TT6(0: 6) = PB :=    << TERMINET >>                  <<01233>>01110000
      %060246,%030006,%050005,%100004,%120003,%150002,%170001; <<01233>>01112000
                                                                        01114000
    ARRAY TT9(0: 6) = PB :=   << MINI BEE >>                            01116000
      %060051,%000006,%040005,%040004,%040003,%040002,%040001;          01118000
                                                                        01120000
    ARRAY TT10(0: 6) = PB :=   << HP2640/44 >>                          01122000
      %060452,%000006,%000005,%000004,%000003,%000002,%000001;          01124000
                                                                        01126000
    ARRAY TT11(0: 6) = PB :=   << HP2640/44 WITH FULL "ENTER" SERVICE >>01128000
      %060453,%000006,%000005,%000004,%000003,%000002,%000001;          01130000
                                                                        01132000
    ARRAY TT12(0:6)= PB :=   <<HP2645K>>                       <<+1.M3>>01134000
       %061454,%000006,%000005,%000004,%000003,%000002,%000001;<<AMS00>>01136000
                                                               <<00.TE>>01138000
    ARRAY TT13(0: 6) = PB :=   << TELENET PSEUDO TERMINAL >>   <<00.06>>01140000
      %060055,%000006,%000005,%000004,%000003,%000002,%000001; <<00.06>>01142000
                                                               <<00.06>>01144000
     ARRAY TT15(0:6) = PB :=   <<HP2635(8-BIT TERM)>>          <<AMS00>>01146000
       %061657,%000006,%000005,%000004,%000003,%000002,%000001;<<AMS00>>01148000
     ARRAY TT16(0:6) = PB :=   <<HP2635(7-BIT TERM)>>          <<AMS00>>01150000
       %060660,%000006,%000005,%000004,%000003,%000002,%000001;<<AMS00>>01152000
     ARRAY TT18(0:6) = PB := << NO PROTOCOL AND NO DC1'S  >>   <<01234>>01154000
       %060062,%000006,%000005,%000004,%000003,%000002,%000001;<<01620>>01156000
                                                               <<01234>>01158000
     ARRAY TT19(0:6) = PB :=   <<HP2631(7-BIT TERM)>>          <<01466>>01160000
       %060263,  6,  5,  4,  3,  2,  1;                        <<01466>>01162000
                                                               <<01466>>01164000
    ARRAY TTUNDEFINED(0: 6) = PB :=  << UNDEFINED TERM TYPE >>          01166000
      %060177,%000106,%040005,%040004,%040003,%040002,%040001;          01168000
                                                                        01170000
   ARRAY TTEND(0: 0) = PB := 0;  << END OF TERM TYPE TABLE >>           01172000
                                                                        01174000
                                                                        01176000
INTEGER SUBROUTINE CHECKSPEED(SPEEDN);                                  01178000
  VALUE SPEEDN;   INTEGER SPEEDN;                                       01180000
  <<                                                                    01182000
    THIS SUBROUTINE CHECKS THAT THE SPEED IS ALLOWED FOR THE TYPE       01184000
    WHOSE BASE IS INDICATED BY TTBASE. IF NOT IT EXITS THE PROCEDURE    01186000
    OTHERWISE THE SPEED AND SYNC WORD IS RETURNED FROM TERMTABLE        01188000
  >>                                                                    01190000
  BEGIN                                                                 01192000
    I := NSPEEDS;                                                       01194000
    IF SPEEDN<>0 THEN  << SEARCH TERMTABLE FOR SPEED >>                 01196000
      BEGIN                                                             01198000
        X := TTBASE; << SET X TO BASE OF THIS TERM TYPES TABLE >>       01200000
        WHILE TERMTABLE(X:=X+1).SPEEDF<>SPEEDN DO                       01202000
          BEGIN   << STEP TO NEXT SPEED >>                              01204000
            I := I - 1;  << DECREMENT NUMBER OF SPEEDS COUNTER >>       01206000
            IF < THEN ASMB( EXIT 4 );   << END OF SPEEDS, BAD SPEED >>  01208000
          END;                                                          01210000
        CHECKSPEED := TERMTABLE(X);                                     01212000
      END;                                                              01214000
  END;  << CHECK SPEED >>                                               01216000
                                                                        01218000
                                                                        01220000
    X := 0;                                                             01222000
    WHILE TERMTABLE(X).TFIELD<>TYPE DO << FIND TERMINAL TYPE >>         01224000
      BEGIN  << STEP TO NEXT AND CHECK FOR END >>                       01226000
        TOS := TERMTABLE(X)&LSR(12);  << GET ENTRY SIZE -1 >>           01228000
        ASMB(ADAX,INCX);   << STEP TO NEXT >>                           01230000
        IF TERMTABLE(X)=0 THEN RETURN;  << TYPE NOT FOUND, BAD >>       01232000
      END;                                                              01234000
                                                                        01236000
    NSPEEDS := TERMTABLE(X)&LSR(12);  << # OF SPEEDS >>                 01238000
    TTBASE  := X;  << SAVE BASE OF ENTRY FOR TYPE >>                    01240000
                                                                        01242000
    TOS := CHECKSPEED(INSPD);  << GET AND CHECK INPUT SPEED >>          01244000
    TOS := CHECKSPEED(OUTSPD);                                          01246000
                                                                        01248000
    DISABLE;                                                            01250000
    DITP(DSPEED).OUTSPEED := S0;                                        01252000
    TOS.CRSYNC := S0.CRSYNCS;  << MOVE CR SYNC COUNT >>        <<00.02>>01254000
    TOS.SCOUNT := 0;                                           <<00.02>>01256000
    DITP(DSYNC) := TOS;   << SET SYNC COUNTS >>                         01258000
    DITP(DSPEED).INSPEED  := TOS;                                       01260000
    IF TYPE=TELENET THEN DITP(DSPEED).ECHO := 0;               <<00.06>>01262000
    DITP( 7 ).(DELECHO':8) := TERMTABLE(TTBASE);                        01264000
       << SET TERMTYPE, DELECHO AND FORMFEED FIELDS IN DTYPE WORD >>    01266000
     DITP(DLDEV).NOPTY := TERMTABLE(TTBASE).(6:1);             <<AMS00>>01268000
             <<SETS 8-BIT DATA FLAG--NO PARITY SET 8TH BIT>>   <<AMS00>>01270000
    DITP(DMODEM).NOSYNC := TERMTABLE(TTBASE).( 7:1);                    01272000
  IF DITP(DLDEV).NOPTY <> 0 THEN  <<CHECK 8-BIT TTYPE>>        <<AMS00>>01274000
     BEGIN                                                     <<AMS00>>01276000
     DITP(DCNTRL).PARITYBITS :=0; <<NO GEN>>                   <<AMS00>>01278000
     DITP.(9:1) := 1; <<SETS PTYCHK IN DFLAG TO CHECK FOR...>> <<AMS00>>01280000
   <<8-BIT DATA>>                                              <<AMS00>>01282000
     END                                                       <<AMS00>>01284000
   ELSE                                                        <<AMS00>>01286000
     BEGIN   <<SETS UP CONDITIONS TO GEN. PARITY >>            <<AMS00>>01288000
     DITP.(9:1) :=0; <<CLEARS 8-BIT PTYCHK FLAG IN DFLAG>>     <<AMS00>>01290000
     DITP(DCNTRL).(7:1):=1;       <<GEN. PARITY>>              <<AMS00>>01292000
     END;                                                      <<AMS00>>01294000
    RSTATUS.CC := CCE;   << SUCCESSFUL COMPLETION >>                    01296000
  END;   << SET TERM TYPE >>                                            01298000
$PAGE                                                                   01300000
                                                                        01302000
  <<------ CHANNEL INITIALIZATION PROCEDURE ------------>>              01304000
                                                                        01306000
                                                                        01308000
PROCEDURE INITCHANNEL(DITP);                                            01310000
  INTEGER ARRAY DITP;                                                   01312000
  OPTION PRIVILEGED, UNCALLABLE;                                        01314000
  BEGIN                                                                 01316000
    DSETCONTROL(INITDSET,DITP);   << SET CD & SA; MONITOR CC = 1 >>     01318000
                                                                        01320000
    MPXCONTROL(ECHOOFF,DITP);    << INITIALIZE RECEIVE CHANNEL >>       01322000
    MPXCONTROL(WRTCHAN,DITP)       << INITIALIZE SEND CHANNEL >>        01324000
  END;  << INIT CHANNEL >>                                              01326000
                                                                        01328000
                                                                        01330000
                                                                        01332000
<<------------- TERMINAL INITIALIZATION PROCEDURE ------------------->> 01334000
                                                                        01336000
                                                                        01338000
PROCEDURE TERMINIT(DITP);                                               01340000
  INTEGER ARRAY DITP;                                                   01342000
  OPTION PRIVILEGED, UNCALLABLE;                                        01344000
  BEGIN                                                                 01346000
    INTEGER POINTER ILTP = Q+1;                                         01348000
                                                                        01350000
    ARRAY CNTRLWORDS(0: 4) = PB :=                                      01352000
      %120413,   << 1200 BAUD >>                                        01354000
      %120427,   <<  600 BAUD >>                                        01356000
      %120457,   <<  300 BAUD >>                                        01358000
      %120537,   <<  150 BAUD >>                                        01360000
      %121202;   <<  110 BAUD >>                                        01362000
                                                                        01364000
    TOS := DITP(DILTP);  << SET ILTP >>                                 01366000
                                                                        01368000
    IF LOGICAL(DITP.UP) THEN   << POWERFAIL RESTART >>                  01370000
      BEGIN                                                             01372000
        INITCHANNEL(DITP);                                              01374000
        IF DITP.DSTATE<>NULL THEN  << RESTART OPERATION >>              01376000
          MPXWRITE(SYNCCHAR,DITP);                                      01378000
        DSETCONTROL(READING,DITP);  << LOOK FOR LINE DROP >>   <<00.03>>01380000
      END                                                               01382000
    ELSE                                                                01384000
      BEGIN  << INITIALIZE DCNTRL AND SET MODEM TYPE IN DIT >>          01386000
        DITP(DSPEED).OUTSPEED := DITP(DLAST).TERMSPEED;        <<00.06>>01388000
        DITP(DTYPE).TTYPE := DITP(DLAST).TERMINALTYPE;         <<00.06>>01390000
        TOS := DITP(DLDEV).UNIT;                                        01392000
           IF DITP(DLDEV).NOPTY <> 0 THEN                      <<AMS00>>01394000
                      <<TTYPE IS 8-BIT TTYPE >>                <<AMS00>>01396000
              DITP(DCNTRL) :=TOS&LSL(9) +2  <<SET NO PRTY,UNIT <<AMS00>>01398000
            ELSE                                               <<AMS00>>01400000
        DITP(DCNTRL) := TOS&LSL(9)+%602;<< CNTRL WORD, GEN ODD <<01.01>>01402000
                                                                        01404000
        TOS := LPDTD(DITP(DLDEV).LDEVN);                                01406000
  << SUBTYPES 14 & 15 ARE USED FOR S.T. 0 & 1 IF TYPE = 32 >>  <<01466>>01408000
  IF S0.(12:4) > 13 THEN TOS := TOS-14;                        <<01466>>01410000
        DITP(DMODEM).MTYPE := TOS;   << SET MODEM TYPE IN DIT >>        01412000
        IF DITP(DMODEM).MTYPE>3 THEN  << NO SPEED SENSING >>   <<01.01>>01414000
          BEGIN                                                <<01.01>>01416000
            DITP(DSPEED).SPDSENSING := 0;                      <<01.01>>01418000
            DITP(DSPEED).INSPEED := DITP(DSPEED).OUTSPEED;     <<01.01>>01420000
          END;                                                 <<01.01>>01422000
        INITCHANNEL(DITP);  << INITIALIZE CHANNEL >>                    01424000
      END;                                                              01426000
                                                                        01428000
    TOS := ILTP(ICNTRL).(8:8);   << GET DRT NUMBER >>          <<01300>>01430000
                                                                        01432000
    X := 0;                                                             01434000
    DO BEGIN  << INITIALIZE DIAGNOSTIC CHANNELS >>                      01436000
      TOS := CNTRLWORDS(X);                                             01438000
      ASMB( WIO 1 );                                                    01440000
      IF = THEN  << OK ,SEND TO CHANNEL AND STEP TO NEXT >>             01442000
        BEGIN                                                           01444000
          TOS := (X+16)&LSL(9)+2;  << CONTROL WORD AND UNIT # >>        01446000
          ASMB( CIO 1 );  << SEND INFO TO CHANNEL >>                    01448000
          IF < THEN IOFAILURE(S1, DITP);                                01450000
                                                                        01452000
          X := X+1;  << STEP TO NEXT CHANNEL >>                         01454000
        END                                                             01456000
      ELSE IF < THEN IOFAILURE(S1, DITP)        << NON RESPONDING >>    01458000
        ELSE DDEL;  << TRY AGAIN >>                                     01460000
    END UNTIL X=5;                                                      01462000
                                                                        01464000
    END;  << TERM INIT >>                                               01466000
$PAGE "SYSTEM BUFFER ROUTINES"                                          01468000
                                                                        01470000
INTEGER PROCEDURE GETSYSBUF(NUM,IMPF);                                  01472000
VALUE NUM,IMPF;                                                         01474000
INTEGER NUM;                                                            01476000
LOGICAL IMPF;                                                           01478000
OPTION PRIVILEGED,UNCALLABLE;                                           01480000
BEGIN                                                                   01482000
                                                                        01484000
ENTRY FGETSYSBUF;                                                       01486000
INTEGER                                                                 01488000
   CSTAT       = Q-1, << CALLER STATUS >>                               01490000
   TYPE        = Q+1, << BUFFER FENCE >>                                01492000
   SIZE        = Q+2; << BUFFER SIZE >>                                 01494000
INTEGER POINTER                                                         01496000
   SYSBUF      = SYSSBUF;                                               01498000
                                                                        01500000
   TOS := 0; << NO BUFFER FENCE >>                                      01502000
   GO AROUND;                                                           01504000
   HELP;  <<FOR HELP PLABEL *************>>                    <<00.05>>01506000
FGETSYSBUF:                                                             01508000
   TOS := 8; << BUFFER FENCE FOR FILESYSTEM TO PREVENT HOGGING >>       01510000
AROUND:                                                                 01512000
   TOS := SYSBUF(TSIZE).ESIZE; << BUFFER SIZE >>                        01514000
   SYSBUF(X) := SYSBUF(TR2) + 1; << INC. REQ. CNTR >>                   01516000
   IF CARRY THEN SYSBUF(X) := SYSBUF(TR1) + 1;                          01518000
   IF NOT(1 <= NUM <= SYSBUF(LIM).LIMIT1) THEN                          01520000
   BEGIN                                                                01522000
      TOS := CCL;                                                       01524000
      GO TO SETCC;                                                      01526000
   END;                                                                 01528000
   DISABLE;                                                             01530000
TRYAGAIN:                                                               01532000
   TOS := NUM + SYSBUF(TUSE).INUSE;                                     01534000
   ASMB(DUP,DDUP);                                                      01536000
   TOS := TOS + TYPE;                                                   01538000
   IF TOS > SYSBUF(LIM).LIMIT1 THEN                                     01540000
   BEGIN << CAN'T SUPPLY ENOUGH BUFFERS >>                              01542000
      << If first overflow, report table full to console >>    <<02806>>01544000
      tos := SYSBUF(TOVRFL);                                   <<02806>>01546000
      if = then                                                <<02806>>01548000
        MPE'TABLE'FULL(1);  << table 1 is SBUF >>              <<02806>>01550000
      SYSBUF(TOVRFL) := tos + 1;                               <<02806>>01552000
      IF IMPF THEN                                                      01554000
      BEGIN << IMPEDE THIS PROCESS >>                                   01556000
         IOIMPEDE(ABS(SYSDB+SYSSBUF));                                  01558000
         ASSEMBLE (DDEL, DEL);                                 <<01596>>01560000
         GO TO TRYAGAIN;                                                01562000
      END;                                                              01564000
      TOS := CCG; << IMFORM CALLER OF BUFFER SHORTAGE >>                01566000
      GO TO SETCC;                                                      01568000
   END;                                                                 01570000
   IF TOS > SYSBUF(TUSE).MAXUSE THEN                                    01572000
   SYSBUF(X).MAXUSE := TOS; <<ENTER NEW MAXUSE IF THIS CNT BIGGER >>    01574000
   SYSBUF(X).INUSE := TOS; << UPDATE USE CNTR >>                        01576000
   TOS := FIRSTINDEX;                                                   01578000
   TOS := (SYSBUF(LIM).LIMIT2 - 1) * SIZE + FIRSTINDEX;                 01580000
   TOS := SYSBUF(THEAD);                                                01582000
   DUPLICATE; << SET START OF BUFFER SCAN >>                            01584000
   GETSYSBUF := TOS; << RETURN INDEX TO CALLER >>                       01586000
   DO                                                                   01588000
   BEGIN                                                                01590000
      X := TOS; << SET SYSBUF POINTER >>                                01592000
      ASMB(DDUP,DECX);                                                  01594000
      IF NOT(TOS <= X <= TOS) THEN SUDDENDEATH(250);                    01596000
      TOS := X - FIRSTINDEX; << CHECK THAT INDEX IS MODULO >>           01598000
      TOS := SIZE;                                                      01600000
      ASMB(DIV,TEST; DDEL);                                             01602000
      IF <> THEN SUDDENDEATH(250);                                      01604000
      TOS := SYSBUF(X);                                                 01606000
      NUM := NUM - 1;                                                   01608000
   END UNTIL =;                                                         01610000
    SYSBUF(X) := 0; << ZERO LAST LINK >>                                01612000
    ASMB(TEST); << CHECK FOR END-OF-LIST CONDITION >>                   01614000
   IF = THEN SYSBUF(TTAIL) := THEAD + 1; << LIST IS NULL >>             01616000
   SYSBUF(THEAD) := TOS; << MAKE HEAD POINT AT NAXT AVAIL. BUF. >>      01618000
   TOS := CCE;                                                          01620000
SETCC:                                                                  01622000
   CSTAT.CC := TOS;                                                     01624000
END;                                                                    01626000
$PAGE "ABORT I/O ROUTINES"                                              01628000
PROCEDURE ABORTPROCIO(PCBNUMB);                                         01630000
VALUE PCBNUMB;  INTEGER PCBNUMB;                                        01632000
OPTION PRIVILEGED, UNCALLABLE;                                          01634000
BEGIN                                                                   01636000
INTEGER POINTER                                                         01638000
   DITP,                                                                01640000
   IOQP,                                                       <<00.TE>>01642000
   DLTP;                                                       <<00.TE>>01644000
LOGICAL POINTER                                                <<00.TE>>01646000
   DLTPL,                                                      <<00.TE>>01648000
   IOQPL     = IOQP,                                           <<00.TE>>01650000
   DITPL     = DITP;                                           <<00.TE>>01652000
LOGICAL                                                        <<00.TE>>01654000
   FOUNDONE;                                                   <<00.TE>>01656000
INTEGER                                                        <<00.TE>>01658000
   DBSAVE,                                                     <<00.TE>>01660000
   PIN,                                                        <<00.TE>>01662000
   I := 0;                                                     <<00.TE>>01664000
                                                               <<00.TE>>01666000
  DBSAVE := SETSYSDB;                                          <<00.TE>>01668000
  PIN := PCBNUMB;                                              <<00.TE>>01670000
  IF = THEN PIN := (ABS(CPCB) - ABS(PCBB))/PCBSIZE;            <<00.TE>>01672000
                                                               <<00.TE>>01674000
  WHILE (I:=I+1)<=LPDT.MAXENTRY DO                             <<00.TE>>01676000
    BEGIN   << SEARCH LPDT FOR PROCCESS I/O TO ABORT >>        <<00.TE>>01678000
    @DITP := LPDTP(I*2);                                       <<00.TE>>01680000
    IF > AND DITP.(TERMINAL':2)<>DISC' THEN                    <<00.TE>>01682000
      BEGIN   << VALID DEVICE FOR ABORTING I/O >>              <<00.TE>>01684000
      FOUNDONE := FALSE;                                       <<00.TE>>01686000
      @DLTPL := DITP(DDLTP);                                   <<00.TE>>01688000
      IF DLTPL.QABORTS THEN  << SEND REQUEST TO ABORT >>       <<00.TE>>01690000
                                                               <<03646>>01692000
        << PCBNUM is passed to datacom driver via the QMISC >> <<03646>>01694000
        << parameter in the call to ATTACHIO.  The datacom  >> <<03646>>01696000
        << driver compares this PIN to all its outstanding  >> <<03646>>01698000
        << IOQ's and aborts only those with the same PIN.   >> <<03646>>01700000
        << This information is per Cathy Smith (DCO lab) on >> <<03646>>01702000
        << 12/28/81.  (AJK - MPE I/O)                       >> <<03646>>01704000
                                                               <<03646>>01706000
        ATTACHIO(I, PIN, 0, 0, ABORT'IO, 0, 0, 0, NOPCB)       <<00.TE>>01708000
      ELSE                                                     <<00.TE>>01710000
        BEGIN    << SET BITS TO CAUSE ABORT >>                 <<00.TE>>01712000
        PDISABLE;                                              <<00.TE>>01714000
        @IOQP := DITP(DIOQP);                                  <<00.TE>>01716000
        WHILE <> DO  << SEARCH DEVICE IOQ LIST >>              <<00.TE>>01718000
          BEGIN                                                <<00.TE>>01720000
          IF NOT IOQPL.COMPLETED AND IOQP(QSTAT).PCBN=PIN THEN <<00.TE>>01722000
            BEGIN    << ABORT REQUEST >>                       <<00.TE>>01724000
            DISABLE;                                           <<00.TE>>01726000
            IOQP.ABORT := 1;                                   <<00.TE>>01728000
            IF DITP>=0 THEN DITP.IAK := 1;<<NOT A TERMINAL >>  <<00.TE>>01730000
            ENABLE;                                            <<00.TE>>01732000
            FOUNDONE := TRUE;                                  <<00.TE>>01734000
            END;                                               <<00.TE>>01736000
          @IOQP := IOQP(QLINK);  << STEP TO NEXT IOQ >>        <<00.TE>>01738000
          END;                                                 <<00.TE>>01740000
        PENABLE;                                               <<00.TE>>01742000
        IF FOUNDONE THEN AWAKEIO(DITP,IMPEDABLE);              <<00.TE>>01744000
        END;                                                   <<00.TE>>01746000
      END;                                                     <<00.TE>>01748000
    END;                                                       <<00.TE>>01750000
                                                               <<00.TE>>01752000
  RESETDB(DBSAVE);                                             <<00.TE>>01754000
END;   <<  ABORT PROC IO  >>                                            01756000
                                                                        01758000
PROCEDURE ABORTIO(LDEVICE);                                             01760000
VALUE LDEVICE;   INTEGER LDEVICE;                                       01762000
OPTION PRIVILEGED, UNCALLABLE;                                          01764000
BEGIN                                                                   01766000
<< This procedure will mark all IOQ's for a LDEV >>            <<02643>>01768000
<< as ABORTED and AWAKEN the monitor to process  >>            <<02643>>01770000
<< the abortion requests.  If a negative LDEV is >>            <<02643>>01772000
<< passed to this routine, only PCB related IOQ's>>            <<02659>>01774000
<< will be marked as aborted.  If the LDEV is    >>            <<02659>>01776000
<< positive, all IOQ's for this device are marked>>            <<02659>>01778000
<< as aborted.  The return status are as follows:>>            <<02643>>01780000
<<            CCE - IOQ's existed & were aborted >>            <<02643>>01782000
<<            CCG - no IOQ's were found          >>            <<02643>>01784000
<<            CCL - invalid LDEV to do ABORTIO   >>            <<02643>>01786000
INTEGER POINTER                                                <<00.TE>>01788000
  DITP,                                                        <<00.TE>>01790000
  DLTP,                                                        <<00.TE>>01792000
  IOQP;                                                        <<00.TE>>01794000
LOGICAL POINTER                                                <<00.TE>>01796000
  IOQPL  =  IOQP;                                              <<00.TE>>01798000
INTEGER                                                        <<00.TE>>01800000
  DBSAVE;                                                      <<00.TE>>01802000
LOGICAL                                                        <<00.TE>>01804000
  FIRST'IOQ'ABORTED := false,<<first IOQ in chain was aborted>><<02659>>01806000
  ABORTALL := true;  <<abort all IOQs for a device>>           <<02643>>01808000
                                                               <<00.TE>>01810000
  DBSAVE := SETSYSDB;                                          <<00.TE>>01812000
  X := LDEVICE;                                                <<00.TE>>01814000
  IF < THEN    << ABORT ONLY PCB RELATED I/O >>                <<00.TE>>01816000
    BEGIN  LDEVICE := -X;   ABORTALL := FALSE;   END;          <<00.TE>>01818000
                                                               <<00.TE>>01820000
  @DITP := LPDTP(LDEVICE*2);                                   <<00.TE>>01822000
  @DLTP := DITP(DDLTP);                                        <<00.TE>>01824000
                                                               <<00.TE>>01826000
  TOS := CCL;  << INVALID DEVICE RETURN >>                     <<00.TE>>01828000
                                                               <<02643>>01830000
<<Check if LDEV is valid, not virtual, and not DISC>>          <<02643>>01832000
  CHECKLDEV(LDEVICE);                                          <<03646>>01834000
  if >= and      << Is valid LDEV >>                           <<03646>>01836000
     nocarry then  << is not a DISC >>                         <<03646>>01838000
    BEGIN   << VALID DEVICE AND TYPE, SO DO ABORT >>           <<00.TE>>01840000
    TOS := CCG;   << ASSUME EMPTY QUEUE >>                     <<00.TE>>01842000
                                                               <<02643>>01844000
<<if device is datacomm, must do ATTACHIO to driver>>          <<02643>>01846000
    IF NOT LOGICAL(DLTP).QABORTS THEN                          <<00.TE>>01848000
      BEGIN   << CHECK QUEUE >>                                <<00.TE>>01850000
      DISABLE; <<protect IOQ chain integrity>>                 <<02643>>01852000
      @IOQP := DITP(DIOQP);                                    <<00.TE>>01854000
      IF <> THEN  << SOMETHING ON QUEUE >>                     <<00.TE>>01856000
        BEGIN                                                  <<00.TE>>01858000
        @IOQP := DITP(DIOQP);                                  <<00.TE>>01862000
        WHILE <> DO  << ABORT REQUEST >>                       <<00.TE>>01864000
          BEGIN                                                <<00.TE>>01866000
          IF NOT IOQPL.COMPLETED AND (ABORTALL OR PCBIO) THEN  <<00.TE>>01868000
            begin                                              <<02659>>01872000
            IOQP.ABORT := 1;   <<mark IOQ aborted>>            <<02659>>01874000
            if @IOQP = DITP(DIOQP) then                        <<02659>>01876000
              FIRST'IOQ'ABORTED := true; <<must awake monitor>><<02659>>01878000
            end;                                               <<02659>>01880000
          @IOQP := IOQP(QLINK);  << STEP TO NEXT IOQ >>        <<00.TE>>01884000
          END;                                                 <<00.TE>>01886000
        <<if first IOQ aborted, waken monitor>>                <<02659>>01890000
        if FIRST'IOQ'ABORTED then                              <<02659>>01892000
          begin                                                <<02659>>01894000
          if DITP>=0 then DITP.IAK := 1; <<NOT a terminal>>    <<02659>>01896000
          ENABLE;                                              <<02659>>01898000
          AWAKEIO(DITP, IMPEDABLE);                            <<02659>>01900000
          end                                                  <<02659>>01902000
        else                                                   <<02659>>01904000
          ENABLE;                                              <<02659>>01906000
        <<now, report a good completion code>>                 <<02659>>01908000
                                                               <<02659>>01910000
        TOS := CCE;  << REPORT I/O ABORTED >>                  <<00.TE>>01914000
        end                                                    <<02643>>01916000
      else                                                     <<02643>>01918000
        ENABLE;  <<enable interrupts>>                         <<02643>>01920000
      END                                                      <<00.TE>>01922000
<<For datacomm, we must issue a request of the driver to>>     <<02643>>01924000
<<abort the current I/O.                                >>     <<02643>>01926000
    ELSE IF IOCONTROL(LDEVICE,ABORT'IO) THEN TOS := CCE;       <<00.TE>>01928000
    END;                                                       <<00.TE>>01930000
                                                               <<00.TE>>01932000
  RSTATUS.CC := TOS;                                           <<00.TE>>01934000
  RESETDB(DBSAVE);                                             <<00.TE>>01936000
END; << ABORT IO >>                                                     01938000
PROCEDURE ABORTIOX(IOQX);                                      <<00.05>>01940000
VALUE IOQX;                                                    <<00.05>>01942000
INTEGER IOQX;                                                  <<00.05>>01944000
OPTION PRIVILEGED,UNCALLABLE;                                  <<00.05>>01946000
BEGIN                                                          <<00.05>>01948000
EQUATE                                                         <<00.05>>01950000
   DISC       = 1; << DEV TYPE IS DISC >>                      <<00.05>>01952000
                                                               <<00.05>>01954000
DEFINE                                                         <<00.05>>01956000
   DCLASS     = (0:2)#; << DEVICE TYPE BITS IN DIT0 >>         <<00.05>>01958000
                                                               <<00.05>>01960000
INTEGER SAVEDB;                                                <<00.05>>01962000
                                                               <<00.05>>01964000
INTEGER POINTER IOQP,DITP,TESTP;                               <<00.05>>01966000
                                                               <<00.05>>01968000
   SAVEDB := SETSYSDB;                                         <<00.05>>01970000
   @IOQP := @IOQ + IOQX;                                       <<00.05>>01972000
   TOS := LPDTD(IOQP(QLDEV).LDEVN);                            <<00.05>>01974000
   DEL;                                                        <<00.05>>01976000
   @DITP := TOS;                                               <<00.05>>01978000
   IF DITP.DCLASS = DISC THEN GO FINISH; << CAN'T ABORT DISC >><<00.05>>01980000
   DISABLE;                                                    <<00.05>>01982000
   IOQP.ABORT := 1; << SET ABORT >>                            <<00.05>>01984000
   IF @IOQP = DITP(DIOQP) THEN                                 <<00.05>>01986000
   BEGIN  << FIRST IOQ ON LIST >>                              <<00.05>>01988000
      IF DITP >= 0 THEN DITP.IAK := 1;                         <<00.05>>01990000
      << SET INTERRUPT ACKNOW. IF NON-TERMINAL >>              <<00.05>>01992000
      ENABLE;                                                  <<00.05>>01994000
      AWAKEIO(DITP,0);                                         <<00.05>>01996000
      GO FINISH;                                               <<00.05>>01998000
   END ELSE                                                    <<00.05>>02000000
   BEGIN                                                       <<00.05>>02002000
      @TESTP := DITP(DIOQP); << SCAN IOQ LIST >>               <<00.05>>02004000
      WHILE @TESTP <> 0 DO                                     <<00.05>>02006000
      BEGIN                                                    <<00.05>>02008000
         IF TESTP(QLINK) = @IOQP THEN                          <<00.05>>02010000
         BEGIN << FOUND IT >>                                  <<00.05>>02012000
            TESTP(QLINK) := IOQP(QLINK); <<DELINK IOQ>>        <<00.05>>02014000
            ENABLE;                                            <<00.05>>02016000
            RETURNIOQ(IOQP);                                   <<00.05>>02018000
            RESETDB(SAVEDB);                                   <<00.05>>02020000
            RETURN;                                            <<00.05>>02022000
         END;                                                  <<00.05>>02024000
         @TESTP := TESTP(QLINK); << STEP TO NEXT IOQ >>        <<00.05>>02026000
      END;                                                     <<00.05>>02028000
   ENABLE;  <<clean up in case IOQ not chained??>>             <<02643>>02030000
   END;                                                        <<00.05>>02032000
FINISH:                                                        <<00.05>>02034000
   RESETDB(SAVEDB);                                            <<00.05>>02036000
   WAITFORIO(IOQX); << WAIT FOR I/O COMPLETION >>              <<00.05>>02038000
END;                                                           <<00.05>>02040000
$PAGE "DEVICE MAINTENENCE REQUEST PROCESSOR"                   <<03102>>02042000
procedure PROC'MAINT'REQ(LDEV,TYPE,SUBTYPE);                   <<03102>>02044000
value LDEV,TYPE,SUBTYPE;                                       <<03102>>02046000
integer LDEV,TYPE,SUBTYPE;                                     <<03102>>02048000
option internal,uncallable,privileged;                         <<03102>>02050000
begin                                                          <<03102>>02052000
                                                               <<03102>>02054000
<< This procedure processes maintence requests from >>         <<03102>>02056000
<< specific devices on the HP3000.  The mechanism   >>         <<03102>>02058000
<< used to invoke this procedure is:                >>         <<03102>>02060000
<< 1) The MPE driver calls procedure MAINT'REQUEST  >>         <<03102>>02062000
<<    in HARDRES.                                   >>         <<03102>>02064000
<< 2) Procedure MAINT'REQUEST sends a memory res-   >>         <<03102>>02066000
<<    ident message facility message to IOMSGPROC,  >>         <<03102>>02068000
<<    which then calls this procedure.              >>         <<03102>>02070000
<<                                                  >>         <<03102>>02072000
<< This procedure then makes the appropriate ATTIO  >>         <<03102>>02074000
<< calls to the device driver to extract the info,  >>         <<03102>>02076000
<< and then calls the MPE logging process to "log"  >>         <<03102>>02078000
<< the information.                                 >>         <<03102>>02080000
                                                               <<03102>>02082000
<< Information returned from driver utility requests are >>    <<03102>>02084000
<< returned in word 10 for CS'80 devices. This means that>>    <<03102>>02086000
<< this array can only hold 758 words of driver return info>>  <<03102>>02088000
                                                               <<03102>>02090000
array BUF(0:767);  << Buffer w/info for ATTACHIO    >>         <<03102>>02092000
byte array B'BUF(*) = BUF;                                     <<03102>>02094000
                                                               <<03102>>02096000
integer TOTAL'LENGTH, << Length of all info to be logged>>     <<03102>>02098000
        REM'LENGTH,   << Remaining bytes to log         >>     <<03102>>02100000
        LENGTH,       << Length to log in this call to LOG>>   <<03102>>02102000
        FNCT,         << ATTACHIO function >>                  <<03102>>02104000
        HEADS,        << Highest number head device has >>     <<03102>>02106000
        J,            << Continuation record number >>         <<03102>>02108000
        PA,PB,        << P1 & P2 of ATTACHIO        >>         <<03102>>02110000
        I,X=x,        << Utility integers >>                   <<03102>>02112000
        CNT;          << ATTACHIO count >>                     <<03102>>02114000
integer pointer BUF'PTR;  << Pointer into array BUF >>         <<03102>>02116000
byte pointer B'BUF'PTR; << Byte pointer into BUF >>            <<03102>>02118000
                                                               <<03102>>02120000
<< All following equates must be even numbers >>               <<03102>>02122000
equate MAX'LOG'LEN = 128,  << Log 128 bytes max at a time >>   <<03102>>02124000
       LOG'OVRHD   = 14,   <<14 bytes overhead per log call>>  <<03102>>02126000
       USABLE'LEN  = MAX'LOG'LEN-LOG'OVRHD;                    <<03102>>02128000
<<***********************************************************>><<03102>>02130000
double subroutine ATTIO;                                       <<03102>>02132000
begin                                                          <<03102>>02134000
                                                               <<03102>>02136000
ATTIO := ATTACHIO(LDEV,0,0,@BUF,FNCT,CNT,PA,PB,1<<blocked>>);  <<03102>>02138000
end;                                                           <<03102>>02140000
<<***********************************************************>><<03102>>02142000
subroutine LOG'TYPE'46;                                        <<03102>>02144000
    begin  << Return status was OK >>                          <<03102>>02146000
                                                               <<03102>>02148000
    << Change total length to positive bytes >>                <<03102>>02150000
    if TOTAL'LENGTH > 0 then                                   <<03102>>02152000
      TOTAL'LENGTH := TOTAL'LENGTH * 2                         <<03102>>02154000
    else if < then                                             <<03102>>02156000
      TOTAL'LENGTH := -TOTAL'LENGTH;                           <<03102>>02158000
                                                               <<03102>>02160000
    REM'LENGTH := TOTAL'LENGTH;                                <<03102>>02162000
                                                               <<03102>>02164000
    << Write records to MPE logging >>                         <<03102>>02166000
    J := 0;  << Record number >>                               <<03102>>02168000
    @B'BUF'PTR := @B'BUF(20); << Info is ret in word 10 >>     <<03102>>02170000
    while   REM'LENGTH > 0 do                                  <<03102>>02172000
      begin                                                    <<03102>>02174000
                                                               <<03102>>02176000
      LENGTH := if   REM'LENGTH > USABLE'LEN then              <<03102>>02178000
                   USABLE'LEN                                  <<03102>>02180000
                else                                           <<03102>>02182000
                   REM'LENGTH;                                 <<03102>>02184000
                                                               <<03102>>02186000
      << Call MPE logging >>                                   <<03102>>02188000
      LOG46(LDEV,TYPE,SUBTYPE,PB, << Maint req type >>         <<03102>>02190000
            I,                    << Head number    >>         <<03102>>02192000
            J,                    << Record number  >>         <<03102>>02194000
            TOTAL'LENGTH,         << Tot bytes      >>         <<03102>>02196000
            LENGTH,               << bytes in rec   >>         <<03102>>02198000
            @B'BUF'PTR,           << byte address   >>         <<03102>>02200000
            LENGTH,               << Len to copy    >>         <<03102>>02202000
            46);                  << LOG type       >>         <<03102>>02204000
                                                               <<03102>>02206000
      << Increment pointers, indicies >>                       <<03102>>02208000
      J := J + 1;   << Record number >>                        <<03102>>02210000
      @B'BUF'PTR := @B'BUF'PTR + LENGTH;                       <<03102>>02212000
      REM'LENGTH := REM'LENGTH - LENGTH;                       <<03102>>02214000
      end; << of writing intermediate records >>               <<03102>>02216000
                                                               <<03102>>02218000
end;                                                           <<03102>>02220000
<<***********************************************************>><<03102>>02222000
subroutine CS'80;                                              <<03102>>02224000
begin                                                          <<03102>>02226000
                                                               <<03102>>02228000
<< Determine how many heads device has >>                      <<03102>>02230000
FNCT := 13;      << Request device limits >>                   <<03102>>02232000
PA := 1;         << Three-vector mode     >>                   <<03102>>02234000
PB := 0;                                                       <<03102>>02236000
CNT := 2;        << Return a max of 2 words >>                 <<03102>>02238000
                                                               <<03102>>02240000
tos := ATTIO;                                                  <<03102>>02242000
assemble(del);   << Remove word count     >>                   <<03102>>02244000
if tos.(13:3) <> 1 then                                        <<03102>>02246000
  tos := 0       << Assume 0 heads if ATTIO failed >>          <<03102>>02248000
else                                                           <<03102>>02250000
  tos := BUF(1).(0:8); << # of heads >>                        <<03102>>02252000
                                                               <<03102>>02254000
<< If number of heads is zero, assume NO heads >>              <<03102>>02256000
assemble(test);                                                <<03102>>02258000
if = then                                                      <<03102>>02260000
  tos := tos - 1;   << Make # of heads negative >>             <<03102>>02262000
HEADS := tos;                                                  <<03102>>02264000
<< We must first request run-time data error log from each >>  <<03102>>02266000
<< of all 13 heads, and then call MPE logging to save info >>  <<03102>>02268000
                                                               <<03102>>02270000
FNCT := 91;   << Function 91 to driver >>                      <<03102>>02272000
PA := 2;                                                       <<03102>>02274000
PB := %305;                                                    <<03102>>02276000
CNT := -1516; << 758 words max driver can return >>            <<03102>>02278000
I := -1;                                                       <<03102>>02280000
while (I:=I+1) <= HEADS do                                     <<03102>>02282000
  begin << Process each head >>                                <<03102>>02284000
                                                               <<03102>>02286000
  BUF := 1;  << 1 byte of descriptor information >>            <<03102>>02288000
  B'BUF(2) := byte(I); << Head number in byte 2  >>            <<03102>>02290000
  tos := ATTIO;                                                <<03102>>02292000
  TOTAL'LENGTH := tos;  << store length transferred >>         <<03102>>02294000
  if tos.(13:3) = 1 then                                       <<03102>>02296000
    LOG'TYPE'46;                                               <<03102>>02298000
                                                               <<03102>>02300000
  end;   << of processing each head >>                         <<03102>>02302000
                                                               <<03102>>02304000
<< Read the fault log >>                                       <<03102>>02306000
PB := %307;     << Fault log >>                                <<03102>>02308000
I := 0;                                                        <<03102>>02310000
BUF := 0;   << 0 parameter bytes >>                            <<03102>>02312000
                                                               <<03102>>02314000
tos := ATTIO;                                                  <<03102>>02316000
TOTAL'LENGTH := tos;                                           <<03102>>02318000
if tos.(13:3) = 1 then                                         <<03102>>02320000
  LOG'TYPE'46;   << ATTACHIO was OK >>                         <<03102>>02322000
                                                               <<03102>>02324000
<< Now, we must clear maintenence info from disc >>            <<03102>>02326000
PA := 0;    << Send utility cmd >>                             <<03102>>02328000
PB := %315; << Clear log utility function >>                   <<03102>>02330000
BUF := 1;   << Send 1 byte >>                                  <<03102>>02332000
B'BUF(2) := 0;   << Byte value is zero >>                      <<03102>>02334000
ATTIO;                                                         <<03102>>02336000
end;   << of subroutine HP7935 >>                              <<03102>>02338000
<<***********************************************************>><<03102>>02340000
<< Case on device type >>                                      <<03102>>02342000
case TYPE of                                                   <<03102>>02344000
                                                               <<03102>>02346000
begin  << of case on type >>                                   <<03102>>02348000
                                                               <<03102>>02350000
<<0>>  ;   << Type 0 (disc) has no maintence requests >>       <<03102>>02352000
                                                               <<03102>>02354000
<<1>>  ;   << Type 1 has no maintenence requests      >>       <<03102>>02356000
                                                               <<03102>>02358000
<<2>>  ;   << Type 2 has no maintenence requests      >>       <<03102>>02360000
                                                               <<03102>>02362000
<<3>>  CS'80; << CS'80 type disc drive maintenence req>>       <<03102>>02364000
                                                               <<03102>>02366000
end;    << of case on device type >>                           <<03102>>02368000
                                                               <<03102>>02370000
end;  << of procedure PROC'MAINT'REQ >>                        <<03102>>02372000
$PAGE "I/O MESSAGE PROCESS"                                             02374000
procedure IOMESSPROC;                                          <<02806>>02378000
option privileged,uncallable;                                  <<02806>>02380000
begin                                                          <<02806>>02382000
                                                               <<02806>>02384000
<<This routine's sole purpose in life is to route messages>>   <<02806>>02386000
<<between terminals (& critical processes) without using  >>   <<02806>>02388000
<<permanent system resources.  This routine will either   >>   <<02806>>02390000
<<dynamically obtain, or release, extra data segments in  >>   <<02806>>02392000
<<MPE to hold a message until the physical I/O is done.   >>   <<02806>>02394000
                                                               <<02806>>02396000
<< Generally, port "0" is used to receive messages for this >> <<04271>>02398000
<< process.  If a process cannot be performed immediately   >> <<04271>>02400000
<< due to lack of resources, IOMESSPROC sends the message   >> <<04271>>02402000
<< to itself in port "3" to defer it until the resource     >> <<04271>>02404000
<< becomes available.  This "resource" is currently message >> <<04271>>02406000
<< buffer entries.  If this check were not made, IOMESSPROC >> <<04271>>02408000
<< could become impeded on itself waiting for an available  >> <<04271>>02410000
<< message buffer (in its call to GENMESSAGE).              >> <<04271>>02412000
                                                               <<04271>>02414000
<< If NUM'MSG'BUFS is changed, must also change in MESSAGE >>  <<02806>>02416000
equate NUM'MSG'BUFS =16; << number of MSG BUFs in DST >>       <<02806>>02418000
                                                               <<04271>>02420000
array IOQ'ARRAY(0:NUM'MSG'BUFS-1), << pending I/O IOQs >>      <<02806>>02422000
      DST'ARRAY(0:NUM'MSG'BUFS-1), << DST buffer offset >>     <<02806>>02424000
      BUF'HDR(0:21);           <<Work area for MSG DST hdr >>  <<02806>>02426000
byte array B'BUF'HDR(*)=BUF'HDR;                               <<02806>>02428000
                                                               <<02806>>02430000
<<equates for GENMSG stacked parameters>>                      <<02806>>02432000
equate DITDST         = 42,                                    <<02806>>02434000
       DITDSTI        = DITDST*4+3,                            <<02806>>02436000
       DSTB           = 14;  <<DST parm bit in GENMSG call>>   <<02806>>02438000
integer BUF           = s-3, <<buffer in GENMSG call>>         <<02806>>02440000
        DSTNUM        = s-2; <<DST number in GENMSG call>>     <<02806>>02442000
logical FLAG;                <<whether REPLY in GENMSG>>       <<02806>>02444000
                                                               <<02806>>02446000
define SYSB'LOC = absolute(%1006)#;<<loc of SYSDB SYSBUF ptr>> <<02806>>02448000
                                                               <<02806>>02450000
integer CURRENT'INDEX,   <<index into I/O arrays>>             <<02806>>02452000
        MOVE'LENGTH,     <<length to move in MDS instructions>><<02806>>02454000
        DSTX,            <<DST number to move from/to>>        <<02806>>02456000
        SAVESIR,         << Save GETSIR information >>         <<04271>>02458000
        SBUFX,           <<System buffer index>>               <<02806>>02460000
        TRLX,            << Index of watchdog timer >>         <<02806>>02462000
        LAST'ENTRY;      <<index of last entry in arrays>>     <<02806>>02464000
                                                               <<02806>>02466000
<< timer declarations >>                                       <<02806>>02468000
double NEW'TIME,           << delta time from LAST'TIME >>     <<02806>>02470000
       LAST'TIME;          << prior cycle TIME obtained >>     <<02806>>02472000
                                                               <<02806>>02474000
define PAUSE'TIME = 30000D#;  << 30 second watchdog timer >>   <<02806>>02476000
                                                               <<02806>>02478000
<<SYSDB-relative location of IOQ table pointer>>               <<02806>>02480000
define IOQ'TABLE'LOC = absolute(%1005)#;                       <<02806>>02482000
                                                               <<02806>>02484000
<< S-relative arguments for RECEIVEMSG >>                      <<02806>>02486000
integer SM0 = s-0,                                             <<02806>>02488000
        SM1 = s-1,                                             <<02806>>02490000
        SM2 = s-2,                                             <<02806>>02492000
        SM3 = s-3;                                             <<02806>>02494000
                                                               <<02806>>02496000
pointer LOG'BUF'PTR;  <<pointer to logging info buffer in stack<<02806>>02498000
                                                               <<02806>>02500000
<<declarations to fire-off PROGEN if SHUTDOWN requested>>      <<02806>>02502000
integer PROGEN = DB + %141;  <<Sysglob location>>              <<02806>>02504000
define SHUTDOWN = absolute(%1300)#; << Shutdown flag >>        <<04186>>02506000
define THISPIN = (absolute(CPCB)-absolute(PCBB))/PCBSIZE#,     <<02806>>02508000
       CONSCELL   = absolute(%1074)#, << system cons ldev >>   <<02806>>02510000
       IOMSGQUEUE = absolute(%1062)#, << Impeded PIN head >>   <<02806>>02512000
       IOMSGDST   = absolute(%1113)#, << MSG buffers DST  >>   <<02806>>02514000
       IOMSGPROC = absolute(%1152)#,  << my PIN (CPCB-PCBB) >> <<02806>>02516000
       PCBM       = (8:8)#;           << NIMP field of PCB8 >> <<02806>>02518000
                                                               <<02806>>02520000
equate MSGSIR  = %24,  << MSG SIR number >>                    <<02806>>02522000
       SBUFDST = 8,    <<DST number of system buffers>>        <<02806>>02524000
       PCB8    = 8;    << eighth word of PCB (NIMP) >>         <<02806>>02526000
$PAGE                                                          <<04186>>02528000
subroutine GIVE'BACK'BUFFER; << return MSG buf to avail list>> <<04186>>02530000
begin                                                          <<02806>>02532000
                                                               <<02806>>02534000
if IOMSGDST = 0 then                                           <<02806>>02536000
  return;    << no DST for buffers yet >>                      <<02806>>02538000
                                                               <<02806>>02540000
<< move in buffer DST header info >>                           <<02806>>02542000
tos := @BUF'HDR;     tos := IOMSGDST;                          <<02806>>02544000
tos := 0;            tos := 4;                                 <<02806>>02546000
assemble(mfds 4);                                              <<02806>>02548000
                                                               <<02806>>02550000
<< get tail pointer >>                                         <<02806>>02552000
if BUF'HDR(3) = 0  then                                        <<02806>>02554000
  begin    << this will be first on avail list >>              <<02806>>02556000
  BUF'HDR(2) := BUF'HDR(3) := DST'ARRAY(CURRENT'INDEX);        <<02806>>02558000
  end                                                          <<02806>>02560000
else                                                           <<02806>>02562000
  begin    << must chain this buffer onto prior buffer >>      <<02806>>02564000
  << move this one's pointer to current last guy's >>          <<02806>>02566000
  tos := IOMSGDST;    tos := BUF'HDR(3);                       <<02806>>02568000
  tos := @DST'ARRAY(CURRENT'INDEX); tos := 1;                  <<02806>>02570000
  assemble(mtds 4);                                            <<02806>>02572000
                                                               <<02806>>02574000
  << fix tail pointer only >>                                  <<02806>>02576000
  BUF'HDR(3) := DST'ARRAY(CURRENT'INDEX);                      <<02806>>02578000
  end;                                                         <<02806>>02580000
                                                               <<02806>>02582000
<< now, write back new header info >>                          <<02806>>02584000
tos := IOMSGDST;        tos := 0;                              <<02806>>02586000
tos := @BUF'HDR;        tos := 4;                              <<02806>>02588000
assemble(mtds 4);                                              <<02806>>02590000
BUF'HDR:=0;tos:=IOMSGDST;tos:=BUF'HDR(3);tos:=@BUF'HDR;tos:=1; <<02806>>02592000
assemble(mtds 4); end;   << of subroutine GIVE'BACK'BUFFER >>  <<02806>>02594000
$PAGE                                                          <<04186>>02596000
subroutine UNIMPEDE'PROCESS;                                   <<04186>>02598000
begin                                                          <<04186>>02600000
                                                               <<04271>>02602000
<< If IOMESSPROC was waiting on buffer, re-queue msg >>        <<04271>>02604000
if PORTSTATUS(3) then                                          <<04271>>02606000
  begin                                                        <<04271>>02608000
  assemble(adds 4);  << return cells >>                        <<04271>>02610000
  RECEIVEMSG(3,4,0);                                           <<04271>>02612000
  SENDMSG(THISPIN,0,4,%140000);                                <<04271>>02614000
  return;                                                      <<04271>>02616000
  end;                                                         <<04271>>02618000
                                                               <<04271>>02620000
PDISABLE;    << protect integrity of IMP chain >>              <<04271>>02622000
if IOMSGQUEUE = 0 then                                         <<04271>>02624000
  begin    << there are no PINs waiting >>                     <<04271>>02626000
  PENABLE;                                                     <<04271>>02628000
  return;                                                      <<04271>>02630000
  end;                                                         <<04271>>02632000
                                                               <<04271>>02634000
<< fix up linking >>                                           <<04271>>02636000
tos := IOMSGQUEUE;   << save PIN to UNIMPEDE on tos >>         <<04271>>02638000
IOMSGQUEUE := absolute(absolute(PCBB) + (IOMSGQUEUE*PCBSIZE) + <<04271>>02640000
              PCB8).PCBM;  << put next PIN into IOMSGQUEUE >>  <<04271>>02642000
X := (S0*PCBSIZE)+absolute(PCBB)+PCB8; << awoken PINs index+8 ><<04271>>02644000
absolute(X).PCBM := 0;  << zero NIMP field of PCB to be awoken <<04271>>02646000
UNIMPEDE(tos*PCBSIZE);  << unimpede pin 1st on list >>         <<04271>>02648000
PENABLE;                                                       <<04271>>02650000
                                                               <<04271>>02652000
<< if process was impeded & watchdog timer, clear timer >>     <<04271>>02654000
if TRLX <> 0 then                                              <<04271>>02656000
  begin    << abort/cancel this timer request >>               <<04271>>02658000
  SETSYSDB;                                                    <<04271>>02660000
  ABORTTIMEREQ(TRLX);                                          <<04271>>02662000
  RESETDB(-1);                                                 <<04271>>02664000
  TRLX := 0;  LAST'TIME := 0D;                                 <<04271>>02666000
  end;                                                         <<04271>>02668000
                                                               <<04271>>02670000
end;   << of subroutine GIVE'BACK'BUFFER >>                    <<04271>>02672000
$PAGE                                                          <<04271>>02674000
logical subroutine NO'BUF'AVAIL;                               <<04271>>02676000
<< Returns TRUE if no MSG buffers available >>                 <<04271>>02678000
begin                                                          <<04271>>02680000
<< Move in buffer DST header >>                                <<04271>>02682000
tos := @BUF'HDR;       tos := IOMSGDST;                        <<04271>>02684000
tos := 0;              tos := 4;                               <<04271>>02686000
assemble(mfds 4);                                              <<04271>>02688000
                                                               <<04271>>02690000
<< See if no available buffers >>                              <<04271>>02692000
if BUF'HDR(2) = 0 then                                         <<04271>>02694000
  NO'BUF'AVAIL := true                                         <<04271>>02696000
else                                                           <<04271>>02698000
  NO'BUF'AVAIL := false;                                       <<04271>>02700000
                                                               <<04271>>02702000
end;                                                           <<04271>>02704000
$PAGE                                                          <<04271>>02706000
subroutine MAKE'BUFFER'AVAIL;                                  <<04271>>02708000
begin <<IO is done, so clean-up>>                              <<04271>>02710000
                                                               <<04271>>02712000
SAVESIR := GETSIR(MSGSIR); << save integrity of MSG bufs >>    <<04271>>02714000
                                                               <<04271>>02716000
<< give buffer back to available pool >>                       <<04271>>02718000
GIVE'BACK'BUFFER;                                              <<04271>>02720000
                                                               <<04271>>02722000
<< if any process waiting on buffers, unimpede >>              <<04271>>02724000
UNIMPEDE'PROCESS;                                              <<04271>>02726000
                                                               <<04271>>02728000
RELSIR(MSGSIR,SAVESIR);  << make MSG SIR avail again >>        <<04271>>02730000
                                                               <<04271>>02732000
<<now, compress the table>>                                    <<04271>>02734000
move IOQ'ARRAY(CURRENT'INDEX) :=                               <<04271>>02736000
IOQ'ARRAY(CURRENT'INDEX+1),(LAST'ENTRY-CURRENT'INDEX);         <<04271>>02738000
move DST'ARRAY(CURRENT'INDEX) :=                               <<04271>>02740000
DST'ARRAY(CURRENT'INDEX+1),(LAST'ENTRY-CURRENT'INDEX);         <<04271>>02742000
LAST'ENTRY := LAST'ENTRY - 1;                                  <<04271>>02744000
CURRENT'INDEX := CURRENT'INDEX - 1;                            <<04271>>02746000
end;                                                           <<04271>>02748000
$PAGE "IOMSGPROC PROCEDURE MAINLINE"                           <<04186>>02750000
LAST'ENTRY := -1;   <<initialize last index pointer used>>     <<02806>>02752000
TRLX := 0;          << no current watchdog timer >>            <<02806>>02754000
                                                               <<02806>>02756000
Start:                                                         <<02806>>02758000
                                                               <<02806>>02760000
if SHUTDOWN.(3:1) then                                         <<02806>>02762000
  begin   <<process stop>>                                     <<02806>>02764000
  SETSYSDB;                                                    <<04186>>02766000
  AWAKE(PROGEN,2<<son>>,0);                                    <<02806>>02768000
  WAIT(0,0);        <<go to sleep forever>>                    <<02806>>02770000
  end;                                                         <<02806>>02772000
                                                               <<02806>>02774000
                                                               <<02806>>02776000
   <<check an see if any IPC messages are waiting>>            <<02806>>02778000
   while PORTSTATUS(0) do                                      <<02806>>02780000
      begin  <<there are messages to get & process>>           <<02806>>02782000
      assemble(adds 4); <<return cells>>                       <<02806>>02784000
      RECEIVEMSG(0,4,0); <<read 4 words from port 0,destructive<<02806>>02786000
      if = then                                                <<02806>>02788000
        begin  <<got message OK>>                              <<02806>>02790000
        case SM3 of                                            <<02806>>02792000
        begin                                                  <<02806>>02794000
                                                               <<02806>>02796000
<<0>>   begin <<error log sysbuf relative>>                    <<02806>>02798000
        SBUFX := SM2;    <<save system buffer index>>          <<02806>>02800000
        MOVE'LENGTH := SM1; <<save length to log from SYSBUF>> <<02806>>02802000
        tos := 0;        <<beginning of temp buffer>>          <<02806>>02804000
        @LOG'BUF'PTR := @SM0; <<save DB addr of this buffer>>  <<02806>>02806000
        tos := MOVE'LENGTH-1; <<addt'l buffer space>>          <<02806>>02808000
        assemble(adds 0);     <<allocate buffer>>              <<02806>>02810000
                                                               <<02806>>02812000
        <<move in information from system buffer>>             <<02806>>02814000
        tos := @LOG'BUF'PTR;  <<target DB address>>            <<02806>>02816000
        tos := SBUFDST;       <<source DST is SYSBUFS>>        <<02806>>02818000
        tos := logical(SBUFX)-SYSB'LOC; <<location of buf in XD<<02806>>02820000
        tos := MOVE'LENGTH;   <<length of data in SYSBUF>>     <<02806>>02822000
        assemble(mfds 4);     <<move in data>>                 <<02806>>02824000
                                                               <<02806>>02826000
        <<now, free up system buffer>>                         <<02806>>02828000
        SETSYSDB;                                              <<02806>>02830000
        RETURNSBUF(SBUFX);                                     <<02806>>02832000
        RESETDB(-1);                                           <<02806>>02834000
                                                               <<02806>>02836000
        <<add in logging information>>                         <<02806>>02838000
        tos := MOVE'LENGTH - 13;  <<length of variable info>>  <<02806>>02840000
        tos := 11;                <<log type>>                 <<02806>>02842000
        LOG;                                                   <<02806>>02844000
                                                               <<02806>>02846000
        end;                                                   <<02806>>02848000
                                                               <<02806>>02850000
<<1>>   begin << table-overflow error >>                       <<02806>>02852000
                                                               <<02806>>02854000
        << move table name to array >>                         <<02806>>02856000
        move B'BUF'HDR := "MPE Table ",2;                      <<02806>>02858000
        case SM3 of   << actually s-2, but have stacked parm>> <<02806>>02860000
        begin                                                  <<02806>>02862000
        move * := "TBUF",2;                                    <<02806>>02864000
        move * := "SBUF",2;                                    <<02806>>02866000
        move * := "IOQ",2;                                     <<02806>>02868000
        move * := "DISC REQUEST",2;                            <<02806>>02870000
        move * := "TRL",2;                                     <<02806>>02872000
        end;                                                   <<02806>>02874000
        move * := (" has overflowed!!!",%7,%7<<bell>>),2;      <<02806>>02876000
        MOVE'LENGTH := (tos-@B'BUF'HDR+1)&lsr(1);     << ajk >><<02806>>02878000
                                                               <<02806>>02880000
        <<get SYSBUF to move it to>>                           <<02806>>02882000
        SETSYSDB;                                              <<02806>>02884000
        @LOG'BUF'PTR := GETSBUF(2);                            <<02806>>02886000
        RESETDB(-1);                                           <<02806>>02888000
        if @LOG'BUF'PTR <> 0 then                              <<02806>>02890000
          begin  << we got one >>                              <<02806>>02892000
          SBUFX := integer(@LOG'BUF'PTR-SYSB'LOC);<<SBUF indx>><<02806>>02894000
          << move data to sysbuf >>                            <<02806>>02896000
          tos := SBUFDST;   <<DST of system buffers>>          <<02806>>02898000
          tos := SBUFX;     <<offset into system buffers>>     <<02806>>02900000
          tos := @BUF'HDR;  <<source DB address>>              <<02806>>02902000
          tos := MOVE'LENGTH;                                  <<02806>>02904000
          assemble(mtds 4);                                    <<02806>>02906000
                                                               <<02806>>02908000
          << now, perform ATTACHIO to send to console, ASAP!>> <<02806>>02910000
     tos:=ATTACHIO(CONSCELL,            <<ldev of console>>    <<02806>>02912000
                   0,  <<QMISC>>                               <<02806>>02914000
                   0,  <<DSTX, SYSBUF used>>                   <<02806>>02916000
                   SBUFX,  <<SYSBUF index>>                    <<02806>>02918000
                   1,  <<FUNC, write>>                         <<02806>>02920000
                   MOVE'LENGTH, <<CNT>>                        <<02806>>02922000
                   0,0,<<P1, P2>>                              <<02806>>02924000
                   %17);<<SBUF,no IMPEDE,no PCB>>              <<02806>>02926000
                                                               <<02806>>02928000
          << if doubleword on tos is zero, then failed >>      <<02806>>02930000
          assemble(dtst,ddel);                                 <<02806>>02932000
          if = then                                            <<02806>>02934000
            begin  << must return system buffer >>             <<02806>>02936000
            SETSYSDB;                                          <<02806>>02938000
            RETURNSBUF(@LOG'BUF'PTR);                          <<02806>>02940000
            RESETDB(-1);                                       <<02806>>02942000
            end;                                               <<02806>>02944000
          end;                                                 <<02806>>02946000
                                                               <<02806>>02948000
        << now, LOG this to console logging >>                 <<02806>>02950000
        LOG15(MOVE'LENGTH*2,@B'BUF'HDR,MOVE'LENGTH*2,15);      <<02806>>02952000
        end;                                                   <<02806>>02954000
                                                               <<02806>>02956000
<<2>>   begin <<IOQ index for sent message>>                   <<02806>>02958000
                                                               <<02806>>02960000
        <<store IOQ & DST associated in last element of array>><<02806>>02962000
        LAST'ENTRY := LAST'ENTRY + 1; <<increment last entry po<<02806>>02964000
        IOQ'ARRAY(LAST'ENTRY) := SM2; <<store IOQ>>            <<02806>>02966000
        DST'ARRAY(LAST'ENTRY) := SM1; <<store DST>>            <<02806>>02968000
                                                               <<02806>>02970000
        <<now, mark the IOQ with this PCB, IW bit>>            <<02806>>02972000
        @LOG'BUF'PTR := logical(SM2)+IOQ'TABLE'LOC; <<load IOQ <<02806>>02974000
        SETSYSDB;                                              <<02806>>02976000
        DISABLE;                                               <<02806>>02978000
        if not LOG'BUF'PTR.(6:1) then <<if not completed>>     <<02806>>02980000
          begin                                                <<02806>>02982000
          LOG'BUF'PTR.(4:1) := 1;  <<turn on WAKE bit>>        <<02806>>02984000
          LOG'BUF'PTR(10).(0:8) := THISPIN; << set this PCB >> <<02806>>02986000
          end;                                                 <<02806>>02988000
        ENABLE;                                                <<02806>>02990000
        RESETDB(-1);                                           <<02806>>02992000
        end;                                                   <<02806>>02994000
<<3>>   begin <<GENMSG from I/O driver, ICS spawned>>          <<02806>>02996000
        SAVESIR := GETSIR(MSGSIR); << Protect MSGBUF integrity <<04271>>02998000
        if NO'BUF'AVAIL then                                   <<04271>>03000000
          begin                                                <<04271>>03002000
          << Send parms to port 3 and put dummy parms on tos >><<04271>>03004000
          SENDMSG(THISPIN,3,4,%100000);                        <<04271>>03006000
          tos := 0D;                                           <<04271>>03008000
          tos := 0D;                                           <<04271>>03010000
          end                                                  <<04271>>03012000
        else                                                   <<04271>>03014000
                                                               <<04271>>03016000
        begin                                                  <<04271>>03018000
        SBUFX := SM2;     <<save sysbuf index>>                <<04271>>03020000
        @LOG'BUF'PTR := SM2; <<load as DB pointer, too>>       <<04271>>03022000
        FLAG := false;    <<reply flag>>                       <<04271>>03024000
        SETSYSDB;                                              <<02806>>03026000
        tos := 0;       <<return value from GENMSG>>           <<02806>>03028000
        X := 0;                                                <<02806>>03030000
        while (X := X+1) < 15 do                               <<02806>>03032000
          tos := LOG'BUF'PTR(X);<<load GENMSG parms on tos>>   <<02806>>03034000
        DSTX := LOG'BUF'PTR(12); <<save DITP in DSTX>>         <<02806>>03036000
        <<return system buffer>>                               <<02806>>03038000
        RETURNSBUF(SBUFX);                                     <<02806>>03040000
        assemble(tbc DSTB); <<see if REPLY and no DST>>        <<02806>>03042000
        if <> then                                             <<02806>>03044000
          begin                                                <<02806>>03046000
          if DSTNUM = 0 then                                   <<02806>>03048000
            SUDDENDEATH(271);                                  <<02806>>03050000
          FLAG := true; <<can't put reply stack relative>>     <<02806>>03052000
          BUF := BUF+DSTNUM-(DST(DITDSTI)-SYSDB);              <<04915>>03054000
          DSTNUM := DITDST;                                    <<02806>>03056000
          end;                                                 <<02806>>03058000
        RESETDB(-1);  <<DB is back to stack>>                  <<02806>>03060000
        assemble(pcal GENMSG);                                 <<02806>>03062000
        assemble(del);  <<delete return value on tos>>         <<02806>>03064000
        if FLAG then                                           <<02806>>03066000
          begin                                                <<02806>>03068000
          SETSYSDB;                                            <<02806>>03070000
          tos := DSTX;            <<get the DIT pntr>>         <<02806>>03072000
          DISABLE;                                             <<02806>>03074000
          PS0.IAK := 1;   <<set interrupt ack bit>>            <<02806>>03076000
          tos := PS0(DIOQP); <<set msg reply in IOQ>>          <<02806>>03078000
          if <> then                                           <<02806>>03080000
            PS0.MSGREPLY := 1;                                 <<02806>>03082000
          ENABLE;                                              <<02806>>03084000
          assemble(del);  <<delete pointer>>                   <<02806>>03086000
          AWAKEIO(*,NOIMPEDE);                                 <<02806>>03088000
          RESETDB(-1);                                         <<02806>>03090000
          end;                                                 <<02806>>03092000
        end;  << of ELSE on NO'BUF'AVAIL >>                    <<04271>>03094000
                                                               <<04271>>03096000
        RELSIR(MSGSIR,SAVESIR);                                <<04271>>03098000
        end;                                                   <<04271>>03100000
                                                               <<02806>>03102000
<<4>>  begin << Process device maintenence request >>          <<03102>>03104000
       PROC'MAINT'REQ(SM2,SM1,SM0);                            <<03102>>03106000
       end;                                                    <<03102>>03108000
                                                               <<03102>>03110000
<<5>>   ; << DCU maintenence request-N/A for Series II/III >>  <<04186>>03112000
                                                               <<04186>>03114000
        end; <<of case on message type>>                       <<02806>>03116000
                                                               <<02806>>03118000
        assemble(subs 4);  <<pop 4 words off tos>>             <<02806>>03120000
        end;  <<of successful RCPT of IPC msg>>                <<02806>>03122000
                                                               <<02806>>03124000
      end;    <<of check for any IPC message>>                 <<02806>>03126000
                                                               <<02806>>03128000
   <<now, see if any IOQ's have completed so we can>>          <<02806>>03130000
   <<release their DST>>                                       <<02806>>03132000
   CURRENT'INDEX := -1;                                        <<02806>>03134000
   while (CURRENT'INDEX:=CURRENT'INDEX+1) <= LAST'ENTRY do     <<02806>>03136000
     begin  <<check the IOQ's>>                                <<02806>>03138000
     IOSTATUS(IOQ'ARRAY(CURRENT'INDEX));                       <<02806>>03140000
     if = then                                                 <<02806>>03142000
       MAKE'BUFFER'AVAIL;  << I/O has completed >>             <<02806>>03144000
     end;                                                      <<02806>>03146000
                                                               <<02806>>03148000
<< perform watchdog timer housekeeping >>                      <<02806>>03150000
if TRLX <> 0 then                                              <<02806>>03152000
  begin   << watchdog timer is set, see if expired >>          <<02806>>03154000
  NEW'TIME := TIMER - LAST'TIME;  << delta time in ms >>       <<02806>>03156000
  if < then   << system clock wrap-around >>                   <<02806>>03158000
    NEW'TIME := %17777777777D - NEW'TIME + 1D;                 <<02806>>03160000
  if NEW'TIME >= PAUSE'TIME then                               <<02806>>03162000
    if LAST'ENTRY >= 0 then                                    <<02806>>03164000
      begin  << we will kill the oldest outstanding msg >>     <<02806>>03166000
      CURRENT'INDEX := 0;                                      <<02806>>03168000
      tos := IOQ'ARRAY(CURRENT'INDEX); << oldest IOQ on tos >> <<02806>>03170000
      SETSYSDB;                                                <<02806>>03172000
      ABORTIOX(*);                                             <<02806>>03174000
      RESETDB(-1);                                             <<02806>>03176000
      MAKE'BUFFER'AVAIL;                                       <<02806>>03178000
      end;                                                     <<02806>>03180000
  end;   << of processing "popped" watchdog timer >>           <<02806>>03182000
                                                               <<02806>>03184000
<< if no watchdog timer & have impeded processes, get one >>   <<02806>>03186000
PDISABLE;                                                      <<02806>>03188000
if IOMSGQUEUE <> 0 then  << there are impeded processes >>     <<02806>>03190000
  if TRLX = 0 then   << there is no current watchdog timer >>  <<02806>>03192000
    begin                                                      <<02806>>03194000
                                                               <<02806>>03196000
    LAST'TIME := TIMER;   << save time of call >>              <<02806>>03198000
    << stack ops for call to TIMEREQ >>                        <<02806>>03200000
    tos := 0;     << TRLX returned >>                          <<02806>>03202000
    tos := %12;   << CODE %12 is watchdog timer >>             <<02806>>03204000
    tos := IOMSGPROC;  << my PCB offset from PCB base >>       <<02806>>03206000
    tos := PAUSE'TIME; << Delay time in ms (double) >>         <<02806>>03208000
                                                               <<02806>>03210000
    SETSYSDB;                                                  <<02806>>03212000
    assemble(pcal TIMEREQ);                                    <<02806>>03214000
    << or tos := TIMEREQ(%12,IOMSGPROC,PAUSE'TIME); >>         <<02806>>03216000
    RESETDB(-1);                                               <<02806>>03218000
                                                               <<02806>>03220000
    << save TRLX index >>                                      <<02806>>03222000
    TRLX := tos;                                               <<02806>>03224000
    end;                                                       <<02806>>03226000
                                                               <<02806>>03228000
PENABLE;                                                       <<02806>>03230000
                                                               <<02806>>03232000
<<now, wait for a new event to wake me up>>                    <<02806>>03234000
WAIT(-(%114)<<IO,timer,msg>>,0);                               <<02806>>03236000
go to Start;                                                   <<02806>>03238000
                                                               <<02806>>03240000
end;   <<of process/procedure IOMESSPROC>>                     <<02806>>03242000
$INCLUDE INCLVDEV                                              <<04341>>03248000
$PAGE "DUMMY SOFTWARE DUMP PROCEDURE FOR SERIES II/III"        <<00136>>03250000
PROCEDURE SDFINIT(MODE);                                       <<00136>>03252000
VALUE MODE;                                                    <<00136>>03254000
LOGICAL MODE;                                                  <<00136>>03256000
  option privileged,uncallable;                                <<02638>>03258000
   BEGIN                                                       <<00136>>03260000
   END;                                                        <<00136>>03262000
$PAGE                                                          <<00575>>03264000
INTEGER PROCEDURE IOTABLEINFO(CODE,P1,P2);                     <<00575>>03266000
  VALUE CODE,P1,P2;                                            <<00575>>03268000
  INTEGER CODE,P1,P2;                                          <<00575>>03270000
  option privileged,uncallable;                                <<02638>>03272000
                                                               <<00575>>03274000
<<                                                           >><<00575>>03276000
<< IOTABLEINFO IS DESIGNED PRIMARILY TO INTERFACE "MEASIO" TO>><<00575>>03278000
<< THE SERIES III AND SERIES 33 I/O TABLES. IT WILL RETURN A >><<00575>>03280000
<< VALUE BASED ON THE "CODE" SUPPLIED. TWO PARAMETERS ARE    >><<00575>>03282000
<< ALLOWED.                                                  >><<00575>>03284000
<< CURRENT "CODE" ASSIGNMENTS ARE:                           >><<00575>>03286000
<<                                                           >><<00575>>03288000
<<   1 => RETURN LDEV # FOR A GIVEN UNIT NUMBER ON A GIVEN   >><<00575>>03290000
<<        CONTROLLER.                                        >><<00575>>03292000
<<           P1 = SYSDB REL. DIT POINTER                     >><<00575>>03294000
<<           P2 = UNIT NUMBER ON THE CONTROLLER              >><<00575>>03296000
<<   2 => RETURN THE NUMBER OF UNITS ON A GIVEN CONTROLLER.  >><<00575>>03298000
<<           P1 = SYSDB REL. DIT POINTER                     >><<00575>>03300000
<<   3 => RETURN TRUE/FALSE IF "MEASIO" WAS/NOT ENABLED ON A >><<00575>>03302000
<<        GIVEN DEVICE.                                      >><<00575>>03304000
<<           P1 = SYSDB REL. DIT POINTER                     >><<00575>>03306000
<<           P2 = LDEV                                       >><<00575>>03308000
<<                                                           >><<00575>>03310000
                                                               <<00575>>03312000
BEGIN                                                          <<00575>>03314000
  EQUATE                                                       <<00575>>03316000
                                                               <<01300>>03318000
                                                               <<01300>>03320000
      MIO'ENABLE = 39,                                         <<00575>>03322000
      MIO'LDEV   = 37;                                         <<00575>>03324000
  DEFINE                                                       <<00575>>03326000
      ILTP      = ABS(P1+SYSDB+DILTP)+SYSDB#, <<ABS LOC ILTP>> <<00575>>03328000
      DITP      = ABS(ILTP+IDITP+P2)+SYSDB#;  <<ABS LOC DIT>>  <<00575>>03330000
  INTEGER                                                      <<00575>>03332000
      I;                                                       <<00575>>03334000
                                                               <<00575>>03336000
                                                               <<00575>>03338000
  IOTABLEINFO := 0;                                            <<00575>>03340000
                                                               <<00575>>03342000
  IF CODE = 1 THEN                                             <<00575>>03344000
     BEGIN                                                     <<01576>>03346000
     IF ABS(DITP) <> 0 THEN                                    <<01576>>03348000
        IOTABLEINFO := ABS(DITP+DLDEV).(8:8); <<LDEV>>         <<01576>>03350000
     END                                                       <<01576>>03352000
  ELSE IF CODE = 2 THEN                                        <<00575>>03354000
    IOTABLEINFO:=ABS(ILTP+IFLAG).HCUNIT     << HIGHEST UNIT #>><<01300>>03356000
  ELSE IF CODE = 3 THEN                                        <<00575>>03358000
  BEGIN                                                        <<00575>>03360000
    I := ABS(ILTP+ISIOP)+SYSDB;                                <<00575>>03362000
    IF ABS(I+MIO'LDEV).(8:8) = P2 AND                          <<00575>>03364000
       ABS(I+MIO'ENABLE) = "OK" THEN                           <<00575>>03366000
       IOTABLEINFO := 1;   <<SET TRUE>>                        <<00575>>03368000
  END;                                                         <<00575>>03370000
END;                                                           <<00575>>03372000
$PAGE "OUTER BLOCK"                                            <<00136>>03374000
$CONTROL SEGMENT=MAIN                                          <<00136>>03376000
END.    << NON RESIDENT I/O SERVICE ROUTINES >>                <<00136>>03378000
