skip book previous and next navigation links
go up to top of book: HP OpenVMS I/O User's Reference Manual HP OpenVMS I/O User's Reference Manual
go to beginning of chapter: Magnetic Tape Drivers Magnetic Tape Drivers
go to previous page: I/O Status Block I/O Status Block
go to next page: Mailbox DriverMailbox Driver
end of book navigation links

Magnetic Tape Drive Programming Examples  



This section presents magnetic tape driver VAX MACRO programming examples.

Device Characteristic Program Example shows the recommended sequence for changing a device characteristic. It retrieves the current characteristics using an IO$_SENSEMODE request, sets the new characteristics bits, and then uses IO$_SETMODE to set the new characteristics.

Set Mode and Sense Mode Program Example shows ways of specifying sense mode and set mode, both with and without a user buffer specified, and with user buffers of different lengths.

In addition, MAGNETIC_TAPE.MAR Device Characteristic Program Example shows how data is written to and read from magnetic tape through the magnetic tape ACP.
Example 2  Device Characteristic Program Example  
$QIOW_S -                                ; Get current characteristics.
        FUNC      = #IO$_SENSEMODE,-     ; - Sense mode
        CHAN      = CHANNEL,-            ; - Channel
        IOSB      = IO_STATUS,-          ; - IOSB
        P1        = BUFFER,-             ; - User buffer supplied
        P2        = #12                  ; - Buffer length = 12
        .
        .
        .
(Check for errors)
        .
        .
        .
(Set desired characteristics bits)
        .
        .
        .
 
$QIOW_S -                                ; Set new characteristics.
        FUNC      = #IO$_SETMODE,-       ; - Set Mode
        CHAN      = CHANNEL,-            ; - Channel
        IOSB      = IO_STATUS,-          ; - IOSB
        P1        = BUFFER,-             ; - User buffer address
        P2        = #12                  ; - Buffer length = 12
        .
        .
        .
(Check for errors)
        .
        .
        .


Example 3  Set Mode and Sense Mode Program Example  
        .PSECT        IMPURE, NOEXE, NOSHR
 
        $IODEF
 
 
DEVICE_NAME:                                  ; Name of device
        .ASCID        /MUA0/                  ;
 
CHANNEL:                                      ; Channel to device
        .WORD        0                        ;
           
BUFFER: .BLKL        3                        ; Set/Sense characteristics
                                              ;  buffer
 
IO_STATUS:                                    ; Final I/O status
        .QUAD        0                        ;
 
 
        .PSECT        CODE, RD, NOWRT, EXE
 
        .ENTRY        MAIN,^M
$ASSIGN_S -                           ; Assign a channel to device
          DEVNAM      = DEVICE_NAME,-   ;
          CHAN        = CHANNEL         ;
 
BSBW    ERR_CHECK2                    ; Check for errors
 
$QIOW_S -                             ; Get current characteristics
          FUNC        = #IO$_SENSEMODE,-; No user buffer supplied
          CHAN        = CHANNEL,-       ;
          IOSB        = IO_STATUS       ;
 
BSBW      ERR_CHECK                     ; Check for errors
 
 
$QIOW_S -                             ; Get current characteristics
         FUNC        = #IO$_SENSEMODE,-; User buffer supplied, length
         CHAN        = CHANNEL,-       ;  defaulted
         IOSB        = IO_STATUS,-     ;
         P1          = BUFFER          ;
 
BSBW     ERR_CHECK                     ; Check for errors
 
$QIOW_S -                             ; Get current characteristics
         FUNC        = #IO$_SENSEMODE,-; User buffer supplied, length
         CHAN        = CHANNEL,-       ;  = 8
         IOSB        = IO_STATUS,-     ;
          P1          = BUFFER,-        ;
          P2          = #8              ;
 
BSBW    ERR_CHECK                     ; Check for errors
 
 
$QIOW_S -                             ; Get extended characteristics
        FUNC        = #IO$_SENSEMODE,-; User buffer supplied, length
        CHAN        = CHANNEL,-       ;  = 12
        IOSB        = IO_STATUS,-     ;
        P1        = BUFFER,-          ;
        P2        = #12               ;
 
BSBW    ERR_CHECK                     ; Check for errors
 
$QIOW_S 
         FUNC        = #IO$_SETMODE,-  ; Length defaulted
         CHAN        = CHANNEL,-       ;
         IOSB        = IO_STATUS,-     ;
         P1          = BUFFER          ;
 
BSBW    ERR_CHECK                     ; Check for errors
 
 
$QIOW_S -                             ; Set new characteristics
         FUNC        = #IO$_SETMODE,-  ; Length = 8
         CHAN        = CHANNEL,-       ;
         IOSB        = IO_STATUS,-     ;
         P1          = BUFFER,-        ;
         P2          = #8              ;
 
BSBW    ERR_CHECK                     ; Check for errors
 
 
$QIOW_S -                             ; Set extended characteristics
        FUNC        = #IO$_SETMODE,-  ; Length = 12
        CHAN        = CHANNEL,-       ;
        IOSB        = IO_STATUS,-     ;
        P1        = BUFFER,-          ;
        P2        = #12               ;
 
BSBW    ERR_CHECK                     ; Check for errors
 
 
RET
 
 
        .ENABLE LSB
 
ERR_CHECK:
        BLBS    IO_STATUS,ERR_CHECK2          ; Continue if good IOSB
        MOVZWL  IO_STATUS,-(SP)               ; Otherwise, set up for stop
        BRB     10$                           ; Branch to common code
 
ERR_CHECK2:
        BLBS    R0,20$                        ; Continue if good status
        PUSHL   R0                            ; Otherwise, set up for stop
10$:    CALLS        #1,G^LIB$STOP            ; Stop execution
 
20$:    RSB
 
        .DISABLE LSB
 
 
        .END        MAIN


Example 4  MAGNETIC_TAPE.MAR Device Characteristic Program Example  
; *********************************************************************
;
 
        .TITLE  MAGTAPE PROGRAMMING EXAMPLE
        .IDENT  /01/
 
;
; Define necessary symbols.
;
 
        $FIBDEF                         ;Define file information block
                                        ;symbols
        $IODEF                          ;Define I/O function codes
;
; Allocate storage for the necessary data structures.
;
 
;
; Allocate magtape device name string and descriptor.
;
 
 
 
TAPENAME:                               ;
        .LONG   20$-10$                 ;Length of name string
        .LONG   10$                     ;Address of name string
10$:    .ASCII  /TAPE/                  ;Name string
20$:                                    ;Reference label
 
;
; Allocate space to store assigned channel number.
;
 
TAPECHAN:                               ;
        .BLKW   1                       ;Tape channel number
;
; Allocate space for the I/O status quadword.
;
 
IOSTATUS:                               ;
        .BLKQ   1                       ;I/O status quadword
;
; Allocate storage for the input/output buffer.
;
 
BUFFER:                                 ;
        .REPT   256                     ;Initialize buffer to
        .ASCII  /A/                     ;contain 'A'
        .ENDR                           ;
;
; Now define the file information block (FIB), which the ACP uses
; in accessing and deaccessing the file.  Both the user and the ACP
; supply the information required in the FIB to perform these
; functions.
;
 
FIB_DESCR:                              ;Start of FIB
        .LONG   ENDFIB-FIB              ;Length of FIB
        .LONG   FIB                     ;Address of FIB
FIB:    .LONG   FIB$M_WRITE!FIB$M_NOWRITE ;Read/write access allowed
        .WORD   0,0,0                   ;File ID
        .WORD   0,0,0                   ;Directory ID
        .LONG   0                       ;Context
        .WORD   0                       ;Name flags
        .WORD   0                       ;Extend control
ENDFIB:                                 ;Reference label
 
 
 
;
; Now define the file name string and descriptor.
;
 
NAME_DESCR:                             ;
        .LONG   END_NAME-NAME           ;File name descriptor
        .LONG   NAME                    ;Address of name string
NAME:   .ASCII  "MYDATA.DAT;1"          ;File name string
END_NAME:                               ;Reference label
;
; *********************************************************************
;
;                        Start Program
;
; *********************************************************************
;
 
; The program first assigns a channel to the magnetic tape unit and
; then performs an access function to create and access a file called
; MYDATA.DAT.  Next, the program writes 26 blocks of data (the letters
; of the alphabet) to the tape.  The first block contains all A's, the
; next, all B's, and so forth.  The program starts by writing a block of
; 256 bytes, that is, the block of A's.  Each subsequent block is reduced
; in size by two bytes so that by the time the block of Z's is written,
; the size is only 206 bytes.  The magtape ACP does not allow the reading
; of a file that has been written until one of three events occurs:
;       1. The file is deaccessed.
;       2. The file is rewound.
;       3. The file is backspaced.
; In this example the file is backspaced zero blocks and then read in
; reverse (incrementing the block size every block); the data is
; checked against the data that is supposed to be there.  If no data
; errors are detected, the file is deaccessed and the program exits.
;
 
        .ENTRY  MAGTAPE_EXAMPLE,^M,R4,R5,R6,R7,R8>
 
;
; First, assign a channel to the tape unit.
;
 
        $ASSIGN_S TAPENAME,TAPECHAN     ;Assign tape unit
        CMPW    #SS$_NORMAL,R0          ;Success?
        BSBW    ERRCHECK                ;Find out
 
 
 
;
; Now create and access the file MYDATA.DAT.
;
 
        $QIOW_S CHAN=TAPECHAN,-         ;Channel is magtape
                FUNC=#IO$_CREATE!IO$M_ACCESS!IO$M_CREATE,-;Function
                -                       ;is create
                IOSB=IOSTATUS,-         ;Address of I/O status
                -                       ;word
                P1=FIB_DESCR,-          ;FIB descriptor
                P2=#NAME_DESCR          ;Name descriptor
        CMPW    #SS$_NORMAL,R0          ;Success?
        BSBW    ERRCHECK                ;Find out
 
;
; LOOP1 consists of writing the alphabet to the tape (see previous
; description).
;
 
        MOVL    #26,R5                  ;Set up loop count
        MOVL    #256,R3                 ;Set up initial byte count
                                        ;in R3
LOOP1:                                  ;Start of loop
        $QIOW_S CHAN=TAPECHAN,-         ;Perform QIOW to tape channel
                FUNC=#IO$_WRITEVBLK,-   ;Function is write virtual
                -                       ;block
                P1=BUFFER,-             ;Buffer address
                P2=R3                   ;Byte count
        CMPW    #SS$_NORMAL,R0          ;Success?
        BSBW    ERRCHECK                ;Find out
;
; Now decrement the byte count in preparation for the next write
; operation and set up a loop count for updating the character
; written; LOOP2 performs the update.
 
        SUBL2   #2,R3                   ;Decrement byte count for
                                        ;next write
        MOVL    R3,R8                   ;Copy byte count to R8 for
                                        ;LOOP2 count
        MOVAL   BUFFER,R7               ;Get buffer address in R7
LOOP2:  INCB    (R7)+                   ;Increment character
        SOBGTR  R8,LOOP2                ;Until finished
        SOBGTR  R5,LOOP1                ;Repeat LOOP1 until alphabet
                                        ;complete
 
 
 
;
; The alphabet is now complete.  Fall through LOOP1 and update the
; byte count so that it reflects the actual size of the last block
; written to tape.
;
 
        ADDL2   #2,R3                   ;Update byte count
 
;
; The tape is now read, but first the program must perform one of
; the three functions described previously before the ACP allows
; read access.  The program performs an ACP control function,
; specifying skip zero blocks.  This is a special case of skip reverse
; and causes the ACP to allow read access.
;
 
        CLRL    FIB+FIB$L_CNTRLVAL      ;Set up to space zero blocks
        MOVW    #FIB$C_SPACE,FIB+FIB$W_CNTRLFUNC ;Set up for space
                                        ;function
        $QIOW_S CHAN=TAPECHAN,-         ;Perform QIOW to tape channel
                FUNC=#IO$_ACPCONTROL,-  ;Perform an ACP control
                -                       ;function
                P1=FIB_DESCR            ;Define the FIB
        CMPW    #SS$_NORMAL,R0          ;Success?
        BSBW    ERRCHECK                ;Find out
 
;
; Read the file in reverse.
;
 
        MOVL    #26,R5                            ;Set up loop count
        MOVB    #^A/Z/,R6                         ;Get first character in R6
LOOP3:                                            ;
        MOVAL   BUFFER,R7                         ;And buffer address to R7
        $QIOW_S CHAN=TAPECHAN,-                   ;Channel is magtape
                FUNC=#IO$_READVBLK!IO$M_REVERSE,- ;Function is read
                -                                 ;reverse
                IOSB=IOSTATUS,-                   ;Define I/O status quadword
                P1=BUFFER,-                       ;And buffer address
                P2=R3                             ;R3 bytes
        CMPW    #SS$_NORMAL,R0                    ;Success?
        BSBW    ERRCHECK                          ;Find out
 
 
 
;
; Check the data read to verify that it matches the data written.
;
 
        MOVL    R3,R4                   ;Copy R3 to R4 for loop count
CHECKDATA:                              ;
        CMPB    (R7)+,R6                ;Check each character
        BNEQ    MISMATCH                ;If error, print message
        SOBGTR  R4,CHECKDATA            ;Continue until finished
        DECB    R6                      ;Go through alphabet in reverse
        ADDL2   #2,R3                   ;Update byte count by 2 for
                                        ;next block
        SOBGTR  R5,LOOP3                ;Read next block
;
; Now deaccess the file.
;
 
        $QIOW_S CHAN=TAPECHAN,-         ;Channel is magtape
                FUNC=#IO$_DEACCESS,-    ;Deaccess function
                P1=FIB_DESCR,-          ;File information block (required)
                IOSB=IOSTATUS           ;I/O status
 
;
; Deassign the channel and exit.
;
 
EXIT:   $DASSGN_S CHAN=TAPECHAN         ;Deassign channel
        RET                             ;Exit
 
;
; If an error had been detected, a program would normally
; generate an error message here.  But for this example the
; program simply exits.
;
 
MISMATCH:                               ;
        BRB     EXIT                    ;Exit
 
ERRCHECK:                               ;
        BNEQ    EXIT                    ;If not success, exit
        RSB                             ;Otherwise, return
 
        .END    MAGTAPE_EXAMPLE



go to previous page: I/O Status Block I/O Status Block
go to next page: Mailbox DriverMailbox Driver