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]