REA TITLE 'DMSREA (CMS) VM/370 - RELEASE 6' 00001000
ISEQ 73,80 00002000
*. 00003000
* MODULE NAME - DMSREA 00004000
* 00005000
* DESCRIPTIVE NAME - ERROR RECORD READ ROUTINE. 00006000
* 00007000
* COPYRIGHT - NONE 00008000
* 00009000
* CHANGE ACTIVITY - NOT APPLICABLE 00010000
* 00011000
* FUNCTION - 00012000
* DMSREA IS AN INTERFACE MODULE FOR THE CMS CPEREP COMMAND. 00013000
* DMSREA READS A SPECIFIED LOGICAL RECORD FROM THE VM/370 00014000
* ERROR RECORDING CYLINDERS AND RETURNS IT TO THE CALLER. 00015000
* THE CALLER SPECIFIES WHICH LOGICAL RECORD HE WANTS BY 00016000
* PASSING A RECORD ADDRESS TO DMSREA. THE RECORD ADDRESS 00017000
* FORMAT RESEMBLES THE STANDARD 5 BYTE CCHHR DISK ADDRESS 00018000
* FORMAT, BUT IS A LITTLE DIFFERENT. THE FORMAT IS: 00019000
* CCB0R 00020000
* WHERE: 00021000
* CC - IS THE RELATIVE DASD CYLINDER ADDRESS (RELATIVE TO 00022000
* THE FIRST OF THE ERROR CYLINDERS, E.G., CC IS 00023100
* X'0000', X'0001', ...,X'0008'). 00024100
* B - IS THE NUMBER OF THE 4K BLOCK (OR PAGE) WITHIN THE 00025000
* SPECIFIED DASD CYLINDER. 00026000
* 0 - A BYTE OF ZERO. 00027000
* R - LOGICAL RECORD NUMBER OF A RECORD WITHIN THE 00028000
* SPECIFIED BLOCK. THE BLOCK CONTAINS VARIABLE LENGTH 00029000
* RECORDS, EACH PRECEEDED BY THE STANDARD 4 BYTE RECORD 00030000
* DESCRIPTOR WORD WHICH CONTAINS THE RECORD LENGTH. 00031000
* SINCE RECORDS IN THE ERROR RECORDING CYLINDERS ARE 00032000
* NEVER LESS THAN 24 BYTES IN LENGTH, THERE CANNOT BE 00033000
* MORE THAN 255 RECORDS IN A BLOCK. RECORDS WITHIN 00034000
* A BLOCK ARE NUMBERED 1 THRU M. 00035000
* THE CCB0R ADDRESS IS NOT ONLY RECEIVED FROM THE CALLER, 00036000
* BUT IS RETURNED TO HIM AFTERWARDS AS WELL, FOR REASONS 00037000
* THAT WILL SOON BE APPARENT. SOMETIMES THE REQUESTED RECORD 00038000
* DOES NOT EXIST OR CANNOT BE READ (DUE TO AN I/O ERROR). 00039000
* IN THESE CASES, THE NEXT LOGICAL RECORD IS RETURNED TO THE 00040000
* CALLER INSTEAD. AND IN THESE CASES THE CCB0R ADDRESS 00041000
* RETURNED TO THE CALLER IS A CORRECTED CCB0R ADDRESS THAT 00042000
* SHOWS WHAT RECORD WAS ACTUALLY GOTTEN. SOME EXAMPLES 00043000
* WILL CLARIFY THIS. 00044000
* 00045000
* ASSUMPTIONS FOR EXAMPLES: 00046000
* * EACH CYLINDER CONTAINS 10 (=X'0A') OF THE 4K BLOCKS. 00047000
* * NO RECORDS WERE RECORDED IN THE 1ST (CC=X'0000') CYLINDER, 00048000
* I.E., ALL 10 BLOCKS THERE ARE FLAGGED AS EMPTY. 00049000
* * BLOCK 1 IN THE 2ND CYLINDER CONTAINS 7 RECORDS. 00050000
* * BLOCK 2 IN THE 2ND CYLINDER IS FLAGGED AS UNREADABLE OR 00051000
* EMPTY. 00052000
* * BLOCK 3 IN THE 2ND CYLINDER CONTAINS 5 RECORDS. 00053000
* * BLOCK 4 IN THE 2ND CYLINDER CONTAINS 3 RECORDS. 00054000
* * THE REMAINING BLOCKS OF THE 2ND CYLINDER ARE EMPTY. 00055000
* EXAMPLE 1: 00056000
* THE CALLER PASSES X'0001030005' AS THE CCB0R ADDRESS. 00057000
* THE REQUESTED RECORD 5 IN BLOCK 3 OF THE 2ND CYLINDER 00058000
* EXISTS, SO THE REQUESTED RECORD IS RETURNED. AND THE 00059000
* ORIGINAL CCB0R VALUE IS RETURNED UNCHANGED. 00060000
* EXAMPLE 2: 00061000
* THE CALLER WANTS TO READ THE NEXT SEQUENTIAL RECORD AFTER 00062000
* THE ONE HE READ IN EXAMPLE 1. SO HE ADDS 1 TO THE R 00063000
* VALUE OF THE CCB0R ADDRESS RETURNED IN EXAMPLE 1, GETTING 00064000
* X'0001030006', WHICH HE NOW PASSES TO DMSREA. SINCE 00065000
* THERE IS NO RECORD 6 IN BLOCK 3, DMSREA RETURNS THE NEXT 00066000
* AVAILABLE RECORD WHICH IS RECORD 1 IN BLOCK 4. AND THE 00067000
* RETURNED ADDRESS IS X'0001040001'. 00068000
* EXAMPLE 3: 00069000
* THE CALLER PASSES X'0001010008' AS THE CCB0R ADDRESS. 00070000
* THERE IS NO RECORD 8 IN BLOCK 1, SO DMSREA TRIES TO GET 00071000
* RECORD 1 FROM BLOCK 2, BUT BLOCK 2 IS FLAGGED AS 00072000
* UNREADABLE, SO IT ADVANCES TO BLOCK 3 AND RETURNS RECORD 00073000
* 1 OF BLOCK 3. THE RETURNED ADDRESS IS X'0001030001'. 00074000
* EXAMPLE 4: 00075000
* THE CALLER PASSES X'0000050005', ATTEMPTING TO READ 00076000
* NON-EXISTENT DATA FROM THE EMPTY 1ST CYLINDER. DMSREA 00077000
* SCANS THRU BLOCKS 5 THRU 10 OF THE 1ST CYLINDER, FINDING 00078000
* NOTHING, AND THEN SWITCHES TO THE 2ND CYLINDER. THERE 00079000
* IT FINDS AND RETURNS RECORD 1 OF BLOCK 1 AND RETURNS 00080000
* THE ADDRESS X'0001010001'. 00081000
* EXAMPLE 5: 00082000
* THE CALLER PASSES X'00000B0001', ATTEMPTING TO READ FROM 00083000
* THE 1ST CYLINDER, BUT BEYOND THE ALLOWED LIMIT OF 00084000
* 10 (=X'0A') BLOCKS PER CYLINDER (AS ASSUMED FOR THIS 00085000
* EXAMPLE). THIS IS NOT ALLOWED. THE RESULTS ARE 00086000
* UNPREDICTABLE. (NOTE: THE CALLER IS NOT EXPECTED TO 00087000
* KNOW HOW MANY BLOCKS ARE ALLOWED IN A CYLINDER ON A 00088000
* PARTICULAR DEVICE. RATHER, IT IS EXPECTED THAT HE WILL 00089000
* ONLY USE ADDRESSES THAT HAVE BEEN RETURNED TO HIM FROM 00090000
* PRIOR CALLS TO DMSREA, WITH ONLY THE R FIELD CHANGED BY 00091000
* HIM. AN EXCEPTION IS THAT HE IS PERMITTED TO MAKE UP 00092000
* AN ADDRESS HIMSELF TO GET STARTED AT THE FIRST BLOCK 00093000
* OF EITHER CYLINDER.) 00094000
* EXAMPLE 6: 00095000
* THE CALLER PASSES X'0001040004' REQUESTING A RECORD 00096000
* FOLLOWING THE FINAL RECORD OF BLOCK 4, 2ND CYLINDER. 00097000
* BLOCKS BEYOND BLOCK 4 ARE ALL EMPTY. DMSREA LOOKS FOR, 00098000
* BUT FAILS TO FIND, A NEXT AVAILABLE RECORD IN THE 00099000
* REMAINING BLOCKS. SO DSMREA RETURNS AN END-OF-FILE 00100000
* INDICATION RATHER THAN A NEXT AVAILABLE RECORD. 00101000
* EXAMPLE 7: 00102000
* FORGET THE ASSUMPTIONS OF THE EARLIER EXAMPLES. ASSUME 00103000
* NOW THAT ALL CYLINDERS ARE EMPTY. THE CALLER PASSES 00104100
* X'0000010001' REQUESTING THE FIRST RECORD OF THE FIRST 00105000
* CYLINDER. DMSREA READS THRU ALL CYLS LOOKING FOR 00106100
* AN AVAILABLE RECORD AND FINALLY RETURNS AN END-OF-FILE 00107000
* INDICATION RATHER THAN A RECORD. 00108000
* 00109000
* ATTRIBUTES - NON-REUSABLE, CMS USER AREA, ENTERED VIA CALL. 00110000
* 00111000
* ENTRY POINTS - DMSREA 00112000
* 00113000
* ENTRY CONDITIONS - 00114000
* R1 = ADDRESS OF THE CCB0R DASD RECORD ADDRESS. 00115000
* R13 = ADDRESS OF A STANDARD 72 BYTE SAVE AREA. 00116000
* R14 = RETURN ADDRESS. 00117000
* 00118000
* EXIT CONDITIONS - 00119000
* R0 = NON-ZERO: ADDRESS OF VARIABLE LENGTH RECORD BEING 00120000
* RETURNED. FIRST 4 BYTES ARE THE RECORD DESCRIPTOR WORD 00121000
* CONTAINING THE RECORD LENGTH. 00122000
* R0 = ZERO: INDICATES END-OF-FILE; NO RECORD WAS AT OR BEYOND 00123000
* THE INPUTTED ADDRESS. 00124000
* R1 = ADDRESS OF THE (SOMETIMES CORRECTED) CCB0R DASD RECORD 00125000
* ADDRESS. THIS IS IN A SEPARATE WORK AREA, NOT 00126000
* OVERLAYING THE INPUTTED CCB0R. 00127000
* R13 = SAME SAVE AREA ADDRESS. 00128000
* R15 = 0; NOTHING UNUSUAL. 00129000
* R15 = 4; AN EMPTY 4K BLOCK WAS SKIPPED. 00130000
* R15 = 8; INPUTTED CCB0R ADDRESS CONTAINED INVALID CC VALUE. 00131000
* R15 = 60; DMSIFC830E (I/O ERROR) 00132000
* 00133000
* CALLS TO OTHER ROUTINES - 00134000
* DIAGNOSE CALLS TO CP AS BELOW: 00135000
* DIAGNOSE CODE X'2C' = FIND RECORDING AREA ON SYSTEM DISK. 00136000
* DIAGNOSE CODE X'30' = READ PAGE SIZE RECORD FROM ERROR 00137000
* RECORDING CYLINDERS. 00138000
* DMSERR - CALLED VIA MACRO SVC TO WRITE ERROR MESSAGE TO 00139000
* THE CONSOLE. 00140000
* 00141000
* EXTERNAL REFERENCES - NONE. 00142000
* 00143000
* TABLES / WORK AREAS - 00144000
* 4K OF STORAGE BEGINNING AT ABSOLUTE LOCATION X'21000' WILL BE 00145000
* USED AS A BUFFER FOR THE BLOCKS OF ERROR RECORDS. 00146000
* 00147000
* MACROS - DMSERR, REGEQU 00148000
* 00149000
* REGISTER USAGE - 00150000
* R0-R9 = SCRATCH 00151000
* R10-R11 = SPARES, NOT PRESENTLY USED. 00152000
* R12 = BASE 00153000
* R13 = SAVE AREA ADDRESS 00154000
* R14-R15 = SCRATCH 00155000
* 00156000
* NOTES - 00157000
* THIS MODULE USES 4K OF (UNALLOCATED) STORAGE AT ABSOLUTE 00158000
* LOCATION X'21000' AS A PAGE BUFFER IN WHICH TO READ THE 4K 00159000
* BLOCKS OF ERROR RECORDS. 00160000
* 00161000
* SIGNIFICANT INTERNAL VARIABLES - 00162000
* STARTCYL - FULLWORD CONTAINING STARTING CYLINDER AND DEVICE 00163000
* CODE OF THE VM/370 ERROR RECORDING CYLINDERS AREA. 00164000
* INITIALIZED ON THE FIRST CALL, IT REMAINS 00165000
* UNCHANGED THEREAFTER. HAS 'VM/370 CONTROL PROGRAM 00166000
* INTERNAL FORMAT'. 00167000
* CYLCOUNT - HALFWORD CONTAINING THE NUMBER OF ERROR 00167100
* RECORDING CYLINDERS. INITIALIZED ON THE 1ST 00167200
* CALL, IT REMAINS UNCHANGED THEREAFTER. 00167300
* AVAILBLK - FULLWORD CONTAINING ADDRESS (IN 'VM/370 CONTROL 00168000
* PROGRAM INTERNAL FORMAT') OF THE LAST BLOCK READ 00169000
* INTO THE 4K BUFFER. VALUE IS RETAINED FROM ONE 00170000
* CALL TO THE NEXT. THE DATA REMAINS AVAILABLE IN 00171000
* THE BUFFER. 00172000
* RECNO - FULLWORD CONTAINING THE NUMBER OF THE LOGICAL 00173000
* RECORD THAT WAS LAST REQUESTED FROM THE 4K BUFFER. 00174000
* VALUE IS RETAINED FROM ONE CALL TO THE NEXT. IT 00175000
* SAVES US FROM HAVING TO COUNT UP THRU ALL THE 00176000
* LOGICAL RECORDS IN THE BUFFER. SAVING IS MAINLY 00177000
* ACHIEVED WHEN SEQUENTIAL ACCESSING IS DONE. 00178000
* RECADDR - FULLWORD CONTAINING THE STORAGE ADDRESS OF THE 00179000
* PARTICULAR RECORD IN THE 4K BUFFER THAT IS 00180000
* INDICATED BY 'RECNO' ABOVE. VALUE IS RETAINED 00181000
* FROM ONE CALL TO THE NEXT. 00182000
* 00183000
* OPERATION - 00184000
* 1. SAVE REGISTERS AS NECESSARY. SET R15 RETURN CODE TO 0. 00185000
* 2. IF THIS IS NOT THE FIRST CALL TO DMSREA, GO TO 4. 00186000
* 3. ISSUE DIAGNOSE X'2C' TO FIND THE START OF THE VM/370 00187000
* ERROR RECORDING CYLINDERS. STORE RETURNED ADDRESS VALUE 00188000
* IN 'STARTCYL'. 'AVAILBLK' IS INITIALLY ZERO; NON-EXISTENT 00189000
* ZERO ADDRESS INSURES THAT IN CODE BELOW WE DO NOT GET 00190000
* FOOLED INTO THINKING 4K BUFFER CONTAINS A BLOCK. 00191000
* THROW 'FIRST TIME' SWITCH. STORE COUNT OF RECORD- 00192100
* ING CYLINDERS IN 'CYLCOUNT'. 00192200
* 4. CHECK CC PORTION OF INPUTTED CCB0R FOR VALID RANGE. 00193000
* IF INVALID, GO TO 16. 00194000
* 5. CONVERT CCB PORTION OF INPUTTED CCB0R ADDRESS TO A 00195000
* 'VM/370 CONTROL PROGRAM INTERNAL FORMAT (CPIF)' ADDRESS. 00196000
* 6. IF COMPUTED CPIF ADDRESS MATCHES VALUE IN 'AVAILBLK', 00197000
* THEN DESIRED BLOCK IS ALREADY IN BUFFER, SO GO TO 11. 00198000
* 7. SET 'RECNO' TO ZERO INDICATING WE HAVE NOT YET COUNTED UP 00199000
* TO ANY PARTICULAR RECORD IN THE NEW BLOCK ABOUT TO BE 00200000
* READ IN. SET 'AVAILBLK' TO ZERO (WE COULD ALMOST AS WELL 00201000
* SET IT TO THE NEW CPIF ADDRESS SINCE WE ARE ABOUT TO 00202000
* READ THAT BLOCK INTO THE BUFFER; BUT THE READ COULD FAIL 00203000
* AND ZERO BEST INDICATES UNDEFINED STATE OF THE BUFFER). 00204000
* ISSUE DIAGNOSE X'30' USING COMPUTED CPIF ADDRESS TO READ 00205000
* THE ADDRESSED BLOCK. TEST CONDITION CODE SET BY DIAGNOSE: 00206000
* CC=0: BLOCK WAS READ SUCCESSFULLY; GO TO 10. 00207000
* CC=1: END OF CYLINDER, ADDRESSED BLOCK IS NON-EXISTENT; 00208000
* GO TO 17. 00209000
* CC=3: SPECIFIED CYLINDER IS OUTSIDE THE ERROR RECORDING 00210000
* AREA; GO TO 16. 00211000
* CC=2: I/O ERROR,BLOCK COULD NOT BE READ; FALL THRU TO 8. 00212000
* 8. ISSUE MESSAGE DMSREA830E (I/O ERROR), SET CODE 60 FOR R15. 00213000
* (WE CANNOT GET THE ADDRESSED RECORD, SO WE WILL TRY FOR 00214000
* THE NEXT AVAILABLE RECORD INSTEAD.) 00215000
* 9. PREPARE TO READ NEXT BLOCK AND USE FIRST RECORD IN IT: 00216000
* ADD ONE TO BLOCK NUMBER IN CPIF ADDRESS; SET R VALUE OF 00217000
* CCB0R TO RECORD 1; GO TO 7. 00218000
* 00219000
* 10. STORE CPIF ADDRESS IN 'AVAILBLK'. 00220000
* IF THE BLOCK IS FLAGGED AS EMPTY, GO TO 9. 00221000
* 11. (COMMENT: BLOCK SPECIFIED BY CPIF ADDRESS IS NOW IN THE 00222000
* BUFFER AND DOES CONTAIN SOME RECORDS. 'RECNO' AND 00223000
* 'RECADDR' EITHER POINT TO SOME RECORD IN THE BUFFER OR 00224000
* 'RECNO' IS ZERO. R IN CCB0R SPECIFIES THE RECORD WE 00225000
* WANT TO FIND IN THE BUFFER.) 00226000
* IF 'RECNO' IS GREATER THAN R, SET 'RECNO' TO ZERO. 00227000
* 12. IF 'RECNO' IS ZERO, SET IT TO ONE AND INITIALIZE 00228000
* 'RECADDR' TO POINT TO FIRST RECORD IN BUFFER. 00229000
* 13. (COMMENT: STEP THRU THE BUFFER INCREMENTING 'RECNO' 00230000
* AND 'RECADDR' UNTIL 'RECNO' MATCHES R OR UNTIL THERE 00231000
* ARE NO MORE RECORDS IN THE BUFFER.) 00232000
* IF 'RECNO' EQUALS R, GO TO 14. 00233000
* INCREMENT 'RECNO' BY ONE AND ADVANCE 'RECADDR' TO NEXT 00234000
* RECORD, IF ANY. 00235000
* IF 'RECADDR' IS BEYOND LAST RECORD IN BUFFER, GO TO 9. 00236000
* OTHERWISE, LOOP TO 13 FOR ANOTHER ITERATION. 00237000
* 00238000
* 14. FROM THE CURRENT R AND CPIF ADDRESS, COMPUTE A CORRECTED 00239000
* CCB0R VALUE TO BE RETURNED TO THE CALLER. PUT ADDRESS 00240000
* OF CORRECTED CCB0R DATA IN R1. LOAD 'RECADDR' INTO R0. 00241000
* 15. RESTORE REGISTERS (EXCEPT OUTPUT PARAMETER REGISTERS) AND 00242000
* RETURN TO THE CALLER. 00243000
* 00244000
* 16. SET ERROR CODE IN R15 FOR INVALID CYLINDER. GO TO 15. 00245000
* 00246000
* 17. (COMMENT: END OF CYLINDER INDICATION WAS RECEIVED.) 00247000
* SET R0 TO ZERO (INDICATES EOF TO CALLER IN CASE THIS 00248000
* CYLINDER IS THE LAST CYLINDER). 00249000
* IF CC PORTION OF CPIF ADDRESS INDICATES WE WERE ALREADY 00250000
* ON THE FINAL CYLINDER, GO TO 15. 00251000
* OTHERWISE ADVANCE TO NEXT CYLINDER: ADD 1 TO CC OF CPIF 00252000
* ADDRESS; SET B OF CPIF ADDRESS TO BLOCK 1; SET R OF CCB0R 00253000
* ADDRESS TO RECORD 1; 00254000
* GO TO 7 (TO READ FIRST AVAILABLE RECORD IN NEXT CYLINDER). 00255000
* 00256000
* RESPONSES - NONE 00257000
* 00258000
* ERROR MESSAGES - DMSREA830E WITH RETURN CODE 60. 00259000
*. 00260000
EJECT 00261000
DMSREA CSECT @V4085A8 00262000
*********************************************************************** 00263000
* 1. SAVE REGISTERS AS NECESSARY. SET R15 RETURN CODE TO 0. 00264000
*********************************************************************** 00265000
SR R15,R15 INITIALIZE RETURN CODE. @V4085A8 00266000
STM R14,R12,SAVER14(R13) @V4085A8 00267000
BALR R12,0 ESTABLISH ADDRESSABILITY. @V4085A8 00268000
USING *,R12 @V4085A8 00269000
SPACE 00270000
*********************************************************************** 00271000
* 2. IF THIS IS NOT THE FIRST CALL TO DMSREA, GO TO 4. 00272000
*********************************************************************** 00273000
FIRSTSW BC *-*,OPER4 BRANCH IF THIS IS NOT THE FIRST CALL.@V4085A8 00274000
* (CONDITION CODE MASK WILL BE MODIFIED.) 00275000
* FALL THRU IF THIS IS THE FIRST CALL TO DMSREA. 00276000
SPACE 00277000
*********************************************************************** 00278000
* 3. ISSUE DIAGNOSE X'2C' TO FIND THE START OF THE VM/370 00279000
* ERROR RECORDING CYLINDERS. STORE RETURNED ADDRESS VALUE 00280000
* IN 'STARTCYL'. 'AVAILBLK' IS INITIALLY ZERO; NON-EXISTENT 00281000
* ZERO ADDRESS INSURES THAT IN CODE BELOW WE DO NOT GET 00282000
* FOOLED INTO THINKING 4K BUFFER CONTAINS A BLOCK. 00283000
* THROW 'FIRST TIME' SWITCH. 00284000
*********************************************************************** 00285000
OI FIRSTSW+1,X'F0' THROW THE SWITCH. @V4085A8 00286000
LA R2,CODE01 CODE X'01' FOR DIAGNOSE '2C' @V5088AA 00286100
DC X'8323002C' DIAGNOSE RETURNS THE DISK @V5088AA 00287100
* ADDR (IN VM/370 CONTROL PROGRAM INTERNAL 00288000
* FORMAT) OF THE START OF THE ERROR 00289000
* RECORDING AREA (IN R2) AND THE 00290100
* NUMBER OF ERROR RECORDING 00290200
* CYLINDERS (IN R3). 00290300
N R2,BLKMASK CLEAR THE PAGE (OR BLOCK) NUMBER @V4085A8 00291000
* BYTE TO X'00'. 00292000
ST R2,STARTCYL SAVE CC0D PERMANENTLY FOR USE @V4085A8 00293000
* DURING THIS CALL AND ALL LATER CALLS. 00294000
STH R3,CYLCOUNT SAVE COUNT OF RECORDING CYLS @V5088AA 00294100
* FOR USE DURING THIS CALL AND 00294200
* ALL LATER CALLS. 00294300
SPACE 00295000
*********************************************************************** 00296000
* 4. CHECK CC PORTION OF INPUTTED CCB0R FOR VALID RANGE. 00297000
* IF INVALID, GO TO 16. 00298000
*********************************************************************** 00299000
OPER4 CLC 0(LENCC,R1),CYLCOUNT R1 (INPUT ARG) POINTS TO @V5088AA 00300100
* CCB0R. 00301000
BNL OPER16 ERROR--CC WAS GREATER THAN @V5088AA 00302100
* NUMBER OF CYLINDERS AVAILABLE 00302200
* FOR ERROR RECORDING 00302300
SPACE 00303000
*********************************************************************** 00304000
* 5. CONVERT CCB PORTION OF INPUTTED CCB0R ADDRESS TO A 00305000
* 'VM/370 CONTROL PROGRAM INTERNAL FORMAT (CPIF)' ADDRESS. 00306000
*********************************************************************** 00307000
MVC WANT0R,DISP0R(R1) MOVE INPUTTED 0R OF CCB0R TO @V4085A8 00308000
* HALFWORD. 00309000
MVC WANTCCBD,0(R1) MOVE INPUTTED CCB0 OF CCBOR TO @V4085A8 00310000
* FULLWORD. 00311000
CLI WANTCCBD+DISPB,X'00' CHECK B FIELD OF CCB0. @V4085A8 00312000
BNE *+8 IT IS NON-0 WHICH IS ACCEPTABLE. @V4085A8 00313000
* BLOCK 0 WAS REQUESTED BUT THERE IS NO SUCH THING. (THIS 00314000
* SHOULDN'T REALLY HAPPEN, AT LEAST NOT IF DMSIFC IS THE CALLER) 00315000
MVI WANTCCBD+DISPB,X'01' ADVANCE TO THE 1ST BLOCK. @V4085A8 00316000
L R1,WANTCCBD LOAD CCB0 (CC IS RELATIVE OFFSET). @V4085A8 00317000
A R1,STARTCYL ADD CC0D GETTING A TRUE CCBD @V4085A8 00318000
* INTERNAL FORMAT DISK ADDRESS (CC ABSOLUTE). 00319000
ST R1,WANTCCBD PUT BACK TRUE CCBD. @V4085A8 00320000
SPACE 00321000
*********************************************************************** 00322000
* 6. IF COMPUTED CPIF ADDRESS MATCHES VALUE IN 'AVAILBLK', 00323000
* THEN DESIRED BLOCK IS ALREADY IN BUFFER, SO GO TO 11. 00324000
*********************************************************************** 00325000
C R1,AVAILBLK COMPARE WANTED CCBD RECORD ADDR @V4085A8 00326000
* WITH ADDR OF RECORD ALREADY IN BUFFER. 00327000
BE OPER11 DESIRED BLOCK IS ALREADY IN BUFFER. @V4085A8 00328000
SPACE 00329000
*********************************************************************** 00330000
* 7. SET 'RECNO' TO ZERO INDICATING WE HAVE NOT YET COUNTED UP 00331000
* TO ANY PARTICULAR RECORD IN THE NEW BLOCK ABOUT TO BE 00332000
* READ IN. SET 'AVAILBLK' TO ZERO (WE COULD ALMOST AS WELL 00333000
* SET IT TO THE NEW CPIF ADDRESS SINCE WE ARE ABOUT TO 00334000
* READ THAT BLOCK INTO THE BUFFER; BUT THE READ COULD FAIL 00335000
* AND ZERO BEST INDICATES UNDEFINED STATE OF THE BUFFER). 00336000
* ISSUE DIAGNOSE X'30' USING COMPUTED CPIF ADDRESS TO READ 00337000
* THE ADDRESSED BLOCK. TEST CONDITION CODE SET BY DIAGNOSE: 00338000
* CC=0: BLOCK WAS READ SUCCESSFULLY; GO TO 10. 00339000
* CC=1: END OF CYLINDER, ADDRESSED BLOCK IS NON-EXISTENT; 00340000
* GO TO 17. 00341000
* CC=3: SPECIFIED CYLINDER IS OUTSIDE THE ERROR RECORDING 00342000
* AREA; GO TO 16. 00343000
* CC=2: I/O ERROR,BLOCK COULD NOT BE READ; FALL THRU TO 8. 00344000
*********************************************************************** 00345000
OPER7 SR R1,R1 @V4085A8 00346000
ST R1,RECNO NO RECORDS COUNTED YET IN NEW BLOCK. @V4085A8 00347000
ST R1,AVAILBLK INDICATES CONTENTS OF BLOCK BUFFER @V4085A8 00348000
* ARE UNKNOWN. 00349000
L R1,WANTCCBD INTERNAL DISK ADDR OF BLOCK TO READ@V4085A8 00350000
L R2,PAGBUFAD ADDR OF BUFFER TO READ BLOCK INTO. @V4085A8 00351000
DC X'83120030' DIAGNOSE READS PAGE OF ERROR RECS. @V4085A8 00352000
BC 8,OPER10 CC=0, BLOCK WAS READ SUCCESSFULLY. @V4085A8 00353000
BC 4,OPER17 CC=1, END OF CYLINDER, BLOCK NOT READ.@V4085A8 00354000
BC 1,OPER16 CC=3, SPECIFIED CYLINDER IS OUTSIDE OF@V4085A8 00355000
* THE ERROR RECORDING AREA. 00356000
* FALL THRU. CC=2, I/O ERROR. 00357000
SPACE 00358000
*********************************************************************** 00359000
* 8. ISSUE MESSAGE DMSREA830E (I/O ERROR), SET CODE 60 FOR R15. 00360000
* (WE CANNOT GET THE ADDRESSED RECORD, SO WE WILL TRY FOR 00361000
* THE NEXT AVAILABLE RECORD INSTEAD.) 00362000
*********************************************************************** 00363000
DMSERR NUM=830,LET=E,TEXT='I/0 ERROR READING A BLOCK OF RECORDX00364000
S FROM THE ERROR RECORDING CYLINDERS',RENT=NO 00365000
MVI SAVER15+3(R13),RC60 PUT RETURN CODE IN R15 IN @V4085A8 00366000
* SAVE AREA. 00367000
SPACE 00368000
*********************************************************************** 00369000
* 9. PREPARE TO READ NEXT BLOCK AND USE FIRST RECORD IN IT: 00370000
* ADD ONE TO BLOCK NUMBER IN CPIF ADDRESS; SET R VALUE OF 00371000
* CCB0R TO RECORD 1; GO TO 7. 00372000
*********************************************************************** 00373000
OPER9 L R1,WANTCCBD PRESENT DISK ADDRESS. @V4085A8 00374000
AH R1,=Y(X'0100') ADD 1 TO B FIELD. (ADVANCE TO @V4085A8 00375000
* NEXT BLOCK.) 00376000
ST R1,WANTCCBD @V4085A8 00377000
MVI WANT0R+1,X'01' RESET R TO RECORD 1 OF NEW BLOCK@V4085A8 00378000
B OPER7 GO READ NEW BLOCK. @V4085A8 00379000
SPACE 3 00380000
*********************************************************************** 00381000
* 10. STORE CPIF ADDRESS IN 'AVAILBLK'. 00382000
* IF THE BLOCK IS FLAGGED AS EMPTY, GO TO 9. 00383000
*********************************************************************** 00384000
OPER10 ST R1,AVAILBLK RETAIN ADDR OF BLOCK CURRENTLY IN @V4085A8 00385000
* BUFFER. 00386000
USING EBLK,R2 LAYOUT OF BLOCK IN PAGE BUFFER. @V4085A8 00387000
C R1,EBADDR DISK ADDRESS IN BLOCK ? @VA12074 00387300
BNE OPER10D NO , BAD BLOCK @VA12074 00387600
CLI EBEMPTY,X'00' IS BLOCK FLAGGED AS EMPTY? @V4085A8 00388000
BE OPER10D YES, EMPTY. GO SET RETURN CODE, THEN @V4085A8 00389000
* TRY NEXT BLOCK. 00390000
LA R1,EBDATA-EBLK OFFSET TO START OF DATA AREA IN @V4085A8 00391000
* BLOCK. 00392000
CH R1,EBNXTAVL IS NEXT AVAILABLE BYTE THE 1ST BYTE@V4085A8 00393000
* OF THE DATA AREA? 00394000
DROP R2 @V4085A8 00395000
BNE OPER10K NO, SO BLOCK DOES CONTAIN RECORDS. @V4085A8 00396000
* YES, DATA AREA OF BLOCK IS EMPTY. SET RETURN CODE, THEN GO 00397000
* TRY NEXT BLOCK. 00398000
OPER10D CLI SAVER15+3(R13),X'00' TEST FOR EXISTING RC. @V4085A8 00399000
BNE OPER9 THERE IS AN ERROR RETURN CODE ALREADY @V4085A8 00400000
* SET. KEEP IT. 00401000
MVI SAVER15+3(R13),RC4 STORE CODE FOR EMPTY BLOCK. @V4085A8 00402000
B OPER9 GO TRY NEXT BLOCK. @V4085A8 00403000
SPACE 00404000
OPER10K DS 0H @V4085A8 00405000
SPACE 00406000
*********************************************************************** 00407000
* 11. (COMMENT: BLOCK SPECIFIED BY CPIF ADDRESS IS NOW IN THE 00408000
* BUFFER AND DOES CONTAIN SOME RECORDS. 'RECNO' AND 00409000
* 'RECADDR' EITHER POINT TO SOME RECORD IN THE BUFFER OR 00410000
* 'RECNO' IS ZERO. R IN CCB0R SPECIFIES THE RECORD WE 00411000
* WANT TO FIND IN THE BUFFER.) 00412000
* IF 'RECNO' IS GREATER THAN R, SET 'RECNO' TO ZERO. 00413000
*********************************************************************** 00414000
OPER11 L R1,RECNO POSSIBLE NUMBER OF A RECORD IN THE @V4085A8 00415000
* BLOCK WHOSE ADDR IN THE BUFFER IS KNOWN FROM 00416000
* A PREVIOUS ACCESS. 00417000
CH R1,WANT0R IF RECNO IS BEYOND THE RECORD THAT WE@V4085A8 00418000
* WANT, RECNO WILL BE OF NO HELP IN FINDING 00419000
* THE WANTED RECORD. 00420000
BNH OPER11B @V4085A8 00421000
* PRESENTLY RECNO IS BEYOND THE RECORD WE WANT. RESET TO 00422000
* SEARCH THRU THE BUFFER FROM THE BEGINNING. 00423000
SR R1,R1 @V4085A8 00424000
ST R1,RECNO RESET. @V4085A8 00425000
OPER11B DS 0H @V4085A8 00426000
SPACE 00427000
*********************************************************************** 00428000
* 12. IF 'RECNO' IS ZERO, SET IT TO ONE AND INITIALIZE 00429000
* 'RECADDR' TO POINT TO FIRST RECORD IN BUFFER. 00430000
*********************************************************************** 00431000
L R2,PAGBUFAD ADDRESS OF PAGE BUFFER. @V4085A8 00432000
USING EBLK,R2 BLOCK IN PAGE BUFFER. @V4085A8 00433000
LTR R1,R1 TEST VALUE OF RECNO IN R1. @V4085A8 00434000
BNZ OPER12F @V4085A8 00435000
LA R1,1 SET RECNO TO 1. @V4085A8 00436000
ST R1,RECNO @V4085A8 00437000
LA R3,EBDATA ADDR OF 1ST RECORD IN BUFFER. @V4085A8 00438000
ST R3,RECADDR @V4085A8 00439000
OPER12F L R3,RECADDR SET UP R3 IN CASE WE GOT HERE VIA B.@V4085A8 00440000
SPACE 00441000
*********************************************************************** 00442000
* 13. (COMMENT: STEP THRU THE BUFFER INCREMENTING 'RECNO' 00443000
* AND 'RECADDR' UNTIL 'RECNO' MATCHES R OR UNTIL THERE 00444000
* ARE NO MORE RECORDS IN THE BUFFER.) 00445000
* IF 'RECNO' EQUALS R, GO TO 14. 00446000
* INCREMENT 'RECNO' BY ONE AND ADVANCE 'RECADDR' TO NEXT 00447000
* RECORD, IF ANY. 00448000
* IF 'RECADDR' IS BEYOND LAST RECORD IN BUFFER, GO TO 9. 00449000
* OTHERWISE, LOOP TO 13 FOR ANOTHER ITERATION. 00450000
*********************************************************************** 00451000
* NOTE: AT THIS POINT WE HAVE THE FOLLOWING REGISTER USAGE: 00452000
* R1 - IS CARRYING THE VALUE OF RECNO. 00453000
* R2 - HAS THE ADDRESS OF THE PAGE BUFFER AND A 'USING' OF 00454000
* EBLK IS STILL IN EFFECT. 00455000
* R3 - IS CARRYING THE VALUE OF RECADDR (ADDR OF RECORD IN 00456000
* BUFFER THAT CORRESPONDS WITH RECNO). 00457000
*********************************************************************** 00458000
LA R6,1 INCREMENT OF 1 IN BXH INCREMENT REGISTER. @V4085A8 00459000
LH R7,WANT0R R VALUE IN BXH COMPARAND REGISTER. @V4085A8 00460000
LA R4,4 INCREMENT IN BXLE INCREMENT REGISTER. @V4085A8 00461000
LR R5,R2 ADDR OF PAGE BUFFER... @V4085A8 00462000
AH R5,EBNXTAVL PLUS OFFSET TO 1ST UNUSED BYTE IS @V4085A8 00463000
* ADDR OF 1ST UNUSED BYTE. 00464000
BCTR R5,0 LESS ONE IS ADDR FOR BXLE COMPARAND. @V4085A8 00465000
DROP R2 @V4085A8 00466000
SPACE 00467000
RECLOOP BXH R1,R6,OPER13H PREMATURELY ADD ONE TO RECNO (IN @V4085A8 00468000
* R1). IF GREATER THAN R (IN R7), 00469000
* THEN RECNO IS R+1 AND WE HAVE FOUND THE 00470000
* RECORD WE ARE LOOKING FOR, SO BRANCH OUT 00471000
* OF LOOP AND DECREMENT RECNO WHICH WAS 00472000
* INCREMENTED PREMATURELY. 00473000
SR R10,R10 CLEAR @VA12074 00473250
ICM R10,3,D2(R3) LENGTH OF NEXT RECORD @VA12074 00473500
BZ OPER10D ZERO @VA12074 00473750
* FALL THRU INDICATES RECNO WAS NOT UP TO RECORD R. RECNO HAS 00474000
* ALREADY BEEN ADVANCED, SO NOW ADVANCE RECADDR TO KEEP UP 00475000
* WITH RECNO. 00476000
AH R3,D2(0,R3) ADVANCE RECADDR (IN R3) BY LENGTH @V4085A8 00477000
* OF RECORD. 00478000
BXLE R3,R4,RECLOOP ADVANCE RECADDR (IN R3) BY 4 @V4085A8 00479000
* BYTES (4 IS INCREMENT IN R4) TO ACCOUNT 00480000
* FOR THE LENGTH DESCRIPTOR WORD. IF NOT 00481000
* AT OR BEYOND 'NEXT AVAILABLE BYTE' 00482000
* (ADDRESS-1 IS IN R5), THEN BRANCH, THERE 00483000
* ARE MORE RECORDS TO LOOK AT. 00484000
SPACE 00485000
* FALL THRU IF RECNO AND RECADDR ARE BEYOND LAST RECORD. THE 00486000
* RECORD NUMBER REQUESTED AS R DOES NOT EXIST. 00487000
B OPER9 GO READ NEXT BLOCK AND USE ITS 1ST RECORD@V4085A8 00488000
SPACE 00489000
OPER13H BCTR R1,0 DECREMENT RECNO WHICH WAS INCREMENTED @V4085A8 00490000
* PREMATURELY. 00491000
ST R1,RECNO GET RECNO VALUE FROM R1 BACK INTO FWD.@V4085A8 00492000
ST R3,RECADDR GET RECADDR VALUE BACK INTO FULLWD. @V4085A8 00493000
SPACE 00494000
*********************************************************************** 00495000
* 14. FROM THE CURRENT R AND CPIF ADDRESS, COMPUTE A CORRECTED 00496000
* CCB0R VALUE TO BE RETURNED TO THE CALLER. PUT ADDRESS 00497000
* OF CORRECTED CCB0R DATA IN R1. LOAD 'RECADDR' INTO R0. 00498000
*********************************************************************** 00499000
LR R0,R3 GET RECADDR INTO R0 FOR RETURN. @V4085A8 00500000
L R1,WANTCCBD LOAD CCBD WHERE CC IS ABSOLUTE. @V4085A8 00501000
S R1,STARTCYL SUBTRACT BASE CC FROM ABSOLUTE CC, @V4085A8 00502000
* 0 FROM B, AND D FROM D GIVING: CCB0 WHERE 00503000
* CC IS A RELATIVE CC. 00504000
ST R1,WANTCCBD STORE CCB0. @V4085A8 00505000
IC R1,WANT0R+1 LOAD R OF 0R... @V4085A8 00506000
STC R1,WANT0R AND STORE IN 0 OF 0R MAKING RR. @V4085A8 00507000
* WANTCCBD AND WANT0R (ADJACENT) NOW FORM CCB0RR WHERE THE 2ND 00508000
* R IS SURPLUS. 00509000
OPER15 DS 0H @VA10044 00509500
LA R1,WANTCCBD ADDR OF CCB0R FOR OUTPUT. @V4085A8 00510000
SPACE 00511000
*********************************************************************** 00512000
* 15. RESTORE REGISTERS (EXCEPT OUTPUT PARAMETER REGISTERS) AND 00513000
* RETURN TO THE CALLER. 00514000
*********************************************************************** 00515000
LM R14,R15,SAVER14(R13) RESTORE REGISTERS @VA10044 00516000
LM R2,R12,SAVER2(R13) @V4085A8 00517000
BR R14 @V4085A8 00518000
SPACE 3 00519000
*********************************************************************** 00520000
* 16. SET ERROR CODE IN R15 FOR INVALID CYLINDER. GO TO 15. 00521000
*********************************************************************** 00522000
OPER16 SR R0,R0 SET EOF IN CASE USER IGNORES CATASTROPHIC@V4085A8 00523000
* ERROR CODE IN R15. 00524000
MVI SAVER15+3(R13),RC8 ERR CODE IN R15 IN SAVE AREA@V4085A8 00525000
B OPER15 GO EXIT. @V4085A8 00526000
SPACE 3 00527000
*********************************************************************** 00528000
* 17. (COMMENT: END OF CYLINDER INDICATION WAS RECEIVED.) 00529000
* SET R0 TO ZERO (INDICATES EOF TO CALLER IN CASE THIS 00530000
* CYLINDER IS THE LAST CYLINDER). 00531000
* IF CC PORTION OF CPIF ADDRESS INDICATES WE WERE ALREADY 00532000
* ON THE FINAL CYLINDER, GO TO 15. 00533000
* OTHERWISE ADVANCE TO NEXT CYLINDER: ADD 1 TO CC OF CPIF 00534000
* ADDRESS; SET B OF CPIF ADDRESS TO BLOCK 1; SET R OF CCB0R 00535000
* ADDRESS TO RECORD 1; 00536000
* GO TO 7 (TO READ FIRST AVAILABLE RECORD IN NEXT CYLINDER). 00537000
*********************************************************************** 00538000
OPER17 SR R0,R0 TENTATIVELY SET EOF INDICATION FOR @V4085A8 00539000
* EXIT IN CASE THIS IS FINAL CYLINDER. 00540000
LH R1,STARTCYL CC OF STARTING CYLINDER @V5088AA 00541100
AH R1,CYLCOUNT ADD NUMBER OF CYLINDERS @V5088AA 00541200
BCTR R1,0 SUBTRACT ONE @V5088AA 00541300
CH R1,WANTCCBD COMPARE ENDING CC OF RECORDING @V5088AA 00541400
* AREA WITH THE CC PORTION OF 00541500
* CURRENT CP INTERNAL FORMAT @. 00541600
BNH OPER15 IF CURRENT CC IS NOT LOWER THAN@V5088AA 00544100
* END OF RECORDING AREA, WE ARE 00544200
* ON THE LAST CYLINDER 00544300
* FALL THRU MEANS THERE IS ANOTHER CYLINDER YET. 00546000
LH R1,WANTCCBD GET DESIRED 'CCBD' ADDRESS @V5088AA 00546100
LA R1,1(0,R1) ADD 1 TO CC. @V4085A8 00547000
STH R1,WANTCCBD CC PART OF CCBD IS UPDATED. @V4085A8 00548000
MVI WANTCCBD+DISPB,X'01' SET B OF CCBD TO BLOCK 1. @V4085A8 00549000
MVI WANT0R+1,X'01' SET R OF 0R TO RECORD 1. @V4085A8 00550000
B OPER7 GO READ 1ST RECORD OF NEXT CYLINDER. @V4085A8 00551000
SPACE 00552000
*********************************************************************** 00553000
DROP R12 @V4085A8 00554000
SPACE 6 00555000
PAGBUFAD DC A(X'21000') ADDRESS OF PAGE I/O BUFFER. @V4085A8 00556000
BLKMASK DS 0F @V4085A8 00557000
DC X'FFFF00FF' @V4085A8 00558000
AVAILBLK DC F'0' CONTAINS ADDRESS (IN 'VM/370 CONTROL @V4085A8 00559000
* PROGRAM INTERNAL FORMAT') OF THE LAST BLOCK READ 00560000
* INTO THE 4K PAGE BUFFER. VALUE IS RETAINED FROM 00561000
* ONE CALL TO THE NEXT. THE DATA REMAINS AVAILABLE 00562000
* IN THE BUFFER. 00563000
SPACE 3 00564000
LTORG @V4085A8 00565000
SPACE 3 00566000
RECADDR DS A CONTAINS THE STORAGE ADDRESS OF THE @V4085A8 00567000
* PARTICULAR RECORD IN THE 4K PAGE BUFFER THAT IS 00568000
* INDICATED BY 'RECNO' BELOW. VALUE IS RETAINED FROM 00569000
* ONE CALL TO THE NEXT. 00570000
RECNO DS F CONTAINS THE NUMBER OF THE LOGICAL RECORD @V4085A8 00571000
* THAT WAS LAST REQUESTED FROM THE 4K PAGE BUFFER. 00572000
* VALUE IS RETAINED FROM ONE CALL TO THE NEXT. IT 00573000
* SAVES US FROM HAVING TO COUNT UP THRU ALL THE LOGICAL 00574000
* RECORDS IN THE BUFFER. SAVING IS MAINLY ACHIEVED 00575000
* WHEN SEQUENTIAL ACCESSING IS DONE. 00576000
STARTCYL DS F CONTAINS STARTING CYLINDER AND DEVICE CODE @V4085A8 00577000
* OF THE VM/370 ERROR RECORDING CYLINDERS AREA. 00578000
* INITIALIZED ON THE FIRST CALL, IT REMAINS UNCHANGED 00579000
* THEREAFTER. HAS 'VM/370 CONTROL PROGRAM INTERNAL 00580000
* FORMAT'. 00581000
CYLCOUNT DS H CONTAINS NUMBER OF CYLINDERS AVAILABLE FOR @V5088AA 00581100
* ERROR RECORDING. INITIALIZED ON THE FIRST 00581200
* CALL, IT THEN REMAINS UNCHANGED. 00581300
SPACE 3 00582000
* THE FOLLOWING TWO FIELDS (WANTCCBD AND WANT0R) MUST BE 00583000
* CONTIGUOUS. 00584000
WANTCCBD DS F CONTAINS CCBD (I.E., INTERNAL DISK ADDRESS) @V4085A8 00585000
* OF DESIRED RECORD. EXCEPT THAT FOR OUTPUT AT EXIT 00586000
* TIME, IT IS CONVERTED TO CCB0 FORMAT. 00587000
WANT0R DS H CONTAINS 0R OF DESIRED RECORD. EXCEPT THAT @V4085A8 00588000
* FOR OUTPUT AT EXIT TIME THE R IS MOVED INTO THE 0 00589000
* POSITION AND AS AN EXTENSION OF WANTCCBD IT 00590000
* FORMS CCB0R. 00591000
SPACE 3 00592000
SAVER14 EQU 12 OFFSET TO R14 IN SAVE AREA. @V4085A8 00593000
SAVER15 EQU SAVER14+4 OFFSET TO R15 IN SAVE AREA. @V4085A8 00594000
SAVER0 EQU SAVER15+4 OFFSET TO R0 IN SAVE AREA. @V4085A8 00595000
SAVER1 EQU SAVER0+4 OFFSET TO R1 IN SAVE AREA. @V4085A8 00596000
SAVER2 EQU SAVER1+4 OFFSET TO R2 IN SAVE AREA. @V4085A8 00597000
SPACE 00598000
LENCC EQU 2 SYMBOLIC LENGTH OF CC FIELD. @V4085A8 00599000
DISP0R EQU 3 DISPLACEMENT TO 0R IN CCB0R. @V4085A8 00600000
LEN0R EQU 2 SYMBOLIC LENGTH OF 0R FIELD. @V4085A8 00601000
DISPB EQU 2 DISPLACEMENT TO B IN CCB0R. @V4085A8 00602000
D2 EQU 2 SYMBOLIC DISPLACEMENT. @V4085A8 00603000
CODE01 EQU 1 CODE X'01' FOR DIAGNOSE '2C' @V5088AA 00603100
SPACE 00604000
RC60 EQU 60 USED AS AN ERROR RETURN CODE. @V4085A8 00605000
RC4 EQU 4 USED AS AN ERROR RETURN CODE. @V4085A8 00606000
RC8 EQU 8 USED AS AN ERROR RETURN CODE. @V4085A8 00607000
SPACE 3 00608000
EBLK DSECT DESCRIBES 4K BLOCK OF ERROR RECORDS IN BUFFER.@V4085A8 00609000
EBADDR DS F DISK ADDRESS OF THIS BLOCK @VA12074 00610000
EBNXTAVL DS H OFFSET (FROM START OF THIS BLOCK) TO THE NEXT@V4085A8 00611000
* AVAILABLE SPACE, I.E., TO THE 1ST UNUSED BYTE IN BLK. 00612000
EBEMPTY DS XL1 IF VALUE IS X'00' THEN PAGE IS EMPTY. @V4085A8 00613000
DS XL1 @V4085A8 00614000
EBDATA DS 0C @V4085A8 00615000
SPACE 3 00616000
REGEQU 00617000
END 00618000