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]