Now we will create a macro to read a card from the card reader.
MACRO
&NAME @CARD &BUF,&DEV=X'00C',&GEN=NO
LCLC &NDX
&NDX SETC '&SYSNDX'
AIF ('&GEN' EQ 'YES').GEN
.*
&NAME @RGCK &BUF,REG=R1
LA R15,@CARD
BALR R14,R15
MEXIT ,
.*
We start off very much the same as our other macros. We pass the address of an 80 byte buffer to read the card data into. The default device address for the card reader is x’00c’. We also have the two forms of the macro GEN=YES/No.
We use @RGCK to get the buffer address into register 1 and then all our @CARD subroutine.
.GEN ANOP ,
@CARD STM R14,R12,12(R13) SAVE CALLERS REGISTERS
ST R1,@&NDX.90 SAVE BUFFER ADDR INTO CCW
MVI @&NDX.90,X'02' READ CARD
LA R2,80 DATA LENGTH
ST R2,@&NDX.90+4 SAVE INTO CCW
LA R2,@&NDX.90 POINT TO CCW
ST R2,72 SAVE INTO CAW
@RGCK &DEV,REG=R2 DEVICE ADDRESS
SIO 0(R2) START I/O
BNZ @&NDX.03 BRANCH IF ERROR
The @CARD subroutine starts by saving the caller’s registers. We then start building the CCW by storing the buffer address. We set the CCW opcode to X’02’ to read a card and set the data length to 80.
After saving the CCW address into the CAW we issue the SIO and check to see if it was accepted.
@&NDX.01 DS 0H
TIO 0(R2) WAIT FOR I/O TO COMPLETE
BZ @&NDX.02 COMPLETE
BC 1,@&NDX.03 ERROR
B @&NDX.01
*
@&NDX.02 DS 0H
LA R15,0 SET RC
CLC @&NDX.91,68 CHANNEL END + DEVICE END ?
BE @&NDX.04 YES - RC=0
LA R15,8 RC =8
B @&NDX.04
We use a TIO loop to wait for the I/O to complete and then check to the CSW for normal completion (Only Channel End + Device End). If there are no error conditions we will return to the caller with a return code of 0. For any type of exceptional condition we will return a value of 8.
@&NDX.03 DS 0H
LA R15,8
@&NDX.04 DS 0H
L R14,12(,R13) RESTORE R14
LM R0,R12,20(R13) RESTORE R0-R12
BR R14 RETURN TO CALLER
*
DS 0D
@&NDX.90 DC X'00',AL3(0),X'00',X'00',AL2(0) CCW
@&NDX.91 DC X'0C00' CHANNEL END - DEVICE END
MEND ,
When we reach label @&NDX.04 we have our return code loaded into register 15. Now we need to restore all the registers except R15 so we don’t wipe out our return code value.
Full Macro Listing Below:
MACRO
&NAME @CARD &BUF,&DEV=X'00C',&GEN=NO
LCLC &NDX
&NDX SETC '&SYSNDX'
AIF ('&GEN' EQ 'YES').GEN
.*
&NAME @RGCK &BUF,REG=R1
LA R15,@CARD
BALR R14,R15
MEXIT ,
.*
.*
.GEN ANOP ,
@CARD STM R14,R12,12(R13) SAVE CALLERS REGISTERS
ST R1,@&NDX.90 SAVE BUFFER ADDR INTO CCW
MVI @&NDX.90,X'02' READ CARD
LA R2,80 DATA LENGTH
ST R2,@&NDX.90+4 SAVE INTO CCW
LA R2,@&NDX.90 POINT TO CCW
ST R2,72 SAVE INTO CAW
@RGCK &DEV,REG=R2 DEVICE ADDRESS
SIO 0(R2) START I/O
BNZ @&NDX.03 BRANCH IF ERROR
@&NDX.01 DS 0H
TIO 0(R2) WAIT FOR I/O TO COMPLETE
BZ @&NDX.02 COMPLETE
BC 1,@&NDX.03 ERROR
B @&NDX.01
*
@&NDX.02 DS 0H
LA R15,0 SET RC
CLC @&NDX.91,68 CHANNEL END + DEVICE END ?
BE @&NDX.04 YES - RC=0
LA R15,8 RC =8
B @&NDX.04
*
@&NDX.03 DS 0H
LA R15,8
@&NDX.04 DS 0H
L R14,12(,R13) RESTORE R14
LM R0,R12,20(R13) RESTORE R0-R12
BR R14 RETURN TO CALLER
*
DS 0D
@&NDX.90 DC X'00',AL3(0),X'00',X'00',AL2(0) CCW
@&NDX.91 DC X'0C00' CHANNEL END - DEVICE END
MEND ,
[Next – Testing The Macros – ABSTEST2]