VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 3 1 .IF DF V$$LST 2 3 .TITLE VFPRE -- Prefix Definitions 4 .IDENT /V03.00/ 5 6 .ENDC ; DF V$$LST 7 8 ; 9 ; VFPRE.MAC -- Prefix file for all Virtual Disk package modules 10 ; 11 ; ************************************************************************ 12 ; * 13 ; Although this program has been tested by the Geological Survey, * 14 ; United States Department of the Interior, no warranty, expressed or * 15 ; implied, is made by the Geological Survey as to the accuracy and * 16 ; functioning of the program and related program material nor shall * 17 ; the fact of distribution constitute any such warranty, and no respon- * 18 ; sibility is assumed by the Geological Survey in connection therewith. * 19 ; * 20 ; Full permission and consent is hereby given to DECUS and to the DECUS * 21 ; Special Interest Groups to reproduce, distribute, and publish and * 22 ; permit others to reproduce in whole or in part, in any form and * 23 ; without restriction, this program and any information relating thereto * 24 ; * 25 ; ************************************************************************ 26 ; 27 ; Define UCB offsets 28 ; 29 .MCALL UCBDF$ 30 31 000000 UCBDF$ ; Define UCB offsets 32 33 34 35 ;D$$BUG = 0 ; Enable to perform debugging 36 ;P$$LOG = 0 ; Enable to perform logging 37 38 39 .IF DF D$$BUG!P$$LOG 40 41 .MCALL PKTDF$,SHDDF$ 42 43 PKTDF$ ; Define I/O packet offsets 44 SHDDF$ ; Define Shadow recording offsets 45 46 .ENDC ; DF D$$BUG 47 48 ; 49 ; Define additional offsets that we require 50 ; 51 000000 LD$VF = 0 ; Loadable VFDRV 52 000020 MX$FIL = 16. ; Maximum of 16. container files 53 54 .IIF NDF P$$OOL .ERROR ; VFDRV requires secondary pool support 55 .IIF NDF R$$IIC .ERROR ; VFDRV requires Internal I/O Completion support 56 57 000000 .ASECT VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 3-1 58 59 000046 . = U.CNT+16 ; End of required UCB offsets 60 61 000046 U.XFLG: .BLKB 1 ; Device flags byte 62 000047 U.XFIL: .BLKB 1 ; Number of active file segments 63 000050 U.XGRP: .BLKB 1 ; Group protection code 64 000051 .BLKB 1 ; Reserved 65 000052 U.CTLP: .BLKW 1 ; Secondary block bias 66 000054 .BLKW 1 ; Secondary block displacement 67 000056 U.IOSB: .BLKW 3 ; Save area for I/O packet I/O status 68 000064 U.XLBN: .BLKW 2 ; Base LBN for current transfer 69 000070 U.ISB2: .BLKW 1 ; Bytes transferred thus far 70 000072 U.VLNK: .BLKW 1 ; Link of all virtual disk UCB's 71 72 .IF DF P$$LOG 73 74 U.SPKT: .BLKW 1 ; Link word 75 .BLKW 1 ; Length word 76 .BLKW 2 ; Sender task name 77 U.ISTS: .BLKW 2 ; Saved I/O status 78 U.PKT: .BLKB I.LGTH ; Save area for I/O packet 79 U.PKT2: .BLKB I.LGTH ; Save area for target I/O packet 80 U.MLND: .BLKB ML.LGH ; Save area for ML node 81 U.PUCB: .BLKW 1 ; TI: UCB address 82 .BLKW 1 ; Current UIC 83 .BLKW 2 ; Target MU task name 84 U.PKLN = . - U.SPKT 85 86 .ENDC ; DF P$$LOG 87 88 ; 89 ; Device flags byte (U.XFLG) bit settings 90 ; 91 000001 XF.WPR = 1 ; Device is write-protected 92 93 ; 94 ; Define Secondary Block file control offsets 95 ; 96 000000 .=0 97 98 000000 X.UCB: .BLKW 1 ; UCB address of target device 99 000002 X.FLAG: .BLKW 1 ; File flags word 100 000004 X.SIZE: .BLKW 2 ; File size in blocks 101 000010 X.OFF: .BLKW 2 ; Virtual LBN offset for this file 102 000014 X.BASE: .BLKW 2 ; Physical LBN base for this file 103 000020 X.FID: .BLKW 3 ; File ID on device 104 000026 X.LEN = . 105 ; 106 ; File flags word (X.FLAG) bit settings 107 ; 108 000001 XF.LCK = 1 ; File has lock bit set 109 000002 XF.TRN = 2 ; Volume transaction count incremented 110 000004 XF.RON = 4 ; Container file is read-only 111 112 000000 .PSECT 113 114 .IIF DF V$$LST .END VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4 1 .Title VFDRV - VF: Virtual Disk Driver 2 .Enabl Lc 3 .Ident /V03.00/ 4 ; 5 ; 6 ; VF: (Virtual Disk) device driver. 7 ; 8 ; Version: V03.00 9 ; Operating Systems: RSX-11M-PLUS V3.0 10 ; MICRO/RSX V3.0 11 ; (has NOT been tested under P/OS) 12 ; 13 ; Originally written by Ralph Stamerjohn 14 ; 15 ; Previously modified by: 16 ; 17 ; R.S. Mearns 18 ; G. Everhart 19 ; 20 ; Updated by: G. L. Maxwell 21 ; U.S. Geological Survey 22 ; 27-AUG-86 23 ; 24 ; ************************************************************************ 25 ; * 26 ; Although this program has been tested by the Geological Survey, * 27 ; United States Department of the Interior, no warranty, expressed or * 28 ; implied, is made by the Geological Survey as to the accuracy and * 29 ; functioning of the program and related program material nor shall * 30 ; the fact of distribution constitute any such warranty, and no respon- * 31 ; sibility is assumed by the Geological Survey in connection therewith. * 32 ; * 33 ; Full permission and consent is hereby given to DECUS and to the DECUS * 34 ; Special Interest Groups to reproduce, distribute, and publish and * 35 ; permit others to reproduce in whole or in part, in any form and * 36 ; without restriction, this program and any information relating thereto * 37 ; * 38 ; ************************************************************************ 39 ; 40 ; This driver and its associated tasks (AVF, DVF) provide a mechanism 41 ; for creating a logical disk drive out of one or more contiguous 42 ; container files located on Files-11 mounted volumes (which may themselves 43 ; be virtual disks). 44 ; 45 ; When an I/O request is received, the Virtual Disk driver translates the 46 ; logical block number requested for the Virtual Disk to the logical 47 ; block number on the appropriate target volume. The I/O packet is 48 ; then queued to the target volume's driver. 49 ; 50 ; The Internal I/O Completion mechanism in RSX-11M-PLUS is utilized by 51 ; this driver. (This differs from the previous implementations of the 52 ; Virtual Disk driver.) When the target volume's driver completes the I/O 53 ; operation, $IOFIN returns to this driver with the I/O packet to 54 ; perform additional processing. This is done so that Virtual Disks may 55 ; be shadowed. A disadvantage is that the Virtual Disk UCB and SCB remain 56 ; marked as busy until the I/O completes. Therefore, one UCB and one SCB are 57 ; built for each Virtual Disk unit to maximize parallelism. VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-1 58 ; 59 ; 60 ; Macro Calls 61 ; 62 .MCALL PKTDF$,SHDDF$,DCBDF$ 63 64 000000 PKTDF$ ; Define I/O packet offsets 65 000000 SHDDF$ ; Define shadow recording contol offsets 66 000000 DCBDF$ ; Define DCB offsets 67 68 ; 69 ; Local Data: 70 ; 71 .IF DF P$$LOG 72 73 .MCALL TCBDF$ 74 TCBDF$ 75 76 SERNAM: .RAD50 /VFL.../ 77 78 SERVER: .WORD 0 ; TCB address of server task 79 80 .ENDC ; DF P$$LOG 81 82 ; 83 ; Device Dispatch Table 84 ; 85 000000 DDT$ VF,0,NONE,,,NEW 86 87 ;+ 88 ; **-VFINI - Virtual Disk I/O Initiation Entry Point 89 ; 90 ; This routine is entered from the Queue I/O Directive when an I/O 91 ; request is generated by a task. The driver is called at this point 92 ; before the I/O packet is placed in the device queue. The driver 93 ; performs checks on the packet before allowing it to be queued. 94 ; 95 ; In particular, we reject all requests for the prototype unit, VF0:. 96 ; This is done specifically because the driver marks VF0: as "busy" 97 ; so that the driver may not be unloaded while virtual units with other 98 ; unique names have context. 99 ; 100 ; Inputs: 101 ; R5= Address of the UCB of the controller to be initiated. 102 ; R4= Address of the SCB of the controller to be initiated. 103 ; R1= Address of the I/O packet. 104 ; 105 ;- 106 000016 VFINI:: 107 000016 016503 000000 MOV U.DCB(R5),R3 ; Get address of the device DCB 108 000022 022763 043126 000004 CMP #<"VF>,D.NAM(R3) ; Is the device name "VF"? 109 000030 001011 BNE 10$ ; If ne no, accept the packet 110 000032 005763 000006 TST D.UNIT(R3) ; Is this VF0:? 111 000036 001006 BNE 10$ ; If ne no, accept the packet 112 000040 010103 MOV R1,R3 ; Copy the I/O packet address 113 000042 012700 000000C MOV #IE.PRI&377,R0 ; Return privilege violation 114 000046 005001 CLR R1 ; Clear bytes transfered count VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-2 115 000050 CALLR $IOFIN ; Finish the I/O and return 116 117 000054 010400 10$: MOV R4,R0 ; Copy pointer to I/O queue listhead 118 119 ; 120 ; Inputs to $QINSP: 121 ; 122 ; R0 = Address of two word listhead 123 ; R1 = Address of packet to be entered in queue 124 ; 125 ; Outputs from $QINSP: None. 126 ; 127 128 000056 CALL $QINSP ; Insert packet in I/O queue 129 130 ; 131 ; Begin serial processing of I/O packets. 132 ; 133 ; This marks where the driver initiates a new function in order to 134 ; propagate the execution of the driver. If the specified "controller" 135 ; is not busy, then an attempt is made to dequeue the next I/O request. 136 ; Else a return to the caller is executed. If the dequeue attempt 137 ; is successful, then the next I/O operation is initiated. Control 138 ; returns to the driver following completion of each virtual I/O request. 139 ; 140 ; Inputs: 141 ; 142 ; R5 = Address of the UCB of the controller. 143 ; 144 ; Outputs: 145 ; 146 ; If the specified controller is not busy and an I/O request is 147 ; waiting to be processed, then the request is dequeued and the 148 ; driver initiates the requested I/O function 149 150 000062 VFINI1:: 151 000062 CALL $GTPKT ; Get next I/O packet to process 152 000066 103001 BCC 10$ ; Proceed if there is work to do 153 000070 000207 RETURN ; Exit driver if no more work 154 000072 10$: ; Reference label 155 ; 156 ; The following arguments are returned by $GTPKT: 157 ; 158 ; R1= Adrs of the I/O request packet 159 ; R2= Physical unit number of the requested drive 160 ; R3= Controller index 161 ; R4= Adrs of the Status Control Block (SCB) 162 ; R5= Adrs of the UCB of the drive to be initiated 163 ; 164 ; Virtual Disk Driver I/O request packet format: 165 ; 166 ; WD. 00 -- I/O queue thread word 167 ; WD. 01 -- Request priority, event flag number 168 ; WD. 02 -- Adrs of the TCB of the requestor task 169 ; WD. 03 -- Pointer to 2nd Lun word in requestor task header 170 ; WD. 04 -- Contents of first Lun word (UCB adrs) 171 ; WD. 05 -- I/O function code VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-3 172 ; WD. 06 -- Virtual adrs of I/O status block 173 ; WD. 07 -- Relocation bias of I/O status block 174 ; WD. 10 -- I/O status block address (displacement +140000) 175 ; WD. 11 -- Virtual adrs of AST service routine 176 ; WD. 12 -- Memory extension bits of I/O transfer 177 ; WD. 13 -- Buffer adrs of I/O transfer 178 ; WD. 14 -- Number of bytes to be transfered 179 ; WD. 15 -- Not used. 180 ; WD. 16 -- Low byte contains high part of logical block number 181 ; WD. 17 -- Low part of logical block number of I/O request 182 ; WD. 20 -- Not used 183 ; WD. 21 -- Not used 184 ; 185 ; Driver usage of words in I/O packet: 186 ; 187 ; I.IOSB is used by the driver to store the VF: UCB address 188 ; so that it may be retrieved following the completion 189 ; of the internal I/O request 190 ; I.IOSB+2 is used to hold the APR 5 bias of this driver 191 ; I.IOSB+4 holds the internal I/O completion routine within this 192 ; driver, Or'ed with bit zero. 193 ; 194 ; I.PRM Parameter word offsets are manipulated as required 195 ; when VFDRV passes a request to another driver. 196 ; 197 198 ; 199 ; ** NOTE THE FOLLOWING ** 200 ; 201 ; There is a possibility at this point that the UCB offsets U.BUF, 202 ; U.BUF+2, and U.CNT, in addition to S.STS and U.STS, have not been 203 ; properly set up, as though we called $GSPKT instead of $GTPKT. 204 ; 205 ; This happens (only?) when this virtual device is the primary unit of 206 ; a shadowed pair, and the secondary unit's container file is located 207 ; on a device whose driver uses $GSPKT (e.g., DUDRV), and the I/O 208 ; function is IO.WLB. The following scenario occurs: 209 ; 210 ; 1. $GTPKT is called to obtain the primary packet 211 ; 2. Since the function is a write, $GTPKT queues the secondary 212 ; packet to the secondary device (another virtual disk); 213 ; if the secondary device is idle, it is called. 214 ; 3. $GTPKT is called again to retrieve the secondary packet. 215 ; 4. The secondary packet is processed and passed to the 216 ; target driver; if it is idle, it is called. 217 ; 5. The target driver calls $GSPKT to obtain the packet and 218 ; starts processing. The low core location $TEMP2 is loaded 219 ; with the address of the driver's acceptance routine. 220 ; 6. Return is eventually made to the $GTPKT context for the 221 ; primary packet. 222 ; 7. Since $TEMP2 now holds the non-standard acceptance routine 223 ; vector, the primary unit's data structures are not 224 ; initialized, and the unit is not marked busy. 225 ; 226 ; Hence, the following code is inserted here.... 227 ; 228 VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-4 229 000072 105764 000000G TSTB S.STS(R4) ; Have we been marked busy? 230 000076 001016 BNE 20$ ; If ne yes, data structures are OK 231 000100 016165 000024 000024 MOV I.PRM(R1),U.BUF(R5) ; Set up UCB structures for later 232 000106 016165 000026 000026 MOV I.PRM+2(R1),U.BUF+2(R5) 233 000114 016165 000030 000030 MOV I.PRM+4(R1),U.CNT(R5) 234 000122 105264 000000G INCB S.STS(R4) ; Mark SCB as busy 235 000126 152765 000200 000005 BISB #US.BSY,U.STS(R5) ; Mark UCB as busy 236 000134 20$: ; Reference label 237 238 .IF DF P$$LOG 239 240 ; Copy the packet into the area in the UCB 241 242 MOV R5,R0 ; Copy the UCB address 243 ADD #U.PKT,R0 ; Point to the area to store it 244 MOV R1,R2 ; Copy the I/O packet address 245 MOV #I.LGTH/2,R3 ; Length of packet 246 29000$: MOV (R2)+,(R0)+ ; Copy the packet 247 SOB R3,29000$ ; Until done 248 249 .ENDC ; DF P$$LOG 250 251 ; 252 ; *** NOTE *** 253 ; 254 ; Disk Data Caching currently does not work (the system crashes), although 255 ; the author does not know why. 256 ; 257 ; If some brave soul figures it out, be sure to enable the following code, 258 ; and enable IO.STC as a valid control function in the driver dispatch table. 259 ; 260 ; If this is a control function, always return success. IO.STC is 261 ; a case we want to handle in the driver (instead of making it a no-op) 262 ; so that virtual disks can be cached. 263 ; 264 ; 265 ; CMPB #IO.STC/256.,I.FCN+1(R1) ; Control function? 266 ; BNE 30$ ; If ne no 267 ; MOV #IS.SUC&377,R0 ; Get final status 268 ; JMP VFALT ; And finish I/O 269 ;30$: ; Reference label 270 271 ; 272 ; ** Block Check the I/O request ** 273 ; 274 ; Inputs to $BLKCK: 275 ; 276 ; R1 Contains the I/O packet address 277 ; R5 Contains the UCB address 278 ; 279 ; Outputs from $BLKCK: 280 ; 281 ; R0 Contains the low order 16 bits of the starting LBN 282 ; R1 Points to I.PRM+12 (low order LBN value) 283 ; R2 Contains the high order bits of the starting LBN 284 ; R3 Contains the I/O Packet address 285 ; VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-5 286 000134 CALL $BLKCK ; Perform Block check (no return on error) 287 ; 288 ; Check function code for transfer function. All others should have 289 ; been no-op'ed by now. 290 ; 291 000140 122763 000000C 000013 CMPB #IO.RLB/256.,I.FCN+1(R3) ; Read logical? 292 000146 103405 BLO 100$ ; If lo then invalid function 293 000150 001420 BEQ 200$ ; Go process read request 294 295 000152 122763 000000C 000013 CMPB #IO.WLB/256.,I.FCN+1(R3) ; Write logical? 296 000160 001404 BEQ 190$ ; If eq do write protect check 297 000162 012700 000000C 100$: MOV #IE.IFC&377,R0 ; Get invalid function code 298 000166 000167 000662 JMP VFALT ; And terminate I/O 299 ; 300 ; Check if this unit was created as a read-only device 301 ; (akin to hardware write protect) 302 ; 303 000172 132765 000001 000046 190$: BITB #XF.WPR,U.XFLG(R5) ; Write-protected device? 304 000200 001404 BEQ 200$ ; If eq no -- accept request 305 000202 012700 000000C MOV #IE.WLK&377,R0 ; Get write-lock error 306 000206 000167 000642 JMP VFALT ; Terminate I/O 307 ; 308 ; At this point, we are ready to initiate the I/O. 309 ; 310 ; First, perform preliminary manipulations on the I/O packet 311 ; and initialize our context variables 312 ; 313 000212 016365 000014 000056 200$: MOV I.IOSB(R3),U.IOSB(R5) ; Save I/O status virtual address 314 000220 016365 000016 000060 MOV I.IOSB+2(R3),U.IOSB+2(R5) ; Save I/O status bias 315 000226 016365 000020 000062 MOV I.IOSB+4(R3),U.IOSB+4(R5) ; Save I/O status displacement 316 317 000234 010563 000014 MOV R5,I.IOSB(R3) ; Save our UCB address in the packet 318 000240 016763 000000G 000016 MOV KISAR5,I.IOSB+2(R3) ; Save our own bias for I/O completion 319 000246 012763 000000C 000020 MOV #,I.IOSB+4(R3) ; Save I/O completion entry point 320 321 000254 010265 000064 MOV R2,U.XLBN(R5) ; Save high order starting LBN 322 000260 010065 000066 MOV R0,U.XLBN+2(R5) ; Save low order starting LBN 323 000264 005065 000070 CLR U.ISB2(R5) ; Clear working I/O status word 2 cell 324 000270 012704 140000 MOV #140000,R4 ; Initialize secondary block displacement 325 ; 326 ; We like to work with buffer addresses as 22-bit quantities. Since we have 327 ; set UC.NPR in our UCB, we get a 22 bit buffer address in U.BUF and U.BUF+2 328 ; (with the high order 6 bits in the upper byte of U.BUF). 329 ; However, if we are running on an 18-bit machine, $MPPHY shoves the high 330 ; order 2 bits into bits 4 and 5 of U.BUF. Hence, the following conditional: 331 ; 332 333 .IF NDF M$$EXT 334 335 MOV U.BUF(R5),R1 ; Get high order bits of buffer address 336 ASH #4,R1 ; Shift them back to the high byte 337 MOV R1,U.BUF(R5) ; And store them back 338 339 .ENDC ; NDF M$$EXT 340 341 ; 342 ; Verify that the secondary block bias is non-zero. This should VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-6 343 ; only happen for a deassigned device which somehow was not marked 344 ; offline. I don't see how that could happen, but if I don't check 345 ; for it, it probably would happen.... 346 ; 347 000274 016501 000052 MOV U.CTLP(R5),R1 ; Get the secondary block bias 348 000300 001004 BNE 290$ ; If ne it exists 349 000302 012700 000000C MOV #IE.DNR&377,R0 ; Return device not ready 350 000306 000167 000542 JMP VFALT ; Finish the I/O 351 352 000312 010167 000000G 290$: MOV R1,KISAR6 ; Map secondary control block 353 354 ; 355 ; Now we look for the file which we will use for the first part of the 356 ; transfer. At this point: 357 ; 358 ; R0 contains low order starting LBN 359 ; R2 contains high order LBN 360 ; R4 contains the secondary block displacement. 361 ; 362 000316 166400 000006 300$: SUB X.SIZE+2(R4),R0 ; Subtract size of next file 363 000322 005602 SBC R2 ; Propagate a borrow 364 000324 166402 000004 SUB X.SIZE(R4),R2 ; Subtract high order 365 000330 002403 BLT VFNEXT ; If LT then we start with this file 366 000332 062704 000026 ADD #X.LEN,R4 ; Point to the next file block 367 000336 000767 BR 300$ ; And try again 368 ; 369 ; ** Top of Dispatch Loop ** 370 ; 371 ; Label VFNEXT marks the start of processing to dispatch the virtual request 372 ; to the next driver. This code calculates the starting LBN and size of 373 ; the request to pass on to the driver, and updates the buffer address 374 ; and total size of transfer as required. 375 ; 376 ; Register usage during this part of the code: 377 ; 378 ; R5 Virtual device UCB address 379 ; R4 Secondary block address (points to current file) 380 ; R3 I/O Packet address 381 ; R0-R2 Scratch variables 382 ; 383 ; First, calculate offset into this file where we begin the transfer 384 ; 385 000340 122763 000000C 000013 VFNEXT: CMPB #IO.WLB/256.,I.FCN+1(R3) ; Write logical? 386 000346 001010 BNE 400$ ; If ne no -- bypass read-only check 387 000350 032764 000004 000002 BIT #XF.RON,X.FLAG(R4) ; Read-only container file? 388 000356 001404 BEQ 400$ ; If eq no -- accept request 389 000360 012700 000000C MOV #IE.WLK&377,R0 ; Get write-lock error 390 000364 000167 000430 JMP VFDON ; Terminate I/O 391 392 000370 016500 000064 400$: MOV U.XLBN(R5),R0 ; Get high order starting LBN 393 000374 016501 000066 MOV U.XLBN+2(R5),R1 ; Get low order LBN 394 000400 166401 000012 SUB X.OFF+2(R4),R1 ; Subtract VF: base offset on this file 395 000404 005600 SBC R0 396 000406 166400 000010 SUB X.OFF(R4),R0 ; R0,R1 hold LBN offset into this file 397 000412 010063 000034 MOV R0,I.PRM+10(R3) ; Store offset in I/O packet 398 000416 010163 000036 MOV R1,I.PRM+12(R3) ; 399 000422 066463 000016 000036 ADD X.BASE+2(R4),I.PRM+12(R3) ; Add physical base LBN of file VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-7 400 000430 005563 000034 ADC I.PRM+10(R3) 401 000434 066463 000014 000034 ADD X.BASE(R4),I.PRM+10(R3) ; Physical LBN of target device 402 ; 403 ; Now calculate how much of our remaining I/O request can be satisfied 404 ; 405 000442 016402 000006 MOV X.SIZE+2(R4),R2 ; Get low order file size 406 000446 160102 SUB R1,R2 ; Subtract starting LBN 407 000450 016401 000004 MOV X.SIZE(R4),R1 ; Get high order size (preserve carry) 408 000454 005601 SBC R1 ; Propagate a borrow 409 000456 160001 SUB R0,R1 ; R1,R2 contain remaining blocks in file 410 ; 411 ; *** BUGCHECK -- Remaining blocks had better be greater than zero! 412 ; 413 .IF DF D$$BUG!X$$DBT 414 415 BLT 420$ ; If LT then crash 416 MOV R1,R0 ; Copy high order size 417 BIS R2,R0 ; Check for no blocks 418 BNE 430$ ; We're OK 419 420$: BPT ; Breakpoint 420 430$: TST R1 ; Test result for following branch 421 422 .ENDC ; DF D$$BUG!X$$DBT 423 424 ; 425 ; If the high order remaining blocks is non-zero, we can always finish 426 ; the complete transfer on this file, since the largest possible 427 ; transfer is 64K bytes. 428 ; 429 000460 001021 BNE 440$ ; If high order not zero, complete transfer 430 ; 431 ; Now calculate how much of the transfer we can perform now. 432 ; 433 000462 016500 000030 MOV U.CNT(R5),R0 ; Get remaining transfer size 434 000466 062700 000777 ADD #777,R0 ; Round up to next block 435 ; 436 ; We use the following instead of ASH because it is faster (honest!) 437 ; 438 000472 006000 ROR R0 ; Number of blocks in high byte 439 000474 105000 CLRB R0 ; Clear low order garbage 440 000476 000300 SWAB R0 ; Number of blocks remaining in transfer 441 000500 020200 CMP R2,R0 ; Compare blocks left with transfer size 442 000502 103010 BHIS 440$ ; If his then we can finish entire transfer 443 000504 010201 MOV R2,R1 ; We can transfer this many blocks 444 ; 445 ; Update the base LBN offset in the UCB for the next portion of the 446 ; transfer. Note that this offset is NOT updated if we can complete 447 ; the entire operation at this time. 448 ; 449 000506 060265 000066 ADD R2,U.XLBN+2(R5) ; Add transfer size in blocks to base LBN 450 000512 005565 000064 ADC U.XLBN(R5) ; Propagate carry 451 452 000516 000301 SWAB R1 ; Convert blocks back to bytes 453 000520 006101 ROL R1 ; Remaining bytes in file 454 000522 000402 BR 450$ ; Proceed 455 456 000524 016501 000030 440$: MOV U.CNT(R5),R1 ; Perform remaining amount of transfer VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-8 457 458 000530 010163 000030 450$: MOV R1,I.PRM+4(R3) ; Store number of bytes in I/O packet 459 000534 160165 000030 SUB R1,U.CNT(R5) ; Subtract from total transfer size 460 ; 461 ; We are through with the secondary block now. Save the current secondary 462 ; block pointer in case we need it to do another segment, and retrieve 463 ; the UCB address of the target disk. 464 ; 465 000540 010465 000054 MOV R4,U.CTLP+2(R5) ; Save secondary block address 466 000544 016404 000000 MOV X.UCB(R4),R4 ; Get the target device UCB address 467 000550 010463 000010 MOV R4,I.UCB(R3) ; Store in the I/O packet 468 ; 469 ; Now convert the current buffer address to an APR 6 bias and displacement 470 ; for non-NPR devices. For 18 bit devices, put the high order two bits 471 ; in bits 4:5, and for the others (11/70 type devices), we're already 472 ; set. 473 ; 474 000554 016500 000024 MOV U.BUF(R5),R0 ; Get high order buffer address 475 000560 016501 000026 MOV U.BUF+2(R5),R1 ; Get low order buffer address 476 000564 132764 000100 000004 BITB #UC.NPR,U.CTL(R4) ; NPR device? 477 000572 001010 BNE 480$ ; If ne yes, no major conversion necessary 478 000574 000300 SWAB R0 ; Get high bits into low byte 479 000576 073027 000012 ASHC #10.,R0 ; Calculate bias 480 000602 073127 177766 ASHC #-10.,R1 ; Calculate displacement 481 000606 062701 140000 ADD #140000,R1 ; Make it an APR 6 displacement 482 000612 000400 BR 490$ ; And proceed 483 484 000614 480$: 485 .IF NDF M$$EXT 486 487 ASH #-4.,R0 ; Put bits <17:18> into <4:5> 488 489 .ENDC ; NDF M$$EXT 490 491 000614 010063 000024 490$: MOV R0,I.PRM(R3) ; Store high order buffer address 492 000620 010163 000026 MOV R1,I.PRM+2(R3) ; Store low order buffer address 493 000624 066365 000030 000026 ADD I.PRM+4(R3),U.BUF+2(R5) ; Update the buffer address 494 000632 105565 000025 ADCB U.BUF+1(R5) ; Propagate to high order address 495 ; 496 ; The last killer. The target device we are about to dispatch to may 497 ; be shadowed. This may pose a problem as an ML node will not exist 498 ; at this time (ML nodes are allocated in $DRQIO, and we're way past 499 ; that step!). Hence, the following code is pirated from DRQIO to 500 ; create an ML node. 501 ; 502 000636 010405 MOV R4,R5 ; Copy UCB address of target device 503 000640 016502 000040 MOV U.UMB(R5),R2 ; Get UMB address for target device 504 000644 001431 BEQ 600$ ; If eq then no UMB 505 000646 032762 000001 000010 BIT #MS.MDA,M.STS(R2) ; Can we allocate new nodes? 506 000654 001025 BNE 600$ ; If ne no 507 000656 012701 000060 MOV #ML.LGH,R1 ; Get node length 508 000662 CALL $ALOCB ; Allocate an ML node 509 000666 103004 BCC 500$ ; If cc then we got one 510 ; 511 ; As commented in DRQIO, it's a shame we have to kill the I/O simply 512 ; because we could not allocate an ML node. Most of the requests will 513 ; be reads, which will be satisfied by the primary I/O. All well... VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-9 514 ; 515 000670 012700 000000C MOV #IE.UPN&377,R0 ; Insufficient DSR 516 000674 000167 000154 JMP VFALT ; And terminate I/O 517 518 000700 010001 500$: MOV R0,R1 ; Copy ML node address 519 000702 005020 CLR (R0)+ ; Clear link word 520 000704 012720 000460 MOV #+ML.LGH,(R0)+ ; Set length and type 521 000710 005020 CLR (R0)+ ; ML.DNC/unused; set done count 522 000712 010320 MOV R3,(R0)+ ; Store primary I/O packet address 523 000714 016500 000040 MOV U.UMB(R5),R0 ; Retrieve UMB address 524 000720 016011 000002 MOV M.LHD(R0),(R1) ; Link first node into this one 525 000724 010160 000002 MOV R1,M.LHD(R0) ; Make this node the first one 526 ; 527 ; Pass the I/O packet along to the next victim and return to caller 528 ; 529 ; Arguments to $DRQRQ: 530 ; 531 ; R1 Contains the I/O packet address 532 ; R5 Contains the address of the UCB for the target device 533 ; 534 ; The driver for the target device is invoked. We regain control when 535 ; the target device completes the I/O. 536 ; 537 000730 010301 600$: MOV R3,R1 ; Copy I/O packet address 538 539 .IF DF P$$LOG 540 541 ; Copy the target I/O packet 542 543 MOV I.IOSB(R3),R0 ; Get virtual device UCB address 544 ADD #U.PKT2,R0 ; Point to the save area 545 MOV #I.LGTH/2,R2 ; Words to copy 546 29500$: MOV (R3)+,(R0)+ ; Copy I/O packet 547 SOB R2,29500$ ; Until done 548 549 .ENDC ; DF P$$LOG 550 551 000732 CALLR $DRQRQ ; Dispatch the I/O and return 552 553 ;+ 554 ; 555 ; ** VFRET -- Internal I/O completion routine 556 ; 557 ; This code is entered from the $IOFIN routine after the target device 558 ; has completed the I/O packet (including any shadowing). 559 ; 560 ; Inputs from $IOFIN: 561 ; 562 ; R3 I/O Packet address 563 ; R5 UCB address of target device 564 ; I.PRM+6 First I/O status word returned from target device 565 ; I.PRM+10 Second I/O status word returned from target device 566 ; 567 ; Required outputs: 568 ; 569 ; R5 must still contain the UCB address for the target device, 570 ; as $IOFIN will return to the target driver. VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-10 571 ; 572 ; Processing proceeds as follows: 573 ; 574 ; Push the UCB address of the target device and push the address 575 ; of an internal routine to restore the target UCB address before 576 ; return is made to $IOFIN. This allows us to propagate ourselves 577 ; while ensuring that the target driver will be properly restored. 578 ; 579 ; If an I/O error was returned, then terminate this I/O 580 ; with the I/O status and the actual bytes transfered. 581 ; 582 ; If the I/O completed successfully, determine if we have completed 583 ; the entire transfer. If not, branch back to label VFNEXT to initiate 584 ; the next part of this transfer. If we have finished everything, 585 ; restore the I/O packet, call $IODON, and look for more work to do. 586 ; 587 000736 VFRET:: 588 000736 010546 MOV R5,-(SP) ; Save the target UCB address 589 000740 012746 001066' MOV #VFRST,-(SP) ; Force driver exit to restore routine 590 000744 016305 000014 MOV I.IOSB(R3),R5 ; Recover our UCB address 591 000750 066365 000034 000070 ADD I.PRM+10(R3),U.ISB2(R5) ; Accumulate actual bytes transferred 592 000756 016300 000032 MOV I.PRM+6(R3),R0 ; Get the returned I/O status 593 000762 122700 000000G CMPB #IS.SUC,R0 ; Successful status returned? 594 000766 001014 BNE VFDON ; If ne no - terminate I/O 595 596 000770 005765 000030 TST U.CNT(R5) ; Check for more work to do 597 000774 001411 BEQ VFDON ; If eq then we have finished I/O 598 000776 016567 000052 000000G MOV U.CTLP(R5),KISAR6 ; Map secondary block 599 600 001004 016504 000054 MOV U.CTLP+2(R5),R4 ; Get secondary block displacement pointer 601 001010 062704 000026 ADD #X.LEN,R4 ; Point to the next file block 602 001014 000167 177320 JMP VFNEXT ; And resume I/O processing 603 604 001020 016501 000070 VFDON: MOV U.ISB2(R5),R1 ; Get second I/O status word 605 001024 010563 000010 MOV R5,I.UCB(R3) ; Restore our UCB in I/O packet 606 001030 016563 000056 000014 MOV U.IOSB(R5),I.IOSB(R3) ; Restore I/O status virtual address 607 001036 016563 000060 000016 MOV U.IOSB+2(R5),I.IOSB+2(R3) ; Restore I/O status bias 608 001044 016563 000062 000020 MOV U.IOSB+4(R5),I.IOSB+4(R3) ; Restore I/O status displacement 609 610 .IF DF P$$LOG 611 612 MOV R5,-(SP) ; Save our UCB address 613 MOV R0,U.ISTS(R5) ; Save first I/O status word 614 MOV R1,U.ISTS+2(R5) ; Save second I/O status word 615 TST SERVER ; Anybody there? 616 BEQ 29600$ ; If eq no 617 618 MOV R5,U.PUCB(R5) ; Store our UCB for kicks 619 MOV R5,R0 ; Copy UCB address 620 ADD #U.MLND,R0 ; Point to the save area 621 CLR (R0) ; Assume one does not exist 622 CALL $SHFND ; Look for ML node 623 BCS 29510$ ; If CS then not there 624 MOV R4,(R0)+ ; Store address of ML node in link 625 MOV #-1,R1 ; Number of words to move 626 TST (R4)+ ; Skip over link word 627 29505$: MOV (R4)+,(R0)+ ; Store ML node VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-11 628 SOB R1,29505$ ; Until done 629 630 29510$: MOV #U.PKLN,R1 ; Length of packet 631 ADD #77,R1 ; Round up 632 ASH #-6,R1 ; Convert to 32 word blocks 633 CALL $ALSEC ; Allocate the pool 634 BCS 29600$ ; All well, give up 635 MOV KISAR6,-(SP) ; Save APR6 636 MOV R0,KISAR6 ; Map the packet 637 MOV #140000,R0 ; Point to the packet 638 MOV R5,R1 ; Copy the UCB 639 ADD #U.SPKT,R1 ; Point to the packet 640 MOV #U.PKLN/2,R2 ; Length of packet in words 641 29550$: MOV (R1)+,(R0)+ ; Copy the packet 642 SOB R2,29550$ ; Until done 643 MOV KISAR6,R1 ; Get packet address 644 MOV (SP)+,KISAR6 ; Restore APR6 645 MOV SERVER,R0 ; Get TCB address of server 646 ADD #T.RCVL,R0 ; Point to receive queue listhead 647 CALL $QSPIF ; Queue the packet 648 MOV SERVER,R0 ; Get the TCB address again 649 CALL $EXRQN ; Request the task 650 651 29600$: MOV (SP)+,R5 ; Get back UCB address 652 MOV U.ISTS(R5),R0 ; Get back first I/O status word 653 MOV U.ISTS+2(R5),R1 ; Get back second I/O status word 654 655 .ENDC ; DF P$$LOG 656 657 001052 000401 BR VFFIN ; Finish I/O 658 659 001054 005001 VFALT: CLR R1 ; Return I/O status word 2 660 661 ; 662 ; Arguments to $IODON: 663 ; 664 ; R0 - First I/O status word 665 ; R1 - Second I/O status word 666 ; R5 - UCB address of device 667 ; S.PKT is assumed to contain the I/O packet address 668 ; 669 670 001056 VFFIN: CALL $IODON ; Finish I/O 671 001062 000167 176774 JMP VFINI1 ; And look for more work to do 672 673 ; 674 ; ** VFRST -- Restore UCB address and return to $IOFIN 675 ; 676 ; This code is executed as the final step of the internal I/O completion 677 ; routine. 678 ; 679 ; Inputs: (SP) Address of target device UCB 680 ; 2(SP) Return address of caller ($IOFIN) 681 ; 682 683 001066 012605 VFRST: MOV (SP)+,R5 ; Restore UCB address 684 001070 000207 RETURN ; And return to caller VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-12 685 686 ; 687 ; ** VFUCB -- Unit online-offline entry point 688 ; 689 ; So why do we need this? Well, if we have supplied support for 690 ; virtual disks with whatever name the user chooses, we have to do 691 ; some checks when VF0: is taken offline to make sure we won't have 692 ; "orphan" databases. 693 ; 694 ; Upon entry, our job is to scan the Virtual Disk list, looking for devices 695 ; which have current I/O activity. If they do, then we reject the 696 ; offline transition. If all devices are quiescent, then we take them 697 ; offline and clear the dispatch table address. 698 ; 699 001072 006100 VFUCB: ROL R0 ; Save the carry bit 700 001074 016504 000000 MOV U.DCB(R5),R4 ; Get DCB address for this unit 701 001100 022764 043126 000004 CMP #<"VF>,D.NAM(R4) ; Is it a VF unit? 702 001106 001061 BNE 200$ ; If ne no, accept request 703 001110 005764 000006 TST D.UNIT(R4) ; Is it VF0:? 704 001114 001056 BNE 200$ ; If ne no, accept request 705 001116 006000 ROR R0 ; Shift the carry back 706 001120 103033 BCC 100$ ; If cc then going online 707 ; 708 ; Offline transition. Check for all offspring virtual units being offline 709 ; 710 001122 010501 MOV R5,R1 ; Copy UCB address 711 001124 016101 000072 10$: MOV U.VLNK(R1),R1 ; Get next UCB 712 001130 001410 BEQ 20$ ; If eq then all are quiet 713 001132 132761 000001 000007 BITB #US.OFL,U.ST2(R1) ; Is this unit offline? 714 001140 001371 BNE 10$ ; If ne yes - proceed to next unit 715 716 001142 112767 000000G 000000G MOVB #IE.RSU,$SCERR ; Mark shareable resource in use 717 001150 000440 BR 200$ ; And return failure 718 ; 719 ; All virtual units are quiescent. Now mark all offspring units have 720 ; having "unloaded" drivers. 721 ; 722 001152 016501 000020 20$: MOV U.SCB(R5),R1 ; Get the SCB address 723 001156 105061 000000G CLRB S.STS(R1) ; Mark VF0: unit as not busy 724 001162 010501 MOV R5,R1 ; Copy UCB address 725 001164 016101 000072 30$: MOV U.VLNK(R1),R1 ; Get next UCB 726 001170 001430 BEQ 200$ ; If eq then all done 727 001172 016100 000000 MOV U.DCB(R1),R0 ; Get the DCB 728 001176 005060 000034 CLR D.PCB(R0) ; And clear the driver PCB cell 729 001202 005060 000012 CLR D.DSP(R0) ; Clear driver dispatch cell 730 001206 000766 BR 30$ ; Back for more 731 ; 732 ; Going online. "Load" the drivers of the offspring virtual units 733 ; 734 001210 016501 000020 100$: MOV U.SCB(R5),R1 ; Get the SCB address 735 001214 105261 000000G INCB S.STS(R1) ; Show VF0: as "busy" 736 001220 010501 MOV R5,R1 ; Copy the UCB address 737 001222 016101 000072 110$: MOV U.VLNK(R1),R1 ; Get next unit 738 001226 001411 BEQ 200$ ; If eq then all done 739 001230 016100 000000 MOV U.DCB(R1),R0 ; Get DCB address 740 001234 016460 000034 000034 MOV D.PCB(R4),D.PCB(R0) ; Point the device to our driver 741 001242 016460 000012 000012 MOV D.DSP(R4),D.DSP(R0) ; Point to our dispatch table VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-13 742 001250 000764 BR 110$ ; And proceed 743 744 001252 200$: 745 .IF DF P$$LOG 746 747 CLR SERVER ; Assume no server alive 748 MOV #SERNAM,R3 ; Point to server task name 749 CALL $SRSTD ; Search for it 750 BCS 29900$ ; Not found 751 MOV R0,SERVER ; Save the TCB address 752 29900$: 753 754 .ENDC ; DF P$$LOG 755 756 001252 000207 RETURN ; Return to caller 757 758 ; 759 ; Alternate driver entry points. 760 ; 761 ; These are all effective no-op's, as the conditions will either be 762 ; handled by the target devices or serve no useful function 763 ; 764 765 001254 VFPWF: ; Power fail entry point: let others handle 766 001254 VFCAN: ; I/O Kill entry point: we CAN'T do anything! 767 001254 VFOUT: ; Timeout entry point: let others handle 768 001254 VFKRB: ; Controller online/offline: we ain't got one 769 001254 000207 RETURN 770 771 000001 .END VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-14 Symbol table AB.CTC= 000004 A.OUTP 000010 C.CSTS 000010 D.VTIN= 177772 I.LGTH= 000050 AB.NPV= 000001 A.PLEN= 000016 C.CTCB 000002 D.VTOU= 177770 I.LNK 000000 AB.TYP= 000002 A.PLGH= 000070 C.CTR 000014 D.VUCB= 000012 I.LN2 000006 AF.AST= 000010 A.POWE 000004 C.CTXT 000016 E$$DVC= 000000 I.PRI 000002 AF.ESQ= 000020 A.PRM 000012 C.CUCB 000004 E$$ICM= 000000 I.PRM 000024 AF.LCK= 000040 A.PROC 000020 C.PCPL 000011 E$$LOG= 000000 I.R0 = 000024 AF.MDE= 000200 A.RECE 000016 C.PDPL 000010 E$$MOU= 000000 I.R1 = 000026 AF.NOT= 000002 A.REL 000000 C.PNAM 000002 E$$NSI= 000000 I.TCB 000004 AF.OOB= 000004 A.RES = 000032 C.PRMT 000012 E$$PER= 000000 I.UCB 000010 AF.QUE= 000100 A.SBUF 000022 C.PSTS 000006 E$$SEF= 000000 I.XDBF 000040 AF.XCC= 000001 A.SLEN 000024 C.PTCB 000000 E$$XPR= 000000 I.XDBL 000044 AK.BUF= 000200 A.SMAP 000020 DU$C0 = 000004 F$$DVN= 000000 I.XIOP 000002 AK.DIO= 000204 A.STA 000015 DU$R0 = 000004 F$$LPP= 000000 I.XLEN= 000046 AK.GBI= 000202 A.TRAN 000022 DV.CCL= 000002 F$$LVL= 000001 I.XLNK 000000 AK.GGF= 000205 CC.CLI= 000020 DV.COM= 020000 F$$MAP= 000000 I.XMOD 000006 AK.OCB= 000201 CC.CTC= 000200 DV.DIR= 000010 F$$NIM= 000000 I.XPBF 000022 AK.TBT= 000203 CC.EXT= 000004 DV.EXT= 000400 GS.DEL= 000001 I.XPBL 000026 AS.CAA= 000007 CC.KIL= 000010 DV.F11= 040000 G$$DVI= 000003 I.XPBV 000030 AS.DIS= 000002 CC.MCR= 000001 DV.ISP= 002000 G$$GEF= 000000 I.XRBF 000012 AS.DLT= 000001 CC.MSG= 000040 DV.MBC= 000400 G$$TPP= 000000 I.XRBL 000016 AS.FPA= 000001 CC.PRM= 000002 DV.MNT= 100000 G$$TSS= 000000 I.XTCB 000004 AS.PEA= 000004 CC.TTD= 000100 DV.MSD= 000100 G$$TTK= 000000 I.XTMO 000020 AS.PFA= 000006 CM.CDS= 000004 DV.OSP= 004000 G.CNT 000004 I.XTTB 000032 AS.RCA= 000002 CM.CEN= 000003 DV.PSE= 010000 G.EFLG 000006 I.XTTL 000036 AS.REA= 000005 CM.ELM= 000005 DV.REC= 000001 G.GRP 000002 KISAR5= ****** GX AS.RRA= 000003 CM.EXT= 000006 DV.SDI= 000020 G.LGTH= 000012 KISAR6= ****** GX A$$CHK= 000000 CM.IND= 000002 DV.SQD= 000040 G.LNK 000000 K$$CNT= 177546 A$$CLI= 000020 CM.INE= 000001 DV.SWL= 001000 G.STAT 000003 K$$CSR= 177546 A$$CNT= 000000 CM.LKT= 000007 DV.TTY= 000004 H$$FME= 000020 K$$DAS= 000000 A$$CPS= 000000 CM.MSG= 000011 DV.UMD= 000200 H$$FMS= 000004 K$$IEN= 000115 A$$NSI= 000000 CM.RMT= 000010 D$$CHE= 000000 H$$FMX= 000002 K$$LDC= 000001 A$$PRI= 000000 CP.CTC= 002000 D$$IAG= 000000 H$$RTZ= 000062 K$$TPS= 000062 A$$TRP= 000000 CP.DSB= 000010 D$$ISK= 000000 IE.DNR= ****** GX LD$CO = 000000 A.ACC 000014 CP.EXT= 000400 D$$L11= 000001 IE.IFC= ****** GX LD$DU = 000000 A.ACCE 000000 CP.LGO= 000004 D$$PAR= 000000 IE.PRI= ****** GX LD$MU = 000000 A.AST 000006 CP.MSG= 000002 D$$SHF= 000000 IE.RSU= ****** GX LD$NL = 000000 A.BYT 000004 CP.NIO= 000100 D$$VMD= 000000 IE.UPN= ****** GX LD$RD = 000000 A.CALL 000024 CP.NUL= 000001 D$$V11= 000001 IE.WLK= ****** GX LD$TT = 000000 A.CBL 000002 CP.POL= 001000 D$$WCK= 000000 IO.RLB= ****** GX LD$VF = 000000 A.CONN 000012 CP.PRV= 000020 D$$YNC= 000000 IO.WLB= ****** GX LD$VT = 000000 A.DEQU 000002 CP.RST= 000200 D$$YNM= 000000 IP.ABO= 000040 LK.SPN= 000002 A.DIS 000002 CP.SGL= 000040 D.DSP 000012 IP.FAK= 000020 LK.WAT= 000010 A.DISC 000014 C$$CDA= 000000 D.LNK 000000 IP.PND= 000100 L$$ASG= 000000 A.DLGH= 000012 C$$CKP= 000000 D.MSK 000014 IP.UMR= 000200 L$$DRV= 000000 A.DQSR 177776 C$$CTC= 000000 D.NAM 000004 IS.SUC= ****** GX L$$GCL= 000000 A.DUCB= 000010 C$$DFB= 000000 D.PCB 000034 I$$CSZ= 000200 L$$LDR= 000000 A.FLEN 000011 C$$INT= 000000 D.UCB 000002 I$$PFS= 000000 L$$NAM= 000000 A.IBUF 000014 C$$ODB= 000000 D.UCBL 000010 I$$P11= 000000 L$$50H= 000000 A.ILEN 000016 C$$ORE= 001000 D.UNIT 000006 I$$RAR= 000000 ML.CNT= 000040 A.IMAP 000012 C$$PCR= 000000 D.VCAN= 000002 I$$RDN= 000000 ML.DNC 000004 A.INPU 000006 C$$RSH= 177564 D.VCHK= 177774 I.AADA 000044 ML.FID= 000024 A.IOS 000026 C$$RUN= 000000 D.VDEB= 177776 I.AST 000022 ML.FSE= 000026 A.KSR5 177774 C.CBLK 000015 D.VINI= 000000 I.ATRL= 000060 ML.LBN= 000044 A.LIN 000012 C.CCT 000006 D.VKRB= 000010 I.ATTL= 000044 ML.LEN 000002 A.MAS 000004 C.CLK 000000 D.VNXC= 177774 I.EFN 000003 ML.LGH= 000060 A.NPR 000010 C.CMCD 000012 D.VOUT= 000004 I.FCN 000012 ML.LNK 000000 A.NUM 000010 C.CSO 000012 D.VPWF= 000006 I.IOSB 000014 ML.PKT 000010 VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-15 Symbol table ML.PRI 000006 P$$LAS= 000000 T$$GMC= 000000 US.MDM= 000020 U.MEDI= 000050 ML.PR0= 000050 P$$LOL= 001130 T$$GTS= 000000 US.MNT= 000100 U.MUP 177772 ML.PR1= 000052 P$$MAX= 000400 T$$KMG= 000000 US.MUN= 000040 U.OAST 000032 ML.SR0= 000034 P$$MON= 000000 T$$LTH= 000000 US.OFL= 000001 U.OCNT 000006 ML.SR1= 000036 P$$OFF= 000000 T$$LWC= 000000 US.OIU= 000001 U.OWN 177776 ML.TCB= 000014 P$$OOL= 000000 T$$OVL= 000000 US.PDF= 000020 U.PRM = 000042 ML.TYP 000003 P$$P45= 000000 T$$RED= 000000 US.PUB= 000004 U.PTCB 000040 MS.CHP= 000002 P$$RFL= 000000 T$$RNE= 000000 US.PWF= 000010 U.RED 000002 MS.MDA= 000001 P$$RTY= 000000 T$$RPR= 000000 US.RED= 000002 U.RED2 000034 MT.PKT= 000001 P$$SRF= 000000 T$$RST= 000000 US.SHR= 000001 U.RPKT 000024 MU$C0 = 000004 P$$WND= 000000 T$$RUB= 000000 US.SIO= 000200 U.SCB 000020 MU$R0 = 000004 Q$$MGR= 000000 T$$SMC= 000000 US.SPU= 000002 U.SLT = 000050 MX$FIL= 000020 Q$$OPT= 000005 T$$TSA= 000000 US.TRN= 000100 U.SNUM= 000040 M$$CRB= 000124 R$$CON= 000000 T$$UMR= 000000 US.UMD= 000010 U.SPRM= 000052 M$$CRX= 000000 R$$DSP= 000000 T$$USP= 000000 US.VV = 000001 U.STS 000005 M$$EXT= 000000 R$$EIS= 000000 T$$UTO= 000036 US.WCK= 000010 U.ST2 000007 M$$FCS= 000000 R$$EXV= 000000 UA.ACC= 000001 UU.ABO= 000400 U.UCBX= 000032 M$$MGE= 000000 R$$FEA= 000000 UA.ALL= 000400 UU.ATN= 000100 U.UC2X= 000054 M$$MUP= 000000 R$$GIN= 000000 UA.CAL= 000100 UU.AVN= 000004 U.UMB = 000040 M$$NET= 002627 R$$IIC= 000000 UA.COM= 000200 UU.BLK= 004000 U.UNIT 000006 M$$OVR= 000000 R$$LKL= 000001 UA.ECH= 000004 UU.GUS= 000010 U.UTIL= 000046 M$$XLN= 000400 R$$MPL= 000000 UA.PRO= 000002 UU.IOS= 002000 U.VCB = 000036 M.LBN 000012 R$$MYA= 000001 UA.PUT= 000040 UU.ONL= 000020 U.VLNK 000072 M.LGH = 000016 R$$NDC= 000006 UA.SPE= 000020 UU.RCT= 000002 U.WPKT 000026 M.LHD 000002 R$$NDH= 000226 UA.TRA= 002000 UU.RDY= 000200 U.XFIL 000047 M.LNK 000000 R$$NDL= 000001 UA.TRN= 001000 UU.SER= 000001 U.XFLG 000046 M.STS 000010 R$$SND= 000000 UA.TYP= 000010 UU.SIO= 001000 U.XGRP 000050 M.UCBS 000004 R$$TPR= 031470 UC.ALG= 000200 UU.SPC= 000040 U.XLBN 000064 N$$DIR= 000000 R$$UDA= 000001 UC.ATT= 000010 U$$DAS= 000000 U2.AT.= 000020 N$$LDV= 000001 R$$11M= 000000 UC.KIL= 000004 U$$MHI= 000000 U2.CRT= 002000 N$$MOV= 000041 SF.IN = 040000 UC.LGH= 000003 U$$MLO= 140000 U2.DH1= 100000 N$$UMR= 000030 SF.PRV= 100000 UC.NPR= 000100 U$$MRN= 170230 U2.DJ1= 040000 O$$LAP= 000000 S$$ECC= 000000 UC.PWF= 000020 U$$UMD= 000000 U2.DZ1= 000100 O.AST 000006 S$$EXC= 000000 UC.QUE= 000040 U$$UMR= 000000 U2.ESC= 001000 O.EFN 000010 S$$HDW= 000000 UD.UNS= 000000 U.AAST 000034 U2.HFF= 010000 O.ESB 000012 S$$HFC= 000036 UD.160= 000004 U.ACP = 000034 U2.HLD= 000040 O.LGTH= 000034 S$$LIB= 000000 UD.200= 000001 U.ATT 000022 U2.LOG= 000400 O.LNK 000000 S$$MAP= 000000 UD.556= 000002 U.BPKT= 000050 U2.LWC= 000001 O.MCRL 000002 S$$NM1= 051522 UD.625= 000005 U.BUF 000024 U2.L3S= 000004 O.PTCB 000004 S$$NM2= 046530 UD.8K = 000006 U.CBF = 000032 U2.L8S= 010000 O.STAT 000014 S$$NM3= 046120 UD.800= 000003 U.CNT 000030 U2.NEC= 004000 PC.ALF= 000004 S$$OPT= 000000 UM.CLI= 000036 U.COTQ 000030 U2.PRV= 000010 PC.ALM= 001000 S$$WPC= 000036 UM.CMD= 002000 U.CTCB 000026 U2.RMT= 020000 PC.HIH= 000001 S$$WPR= 000005 UM.CNT= 001000 U.CTL 000004 U2.R04= 100000 PC.LOW= 000002 S$$WRG= 000000 UM.DSB= 000200 U.CTLP 000052 U2.SLV= 000200 PC.NRM= 000400 S$$WST= 000000 UM.KIL= 010000 U.CW1 000010 U2.VT5= 000002 PC.XIT= 000200 S$$YSZ= 020000 UM.NBR= 000400 U.CW2 000012 U2.7CH= 010000 PF.ALL= 177777 S.STS = ****** GX UM.OVR= 000001 U.CW3 000014 U3.DBF= 000002 PF.INS= 000040 T$$ACD= 000000 UM.SER= 004000 U.CW4 000016 U3.FDX= 000001 PF.LOG= 000100 T$$BTW= 000000 US.ABO= 000001 U.DCB 000000 U3.OPA= 100000 PF.REQ= 000200 T$$CCA= 000000 US.BSY= 000200 U.FCDE= 000042 U3.PAR= 040000 P$$BPR= 000063 T$$COM= 000000 US.CRW= 000004 U.IAST 000030 U3.RPR= 000004 P$$CTL= 000000 T$$CON= 000000 US.DSB= 000002 U.ICSR= 000046 U3.UPC= 020000 P$$D70= 000000 T$$CTR= 000000 US.FOR= 000040 U.IOSB 000056 U4.CR = 000100 P$$FRS= 000310 T$$CUP= 000000 US.FRK= 000002 U.ISB2 000070 VFALT 001054R P$$GMX= 000000 T$$EIO= 000000 US.LAB= 000004 U.KRB1= 000044 VFCAN 001254R P$$HIL= 003100 T$$ESC= 000000 US.MDE= 000002 U.LUIC 177774 VFDON 001020R VFDRV - VF: Virtual Disk Driver MACRO V05.05 Wednesday 07-Sep-88 13:35 Page 4-16 Symbol table VFFIN 001056R XC.OVR= 000010 X.CST2 000073 X.LEN = 000026 X.USVR 000036 VFINI 000016RG XC.RDA= 000001 X.CYL 000034 X.LGTH= 000074 X.VSER 000050 VFINI1 000062RG XF.LCK= 000001 X.CYLC 000042 X.MEDI 000020 X.WCNT 000036 VFKRB 001254R XF.RON= 000004 X.DFFL= 000012 X.MLUN 000000 X.XDAT 000066 VFNEXT 000340R XF.TRN= 000002 X.DFHL= 000005 X.NAME 000022 X.XDIR 000070 VFOUT 001254R XF.WPR= 000001 X.DFSL= 000010 X.OFF 000010 X.XLOG 000071 VFPWF 001254R XX.DAT= 000005 X.DNAM 000052 X.RBNS 000042 X.XOVR 000072 VFRET 000736RG XX.DIR= 000001 X.DSKD 000051 X.RCTC 000043 X.XRDA 000067 VFRST 001066R XX.LOG= 000001 X.DUSZ= 000054 X.RCTS 000040 X2.DEA= 000001 VFUCB 001072R XX.MAX= 000177 X.ERHC 000035 X.SHST 000026 $ALOCB= ****** GX V$$CTR= 001000 XX.OVR= 000004 X.ERHL 000033 X.SHUN 000024 $BLKCK= ****** GX V$$TLD= 000170 XX.RDA= 000005 X.ERSC 000034 X.SIZE 000004 $DRQRQ= ****** GX V$$TLM= 000270 X$$HDR= 000000 X.ERSL 000032 X.TRCK 000030 $GTPKT= ****** GX V$$TRM= 000000 X$$SEC= 000000 X.FCUR 000050 X.UCB 000000 $IODON= ****** GX XC.ACT= 000100 X.BASE 000014 X.FID 000020 X.UHVR 000037 $IOFIN= ****** GX XC.DAT= 000004 X.CCED 000062 X.FLAG 000002 X.UNFL 000002 $QINSP= ****** GX XC.DFR= 000040 X.CCYL 000046 X.FLIM 000051 X.UNIT 000054 $SCERR= ****** GX XC.DIR= 000020 X.CPCB 000056 X.GRP 000032 X.UNSZ 000044 $VFTBE 000014RG XC.ENA= 000200 X.CSBA 000060 X.IOC 000026 X.UNTI 000010 $VFTBL 000000RG XC.LOG= 000002 X.CSTS 000055 . ABS. 177776 000 (RW,I,GBL,ABS,OVR) 001256 001 (RW,I,LCL,REL,CON) Errors detected: 0 *** Assembler statistics Work file reads: 0 Work file writes: 0 Size of work file: 14189 Words ( 56 Pages) Size of core pool: 15586 Words ( 59 Pages) Operating system: RSX-11M/M-PLUS Elapsed time: 00:00:20.48 VFDRV,VFDRV/-SP=LB:[1,1]EXEMC.MLB/ML,LB:[11,10]RSXMC.MAC/PA:1,SY:[307,20]VFPRE,VFDRV