; ********************************************************************* ; .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 ; ; 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