*DECK,    IORANDM 
          IDENT    IORANDM
          TITLE    IORANDM - FOR MACROS READIN, WRITOUT WITH RANDOM FILE
**DOCK    EJECT  4,10                                                   0125 738
**DOCK    TITLE  SPACE,4,10                                             0125 739
*     AUTHOR -- A.F.R.BROWN 
          SPACE    2
****
*     FUNCTION - IORANDM IS USED TO BEGIN READING OR BEGIN WRITING
*     A RECORD IN A RANDOM FILE. IF READING, IT GETS THE DISK ADDRESS 
*     FROM THE INDEX AND PUTS IT IN FET+6 TO FORCE A DEPARTURE
*     FROM CHAIN SEQUENCE. IF WRITING, IT PUTS THE ADDRESS OF THE 
*     PROPER INDEX LOCATION INTO FET+6, SO THAT WHEN THE BEGINNING
*     OF THE RECORD IS ACTUALLY WRITTEN, ITS DISK ADDRESS IS
*     INSERTED IN THE INDEX AUTOMATICALLY.
*     IORR AND IORW LOOK LIKE SUBROUTINES, AND RETURN JUMPS TO THEM 
*     ARE WHAT THE MACROS BECOME. BUT EACH OF THEM IMMEDIATELY
*     CALLS IOSAV (IN THE PROGRAM IO) WHICH SETS UP THE FINAL 
*     RETURN AT IORE, IN PROGRAM IO. THEN THE TRUE SUBROUTINES IORA 
*     AND IORB ARE CALLED, AND FINALLY WE BRANCH TO IOIO IN PROGRAM IO. 
*     RANDOM REWRITE FUNCTION (IORRW) IS ADDED. 
*     IN REWRITING, IT GETS THE DISK ADDRESS FROM THE INDEX 
*     AND PUTS IT INTO FET+6. 
          SPACE    2
*     ENTRY INFORMATION -- A CALLING SEQUENCE 
*        RJ  IORR,   RJ  IORW   OR   RJ  IORRW
*        VFD 60/FET 
*        VFD 60/RECNUM   OR    VFD 42/RECNAME,18/0
*     EXIT INFORMATION -- X1, ON RETURN FROM EXECUTING THE MACRO, 
*     CONTAINS 0 UNLESS A READ WAS CALLED FOR AND COULD NOT BE
*     FULLY CARRIED OUT. THEN X1 WILL CONTAIN THE ADDRESS OF THE
*     FIRST UNFILLED WORD IN THE WORKSPACE. IN THE CASE OF A BCD
*     FILE, THIS WILL NECESSARILY BE THE FIRST WORD OF THE WORKSPACE. 
          SPACE    2
*     REGISTERS USED -- A1, A6, X1, X6
          SPACE    2
*     OTHER PROGRAMS CALLED -- CPC
          SPACE    2
****
          ENTRY    IORR,IORW,IORRW
          EXT       CPC,CPC02,CPC999,IOIO,IOSAV,IOZW,IOZZ 
          EJECT 
**    SUBROUTINE IORR IS CALLED IN MACRO READIN FOR THE BEGINNING 
*     OF A RECORD IN A RANDOM FILE. FIRST IOSAV IS CALLED, WITH 2 IN
*     THE CALLING SEQUENCE TO SHOW THE CALLING SEQUENCE FOR IORR WAS
*     3 WORDS LONG. IOSAVE SAVES REGISTERS, SETS UP THE EXIT FOR
*     IORR AT IORE, SETS B1=1, A0=FET, AND X4= THE ADDRESS OF THE 
*     FIRST PARAMETER IN THE CALLING SEQUENCE TO IORR.
          SPACE    1
 IORR     DATA     0
          RJ       IOSAV           SETS A0=LFN
 -        JP       2
          SPACE    1
**    NOW CALL IORA TO CHECK THAT THE FET IS PLAUSIBLE, AND PUT THE 
*     INDEX LENGTH IN B6, ITS STARTING ADDRES IN B5, AND THE NUMBER 
*     OF THE RECORD MOST RECENTLY ADDRESSED IN B7, AND THEN TO WAIT 
*     TILL THE FILE IS NOT BUSY.
          RJ       IORA 
          SA1      A0+2 
          BX6      X1 
          SA6      A1+B1           SET OUT=IN 
**    NOW CALL IORB TO CONVERT THE RECORD NAME TO A NUMBER, IF
*     NECESSARY, LEAVING IT IN X1, AND ITS DISK ADDRESS FROM THE
*     INDEX IN X5.
          RJ       IORB            GET POINTER
          ZR        X1,IORER5A     NAME NOT IN INDEX
          SX0      10B
**    X0 WILL SHOW WE ARE READING AFTER WE BRANCH TO IOIO.
 IORRAB   SA1      IORN 
          ZR        X5,IORER5A          RECORD HAS NEVER BEEN WRITTEN 
IORRA     LX1      42 
          SA3      A0+7            PUT IN AS LAST RECORD NUMBER 
          MX6      18 
          BX6      -X6*X3 
          BX6      X1+X6
          SA6      A3 
**    HAVING INSERTED THE NEW RECORD NUMBER AS LAST RECORD NUMBER 
*     IN BITS 42-59 OF FET+7, WE SHALL NOW PUT THE DISK ADDRESS IN
*     BITS 0-23 OF FET+6 TO FORCE READING TO BEGIN THERE. THEN
*     BRANCH TO IOIO IN PROGRAM IO TO DO THE READING. 
          SA3      A3-B1
          MX6      36 
          BX5      -X6*X5 
          BX3      X6*X3
          BX6      X3+X5
          SA6      A6-B1           DISK ADDRESS 
          EQ       IOIO 
          EJECT 
**    SUBROUTINE IORW IS CALLED IN MACRO WRITOUT FOR THE BEGINNING
*     OR A RECORD IN A RANDOM FILE. FIRST IOSAVE IS CALLED, WITH 2
*     IN THE CALLING SEQUENCE TO SHOW THE CALLING SEQUENCE FOR IORW 
*     WAS 3 WORDS LONG. IOSAV SAVES REGISTERS, SETS UP THE EXIT FOR 
*     IORW AT IORE, AND SETS B1=1, A0=FET, AND X4=THE ADDRESS OF THE
*     FIRST PARAMETER IN THE CALLING SEQUENCE TO IORW.
          SPACE    1
 IORW     DATA     0
          RJ       IOSAV           SETS A0=LFN
 -        JP       2
          SPACE    1
**    NOW CALL IORA TO CHECK THAT THE FET IS PLAUSIBLE, AND PUT THE 
*     INDEX LENGTH IN B6, ITS STARTING ADDRESS IN B5, AND THE NUMBER
*     OF THE RECORD MOST RECENTLY ADDRESSED IN B7, AND THEN TO WAIT 
*     UNTIL THE FILE IS NOT BUSY. 
          RJ       IORA 
          SA1      A0 
**    NOW WE CHECK WHETHER THE FET SHOWS WRITE STATUS, BUT NOT END OF 
*     RECORD. IF NOT, GO TO IORWA, AND IF SO, WRITE END OF RECORD 
*     FIRST.
          SX6      774B 
          BX6      X1*X6
          SX6      X6-14B 
          NZ     X6,IORWAA         JUMP IF NOT WRITE
          RJ       CPC             END PREVIOUS RECORD WRITE
          DATA     03111720000000000024B
          EQ     IORWA
 IORWAA   SX6      X6-200B
          NZ     X6,IORWA 
          RJ     CPC               END PREVIOUS RECORD REWRITE
          DATA     03111720000000000224B
          SPACE    1
**    NOW WE SET THE STATUS OF THE FET TO WRITE COMPLETED, AND
*     THEN CALL IORB TO INVESTIGATE THE RECORD NAME OR NUMBER 
*     AND THE INDEX.
 IORWA    RJ     IORB 
**    IORB RETURNS EITHER A RECORD NUMBER IN X1, OR IF THE RECORD IS
*     IDENTIFIED BY NAME AND THE NAME IS NOT YET FOUND IN THE INDEX,
*     THE NUMBER OF THE FIRST FREE SLOT IN THE INDEX IS IN X4.
          NZ       X1,IORWB        RECORD NUMBER NOT 0
          ZR        X4,IORER6A     NO SLOT AVAILABLE IN INDEX 
          SX2      X4+B5           ADD INDEX START TO TWICE RECORD NUMB 
          IX2      X4+X2
          SA1      IORN 
          BX6      X1 
          SA6      X2-1            PUT NEW NAME IN INDEX
          BX1      X4 
 IORWB    SA5      B5              START OF INDEX 
**    THE FIRST WORD OF THE INDEX IS ZERO AS LONG AS THE INDEX IS 
*     EMPTY. THE FIRST TIME A RECORD ADDRESS IS STORED IN THE INDEX,
*     THE FIRST WORD OF THE INDEX IS SET POSITIVE NONZERO IF THE
*     RECORD WAS IDENTIFIED BY NUMBER, OR NEGATIVE IF BY NAME.
*     IF THE FIRST RECORD IS WRITTEN BY NUMBER, NO RECORDS CAN BE 
*     WRITTEN BY NAME THEREAFTER. BUT THE CONVERSE IS NOT TRUE. 
          SX2      X1+B5
          PL       X5,IORWC 
          IX2      X2+X1
 IORWC    SX5      X2 
          SX0      14B
          SA3    A0 
          SX6    774B 
          BX3    -X6*X3 
          BX6    X3+X0
          SA6    A0 
          EQ       IORRA
**    WE HAVE SET X5 TO THE ADDRESS OF THE WORD IN THE INDEX
*     WHERE THE DISK ADDRESS OF THE RECORD IS TO BE STORED. 
*     THE 14B IN X0 WILL IDENTIFY THE ACTION AS WRITING, NOT READING, 
*     WHEN WE BRANCH TO IOIO IN PROGRAM IO. THEN WE BRANCH BACK TO
*     IORRA TO INSERT THE RECORD NUMBER AS ((LAST RECORD NUMBER)) 
*     IN FET+7, AND THE ADDRESS OF THE INDEX WORD IN FET+6. FROM
*     THERE WE BRANCH TO IOIO TO BEGIN FILLING THE BUFFER AND 
*     WRITING.
          SPACE    2
**    IORN IS USED HERE AND THERE TO HOLD THE CURRENT RECORD NUMBER 
*     OR NAME.
          SPACE    2
 IORN     DATA     0
          EJECT 
**    SUBROUTINE IORRW IS CALLED IN MACRO WRITIN FOR THE BEGINNING
*     OF A RECORD IN A RANDOM FILE, FIRST IOSAV IS CALLED, WITH 2 IN
*     THE CALLING SEQUENCE TO SHOW THE CALLING SEQUENCE FOR IORRW 
*     WAS 3 WORDS LONG.  IOSAV SAVES REGISTERS, SETS UP THE EXIT FOR
*     IORRW AT IORE, AND SETS B1=1, A0=FET, AND X4= THE ADDRESS 
*     OF THE FIRST PARAMETER IN THE CALLING SEQUENCE TO IORRW.
  
IORRW     DATA   0
          RJ   IOSAV               SETS A0=LFN
-         JP   2
  
**    NOW CALL IORA TO CHECK THAT THE FET IS PLAUSIBLE, AND PUT 
*     THE INDEX LENGTH IN B6, ITS STARTING ADDRESS IN B5, AND 
*     THE NUMBER OF THE RECORD MOST RECENTLY ADDRESSED IN B7, 
*     AND THEN TO WAIT UNTIL THE FILE IS NOT BUSY.
  
          RJ   IORA 
          SA1    A0 
  
**    NOW WE CHECK WHETHER THE FET SHOWS WRITE OR REWRITE STATUS, 
*     BUT NOT END OF RECORD, IF NOT, GO TO IORRWA, AND IF SO, 
*     WRITE OR REWRITE END OF RECORD FIRST. 
  
          SX6    774B 
          BX6    X1*X6
          SX6    X6-14B 
          NZ   X6,IORRWAA 
          RJ   CPC                 END PREVIOUS RECORD WRITE
          DATA   03111720000000000024B
          EQ   IORRWA 
IORRWAA   SX6    X6-200B
          NZ   X6,IORRWA
          RJ   CPC                 END PREVIOUS RECORD REWRITE
          DATA   03111720000000000224B
  
**    NOW WE SET THE STATUS OF THE FET TO REWRITE COMPLETED,
*     AND THEN CALL IORB TO INVESTIGATE THE RECORD NAME OR NUMBER 
*     AND THE INDEX, AND TO GET ITS DISK ADDRESS FROM THE INDEX IN X5.
  
IORRWA    SA1    A0 
          SX6    774B 
          BX1    -X6*X1 
          SX6    214B 
          BX6    X1+X6
          SA6    A1 
          RJ   IORB                GET POINTER
  
**    NOW WE BRANCH TO IORRAB TO SET FET FOR REWRITING, 
*     FROM THERE WE BRANCH TO IOIO TO BEGIN FILLING THE BUFFER
*     AND REWRITING.
  
          ZR   X1,IORER5A          NAME NOT IN INDEX
          SX0    214B 
**    X0 WILL SHOW WE ARE REWRITING AFTER WE BRANCH TO IOIO.
          EQ   IORRAB 
          EJECT 
**    SUBROUTINE IORA IS USED TO CHECK THE FET OF A FILE FOR
*     PLAUSIBILITY AS A RANDOM FILE, TO PUT THE INDEX LENGTH
*     IN B6, ITS START IN B5, AND THE LAST RECORD NUMBER IN B7, 
*     AND TO WAIT TILL THE FILE IS NOT BUSY.
          SPACE    1
**    ENTRY INFORMATION -- THE ADDRESS OF THE FET IN A0.
*     EXIT INFORMATION - THE LENGTH OF THE INDEX IN B6, ITS START 
*     IN B5, AND THE LAST RECORD NUMBER IN B7.
*     SUBROUTINE CALLED - CPC02 IN PROGRAM CPC. 
*     REGISTERS USED - A1, A3, A6, X0, X1, X2, X3, X6 
          SPACE    2
 IORA     DATA     0               CHECK FOR RANDOMNESS,WAIT TILL 
          SA1      A0+B1            FI3E NOT BUSY 
          PL       X1,IORAB        ALLOCATABLE DEVICE 
          MX0      1
          LX0      48              NOT ALLOCATABLE,KILL RANDOM BIT
          BX6      -X0*X1 
          SA6      A1 
          EQ       IORER7 
 IORAB    LX1      12 
          PL       X1,IORER1       NOT RANDOM 
          AX1      30 
          MX0      54 
          BX0      -X0*X1          FET LENGTH - 5 
          SX0      X0-3 
          NG       X0,IORER2       NO INDEX POINTER IN FET
          SA3      A0+7            INDEX POINTER WORD 
          SB5      X3              INDEX START
          LX3      42 
          SB6      X3              INDEX LENGTH 
          ZR       B6,IORER2       ZERO INDEX LENGTH
          LX3      36 
          SB7      X3              LAST RECORD NUMBER 
**    NOTE THAT TO CALL CPC02 TO WAIT UNTIL THE FILE IS NOT BUSY, 
*     WE MUST HAVE THE FET ADDRESS IN B2. BUT IOSAV HAS ALREADY 
*     PUT THE LWA+1 ADDRESS OF THE WORKSPACE IN B2, AND THIS WILL 
*     BE NEEDED AFTER WE BRANCH TO IOIO. SO WE SAVE B2 TEMPORARILY
*     IN X3, WHICH CPC02 DOES NOT TOUCH.
          SX3      B2              SAVE LWA+1 
          SB2      A0 
          RJ       CPC02           WAIT TILL FILE NOT BUSY
          SB2      X3              RESTORE LWA+1
          EQ       IORA 
          EJECT 
**    SUBROUTINE IORB CLEARS THE CODE AND STATUS FIELD IN FET,
*     EXCEPT FOR BITS 0-1. IT PUTS THE RECORD NAME OR NUMBER IN IORN, 
*     AND EXITS WITH THE RECORD NUMBER IN X1, OR IF THE RECORD IS 
*     NAMED FOR WRITING AND THE NAME HAS NOT BEEN PREVIOUSLY BEEN 
*     PUT IN THE INDEX, WITH THE NUMBER OF THE FIRST FREE INDEX 
*     SLOT IN X4, AND WITH THE DISK ADDRESS IN X5 FOR READING,
*     OR SOMETHING IRRELEVANT IN X5 FOR WRITING.
          SPACE    2
**    ENTRY INFORMATION -- X4 WAS SET BY IOSAVE TO POINT TO THE FIRST 
*     PARAMETER OF THE CALLING SEQUENCE TO IORR OR IORW. B5,B6 AND
*     B7 HAVE BEEN SET BY IORA -- SEE ABOVE.
          SPACE    1
**    EXIT INFORMATION -- THE RECORD NUMBER IN X1. IF WRITING, AND
*     THE RECORD IS NAMED AND THIS IS A NEW NAME, THE NUMBER OF THE 
*     FIRST FREE SLOT IN THE INDEX IN X4. IF READING, THE DISK
*     ADDRESS IN X5.
          SPACE    1
**    REGISTERS USED - A2,A3,A5,A6,X1,X2,X3,X4,X5,X6,B4,B6
          SPACE    2
 IORB     DATA     0
          SA2      X4+B1   X4 SET BY IOSAVE TO ADDR OF 1ST PARAMETER
          NZ       X2,IORBA        NUMBER OR NAME GIVEN 
          SX2      B7+B1           NUMBER 0, USE PREVIOUS +1
 IORBA    BX6      X2 
          SA6      IORN 
          AX6      18              NOW X6=0 IF NUMBER 
          SA5      B5              INDEX START
          ZR       X6,IORBQ        REC REFERENCED BY NUMBER 
          SX1      B0              BY NAME-CONVERT TO NUMBER
          SX4      B0              FOR NUMBER OF 1ST EMPTY SLOT 
          NZ       X5,IORBS        FILE HAS BEEN USED 
          MX6      2               STILL VIRGIN - SET INDEX 
          SA6      A5                TO USE NAMES 
          MX5      2
 IORBS    PL       X5,IORER3       FILE SET FOR NUMBERS ONLY
 IORBT    SX1      X1+B1           NEXT RECORD NUMBER 
          SB6      B6-2 
          NG       B6,IORBU        NO NEXT PAIR,NO SUCH NAME
          SA5      A5+B1           POINTS TO 1ST WORD OF NEXT PAIR
          BX6      X4+X5
          NZ       X6,IORBX 
          BX4      X1  SAVE SLOT NO. IF EMPTY AND NONE SAVED YET
 IORBX    IX6      X5-X2           COMPARE NAMES
          SA5      A5+B1           GET DISK ADDRESS FROM THIS SLOT
          NZ       X6,IORBT        NO MATCH 
          BX6      X1              RECORD NUMBER
          SA6      IORN 
          EQ       IORBV
 IORBU    SX1      B0              SHOW NO SUCH NAME
          EQ       IORB 
 IORBQ    NZ       X5,IORBQA       FILE HAS BEEN USD
          SX6      B1              VIRGIN - SET UP FOR NUMBERED 
          SA6      A5                 RECORDS ONLY
 IORBQA   SX1      X2              RECORD NUMBER
          SB4      X1 
          PL       X5,IORBQB
          SB4      X1+B4           2 WORDS PER SLOT IF NAMES ALLOWED
 IORBQB   LT        B6,B4,IORER4A  RECORD NUMBER TOO HIGH FOR INDEX 
          GE        B0,B4,IORER4A 
          SA5      A5+B4
 IORBV    SA3      A0 
          SX6      774B            FET OP CODE SHOULD NOT BE CLEARED
          BX6      X3*X6            WHEN IT IS
          SX6      X6-14B            14B (WRITE) OR 
          ZR     X6,IORB
          SX6      X6-200B           214B (REWRITE) 
          ZR     X6,IORB
          MX6      44 
          LX6      2
          BX6      X6*X3
          SA6      A3        CLEAR OP CODE IN FET 
          EQ       IORB            EXIT WITH DISK ADDRES IN X5
          EJECT 
 IORER4A  SB4       IORER4
          SX2       25B 
          EQ        BODY
IORER5A   SB4       IORER5
          SX2       26B 
          EQ        BODY
 IORER6A  SB4       IORER6
          SX2       27B 
 BODY     SA1       A0             FIRST WORD OF FET
          LX2       9 
          MX0       5 
          LX0       14
          BX1       -X0*X1
          BX6       X1+X2 
          SA6       IOZW
          SA1       A0+B1 
          LX1       15             CHECK EP BIT 
          PL        X1,BOMB        IF 0, ABORT
          SA1       A0+8
          SX6       X1             ERROR OWNCODE ADDRESS
          NZ        X6,BODZ 
          SA1       A6             =IOZW
          BX6       X1
          SA6       A0             IF NO ERROR OWNCODE ADDRESS, SET 
          EQ        IOZZ           ERROR BITS IN 1ST WORD OF FET, 
*                                  THEN RETURN TO CALLER WITH SAME IN X1
 BODZ     MX0       42
          SA2       RJCOM 
          BX2       X0*X2 
          BX6       X2+X6 
          SA6       A2
          JP        RJCOM          VOID THE STACK 
 RJCOM    SA1       IOZW           WITH X1 = 1ST WORD OF FET, 
 -        RJ        *              ENTER OWNCODE
          EQ        IOZZ           THEN RETURN TO CALLER WITH 
*                                  CONTENT OF IOZW IN X1. 
 BOMB     JP        B4             MESSAGE AND ABORT. 
 IORER1   RJ       CPC999 
 -        JP       IORER2 
          DIS      3,RANDOM CALL,NONRANDOM FILE 
 IORER2   RJ       CPC999 
 -        JP       IORER3 
          DIS      4,NO INDEX POINTER IN FET,OR 0 LGTH. INDEX 
 IORER3   RJ       CPC999 
 -        JP       IORER4 
          DIS      3,FILE RECORDS NOT NAMED 
 IORER4   RJ       CPC999 
 -        JP       IORER5 
          DIS      3,RECORD NUMBER TOO HIGH 
 IORER5   RJ       CPC999 
 -        JP       IORER6 
          DIS      3,RECORD NAME NOT IN FILE INDEX
 IORER6   RJ       CPC999 
 -        JP       IORER7 
          DIS      3,NO ROOM IN INDEX FOR NEW NAME
 IORER7   RJ     CPC999 
 -        JP       IORER8 
          DIS      3,FILE DEVICE NOT ALLOCATABLE
 IORER8   RJ       CPC999 
 -        JP       IORER9 
 IORER9   RJ       CPC999 
 -        JP       *+1
          END 
