$CONTROL MAP,CODE,USLINIT                                               00010000
<<IOCDRD0 - MODULE 20>>                                                 00015000
<< HP32002C MPE SOURCE C.00.00 >>                                       00020000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00025000
<<     THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A       >>  00030000
<<     TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR     >>  00035000
<<     STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION >>  00040000
<<     OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED   >>  00045000
<<     WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY.>>  00050000
<< **** Note - Dollar Copyright cannot be used with this module *** >>  00055000
$TITLE "DEC 26,1975   CARD READER DRIVER  -  IOCDRD0(20)"               00060000
$CONTROL PRIVILEGED,UNCALLABLE,MAIN=IOCDRD0                             00065000
$THIRTY                                                                 00070000
                                                                        00075000
  <<                                                                    00080000
     CARD READER  REQUEST CODES -                                       00085000
                                                                        00090000
  OPERATION         FUNC         PARAMETERS                             00095000
                                                                        00100000
    READ             0    P1 - END OF FILE SPECIFICATION                00105000
                                                                        00110000
                          P2.(11:2) - DATA MODE                         00115000
                                                                        00120000
                                0 - PACKED ASCII                        00125000
                                     COUNT TRUNCATED TO 80 BYTES MAX    00130000
                                1 - COLUMN BINARY                       00135000
                                     COUNT TRUNCATED TO 80 WORDS MAX    00140000
                                                                        00145000
  ALL ODD BYTE COUNTS ARE ROUNDED UP TO AN EVEN NUMBER                  00150000
                                                                        00155000
                                                                        00160000
                                                                        00165000
  FILE  OPEN         2    NO OPERATION                                  00170000
  FILE  CLOSE        3    NO OPERATION                                  00175000
  DEVICE CLOSE       4    CLEAR EOF STATUS IN LPDT                      00180000
                                                                        00185000
                                                                        00190000
    STATUS  RETURNS -                                                   00195000
                                                                        00200000
       01  - NORMAL COMPLETION                                          00205000
                                                                        00210000
       33  - REQUEST ABORTED EXTERNALLY                                 00215000
       63  - REQUEST ABORTED BECAUSE OF POWER FAILUE                    00220000
                                                                        00225000
       04  - INVALID REQUEST, FUNCTION OR PARAMETER                     00230000
       44  - START SIO FAILURE                                          00235000
      124  - NO MESSAGE LINK BUFFERS AVAILABLE                          00240000
  >>                                                                    00245000
                                                                        00250000
                                                                        00255000
                                                                        00260000
                                                                        00265000
BEGIN                                                                   00270000
$PAGE                                                                   00275000
                                                                        00280000
  EQUATE                                                                00285000
    BANKN     = 3,         << BANK NUMBER IN SIO PROGRAM >>             00290000
    BUFADR    = 5,         << BUFFER ADDRESS IN SIO PROGRAM >>          00295000
    BUFBASE   =%1010,      << OFFSET TO ADDRESS AUX READ BUFFER >>      00300000
    DWCNT     = 8,         << HOLDS REQUESTED WORD COUNT >>             00305000
    CRDITSIZE = 10,        << CARD READER DIT SIZE >>          <<01340>>00310000
    CRSIOSIZE = 48,        << INCLUDES AUXILLARY READ BUFFER >>         00315000
    CRSIOSIZED2 = CRSIOSIZE/2,  << SIOSIZE/2 FOR INITIAL >>    <<01300>>00320000
    OPCONSOLE = 0,         << OUTPUT MESSAGE TO OPERATOR >>             00325000
    ABORTED   =%33,        << REQUEST ABORTED RETURN STATUS >>          00330000
    CNTRL     =%40000,     << SIO CONTROL ORDER >>                      00335000
    DCLOSE    = 4,         << DEVICE CLOSE FUNCTION CODE >>             00340000
    DDP       = 9,         << DIT DRIVER DEPENDENT WORD >>     <<01383>>00345000
    DLDEV     = 3,         << LOGICAL DEVICE AND UNIT NUMBERS >>        00350000
    DLOGERROR =  9,        << ERROR LOG STATUS >>              <<01340>>00355000
    DSERR     = 7,         << HARDWARE I/O ERROR STATUS IN DIT >>       00360000
    DSTAT     = 6,         << LAST HARDWARE INTERRUPT STATUS >>         00365000
    FOPEN     = 2,         << FOPEN FUNCTION CODE >>                    00370000
    GOODIO    = 1,         << SUCCESSFUL I/O STATUS RETURN >>           00375000
    INTRPTWAIT=%13,        << WAIT FOR COMPLETION DRIVER RETURN >>      00380000
    INVALIDOP = 4,         << INVALID OPERATION REQUESTED >>            00385000
    NOTRDYMSG = 11,        << NOT READY MESSAGE NUMBER TO MESS PROC >>  00390000
    NOTREADY  = 7,         << NOT READY DRIVER RETURN CODE >>           00395000
    PFABORT   =%63,        << REQUEST ABORTED BECAUSE OF POWERFAIL >>   00400000
    QFUNC     = 6,         << FUNCTION  >>                              00405000
    QMISC     = 3,         << MISCELLANEOUS STORAGE >>                  00410000
    QPAR2     = 9,         << READ STOP CHAR; WRITE PRESPACE FLAG >>    00415000
    QWBCT     = 7,         << WORD (+) OR BYTE (-) COUNT >>             00420000
    QSTAT     =10,         << REQUEST STATUS AND PCB NUMBER >>          00425000
    RDCHKMSG  = 17,        <<READ CHECK MSG. NO.>>             <<00430>>00430000
    READORDER = 4,         << READ ORDER IN SIO PROGRAM >>              00435000
    REQUESTDONE= 5,        << REQUEST COMPLETED DRIVER RETURN CODE >>   00440000
    SETBANK   =%14000,     << SIO SET BANK ORDER >>                     00445000
    SIOFAIL   =%44,        << START SIO FAILURE >>                      00450000
    SIOENDI   =%34000,     << SIO END ORDER WITH INTERRUPT >>           00455000
    SIOREAD1  =%77777,     << SIO READ OF ONE WORD >>                   00460000
    SYSERROR  =%124,       << SYSTEM ERROR REQUEST STATUS RETURN CODE >>00465000
    SYSLPDT   =%10,        << LOGICAL PHYSICAL DEVICE TABLE >>          00470000
    UFAILMSG  = 208,       <<UNIT FAILURE MSG. NO.>>           <<00430>>00475000
  ENDEQ       = 0;                                                      00480000
                                                                        00485000
                                                                        00490000
  DEFINE                                                                00495000
    ASMB      = ASSEMBLE#,                                              00500000
    ASCII     =NOT LOGICAL(DATAMODE)#, << ASCII READ MODE REQUESTED >>  00505000
    BADHOLLERITH=(11:1)#,  << INVAILD HOLLERITH STATUS >>               00510000
    DLDEVN    =(8:8)#,     << LOGICAL DEVICE NUMBER OF DIT >>           00515000
    EOFBIT    =( 8:1)#,    << END OF FILE STATUS BIT >>                 00520000
    EOF       =( 7:3)#,    << EOF STATE IN LPDT >>                      00525000
    FUNC      =( 8:8)#,    << QFUNC, FUNCTION CODE >>                   00530000
    HESF     =(10:1)#,    <<HOPPER EMPTY OR STACKER FULL>>     <<00523>>00535000
    IOSTAT    =( 8:8)#,    << TOTAL REQUEST STATUS RETURNED >>          00540000
    LOADMEMORY=ASSEMBLE( LSEA )#,                                       00545000
    NRDY     =(15:1)#,    <<NOT READY OR OFFLINE>>             <<00523>>00550000
    NRMESSAGE = (9:1)#,<< DIT0.(9:1) NOT READY MESSAGE ISSUED ><<01383>>00555000
    PFAIL     =(11:1)#,    << ABORT SET BECAUSE OF POWER FAIL >>        00560000
    RDCHK     =(4:1)#,     <<LIGHT/DARK CHECK STATUS BIT>>     <<00430>>00565000
    READDONE  =( 9:1)#,    << AUX BUF HOLDS CARD AFTER EOF RETURNED >>  00570000
    SFAIL     =(10:1)#,    << FAILURE ON DELAYED START SIO >>           00575000
    SUBTYPE   =(12:4)#,                                        <<00877>>00580000
    TROUBLE   =(14:1)#,   <<TIMING,LIGHT,COMPARE,HOPPER,HOLLERITH,PICK>>00585000
    ENDDEF    = 0#;                                                     00590000
$PAGE                                                                   00595000
                                                                        00600000
    LOGICAL LS0 = S-0,  LX = X;                                         00605000
    INTEGER S0 = S-0, S1 = S-1, X = X;                                  00610000
    DOUBLE ARRAY LPDTD(@) = DB + SYSLPDT;                               00615000
                                                                        00620000
                                                                        00625000
                                                                        00630000
                                                                        00635000
     << DIT DEFINITION AND DRIVER LINKAGE AREA  >>                      00640000
                                                                        00645000
BYTE ARRAY  DLT(0:7) = DB :=                                            00650000
 CRDITSIZE, 1, 0, 0, 0, 0, CRSIOSIZED2, 0; << TYPE 1 MONITOR >><<01300>>00655000
                                                                        00660000
ARRAY DIT( 1:CRDITSIZE) = DB :=                                         00665000
  0, 0, 0, 0, 0, 0, 0, 0, 0,                                   <<01340>>00670000
  0;   <<DLOGERROR>>                                           <<01340>>00675000
                                                                        00680000
ARRAY SIOA(1:CRSIOSIZE) = DB :=                                         00685000
  CNTRL,     0, SETBANK,0,    << SET DATA MODE AND BUFFER BANK >>       00690000
  SIOREAD1,  0,    << MAIN BLOCK READ >>                                00695000
  SIOENDI,   0;                                                         00700000
                                                                        00705000
                                                                        00710000
    <<------------ EXTERNAL PROCEDURE DECLARATIONS -------------->>     00715000
                                                                        00720000
PROCEDURE EOFCHECK(IOQP,BUFR,COUNT,BLANK);                              00725000
  VALUE IOQP, BUFR, COUNT, BLANK;   POINTER IOQP;                       00730000
  INTEGER COUNT;  LOGICAL BLANK;                                        00735000
  DOUBLE  BUFR;      OPTION EXTERNAL;                                   00740000
                                                                        00745000
PROCEDURE  GIP;   OPTION EXTERNAL;                                      00750000
                                                                        00755000
PROCEDURE HELP;   OPTION EXTERNAL;                                      00760000
                                                                        00765000
LOGICAL PROCEDURE IOMESSAGE(SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,   <<0U.EB>>00770000
   DEST,REPLY,OFFSET,DITP,IOTYPE);                             <<0U.EB>>00775000
VALUE SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,DEST,REPLY,OFFSET,DITP,  <<0U.EB>>00780000
   IOTYPE;                                                     <<0U.EB>>00785000
INTEGER SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,DEST,REPLY,OFFSET,     <<0U.EB>>00790000
   IOTYPE;                                                     <<0U.EB>>00795000
INTEGER POINTER DITP;                                          <<0U.EB>>00800000
OPTION VARIABLE,EXTERNAL;                                      <<0U.EB>>00805000
                                                                        00810000
PROCEDURE MASTERCLEAR(DITP);                                            00815000
  ARRAY DITP;  OPTION EXTERNAL;                                         00820000
                                                                        00825000
PROCEDURE SIODM(DITP,FLAGS);                                            00830000
  VALUE DITP, FLAGS;   LOGICAL FLAGS;                                   00835000
  POINTER DITP;    OPTION  EXTERNAL;                                    00840000
                                                                        00845000
PROCEDURE STARTIO(DITP,SIOP,QFLAG);                                     00850000
  VALUE  DITP, SIOP, QFLAG;     LOGICAL QFLAG;                          00855000
  POINTER DITP, SIOP;    OPTION EXTERNAL;                               00860000
$PAGE  "CARD READER DRIVER PROCEDURE - CRDRVR"                          00865000
                                                                        00870000
INTEGER PROCEDURE CRDRVR(IOQP,DITP,BANK,BUFADDR,SIOP,DRTNUMB);          00875000
  <<                                                                    00880000
     THIS PROCEDURE INITIATES AND COMPLETES I/O FOR CARD READERS        00885000
                                                                        00890000
    MODE RETURNS IN CRDRVR -                                            00895000
                                                                        00900000
        5  - REQUEST COMPLETED                                          00905000
        7  - NOT READY WAIT                                             00910000
      %13  - INTERRUPT WAIT OR WAIT FOR COMPLETION                      00915000
  >>                                                                    00920000
                                                                        00925000
  VALUE  DRTNUMB, BANK, BUFADDR;                                        00930000
  INTEGER  BANK, BUFADDR, DRTNUMB;                                      00935000
  INTEGER  ARRAY IOQP, DITP, SIOP;                                      00940000
  OPTION PRIVILEGED, UNCALLABLE;                                        00945000
  BEGIN                                                                 00950000
    INTEGER LDEV      = Q+1;  << LOGICAL DEVICE NUMBER >>               00955000
    INTEGER DATAMODE  = LDEV+1;  << HOLDS DATA READ MODE >>             00960000
    DOUBLE AUXBUFADDR = DATAMODE+1;  << CARD SAVING BUF ADDRESS >>      00965000
    INTEGER WCNT      = AUXBUFADDR+2;  << WORD CNT FOR CONV. >><<00877>>00970000
         INTEGER MODE = CRDRVR;  << CURRENT REQUEST STATE >>            00975000
                                                                        00980000
                                                                        00985000
    DOUBLE POINTER SIOPD = Q-5;                                         00990000
                                                                        00995000
    LOGICAL ARRAY                                                       01000000
      DITPL(*)           = DITP,                                        01005000
      IOQPL(*)           = IOQP;                                        01010000
                                                                        01015000
    DOUBLE BUFADDRD      = Q- 7;  << BANK AND OFFSET >>                 01020000
                                                                        01025000
    ARRAY MAXCOUNT(0:1) = PB := 40,80;  << MAX TRANSFER ALLOWED >>      01030000
    ARRAY CONTROLWORD(0:1) =PB := %12,5; << ASCII/COL BINARY CNTRL >>   01035000
                                                                        01040000
    INTEGER ARRAY KARDIN(0:255)= PB :=                         <<00877>>01045000
      << KARD TO JIS8 CONVERSION TABLE >>                      <<00877>>01050000
      %000,%001,%002,%003,%004,%005,%006,%007,                 <<00877>>01055000
      %010,%011,%012,%013,%014,%015,%016,%017,                 <<00877>>01060000
      %020,%021,%022,%023,%024,%025,%026,%027,                 <<00877>>01065000
      %030,%031,%032,%033,%034,%035,%036,%037,                 <<00877>>01070000
      %040,%041,%042,%043,%044,%045,%046,%047,                 <<00877>>01075000
      %050,%051,%052,%053,%054,%055,%056,%057,                 <<00877>>01080000
      %060,%061,%062,%063,%064,%065,%066,%067,                 <<00877>>01085000
      %070,%071,%072,%073,%074,%075,%076,%077,                 <<00877>>01090000
      %100,%101,%102,%103,%104,%105,%106,%107,                 <<00877>>01095000
      %110,%111,%112,%113,%114,%115,%116,%117,                 <<00877>>01100000
      %120,%121,%122,%123,%124,%125,%126,%127,                 <<00877>>01105000
      %130,%131,%132,%133,%134,%135,%136,%137,                 <<00877>>01110000
      %140,%261,%262,%263,%264,%265,%266,%267,                 <<00877>>01115000
      %270,%271,%300,%301,%302,%303,%304,%305,                 <<00877>>01120000
      %306,%307,%310,%315,%316,%317,%320,%321,                 <<00877>>01125000
      %322,%323,%324,%173,%174,%175,%176,%177,                 <<00877>>01130000
      %200,%201,%202,%203,%204,%205,%206,%207,                 <<00877>>01135000
      %210,%211,%212,%213,%214,%215,%216,%217,                 <<00877>>01140000
      %220,%221,%222,%223,%224,%225,%226,%227,                 <<00877>>01145000
      %230,%231,%232,%233,%234,%235,%236,%237,                 <<00877>>01150000
      %241,%242,%243,%244,%245,%246,%247,%250,                 <<00907>>01155000
      %251,%252,%253,%254,%255,%256,%257,%240,                 <<00907>>01160000
      %260,%141,%142,%143,%144,%145,%146,%147,                 <<00877>>01165000
      %150,%151,%156,%160,%161,%162,%165,%164,                 <<00877>>01170000
      %152,%153,%154,%155,%272,%157,%273,%274,                 <<00877>>01175000
      %275,%276,%277,%311,%166,%163,%312,%313,                 <<00877>>01180000
      %314,%167,%325,%171,%326,%327,%330,%331,                 <<00877>>01185000
      %172,%170,%342,%343,%344,%345,%346,%347,                 <<00877>>01190000
      %340,%341,%332,%333,%334,%335,%336,%337,                 <<00877>>01195000
      %350,%351,%352,%353,%354,%355,%356,%357,                 <<00877>>01200000
      %360,%361,%362,%363,%364,%365,%366,%367,                 <<00877>>01205000
      %370,%371,%372,%373,%374,%375,%376,%377;                 <<00877>>01210000
                                                               <<00877>>01215000
                                                                        01220000
                                                                        01225000
   <<------------ BEGIN CARD READER DRIVER -------------->>             01230000
                                                                        01235000
    TOS := DITP(DLDEV).DLDEVN;   << SET LDEV >>                         01240000
    TOS := IOQP(QPAR2).(11:2);   << SET DATA MODE >>                    01245000
    TOS := DOUBLE(@SIOP+BUFBASE);   << SET AUXBUFADDR >>                01250000
    TOS := 0;                        << SET WORD COUNTER >>    <<00877>>01255000
                                                                        01260000
    TOS := IOQP;    << GET QFLAGS >>                                    01265000
    IF < THEN   << REQUEST ABORTED >>                                   01270000
      BEGIN                                                             01275000
        MASTERCLEAR(DITP);                                              01280000
                                                                        01285000
        TOS := IF IOQPL.PFAIL THEN PFABORT ELSE ABORTED;                01290000
        GOTO CLEARCOUNT;                                                01295000
        HELP;   << FOR LINKAGE ******************************>>         01300000
      END;                                                              01305000
                                                                        01310000
    IF DITPL.NRMESSAGE AND NOT DITPL(DSTAT) THEN                        01315000
      DITP.NRMESSAGE := 0;   << CARD READER READY >>                    01320000
                                                                        01325000
    IF MODE<>2 THEN GOTO COMPLETOR;                                     01330000
                                                                        01335000
    X := IOQP(QFUNC).FUNC;                                              01340000
    IF <> THEN  << NOT A READ REQUEST >>                                01345000
      BEGIN                                                             01350000
        IF NOT(FOPEN<=X<=DCLOSE) THEN GOTO BADCALL; << BAD FUNCTION >>  01355000
        X := X - DCLOSE;                                                01360000
        IF = THEN   << DCLOSE, CLEAR EOF STATE >>                       01365000
          BEGIN                                                         01370000
            TOS := LPDTD(LDEV);                                         01375000
            TOS.EOF := 0;                                               01380000
            LPDTD( X ) := TOS;                                          01385000
          END;                                                          01390000
        GOTO GOODDONE;                                                  01395000
      END;                                                              01400000
                                                                        01405000
    IF DITPL(DSTAT).EOFBIT THEN  << HARDWARE EOF >>                     01410000
      BEGIN                                                             01415000
        TOS := LPDTD(LDEV);                                             01420000
        TOS.EOF := 1;                                                   01425000
        LPDTD( X ) := TOS;                                              01430000
      END;                                                              01435000
                                                                        01440000
    EOFCHECK(IOQP, 0D, 0, 0);                                           01445000
    IF <> THEN GOTO IODONE;   << END OF FILE >>                         01450000
                                                                        01455000
    IF DATAMODE>1 THEN   << INVALID MODE SPECIFICATION >>               01460000
      BEGIN                                                             01465000
BADCALL:                                                                01470000
        TOS := INVALIDOP;                                               01475000
        GOTO CLEARCOUNT;                                                01480000
      END;                                                              01485000
                                                                        01490000
FORMCOUNT:                                                              01495000
    TOS := MAXCOUNT(DATAMODE);                                          01500000
    TOS := IOQP(QWBCT);                                                 01505000
    IF < THEN TOS := -(TOS&ASR(1));  << CONVERT TO WORDS >>             01510000
                                                                        01515000
    ASMB(DDUP,CMP );                                                    01520000
    IF < THEN  << MAXIMUM < REQUESTED >>                                01525000
      BEGIN   << ROUND DOWN TO MAXIMUM >>                               01530000
        TOS := IOQP(X);  DDEL;  << GET SIGN OF ORGINAL COUNT >>         01535000
        IF < THEN TOS := -TOS&ASL(1);  << FORM BYTE COUNT >>            01540000
        IOQP(X) := TOS;   << SET UPDATED COUNT >>                       01545000
        GOTO FORMCOUNT;    << GO FORM WORD COUNT >>                     01550000
      END;                                                              01555000
                                                                        01560000
    DITP(DWCNT) := S0;  << SAVE REQUESTED WORD COUNT >>                 01565000
                                                                        01570000
    DITP(DDP).READDONE := 0;                                   <<01383>>01575000
    IF <> THEN     << CARD ALREADY READ & ASCII REQUESTED >>            01580000
      BEGIN                                                             01585000
        IF LOGICAL(DATAMODE) THEN   << BINARY AND CARD READ IN ASCII >> 01590000
          GOTO BADCALL;                                                 01595000
        TOS := 1;   << TO INDICATE AUX BUFFER READ >>                   01600000
        GOTO CHECKDATA;   << MOVE DATA TO USER FROM AUXILLARY BUFFER >> 01605000
      END;                                                              01610000
                                                                        01615000
    TOS := -TOS;   << MAKE WORD COUNT NEGATIVE >>                       01620000
    IF S0>-40 THEN                                                      01625000
      BEGIN   << READ 40 WORDS INTO AUXILLARY FOR BACKUP >>             01630000
        IOQP(QMISC) := 1;   << SET AUXILLARY BUFFER FLAG >>             01635000
        TOS := -40;                                                     01640000
        TOS := AUXBUFADDR;   << ADDRESS OF SAVE BUFFER >>               01645000
      END                                                               01650000
    ELSE TOS := BUFADDRD;                                               01655000
                                                                        01660000
    SIOP(BUFADR) := TOS;     << BUFFER ADDRESS >>                       01665000
    SIOP(BANKN) := TOS;     << SET MAIN BLOCK BANK NUMBER >>            01670000
                                                                        01675000
    TOS.(0:1) := 0;     << FORM READ ORDER FROM NEG WORD COUNT >>       01680000
    SIOP(READORDER) := TOS;     << SET MAIN BLOCK READ ORDER >>         01685000
                                                                        01690000
    SIOP(1) := CONTROLWORD(DATAMODE);  << ASCII/BINARY READ >>          01695000
    STARTIO(DITP,SIOP,TRUE);                                            01700000
    IF > THEN        << READER NOT READY? >>                            01705000
SIOFAILURE:                                                             01710000
      IF DITPL(DSTAT) THEN GOTO NOTRDY ELSE                             01715000
        BEGIN  << SIO FAILURE >>                                        01720000
          TOS := SIOFAIL;                                               01725000
          GOTO BADIO;                                          <<00.05>>01730000
        END;                                                            01735000
                                                                        01740000
    TOS := INTRPTWAIT;                                                  01745000
    GOTO OUT;                                                           01750000
                                                                        01755000
                                                                        01760000
COMPLETOR:                                                              01765000
    IF TOS.SFAIL THEN GOTO SIOFAILURE; << START SIO FAIL ELSEWH<<00.05  01770000
                                                               <<00.05>>01775000
    IF DITPL(DSTAT).TROUBLE THEN                                        01780000
      BEGIN                                                             01785000
        IF DITPL(X).BADHOLLERITH THEN                                   01790000
          BEGIN                                                         01795000
            TOS := SIOP(BANKN);                                         01800000
            TOS := SIOP(BUFADR);  << GET BANK AND OFFSET >>             01805000
                                                                        01810000
            X := 0;                                                     01815000
            WHILE (X:=X+1)<=80 DO                                       01820000
              BEGIN                                                     01825000
                LOADMEMORY;                                             01830000
                IF LX THEN TOS := TOS&LSR(8)  << GET LEFT BYTE >>       01835000
                  ELSE ASMB(INCB     );  << BUMP WORD ADDRESS >>        01840000
                                                                        01845000
                IF TOS.(8:8)=%32 THEN  << INVALID CODE FOUND >>         01850000
                  IF IOMESSAGE(1,12,%11000,LDEV,X,,,,          <<0U.EB>>01855000
                     OPCONSOLE) THEN                           <<0U.EB>>01860000
                    GOTO NRWAIT << INVALID HOLLERITH MESSAGE ISSUED >>  01865000
                      ELSE GOTO SYSERR;                                 01870000
              END;                                                      01875000
          END;                                                          01880000
                                                                        01885000
        TOS := DITPL(X) LAND %14400; <<CHECK TIMING,LIGHT/DARK,COMPARE>>01890000
        IF <> THEN     <<ERROR, SET UP MESSAGE>>               <<00430>>01895000
          BEGIN                                                         01900000
            DITP(DSERR):= [8/1,8/DLOGERROR];                   <<01340>>01905000
            DITP(DLOGERROR):= DITP(DSTAT);  <<LOG ERROR>>      <<01340>>01910000
            IF TOS.RDCHK = 1   THEN  X := RDCHKMSG             <<00430>>01915000
                               ELSE  X := UFAILMSG;            <<00430>>01920000
          END                                                           01925000
        ELSE                                                            01930000
NOTRDY:                                                                 01935000
          X := NOTRDYMSG;                                               01940000
                                                                        01945000
        DITP.NRMESSAGE := 1;  << SET MESSAGE ISSUED FLAG >>             01950000
        IF <> OR IOMESSAGE(1,X,%10000,LDEV,,,,,OPCONSOLE) THEN <<0U.EB>>01955000
          BEGIN  << ISSUE MESSAGE OR ALREADY ISSUED >>                  01960000
NRWAIT:                                                                 01965000
            TOS := NOTREADY;                                            01970000
            GOTO OUT;                                                   01975000
          END;                                                          01980000
                                                                        01985000
SYSERR:                                                                 01990000
        TOS := SYSERROR;  << NO MESSAGE LINK BUFFERS >>                 01995000
                                                                        02000000
BADIO:                                                         <<00.05>>02005000
       DITP(DSERR):= [8/1,8/DLOGERROR];                        <<01340>>02010000
       DITP(DLOGERROR):= DITP(DSTAT);    << LOG ERROR >>       <<01340>>02015000
        MASTERCLEAR(DITP);                                     <<00.05>>02020000
                                                                        02025000
CLEARCOUNT:                                                             02030000
        IOQP(QWBCT) := 0;                                               02035000
        GOTO SETSTATUS;                                                 02040000
      END;                                                              02045000
                                                                        02050000
      <<IF HOPPER EMPTY/STACKER FULL AND DEVICE READY>>        <<00523>>02055000
      <<THEN STACKER FULL OR HOPPER EMPTY MICROSWITCH>>        <<00523>>02060000
      <<IS STICKING.  NOTIFY THE OPERATOR.>>                   <<00523>>02065000
    IF DITPL(DSTAT).HESF LAND NOT DITPL(DSTAT).NRDY  THEN      <<00523>>02070000
    BEGIN                                                      <<00523>>02075000
      IOMESSAGE(1,209,%10000,LDEV,,,,,OPCONSOLE);              <<00523>>02080000
       DITP(DSERR):= [8/1,8/DLOGERROR];                        <<01340>>02085000
       DITP(DLOGERROR):= DITP(DSTAT);    << LOG ERROR >>       <<01340>>02090000
    END;                                                       <<00523>>02095000
                                                               <<00523>>02100000
    TOS := IOQP(QMISC);   << AUXILLARY BUFFER FLAG >>                   02105000
                                                                        02110000
CHECKDATA:                                                              02115000
    EOFCHECK(IOQP,IF LS0 THEN AUXBUFADDR ELSE BUFADDRD,40,              02120000
                  IF ASCII THEN 1 ELSE -1);                             02125000
                                                                        02130000
    IF TOS THEN     << READ INTO AUXILLARY BUFFER >>                    02135000
      BEGIN                                                             02140000
        IF = THEN  << NO EOF >>                                         02145000
          BEGIN  << MOVE DATA TO USERS BUFFER >>                        02150000
            TOS := BUFADDRD;                                            02155000
            TOS := AUXBUFADDR;                                          02160000
            TOS := DITP(DWCNT);  << WORD COUNT TO MOVE >>               02165000
            ASMB( MABS );                                               02170000
            GOTO GOODDONE;                                              02175000
          END;                                                          02180000
                                                                        02185000
        IF < THEN GOTO SETREADDONE;     << BACK UP CARD >>              02190000
      END                                                               02195000
                                                                        02200000
    ELSE IF < THEN   << READ TO USER BUFFER AND BACK UP >>              02205000
      BEGIN  << BACK UP, SO SAVE DATA IN AUX BUFFER >>                  02210000
        TOS := AUXBUFADDR;                                              02215000
        TOS := BUFADDRD;                                                02220000
        TOS := 40;                                                      02225000
        ASMB( MABS 1 );  << LEAVE SOURCE ADDRESS ON TOS >>              02230000
                                                                        02235000
        X := DITP(DWCNT);                                               02240000
        DO BEGIN  << BLANK USER'S BUFFER >>                             02245000
             TOS := TOS-1;   TOS := 0;                                  02250000
             ASMB( SSEA );                                              02255000
           END                                                          02260000
        UNTIL DXBZ;                                                     02265000
                                                                        02270000
SETREADDONE:                                                            02275000
        IF ASCII THEN DITP(DDP).READDONE := 1;                 <<01383>>02280000
      END                                                               02285000
    ELSE IF = THEN   << NO EOF >>                                       02290000
      BEGIN                                                             02295000
GOODDONE:                                                               02300000
        X := IOQP(QFUNC).FUNC;       << I/O REQUEST TYPE >>    <<00877>>02305000
        IF <> THEN GOTO CONVERTDONE; << NOT READ REQUEST >>    <<00877>>02310000
        TOS := LPDTD(LDEV);          << GET SUBTYPE >>         <<00877>>02315000
        DELB;                        << STACK ERASE >>         <<00877>>02320000
        IF TOS.SUBTYPE=1 AND ASCII THEN                        <<00877>>02325000
        BEGIN                        << KATAKANA CHAR >>       <<00877>>02330000
           WCNT := 0;                << WCNT INITIALIZE >>     <<00877>>02335000
           WHILE WCNT < INTEGER (DITP(DWCNT)) DO               <<00877>>02340000
           BEGIN                     << START CONVERT & MOVE >><<00877>>02345000
              TOS := BUFADDRD;       << LOAD BUFADDRD >>       <<00877>>02350000
              TOS := TOS+WCNT;       << ADDR OF CONVERT DATA >><<00877>>02355000
              ASMB(LSEA);            << LOAD DATA >>           <<00877>>02360000
              ASMB(DELB,DELB);       << CLEAR ADDR ON STACK >> <<00877>>02365000
              ASMB(DUP);                                       <<00877>>02370000
              ASMB(ANDI 255);        << RIGHT BYTE >>          <<00877>>02375000
              X := TOS;                                        <<00877>>02380000
              TOS := KARDIN(X);      << CONVERT TO JIS8 >>     <<00877>>02385000
              ASMB(XCH);             << NEXT BYTE >>           <<00877>>02390000
              TOS := TOS & LSR(8);   << LEFT BYTE >>           <<00877>>02395000
              X := TOS;                                        <<00877>>02400000
              TOS := KARDIN(X);      << CONVERT TO JIS8 >>     <<00877>>02405000
              TOS := TOS & LSL(8);   << SHIFT TO LEFT >>       <<00877>>02410000
              ASMB(OR);              << MERGE R. AND L. BYTE >><<00877>>02415000
              TOS := BUFADDRD;                                 <<00877>>02420000
              TOS := TOS+WCNT;       << CONVERTED DATA ADR >>  <<00877>>02425000
              ASMB(CAB;SSEA;DDEL);   << MOVE AND CLEAR ADDR >> <<00877>>02430000
              WCNT := WCNT+1;        << UPDATE WORD COUNTER >> <<00877>>02435000
           END;                                                <<00877>>02440000
        END;                                                   <<00877>>02445000
CONVERTDONE:                                                   <<00877>>02450000
                                                               <<00877>>02455000
                                                               <<00877>>02460000
        TOS := GOODIO;                                                  02465000
                                                                        02470000
SETSTATUS:                                                              02475000
        IOQP(QSTAT).IOSTAT := TOS;                                      02480000
      END;                                                              02485000
                                                                        02490000
IODONE:                                                                 02495000
    TOS := REQUESTDONE;                                                 02500000
                                                                        02505000
OUT:                                                                    02510000
    CRDRVR := TOS;                                                      02515000
                                                                        02520000
  END;      <<----  C R D R V R ------- >>                              02525000
                                                                        02530000
                                                                        02535000
                                                                        02540000
                                                                        02545000
  <<*************** DRIVER LINKAGE AREA ******************>>            02550000
                                                                        02555000
                                                                        02560000
ASMB(                                                                   02565000
    PCAL SIODM;   << MONITOR   >>                                       02570000
    PCAL CRDRVR;  << INITIATOR >>                                       02575000
    PCAL CRDRVR;  << AND COMPLETOR >>                                   02580000
                                                                        02585000
    CON  0;       << NO IO PROCESS >>                                   02590000
                                                                        02595000
    CON  0;       << NO INITIALIZATION >>                               02600000
                                                                        02605000
    CON  1;       << ONE INTERRUPT HANDLER >>                           02610000
    PCAL GIP);    << INTERRUPT HANDLER >>                               02615000
                                                                        02620000
END.   << CARD READER DRIVER - IOCDRD0 >>                               02625000
