From:	MERC::"uunet!TGV.COM!mahan" 12-NOV-1992 02:27:17.90
To:	galaxy::gleeve
CC:	
Subj:	VDDRIVER (Alpha Port of VDDRIVER) 1/3

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On 11-NOV-1992 22:59:25.64   By user MAHAN (Patrick Mahan)
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 3 PARTS, TO KEEP EACH PART
$!  BELOW 100 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. ASNVDM6.ALPHA_OPT;2
$!       2. ASNVDM6.CLD;1
$!       3. ASNVDM6.MAR;4
$!       4. MAKE.COM;12
$!       5. VDDRIVER.ALPHA_OPT;8
$!       6. VDDRIVER.LNK;11
$!       7. VDDRIVER.MAR;3
$!       8. VDDRIVER.OPT;9
$!       9. VDDRIVERA.LNK;1
$!      10. VDDRIVERALPHA.MAR;13
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
Xasnvdm6.alpha_obj
Xalpha$loadable_images:sys$base_image.exe/share
$ CALL UNPACK ASNVDM6.ALPHA_OPT;2 725289447
$ create 'f'
XReceived: from relay2.UU.NET (`5B137.39.1.7`5D) by TGV.COM via INTERNET ;
X          Wed, 21 Oct 92 09:48:21 PDT
XReceived: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMT
VP`20
X`09(5.61/UUNET-internet-primary) id AA23495; Wed, 21 Oct 92 12:48:21 -0400
XMessage-Id: <9210211648.AA23495@relay2.UU.NET>
XReceived: from raxco.UUCP by uunet.uu.net with UUCP/RMAIL
X`09(queueing-rmail) id 124742.29155; Wed, 21 Oct 1992 12:47:42 EDT
XDate: Wed, 21 Oct 92 12:42:20 -0400
XFrom: raxco!galaxy.dnet!gleeve@uunet.UU.NET
XTo: "mahan@tgv.com"@uunet.UU.NET
XSubject: asnvdm6.cld
X
X! Set up VD: units with ADVD, assuming VDDRIVER is already
X! loaded somewhere.
XDEFINE VERB Asnvdm6
X   IMAGE sys$login:ASNVDm6.EXE
X     parameter p1,prompt="VDn:",value(required,type=$device),label=UNIT
X     parameter p2,label=FNAM,prompt="file",value(type=$infile)
X     qualifier ASSIGN
X     qualifier DEASSIGN
X     qualifier SEC64
X     qualifier SEC32
X     qualifier REPORT
X     qualifier DEVICE
X     qualifier LBN,value(required,type=$number)
X     qualifier LENGTH,value(required,type=$number)
X  disallow lbn and report
X  disallow length and report
X  disallow sec64 and sec32
X  disallow device and lbn
X  disallow device and sec64
X  disallow device and sec32
X! Uses ASNVD image. Note that vddriverv3a.mar contains code to
X! handle the assign function in the FORMAT code. For now we don't
X! use this, but just let the priv'd image do it.
X! Needs CMKRNL at least. Maybe some others.
X! Usage: asnvdm6/switches vdn: dev:file
X!  where /switches are:
X!  /report  - Tell what file is associated with a virtual disk (omit dev:fil
Ve arg)
X!  /assign  - Assign a file to a virtual disk unit
X!  /Deassign - Deassign a virtual disk from a file (puts vdn: offline)
X!  /SEC64   - Make vdn: geometry 64 sect/trk, 1 trk/cyl, n cyl
X!  /SEC32   - make vdn: geometry 32 sect/trk, 32 trk/cyl, n cyl
X!   (disks smaller than 65530 blks get 1 sect/trk, 1 trk/cyl, n cyl)
X! default: Use /sec64 geometry unless disk is a "recognized" size in which
X! case emulate geometry of the recognized disk type.
X! Sizes recognized are of types following:
X!;`09`09losiz`09hisiz`09blks`09cyl`09trk`09sect`09id
X!`09Geotbl  800,`09805,`09800,`091,`0980,`0910`09;rx50
X!`09Geotbl`094800,`094810,`094800,`09200,`092,`0912`09;RK05
X!`09Geotbl`0910240,`0910250,`0910240,`09256,`092,`0940`09;RL01 (sect=256 byt
Ves)
X!`09Geotbl`0920480,`0920500,`0920480,`09512,`092,`0940`09;RL02 (Sect=256 byt
Ves)
X!`09Geotbl`0927126,`0927150,`0927126,`09411,`093,`0922`09;RK06
X!`09GeoTbl`0953790,`0953830,`0953790,`09815,`093,`0922`09;RK07
X!`09GeoTbl`09131680,`09131700,`09131680,`09823,`095,`0932`09;RM03
X!`09GeoTbl`09138672,`09138690,`09138672,`091024,`098,`0917`09;RD53
X!`09GeoTbl`09171798,`09171850,`09171798,`09411,`0919,`0922`09;RP04
X!`09GeoTbl`09242606,`09242650,`09242606,`09559,`0914,`0931`09;RM80 (or RB80)
X!`09GeoTbl`09340670,`09340720,`09340670,`09815,`0919,`0922`09;RP06
X!`09GeoTbl`09500384,`09500420,`09500384,`09823,`0919,`0932`09;RM05
X!`09GeoTbl`09891072,`09891110,`09891072,`091248,`0914,`0951`09;RA81
X!`09GeoTbl`091008000,1008500,1008000,630,`0932,`0950`09;RP07
X!`09GeoTbl`091216665,1216700,1216665,1423,`0915,`0957`09;RA82
X!  where losiz and hisiz are sizes of files recognized as being containers o
Vf
X!  the device types, and the other columns are number of blocks, and geometr
Vy,
X!  for the devices. the id column is the device being emulated. Note that
X!  the device type will still be dt$_FD1 or dt$_rp06 (in vddriver) but
X! the geometry is determined as above.
X!
X! If the /LBN=nnnnn and /LEN=mmmmm switches are used, a command of form
X! asnvdm6/assign/lbn=nnnnn/len=mmmmm vdn: device:foo
X!  will assign the mmmmm blocks starting with logical block nnnnn on device:
X! as the container for vdn: (e.g. vd2:) instead of requiring a container fil
Ve.
X! This allows use of foreign mounted or unmounted disks, or any other contig
Vuous
X! space. BE CAREFUL using it though; it can totally clobber file structures
X! if misused.
X! /DEVICE simply assigns the entire container device to the virtual disk
X! and overrides file specifiers AND /LBN specifiers.
X!   When using INIT on emulated disks, use the /NOVERIFY switch to avoid los
Ving
X! a bunch of blocks at the end as "bad" (even though they're OK). Otherwise
V the
X! failure to find hardware badblock info causes INIT to declare the last
X! track bad.
X!   You can add new devices to the table by modifying the geotbl entries
X! in asnvdm6.mar. Be sure that losiz is at least as large as blks,
X! that blks=trk*sect*cyl, and that hisiz>losiz. Also, enter the table
X! entries in order of size for sensibility. Hisiz can be equal to losiz
X! if that's what you want, but I suggest that it be larger by the
X! value of sect anyway; you'd lose less space. Fictitious geometries
X! can be added, just so cyl fits into a 16 bit word and trk and sect
X! fit into 8 bit bytes. Set the sign bit at your own risk, though.
X! Things might break if the number of sectors/track or tracks/cyl
X! ever exceed 127. Cylinders of 65000 have been tried and do indeed
X! work however.
$ CALL UNPACK ASNVDM6.CLD;1 1128881113
$ create 'f'
X`09.TITLE`09ADVD - VAX/VMS VIRT DISK DRIVER ASSIGN/DEASSIGN
X`09.IDENT`09'V03-001'
X;
X; FACILITY:
X;`20
X; ASSIGN/DEASSIGN VIRTUAL DISK TASK THAT WORKS WITH VDDRIVER
X;  ESTABLISHES CONNECTION (OR BREAKS IT) BETWEEN A LUN OF
X;  VD: AND A CONTIGUOUS FILE.
X;
X; Also this version will save the container file spec in the
X; UCB area ucb$vdcontfil as a null terminated string up to 79
X; bytes long. Also it has an option to report the assigned
X; file so associated. (/report)
X;
X; ALSO, this version will recognize a couple container file sizes.
X; Specifically: a file sized 500384 to 500400 blocks long will be
X; treated as an RM05, with 823 cylinders, 19 tracks/cylinder,
X; and 32 sectors per track. A file under 65530 blocks long will
X; get geomtery n cylinders, 1 sector/track, 1 track/cyl, and
X; a file of size 131680 to 131700 blocks long will be treated as
X; an RM03 with 823 cylinders, 5 tracks/cylinder, and 32 sectors
X; per track. This will facilitate use for some kinds of backups.
X; Other disk types can be wedged in as needed. Note the physical
X; structure for small disks thus generated is DIFFERENT from the
X; "standard" driver set. A /sec64 switch will allow this to be
X; overridden where we need compatibility.
X; Also added is RX50 recognition. The RX50 has an unusual physical
X; structure (1 cylinder, 80 trks/cyl and 10 sect/trk) considering
X; the actual layout. The geotbl entry reflects the structure as seen
X; by show device/full on VMS. Other structures are added by GEOTBL
X; macros in the table; most disk structures I could lay my hands
X; on are included. The /sec32 structure is provided to give
X; compatible handling with the Bear Systems virtual disk, which
X; uses 32 tracks/cyl and 32 sector/track for large unrecognized
X; disks. We used the Bear driver on our 750 and I needed to be
X; able to get at the virtual disks compatibly using vddriver.
X;
X;
X;With version 3 is added facility to use VD: with an arbitrary
X; section of disk. The /LBN=number/LEN=number switches will
X; allow one to force an LBN and length in blocks for a VD:
X; assignment even if the file assigned is NOT contiguous.
X;  The motive for this is: I have noticed that my SYSDUMP.DMP file
X; (after backup/restore) exists as one contiguous area, even though
X; it is not marked contiguous. Addition of these commands to ASNVD
X; will allow use of such areas of disk for things like scratch
X; space, where the volatility of scratch area is not an issue.
X; This method will also allow entire physical disks to be assigned
X; through the VD: driver, or permit partitioning of physical disks
X; without the overhead of a Files-11 index structure on the disk.
X; (the code added will probably be moved to ASNVQ also, where such
X; disk assignment has other uses also.)
X;
X; Command format:
X; ADVD/switches VDn: file
X;  where a .CLD file is expected so that this can all be parsed by
X;  the CLI. The legal switches will just be /ASSIGN or /DEASSIGN
X;  to specify which operation is required. In the /DEASSIGN
X;  case no filename is needed of course; the virtual disk must
X;  however be dismounted before this utility will allow it to
X;  be deassigned. The ucb$w_refc field must be zero before the
X;  deassign is thus permitted.
X;  We must set the UCB$L_MAXBLOCK longword to the size of the file
X;  here also. This requires reading the statistics on the file to
X;  discover the size if contiguous; the statistics block will
X;  show zero if noncontig...
X;   Device geometry is needed by INIT and MOUNT, though vddriver
X; doesn't care. Therefore a "sensible" geometry is always generated,
X; and device size is always an integral number of cylinders. Vddriver
X; doesn't support physical I/O really, but init and mount use the
X; physical structure to figure where to put home blocks or look for
X; them.
X;
X; Note: define VMS$V5 to build for Version 5.x of VMS.
XVMS$V5=1
X;
X;`20
X; AUTHOR:
X;`20
X; G. EVERHART
X;
X; 04-Aug-1989`09D. HITTNER`09Cleaned up definitions, added messages
X; 29-Aug-1989   G. Everhart`09Added more flexible device geometry selection
X;--
X`09.PAGE
X`09.SBTTL`09EXTERNAL AND LOCAL DEFINITIONS
X
X`09.LIBRARY /ALPHA$LIBRARY:LIB/
X;`20
X; EXTERNAL SYMBOLS
X;`20
X
X`09$dyndef
X`09$ADPDEF`09`09`09`09;DEFINE ADAPTER CONTROL BLOCK
X`09$ATRDEF
X`09$CRBDEF`09`09`09`09;DEFINE CHANNEL REQUEST BLOCK
X`09$DCDEF`09`09`09`09;DEFINE DEVICE CLASS
X`09$DDBDEF`09`09`09`09;DEFINE DEVICE DATA BLOCK
X`09$DEVDEF`09`09`09`09;DEFINE DEVICE CHARACTERISTICS
X`09$DPTDEF`09`09`09`09;DEFINE DRIVER PROLOGUE TABLE
X`09$DVIDEF`09`09`09`09;Symbols for $GETDVI service.
X`09$EMBDEF`09`09`09`09;DEFINE ERROR MESSAGE BUFFER
X`09$FABDEF
X`09$FATDEF
X`09$FIBDEF`09`09`09`09;Symbols for file information block.
X`09$IDBDEF`09`09`09`09;DEFINE INTERRUPT DATA BLOCK
X`09$IODEF`09`09`09`09;DEFINE I/O FUNCTION CODES
X`09$IRPDEF`09`09`09`09;DEFINE I/O REQUEST PACKET
X`09$NAMDEF
X`09$PRDEF`09`09`09`09;DEFINE PROCESSOR REGISTERS
X`09$RMSDEF
X`09$SBDEF
X`09$SCSDEF
X`09$SSDEF`09`09`09`09;DEFINE SYSTEM STATUS CODES
X`09$STSDEF`09`09`09`09;Symbols for returned status.
X`09$TPADEF`09`09`09`09;Symbols for LIB$TPARSE calls.
X`09$UCBDEF`09`09`09`09;DEFINE UNIT CONTROL BLOCK
X`09$VECDEF`09`09`09`09;DEFINE INTERRUPT VECTOR BLOCK
X`09$XABDEF
X
X;`20
X; UCB OFFSETS WHICH FOLLOW THE STANDARD UCB FIELDS
X; DEFINE THESE SO WE KNOW WHERE IN THE UCB TO ACCESS. WE MUST
X; SET THE ONLINE BIT OR CLEAR IT, AND ALSO SET
X; UCB$HUCB (HOST UCB ADDRESS), UCB$HFSZ (HOST FILE SIZE),
X; AND UCB$HLBN (HOST LOGICAL BLOCK NUMBER OF FILE START)
X;
X; Note: These MUST match the definitions in VDDRIVER. Don't
X; change one without changing the other to match it!!!
X;`09G. Everhart 9/5/1986
X;`20
X; Since I/O postprocessing on virtual or paging I/O makes lots of
X; assumptions about location of window blocks, etc., which are
X; not true here (wrong UCB mainly), we'll bash the function code status
X; we send to the host driver to look like logical I/O is being
X; done and save the real status code here. Later when VD: does
X; I/O completion processing, we'll replace the original function
X; from here back in the IRP. This will be saved/restored along with
X; ucb$ppid (irp$l_pid field) and so synchronization will be detected
X; with ucb$ppid usage.
X
X`09$DEFINI`09UCB`09`09`09;START OF UCB DEFINITIONS
X
X;.=ucb$w_bcr+2`09`09`09`09;BEGIN DEFINITIONS AT END OF UCB
X.=ucb$k_lcl_disk_length`09`09`09;vms v4, right out of the book...
X`09`09`09`09`09;LOCAL DATA FOR VIRT DISK.
X$DEF`09UCB$W_DY_WPS`09.BLKW`091`09;Words per sector.
X$DEF`09UCB$W_DY_CS`09.BLKW`091`09;CONTROL STATUS REGISTER
X$DEF`09UCB$W_DY_DB`09.BLKW`091`09;UCB ADDRESS OF HOST DRIVER
X$DEF`09UCB$W_DY_DPN`09.BLKW`091`09;(LONGWORD)
X$DEF`09UCB$L_DY_DPR`09.BLKL`091`09;START LBN OF HOST CONTIG FILE
X$DEF`09UCB$L_DY_FMPR`09.BLKL`091`09;
X$DEF`09UCB$L_DY_PMPR`09.BLKL`091`09;PREVIOUS MAP REGISTER
X$DEF`09UCB$B_DY_ER`09.BLKB`091`09;SPECIAL ERROR REGISTER
X`09`09`09.BLKB`091`09;Reserved.
X$DEF`09UCB$B_DY_LCT`09.BLKB`091`09;LOOP COUNTER
X$DEF`09UCB$B_DY_XBA`09.BLKB`091`09;BUS ADDRESS EXTENSION BITS
X$DEF`09UCB$W_DY_PWC`09.BLKW`091`09;PARTIAL WORD COUNT
X$DEF`09UCB$W_DY_SBA`09.BLKW`091`09;SAVED BUFFER ADDRESS
X$DEF`09UCB$L_DY_XFER`09.BLKL`091`09;TRANSFER FUNCTION CSR BITS
X$DEF`09UCB$L_DY_LMEDIA`09.BLKL`091`09;LOGICAL MEDIA ADDRESS
X$DEF`09UCB$Q_DY_EXTENDED_STATUS`09; Area into which we do READ ERROR
X`09`09`09.BLKQ`091`09;  REGISTER command.
X$DEF`09UCB$Q_DY_SVAPTETMP`09`09; Area in which we save UCB fields -
X`09`09`09.BLKQ`091`09;  SVAPTE, BOFF, and BCNT.
X$DEF`09UCB$L_DY_MAPREGTMP`09`09; Area in which we save CRB fields -
X`09`09`09.BLKL`091`09;  MAPREG, NUMREG, and DATAPATH.
X$DEF`09UCB$L_DY_SAVECS`09.BLKL`091`09; Area in which we save CS and DB regs.
X$DEF`09UCB$HUCB`09.BLKL`091`09;ADDRESS OF HOST UCB
X$DEF`09UCB$HLBN`09.BLKL`091`09;LBN OF HOST FILE
X$DEF`09UCB$HFSZ`09.BLKL`091`09;SIZE OF HOST FILE, BLKS
X$DEF`09UCB$PPID`09.BLKL`091`09;PID save area for active requests
X$DEF`09UCB$STATS`09.BLKL`091`09;IRP STATUS CODE SAVE AREA
X$DEF`09UCB$OBCT`09.BLKL`091`09;STORE FOR IRP$L_OBCNT too
X$DEF`09UCB$LMEDIA`09.BLKL`091`09;irp$l_media store
X$DEF`09UCB$OWIND`09.BLKL`091`09; store irp$l_wind...
X$DEF`09UCB$OSEGV`09.BLKL`091`09; and irp$l_segvbn
X$DEF`09UCB$L_VD_HOST_DESCR
X`09`09`09.BLKL`092
X$DEF`09UCB$VDCONTFIL`09.BLKB`0980`09;container file spec, 0 term'd
X$DEF`09UCB$K_VD_LEN`09.BLKW`091`09;length
X;ucb$k_dy_len=.`09`09`09`09;LENGTH OF UCB
X
X`09$DEFEND`09UCB`09`09`09;END OF UCB DEFINITONS
X
X; TO SET ONLINE:
X;`09BISW`09#UCB$M_ONLINE,UCB$W_STS(R5)  ;SET UCB STATUS ONLINE
X
X; Macro to check return status of system calls.
X;
X`09.MACRO`09ON_ERR`09THERE,?HERE
X`09BLBS`09R0,HERE
X`09BRW`09THERE
XHERE:`09.ENDM`09ON_ERR
X
X;
X;
X;
X`09.PSECT`09ADVDD_DATA,RD,WRT,NOEXE,LONG
X;
X; KERNEL ARG LIST
XK_ARG:
X`09.LONG`092`09`09`09;2 ARGS: HOST-DVC NAME, VD DVC NAME
X`09.ADDRESS`09DEV_BUF_DESC
X`09.ADDRESS`09VDV_BUF_DESC
X;`09.ADDRESS`09DDFNM
X;`09.ADDRESS`09VDFNM
X
XDEFAULT_DEVICE:
X`09.ASCID`09/SYS$DISK/
X
X`09.ALIGN LONG
XDFAB_BLK: $FAB FNM=<VD0.DSK>,XAB=FNXAB,FAC=<GET,PUT>,DNM=<VDCONT.DSK>
X;
XFNXAB:`09$XABFHC`09; XAB STUFF TO GET LBN, SIZE
X`09.BLKL`0920 ;SAFETY
XIOSTATUS: .BLKQ 1
XDEV_BUF:`09`09`09; Buffer to hold device name.
X`09.BLKB`0940
XDEV_BUF_SIZ = . - DEV_BUF
X
XDEV_BUF_DESC:`09`09`09; Descriptor pointing to device name.
X`09.LONG`09 DEV_BUF_SIZ
X`09.ADDRESS DEV_BUF
X
XPID:`09`09`09`09; Owner of device (if any).
X`09.BLKL`091
X
XDEV_ITEM_LIST:`09`09`09; Device list for $GETDVI.
X`09.WORD`09 DEV_BUF_SIZ`09; Make sure we a have a physical device name.
X`09.WORD`09 DVI$_DEVNAM
X`09.ADDRESS DEV_BUF
X`09.ADDRESS DEV_BUF_DESC
X`09.WORD`09 4`09`09; See if someone has this device allocated.
X`09.WORD`09 DVI$_PID
X`09.ADDRESS PID
X`09.LONG`09 0
X`09.WORD`09 4
X`09.WORD`09 DVI$_DEVCLASS`09; Check for a terminal.
X`09.ADDRESS DEV_CLASS
X`09.LONG`09 0
X`09.LONG`09 0`09`09; End if item list.
X
XDEV_CLASS:
X`09.LONG`091
X;**
XVDV_BUF:`09`09`09; Buffer to hold VDVice name.
X`09.BLKB`0940
XVDV_BUF_SIZ = . - VDV_BUF
X
XVDV_BUF_DESC:`09`09`09; Descriptor pointing to VDVice name.
X`09.LONG`09 VDV_BUF_SIZ
X`09.ADDRESS VDV_BUF
X
XVPID:`09`09`09`09; Owner of VDVice (if any).
X`09.BLKL`091
X
XVDV_ITEM_LIST:`09`09`09; VDVice list for $GETDVI.
X`09.WORD`09 VDV_BUF_SIZ`09; Make sure we a have a physical device name.
X`09.WORD`09 DVI$_DEVNAM
X`09.ADDRESS VDV_BUF
X`09.ADDRESS VDV_BUF_DESC
X`09.WORD`09 4`09`09; See if someone has this device allocated.
X`09.WORD`09 DVI$_PID
X`09.ADDRESS VPID
X`09.LONG`09 0
X`09.WORD`09 4
X`09.WORD`09 DVI$_DEVCLASS`09; Check for a terminal.
X`09.ADDRESS VDV_CLASS
X`09.LONG`09 0
X`09.LONG`09 0`09`09; End if item list.
X
XVDV_CLASS:
X`09.LONG`091
X;**
XDEFNAM:
X
XWRK:`09.BLKL`091`09;SCRATCH INTEGER
X; DESCRIPTOR FOR VDn: "FILENAME"
X`09.ALIGN LONG
XVDFNM:`09.WORD`09 255.`09;LENGTH
XVDFTP:`09.BYTE`09DSC$K_DTYPE_T`09;TEXT TYPE
X`09.BYTE`091`09; STATIC STRING
X`09.ADDRESS`09VDFNMD
XVDFNMD:`09.BLKB`09256.`09; DATA AREA
X`09.align long
Xwrkstr:`09.word`0920`09;length
X`09.byte`09dsc$k_dtype_t`09;text
X`09.byte`091`09;static
X`09.address`09wrkdat
Xwrkdat:`09.blkb`0920
X`09.byte`090,0,0,0`09;safety
X;
X; DESCRIPTOR FOR DVn:DSKFIL "FILENAME"
X`09.ALIGN LONG
XDDFNM:`09.WORD`09 255.`09;LENGTH
XDDFTP:`09.BYTE`09DSC$K_DTYPE_T`09;TEXT TYPE
X`09.BYTE`091`09; STATIC STRING
XDDFNA:`09.ADDRESS`09DDFNMD
XDDFNMD:`09.BLKB`09256.`09; DATA AREA
XDDCHN:`09.LONG`090
XVDCHN:`09.LONG`090`09;CHANNEL HOLDERS
X;
X; FOR initial use, don't bother allocating the file. Assume the
X; user can somehow allocate a contiguous file of the size he wants
X; for himself.
X;
Xrepdsc:`09.ascid`09/REPORT/`09;report associated file
Xrepflg:`09.long`090`09`09;1 if reporting, 0 otherwise
Xreptxt:`09.word`0980`09`09;80 byte long
X`09.byte dsc$k_dtype_t`09;static, fixed length string of text
X`09.byte 1
X`09.address`09repwrk`09;data pointer is repwrk's address
Xrepwrk:`09.blkb`0980`09`09;copy of filespec
Xs64dsc:`09.ascid`09/SEC64/`09`09;flag this if 64 sectors/trk geometry needed
Xs32dsc:`09.ascid`09/SEC32/`09`09;md: type 32 sector forcer
XASDSC:`09.ASCID`09/ASSIGN/
XDASDSC:`09.ASCID`09/DEASSIGN/
XP1DSC:`09.ASCID`09/UNIT/
XP2DSC:`09.ASCID`09/FNAM/
XLBNDSC:`09.ASCID`09/LBN/
XLENDSC:`09.ASCID`09/LENGTH/
X`09.EVEN
XASDAS:`09.LONG`090`09;DEFAULT DEASSIGN
XvSec64:`09.long`090`09;1 if using /sec64 geometry
Xvsec32:`09.long`090`09;1 if using /sec32 geometry
XLBNn:`09.long`090`09;temp storage for /lbn=number
XLENn:`09.long`090`09;temp storage for /len=number
X;
X; ucb data area
XHSTUCB:`09.LONG`090`09;HOST UCB ADDRESS
XHSTLBN:`09.LONG`090`09;LBN OF 1ST BLK OF HOST FILE
XHSTFSZ:`09.LONG`090`09;LENGTH IN BLOCKS OF HOST FILE
X; debug words
Xvducb: .long 0
Xvdsts:`09.long 0
Xvdsts2:`09.long 0
Xvdsts3:`09.long 0
Xvdcyl:`09.long 0
Xvdprog:`09.long 0`09;counts where we've been
X;
X;
XERROR:`09.LONG`092
XMESS:`09.LONG`09SS$_ABORT
X`09.LONG`090
X
X; Device geometry
X; Use this table for "large" devices so that container files of
X; sizes matching known geometry devices are made to appear to
X; have exactly the known geometry. This will avoid a LOT of special
X; case testing and allow insertion of more device geometries as we
X; like
X`09.macro`09Geotbl losz,hisz,blks,cyl,trk,sect,typ
X`09.Long`09losz`09;low limit file size this geom
X`09.Long`09hisz`09;high limit file size this geom
X`09.long`09blks`09;Number of blks on device
X`09.word`09cyl`09;number cylinders
X`09.byte`09trk`09;number tracks/cyl
X`09.byte`09sect`09;number sectors/track
X`09.long`09typ`09;drive type (for ucb$b_devtype)
X`09.endm
X; Geoms MUST be in increasing order of size.
XGeoms:
X;`09`09losiz`09hisiz`09blks`09cyl`09trk`09sect`09typ`09id
X;`09(can't do rx01...blks not 512 bytes long, but 128.)
X;`09GeoTbl`09494,`09494,`09494,`0977,`091,`0926`09dt$_rx01;rx01
X`09GeoTbl`09512,`09512,`09512,`091,`094,`09128`09dt$_tu58;tu58
X`09GeoTbl`09576,`09576,`09576,`091,`094,`09144`09dt$_tu56;tu56 (old DECtape)
X`09Geotbl  800,`09805,`09800,`091,`0980,`0910`09dt$_rx50;rx50
X`09GeoTbl`091440,`091440,`091440,`0980,`092,`099`09dt$_rx23s;rx23s loden
X`09GeoTbl`091976,`091976,`091976,`0976,`091,`0926`09dt$_rx04;rx04
X`09GeoTbl`092880,`092880,`092880,`0980,`092,`0918`09dt$_rx23s;rx23s hidens`2
V0
X`09Geotbl`094800,`094810,`094800,`09200,`092,`0912`09dt$_generic_dk;RK05
X`09Geotbl`0910240,`0910250,`0910240,`09256,`092,`0940`09dt$_rl01;RL01 (sect=
V256 bytes)
X`09GeoTbl`0915000,`0915002,`0915000,`0915000,`091,`091`09dt$_rd51;my virt ds
Vk
X`09Geotbl`0920480,`0920500,`0920480,`09512,`092,`0940`09dt$_rl02;RL02 (Sect=
V256 bytes)
X`09Geotbl`0927126,`0927150,`0927126,`09411,`093,`0922`09dt$_rk06;RK06
X`09GeoTbl`0953790,`0953830,`0953790,`09815,`093,`0922`09dt$_rk07;RK07
X`09GeoTbl`09131680,`09131700,`09131680,`09823,`095,`0932`09dt$_rm03;RM03
X`09GeoTbl`09138672,`09138690,`09138672,`091024,`098,`0917`09dt$_rd53;RD53
X`09GeoTbl`09171798,`09171850,`09171798,`09411,`0919,`0922`09dt$_rp04;RP04
X`09GeoTbl`09242606,`09242650,`09242606,`09559,`0914,`0931`09dt$_rm80;RM80 (o
Vr RB80)
X`09GeoTbl`09251328,`09251330,`09251328,`09561,`0914,`0932`09dt$_rb80;rb80
X`09GeoTbl`09340670,`09340720,`09340670,`09815,`0919,`0922`09dt$_rp06;RP06
X        GeoTbl  409792, 409850, 409792,1348,    8,      38      dt$_rz24;RZ2
V4
X`09GeoTbl`09500384,`09500420,`09500384,`09823,`0919,`0932`09dt$_rm05;RM05
X`09GeoTbl`09891072,`09891110,`09891072,`091248,`0914,`0951`09dt$_ra81;RA81
X`09GeoTbl`091008000,1008500,1008000,630,`0932,`0950`09dt$_rp07;RP07
X`09GeoTbl`091216665,1216700,1216665,1423,`0915,`0957`09dt$_ra82;RA82
X        GeoTbl  1954050,1954100,1954050,1835,   15,     71      dt$_rz57;RZ5
V7
X        GeoTbl  2376153,2376200,2376153,2649,   13,     69      dt$_ra90;RA9
V0
X`09.Long`090,0,0,0`09`09;list terminator
X;
X;
X;
X
X`09.PSECT`09ADVDD_CODE,RD,NOWRT,EXE,LONG
X.if`09DF,EVAX
XADVDD::
X`09.CALL_ENTRY Home_Args=True,Preserve=<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11>
X.iff
X`09.ENTRY`09ADVDD,`5EM<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11>
X.endc
X`09clrl`09repflg`09`09;say not reporting initially
X`09movab`09repwrk,r0`09;clear work string initially
X`09movl`09#80,r1
X1$:`09clrb`09(r0)+
X`09sobgtr`09r1,1$`09`09;zero the array out
X
X`09MOVL`09#1,ASDAS`09;SET ASSIGN
X`09PUSHAB`09WRK`09`09;PUSH LONGWORD ADDR FOR RETLENGTH
X`09PUSHAB`09VDFNM`09`09;ADDRESS OF DESCRIPTOR TO RETURN
X`09PUSHAB`09P1DSC`09`09; GET P1 (VDn: UNIT)
X`09CALLS`09#3,G`5ECLI$GET_VALUE`09;GET VALUE OF NAME TO VDFNM
X`09ON_ERR`09ADVDD_EXIT
X`09clrl`09vsec64`09`09;zero s64 flag
X`09clrl`09vsec32`09`09;ditto s32 flag
X`09pushab`09s64dsc
X`09calls`09#1,g`5Ecli$present`09;see if /sec64 specified
X`09cmpl`09r0,#cli$_present
X`09bneq`09503$`09`09`09;if neq not there
X`09incl`09vsec64
X503$:
X`09pushab`09s32dsc
X`09calls`09#1,g`5Ecli$present`09;see if /sec32 specified
X`09cmpl`09r0,#cli$_present
X`09bneq`091503$`09`09`09;if neq not there
X`09incl`09vsec32
X1503$:
X`09pushab`09repdsc
X`09calls`09#1,g`5Ecli$present`09;/report used?
X`09cmpl`09r0,#cli$_present
X`09bneq`09103$`09`09`09;if not there, skip...
X`09movl`09#1,repflg
X`09jmp`09das1`09`09`09;if there, no need for 2nd file either
X;
X; IF "DEASSIGN" WE DON'T NEED 2ND ARG... SEE...
X;
X103$:
X`09PUSHAB`09DASDSC`09`09`09; 'DEASSIGN'
X`09CALLS`09#1,G`5ECLI$PRESENT`09; IS /DEASSIGN USED?
X`09CMPL`09R0,#CLI$_PRESENT`09; IF EQ YES
X`09BEQL`09DAS1
X
X`09PUSHAB`09WRK`09`09`09; GET 2ND FILE (REAL FILE)
X`09PUSHAB`09DDFNM`09`09`09; & ITS DESCRIPTOR
X`09PUSHAB`09P2DSC`09`09`09; & PARAMETER NAME 'P2'
X`09CALLS`09#3,G`5ECLI$GET_VALUE`09; GET FNM
X`09ON_ERR`09ADVDD_EXIT
X`09BRB`09DAS2
XDAS1:`09CLRL`09ASDAS`09`09`09; FLAG /DEAS
XDAS2:
X
X`09TSTL`09ASDAS`09`09`09; IF 0, DEASSIGNING SO NO CHNL FOR HOST
X`09`09`09`09`09; FILE
X`09BEQL`09290$
X`09tstl`09repflg
X`09bneq`09290$`09`09`09;/report doesn't need file either
X`09$ASSIGN_S -`09`09`09; Get a channel to the`20
X`09`09DEVNAM=DDFNM,-`09`09; device for host file
X`09`09CHAN=DDCHN
X`09ON_ERR`09ADVDD_EXIT
X; LET ERRORS BY FOR THIS SINCE WE GET OUR INFO VIA OPEN ANYWAY SO
X; CHANNEL REALLY DOESN'T HAVE TO BE THERE.
X; Get the physical device name, and see if this device has an owner.
X; (We must do this so we can get the host UCB address)
X`09$GETDVI_S -
X`09`09CHAN=ddchn,-`09`09; Command line has device name.
X`09`09ITMLST=DEV_ITEM_LIST
X`09BLBS`09R0,40$
X`09BRW`09advdd_EXIT
X40$:
X290$:
X; MUST HAVE ASSIGNMENT TO VD: UNIT IN ANY CASE.
X`09$ASSIGN_S -
X`09`09DEVNAM=VDFNM,-`09`09; GET CHANNEL FOR VDn:
X`09`09CHAN=VDCHN
X`09ON_ERR`09ADVDD_EXIT`09`09; SKIP OUT IF ERROR
X`09$GETDVI_S -
X`09`09CHAN=vdchn,-`09`09; Command line has device name.
X`09`09ITMLST=VDV_ITEM_LIST
X`09BLBS`09R0,140$
X`09BRW`09advdd_EXIT
X140$:
X`09clrl`09lbnn
X`09clrl`09lenn`09`09;zero lbn and length flags.
X`09brb`091401$
X1400$:`09brw`091501$
X1401$:
X`09PUSHAB`09LBNDSC`09`09`09; 'lbn='
X`09CALLS`09#1,G`5ECLI$PRESENT`09; IS /DEASSIGN USED?
X`09CMPL`09R0,#CLI$_PRESENT`09; IF EQ YES
X`09Bneq`091400$`09`09`09; if neq no
X`09pushab`09lendsc`09`09`09; /len=nnnn
X`09calls`09#1,g`5Ecli$present`09;see it too? (must have both)
X`09cmpl`09r0,#cli$_present
X`09Bneq`091400$
X; have both /len and /lbn specified. Get values for them. If they
X; look OK, bypass file open and replace logic.
X`09PUSHAB`09WRK`09`09;PUSH LONGWORD ADDR FOR RETLENGTH
X`09pushab`09wrkstr`09`09;scratch string
X`09PUSHAB`09lbndsc`09`09; GET lbn
X`09CALLS`09#3,G`5ECLI$GET_VALUE`09;GET VALUE OF LBN
X`09ON_ERR`09ADVDD_EXIT
X; string in wrkdat
X`09pushl`09#17`09`09;mask...ignore blanks
X`09pushl`09#4`09`09;4 bytes
X`09pushab`09lbnn`09`09;where to store
X`09pushab`09wrkstr`09`09;string descriptor
X`09calls`09#4,g`5Eots$cvt_tu_l ;convert to binary
X`09on_err advdd_exit
X; lbnn now is start logical blk
X`09PUSHAB`09WRK`09`09;PUSH LONGWORD ADDR FOR RETLENGTH
X`09pushab`09wrkstr`09`09;scratch string
X`09PUSHAB`09lendsc`09`09; GET length
X`09CALLS`09#3,G`5ECLI$GET_VALUE`09;GET VALUE OF Length
X`09ON_ERR`09ADVDD_EXIT
X; string in wrkdat
X`09pushl`09#17`09`09;mask...ignore blanks
X`09pushl`09#4`09`09;4 bytes
X`09pushab`09lenn`09`09;where to store
X`09pushab`09wrkstr`09`09;string descriptor
X`09calls`09#4,g`5Eots$cvt_tu_l ;convert to binary
X`09on_err advdd_exit
X;len must be positive!
X`09tstl`09lenn`09`09;so IS it positive?
X`09blss`091501$`09`09;if lss then no, it's negative so try and probably
X`09`09`09`09; fail to open file.
X`09movl`09lbnn,hstlbn`09;looks ok so save host LBN
X`09movl`09lenn,hstfsz`09;and start blk
X`09brw`091785$`09`09;then merge common path in again.
X1501$:
X;
X; NOW LOCATE THE FILE AND VERIFY IT'S REALLY CONTIGUOUS, AND FIND
X; OUT HOW BIG IT IS. STORE RESULTS IN HSTLBN AND HSTFSZ AND
X; CALL KERNEL ROUTINE TO BASH THE VDn: UCB APPROPRIATELY.
X;
X; DON'T NEED TO DO THIS FOR DEASSIGN SO CHECK THAT FIRST...
X`09TSTL`09ASDAS`09`09`09; IF ZERO WE DEASSIGN
X`09BEQL`09296$
X`09tstl`09repflg
X`09bneq`09296$`09`09`09;forget file open if /report only
X; OPEN THE FILE, CHECK ITS INITIAL LBN
X; IF ERROR OR NOT CONTIG, EXIT...
X; DO VIA OPENING FILE AND READING ITS' STATBLOCK VIA
X; QIO...
X; SET UP FOR FILENAME WE REALLY FOUND IN FAB...
X`09MOVL`09DDFNA,DFAB_BLK+FAB$L_FNA`09;SET UP FILENAME ADDR
X`09MOVB`09DDFNM,DFAB_BLK+FAB$B_FNS`09;AND LENGTH
X`09$OPEN`09FAB=DFAB_BLK
X`09BLBC`09R0,300$`09`09`09; FAILURE IF FILE WON'T OPEN
X; FNXAB HAS INFO ON LBN, SIZE
X`09MOVL`09FNXAB+XAB$L_SBN,HSTLBN`09; GET HOST'S LBN
X`09BEQL`09301$`09`09`09;;; RESTRICTION FOR NOW ...
X`09`09`09`09`09;;; IF ZERO, FILE NONCONTIG
X`09`09`09`09`09;;; SO FORGET IT...
X`09MOVL`09FNXAB+XAB$L_HBK,HSTFSZ`09; GET FILE SIZE. (CHECK THAT BELOW)
X1785$:
X`09.if`09ndf,phy$io
X`09tstl`09vsec64
X`09beql`09784$
X`09BICL2`09#63,HSTFSZ`09`09;;;MAKE A MULTIPLE OF 64 BLKS
X;;; As long as the driver doesn't do physical I/O we can omit this...
X;;; except INIT seems unhappy then
X`09brb`09785$
X784$:
X`09cmpl`09hstfsz,#65530`09`09;big disk?
X`09blss`09785$`09`09`09;if not leave size alone.
X;`09bicl2`09#31,hstfsz`09`09;else make granular to 32 sectors anyhow
X785$:
X`09.endc
X;;;HAS TO BE A MULTIPLE OF 64 BLKS DUE TO FAKED-OUT PHYSICAL DRIVE
X;;; STRUCTURE OF 64 SECTORS/TRACK, 1 TRACK/CYL, NNN CYLINDERS...
X`09TSTL`09HSTFSZ`09`09`09; HOST SIZE POSITIVE
X`09BLSS`09301$`09`09`09; IF <0 OR =0 THEN ILLEGAL; BUG OUT
X`09`09`09`09`09; ELSE ISSUE THE REQUESTS TO GET THE
X`09`09`09`09`09; DEVICES...
X296$:
X
X`09$CMKRNL_S -
X`09`09ROUTIN=BASHUCB,ARGLST=K_ARG
X`09CMPL`09R0,#SS$_NORMAL`09`09`09`09;Any errors?
X`09BEQL`09300$`09`09`09`09`09;No, skip error routine
X`09MOVL`09R0,MESS`09`09`09`09`09;Move error to message
X;;;`09BRW`09300$
X301$:
X; ERROR RETURN ... CLOSE FAB & LEAVE
X`09$PUTMSG_S`09MSGVEC=ERROR`09`09`09;Pump out error message
X`09$CLOSE FAB=DFAB_BLK
X300$:
X; BE SURE WE DON'T LEAVE THE CHANNELS ASSIGNED TO THE DEVICES
X; EITHER...
X`09$DASSGN_S CHAN=VDCHN
X`09tstl`09repflg
X`09bneq`09550$
X`09TSTL`09ASDAS`09`09`09`09; IF ZERO WE DEASSIGN
X`09beql`09540$`09`09`09`09; if zero, no file chnl to deass
X`09$DASSGN_S CHAN=DDCHN`09`09`09;CLEAN UP I/O CHANNELS
X540$:`09; skip deassign file chnl on advd/deassign
X`09; to avoid final error msg
X`09RET
X550$:
X; print out the filespec
X`09tstb`09repwrk`09`09`09`09;got any file assigned?
X`09beql`09552$`09`09`09`09;if not, don't emit name
X`09pushab`09reptxt`09`09`09`09;text descr. of filename
X`09calls`09#1,g`5Elib$put_output`09`09;emit same
X552$:
X`09ret
Xadvdd_exit:
X`09RET
X
X; BASHUCB - AREA TO MESS UP UCB WITH OUR FILE DATA
X; BEWARE BEWARE BEWARE
X;  runs in KERNEL mode ... HAS to be right.
X
X.if`09Df, EVAX
XBASHUCB::
X`09.Call_Entry Home_Args=True,Max_Args=2,Preserve=<R2,R3,R4,R5,R6,R7,R8>
X.iff
X`09.ENTRY`09BASHUCB,`5EM<R2,R3,R4,R5,R6,R7,R8>
X.endc
X; TAKEN LOOSELY FROM ZERO.MAR
X`09.if`09ndf,vms$v5
X`09MOVL`09G`5ESCH$GL_CURPCB,R4`09;;; NEED OUR PCB
X`09.iff
X`09MOVL`09G`5ECTL$GL_PCB,R4`09`09;;; NEED OUR PCB (VMS V5)
X`09.endc
X`09JSB`09G`5ESCH$IOLOCKW`09`09;;; LOCK I/O DATABASE
X`09CLRL`09HSTUCB`09`09`09;;; ZERO "HOST" UCB
X`09movl`09#1,vdprog`09`09;;; got to start
X`09tstl`09repflg
X`09bneq`0990$`09`09`09;;;no host lookup on /report
X`09TSTL`09ASDAS`09`09`09;;; IF DEASSIGN, ZERO
X`09BEQL`0990$`09`09`09;;; SO IF EQUAL SKIP LOCATE HOST UCB
X`09MOVL`094(AP),R1`09`09;;; ADDRESS DVC NAME DESCRIPTORS
X`09JSB`09G`5EIOC$SEARCHDEV`09`09;;; GET UCB ADDRESS INTO R1
X`09BLBS`09R0,60$
X`09BRW`09BSH_XIT
X60$:
X;`09TSTL`09UCB$L_PID(R1)`09`09;;; ENSURE DVC NOT ALLOCATED
X;`09BEQL`0980$
X;`09MOVL`09#SS$_DEVALLOC,R0
X;`09BRW`09BSH_XIT
X; ALLOCATED OK SINCE IT COULD JUST BE PRIVATE MOUNT...
X;
X80$:
X`09movl`09#2,vdprog`09`09;;; got host ucb ok
X`09MOVL`09R1,HSTUCB`09`09;;; SAVE HOST UCB ADDRESS
X`09BEQL`09167$`09`09`09;;; ... BUT ZERO UCB ADDRESS LOOKS BAAAAD
X90$:
X`09MOVL`098(AP),R1`09`09;;; ADDRESS VDn NAME DESCRIPTORS
X`09movl`09#3,vdprog`09`09;;; got vdn: descriptor
X`09JSB`09G`5EIOC$SEARCHDEV`09`09;;; GET UCB ADDRESS INTO R1
X`09BLBS`09R0,160$
X`09BRW`09BSH_XIT
X160$:
X`09movl`09r1,vducb`09`09;;; store vd ucb
X`09movl`09#4,vdprog`09`09;;; got vd ucb
X`09tstl`09repflg
X`09bneq`09168$`09`09`09;;;on /report don't mess ucb up
X`09TSTL`09UCB$L_PID(R1)`09`09;;; ENSURE DVC NOT ALLOCATED
X`09BEQL`09180$
X165$:
X`09MOVL`09#SS$_DEVALLOC,R0
X167$:`09BRW`09BSH_XIT
X168$:`09brw`09455$
X180$:
X`09movl`09#5,vdprog`09`09;;; not allocated yet
X; BUGGER THE UCB
X; ASSUMES FILE LBN AND SIZE ALREADY RECORDED
X; ALSO ASSUMES THAT ZERO LBN OR SIZE MEANS THIS ENTRY NEVER CALLED.
X; (REALLY ONLY WORRY ABOUT ZERO SIZE; IF WE OVERMAP A REAL DEVICE
X; THEN ZERO INITIAL LBN COULD BE OK.)
X;
X; CHECK REF COUNT FIRST... ONLY CAN GET AWAY WITH THIS ON DEVICE
X; NOBODY'S USING...
X; .. fake this since device may have count messed by advd somehow
X; but will be allocated if mounted.
X; ... for now ...
X554$:
X`09movl  ucb$l_refc(r1),vdsts2`09;;; save status for debug
X`09CMPL`09UCB$L_REFC(R1),#1`09;;; CHECK COUNT VS 1 FOR THIS
X`09BGTRU`09165$
X;`09TSTW`09UCB$L_REFC(R1)`09`09;;; IF MOUNTED DON'T TOUCH
X;`09BNEQ`09165$`09`09`09;;; IF NEQ IT'S ACCESSED...
X`09movl`09#6,vdprog`09`09;;; not mounted either
X`09MOVL`09HSTUCB,UCB$HUCB(R1)`09;;; SAVE HOST UCB OR 0
X`09BNEQ`09184$`09`09`09;;; IF NE, OK NOW
X;;; ZERO -- DEASSIGNING. FLAG VOLUME INVALID
X`09BICL`09#UCB$M_ONLINE,UCB$L_STS(R1) ;;; FLAG OFFLINE
X`09BICL`09#UCB$M_VALID,UCB$L_STS(R1) ;;; AND INVALID
X`09clrb`09ucb$vdcontfil(r1)`09;;;clr container file name
X`09BRW`09200$
X184$:`09MOVL`09HSTLBN,UCB$HLBN(R1)`09;;; SAVE HOST'S LBN
X`09MOVL`09HSTFSZ,UCB$HFSZ(R1)`09;;; AND FILE SIZE
X`09MOVL`09HSTFSZ,UCB$L_MAXBLOCK(R1) ;;; (SAVE SIZE TWICE, FOR RMS
X`09clrl`09ucb$ppid(r1)`09`09;;;zero original PID
X`09movl`09r4,-(sp)
X`09movl`09hstucb,r4`09`09;;;get host UCB
X`09beql`09189$`09`09`09;;;forget it if none
X;;;must make maxbcnt and fipl match!!!
X;`09movb`09ucb$b_fipl(r4),ucb$b_fipl(r1)`09;;;ensure fork levels match
X`09movl`09ucb$l_maxbcnt(r4),ucb$l_maxbcnt(r1) ;;;store max bytes as a word
X189$:
X`09movl`09(sp)+,r4
X`09movl`09#7,vdprog`09`09;;; filled in stuff
X`09`09`09`09`09;;; AND QIO CHECKS, AND OUR SAFETY
X`09`09`09`09`09;;; ONES)
X`09MOVL`09HSTFSZ,R0`09`09;;; GET HOST SIZE
X`09ASHL`09#-6,R0,R0`09`09;;; GET # CYLINDERS IN SIZE NOW
X;Set default geometry as 1 track/cylinder, 64 sectors/track, and
X; as many cylinders as needed for device size. We use this if the
X; /SEC64 switch is given. Otherwise we check to see if the container
X; file is size same as some known disk and adopt its' geometry, or
X; if that fails use either a 1 sector/trk 1 trk/cyl n cylinder
X; geometry for small disks (under 65000 blocks), or a 32 sect/trk
X; 32 trk/cyl n cylinder geometry for large disks.
X;
X;  *** Where one gets over 2 billion blocks and sets the sign bit
X;  *** in the blocks count, this code will break due to not
X;  *** ensuring sign extension is avoided. Since this corresponds
X;  *** to a single disk of 1 terabyte, it seems unlikely to cause
X;  *** difficulties for a while. The 64 sector geometry breaks down
X;  *** at 64*65536 blocks (2 GB) and the 32*32*n geometry breaks
X;  *** down at 1024 * 65536 blocks. These seem high enough not to`20
X;  *** worry about for now. If they become a problem, play with
X;  *** geometry!!!
X;
X`09MOVW`09R0,UCB$W_CYLINDERS(R1)`09;;; SAVE IN UCB FOR REST OF VMS
X`09movl`09r0,vdcyl`09`09;;; store cylinders for debug
X`09movb`09#64,ucb$b_sectors(r1)`09;;;init sectors to 64 always
X`09movb`09#1,ucb$b_tracks(r1)`09;number of tracks/cyl=1
X`09tstl`09vsec64`09`09;;;did user say he needs 64 sector geometry?
X`09beql`096843$`09`09`09;;;if eql no, do tests
X`09brw`096841$`09`09`09;;;if neql leave geometry alone...
X6843$:
X`09tstl`09vsec32`09`09`09;;;did he ask for 32 sect/32 trk geom?
X; get md: geometry if /sec32 spec'd.
X; was bneq 685$
X`09bneq`09687$`09`09`09;;;if so (neq) skip geom table.
X`09movl`09r2,-(sp)`09`09;;;Need a register to point to geoms
X`09movab`09geoms,r2`09`09;;;so we can test sizes
X; Check for file sizes of known disks and set geometry of those
X; disks IF we match.
X686$:`09tstl`09(r2)`09`09`09;;;end of table?
X`09beql`09687$`09`09`09;;;if eql yes, skip out
X`09cmpl`09hstfsz,(r2)`09`09;;;above min size this disk type?
X`09blss`09688$`09`09`09;;;if too small, we're done so exit the loop
X`09cmpl`09hstfsz,4(r2)`09`09;;;see if too big
X`09bgtr`09688$`09`09`09;;;if too big, look at next
X; got a match. Now fill in geometry
X; (r2) = lo size (must be at LEAST as large as device)
X; 4(r4) = hi size lim
X; 8(r2) = # blks on device
X; 12(r2) = cyl
X; 14(r2) = trk
X; 15(r2) = cyl
X; 16(r2) = type
X`09movl`098(r2),ucb$l_maxblock(r1)`09;Set up maximum block
X`09movw`0912(r2),ucb$w_cylinders(r1)`09;number of cylinders
X`09movb`0914(r2),ucb$b_tracks(r1)`09`09;number of tracks/cyl
X`09movb`0915(r2),ucb$b_sectors(r1)`09;number sectors/track
X`09movb`0916(r2),ucb$b_devtype(r1)`09;set type too.
X`09movl`09(sp)+,r2`09`09`09;restore our register
X`09brb`09684$`09`09`09`09;exit, we got our device
X; Notice we must pass the "small device" test since some devices have
X; less than 65000 blocks. We won't emulate device TYPE exactly, but will
X; emulate device GEOMETRY with this logic.
X688$:;`09addl2`09#20,r2`09`09`09`09;pass to next entry of geoms table
X`09cmpl`09(r2)+,(r2)+
X`09cmpl`09(r2)+,(r2)+
X`09tstl`09(r2)+
X`09brb`09686$`09`09`09`09;go check for next device or end
X687$:
X`09movl`09(sp)+,r2`09`09;;;restore reg
X; test for small files
X`09cmpl`09hstfsz,#65530`09`09;"small" disks?
X`09bgtr`09685$
X`09movw`09hstfsz,ucb$w_cylinders(r1)`09;yep...save size in cyl
X`09movb`09#1,ucb$b_sectors(r1)`09`09;and set 1 sector/trk
X`09movb`09#1,ucb$b_tracks(r1)`09`09;and 1 track/cyl (should be ok already)
X`09brw`09684$`09`09`09`09;done with geometry
X685$:
X; Add other checks here
X; Make geometry like mdan: disks, that is, 32 sectors and 32 tracks/cyl.
X; unless /sec64 switch was set. This facilitates random use as a switch
X; over from md: type disks. Note 32 * 32 = 1024
X`09MOVL`09HSTFSZ,R0`09`09;;; GET HOST SIZE
X`09ASHL`09#-10,R0,R0`09`09;;; GET # CYLINDERS IN SIZE NOW as #/1024
X`09MOVW`09R0,UCB$W_CYLINDERS(R1)`09;;; SAVE IN UCB FOR REST OF VMS
X`09bicl2`09#1023,ucb$l_maxblock(r1)`09;ensure even number of cylinders
X`09movb`09#32,ucb$b_sectors(r1)`09;set 32 sectors/track
X`09movb`09#32,ucb$b_tracks(r1)`09;and 32 tracks/cylinder
X`09brb`09684$`09`09`09`09;This is the "large disk" default
X;`09`09`09`09`09`09;unless /sec64 sets 64 sect geom.
X6841$:
X; If here, we are using the 64 sector/track geometry
X`09bicl2`09#63,ucb$l_maxblock(r1)`09`09;make disk size a multiple of sect/tr
Vk
X684$:
X`09movl`09#8,vdprog
X`09pushl`09r0
X`09pushl`09r1
X`09pushl`09r2
X; Fill in filename as 1st 79 chars of what user sent us
X`09movab`09ddfnmd,r0`09`09;data address
X`09movl`09#79,r2`09`09`09;copy 79 bytes
X`09addl`09#ucb$vdcontfil,r1`09;point at ucb offset
X457$:`09movb`09(r0)+,(r1)+
X`09sobgtr`09r2,457$`09`09`09;copy the data
X`09clrb`09(r0)+`09`09`09;null terminate
X`09popl`09r2
X`09popl`09r1
X`09popl`09r0
X`09BISL`09#UCB$M_ONLINE,UCB$L_STS(R1) ;;; FLAG ONLINE NOW
X`09BISL`09#UCB$M_VALID,UCB$L_STS(R1) ;;; AND VOL VALID
X`09movl`09ucb$l_sts(r1),vdsts`09;;; save VD status
X;;; THAT'S IT... SHOULD BE OK NOW.
X`09brb`09200$
X455$:
X; copy vd: stored name into prog area
X`09pushl`09r1
X`09pushl`09r2
X`09movab`09repwrk,r0`09`09;;;get report area
X`09movl`09#80,r2`09`09`09;;;80 bytes max
X`09addl2`09#ucb$vdcontfil,r1`09;;;point at in area
X456$:`09movb`09(r1)+,(r0)+
X`09beql`09458$`09`09`09;;;on null terminator stop copy
X`09`09`09`09`09;;;(keeps old name junk from reappearing)
X`09sobgtr`09r2,456$`09`09`09;;;copy the data
X458$:
X`09popl`09r2
X`09popl`09r1
X200$:
X`09MOVL`09#SS$_NORMAL,R0
XBSH_XIT:
X`09PUSHL`09R0
X`09JSB`09G`5ESCH$IOUNLOCK`09`09;;; UNLOCK I/O DATABASE (DROP IPL)
X`09POPL`09R0`09`09`09;;; REMEMBER R0
X`09RET`09;;; BACK TO USER MODE NOW
X`09.END ADVDD
$ CALL UNPACK ASNVDM6.MAR;4 1426467438
$ create 'f'
X$ SAVE_VERIFY='F$VERIFY(0)
X$!
X$ if p1 .Eqs. "CLEAN" then goto clean
X$ if p1 .Eqs. "CLOBBER" then goto clobber
X$ if p1 .Eqs. "INSTALL" then goto install
X$!
X$!`09Compile the VDDRIVER
X$!
X$ Set Symbol/Scope=NoGlobal
X$!
X$! Establish the Compiling Environment
X$!
X$ Compile_For_Alpha = F$TrnLNM("COMPILE_FOR_ALPHA")
X$ If Compile_For_Alpha
X$ Then
X$`09CC := GEMCC/STANDARD=VAXC/PREFIX=ALL
X$`09LIBRARY := LIBRARY/ALPHA
X$`09MACRO := MACRO/MIGRATION
X$`09LINK := LINK/ALPHA/NATIVE/BPAGE=14/SECTION/NOTRACE/NODEMAND_ZERO/SYSEXE=
VSELECTIVE/NOSYSSHR
X$`09OBJ = "ALPHA_OBJ"
X$`09OLB = "ALPHA_OLB"
X$`09OPT = "ALPHA_OPT"
X$`09EXE = "ALPHA_EXE"
X$`09MAP = "ALPHA_MAP"
X$`09ARCH = "ALPHA"
X$`09PREFIX = "ALPHA$LIBRARY:ARCH_DEFS+"
X$ Else
X$`09OBJ = "OBJ"
X$`09OLB = "OLB"
X$`09OPT = "OPT"
X$`09EXE = "EXE"
X$`09MAP = "MAP"
X$`09ARCH = ""
X$`09PREFIX = ""
X$ Endif
X$!
X$!  Get the compiler options via the logical name MOPTS
X$!
X$ mac_options = f$trnlnm("MOPTS")
X$!
X$!  Get the linker options via the logical name LOPTS
X$!
X$ link_options = f$trnlnm("LOPTS")
X$!
X$!  Compile the "C" files
X$!
X$! procedure target`09command `09`09`09depends upon
X$! CALL MAKE FILE.OBJ`09"CC ''cc_options' FILE.C"`09FILE.C
X$!
X$ write sys$output "Compiling VDDRIVER sources"
X$ CALL MAKE ASNVDM6.'OBJ'`09"MACRO/OBJ=ASNVDM6.''OBJ' ''PREFIX'SYS$DISK:`5B`
V5DASNVDM6"`09`09ASNVDM6.MAR
X$ CALL MAKE VDDRIVER.'OBJ'`09"MACRO/OBJ=VDDRIVER.''OBJ' ''PREFIX'SYS$DISK:`5
VB`5DVDDRIVER''ARCH'"`09VDDRIVER'ARCH'.MAR
X$!
X$ write sys$output "Building VDDRIVER images"
X$ CALL MAKE ASNVDM6.'EXE'  "LINK/EXE=ASNVDM6.''EXE' ASNVDM6.''OPT'/OPT"`09AS
VNVDM6.'OBJ'
X$ CALL MAKE VDDRIVER.'EXE' "LINK/SHARE/EXE=VDDRIVER.''EXE'/MAP=VDDRIVER.''MA
VP'/FULL/CROSS VDDRIVER.''OPT'/OPT" -
X`09VDDRIVER.'OBJ'
X$!
X$ exit
X$!
X$ Clobber:`09! Delete executables, Purge directory and clean up object files
V and listings
X$ Delete/noconfirm/log *.exe;*
X$!
X$ Clean:`09! Purge directory, clean up object files and listings
X$ Purge
X$ Delete/noconfirm/log *.lis;*
X$ Delete/noconfirm/log *.obj;*
X$!
X$ exit
X$!
X$ Install:
X$ Copy/log *.exe X11Bin:
X$ exit
X$!
X$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
X$ V = 'F$Verify(0)
X$! P1 = What we are trying to make
X$! P2 = Command to make it
X$! P3 - P8  What it depends on
X$
X$ If F$Search(P1) .Eqs. "" Then Goto Makeit
X$ Time = F$CvTime(F$File(P1,"RDT"))
X$arg=3
X$Loop:
X$`09Argument = P'arg
X$`09If Argument .Eqs. "" Then Goto Exit
X$`09El=0
X$Loop2:
X$`09File = F$Element(El," ",Argument)
X$`09If File .Eqs. " " Then Goto Endl
X$`09AFile = ""
X$Loop3:
X$`09OFile = AFile
X$`09AFile = F$Search(File)
X$`09If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
X$`09If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
X$`09Goto Loop3
X$NextEL:
X$`09El = El + 1
X$`09Goto Loop2
X$EndL:
X$ arg=arg+1
X$ If arg .Le. 8 Then Goto Loop
X$ Goto Exit
X$
X$Makeit:
X$ Set Verify
X$ 'P2
X$ VV='F$Verify(0)
X$Exit:
X$ If V Then Set Verify
X$ENDSUBROUTINE
$ CALL UNPACK MAKE.COM;12 407965759
$ create 'f'
Xcluster=vddrv,,,-
X`09vddriver.alpha_obj,-
X`09ALPHA$LIBRARY:STARLET/INCLUDE:(-
X`09`09SYS$DOINIT,-
X`09`09SYS$DRIVER_INIT)
X!
X! set psect options
X!
XPSECT_ATTR=_AMAC$CODE,PIC,USR,CON,REL,GBL,NOSHR,EXE,RD,NOWRT,NOVEC
XPSECT_ATTR=_AMAC$LINKAGE,PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC
XPSECT_ATTR=$CODE$,PIC,USR,CON,REL,GBL,NOSHR,EXE,RD,NOWRT,NOVEC
XPSECT_ATTR=$LINK$,PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC
XPSECT_ATTR=$PLIT$,PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC
XPSECT_ATTR=$OWN$,PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC
XPSECT_ATTR=$GLOBAL$,PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC
XPSECT_ATTR=EXEC$INIT_CODE,NOSHR
XPSECT_ATTR=EXEC$INIT_LINKAGE,PIC,USR,CON,REL,GBL,NOSHR,EXE,RD,WRT,NOVEC
XPSECT_ATTR=$LINKAGE,NOPIC,CON,REL,LCL,NOSHR,NOEXE,NOWRT,NOVEC,MOD,PAGE
XPSECT_ATTR=$$$115_LINKAGE,PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC
X!
X! collect stuff
X!
X!collect=vddrv,$linkage,$$$105_prologue,$$$110_data,$$$130_tbl,$$$115_driver
V,. blank .
XCOLLECT=NONPAGED_READONLY_PSECTS/ATTRIBUTES=RESIDENT,-
X        _AMAC$CODE,-
X        EXEC$NONPAGED_CODE,-
X`09$$$115_DRIVER,-
X        $CODE$
XCOLLECT=NONPAGED_READWRITE_PSECTS/ATTRIBUTES=RESIDENT,-
X        _AMAC$LINKAGE,-
X        EXEC$NONPAGED_DATA,-
X        EXEC$NONPAGED_LINKAGE,-
X`09$$$105_PROLOGUE,-
X`09$$$110_DATA,-
X`09$$$115_LINKAGE,-
X        $PLIT$,-
X        $GLOBAL$,-
X        $OWN$,-
X        $LINK$
XCOLLECT=INITIALIZATION_PSECTS/ATTRIBUTES=INITIALIZATION_CODE,-
X        EXEC$INIT_LINKAGE,-
X        EXEC$INIT_CODE,-
X        EXEC$INIT_000,-
X        EXEC$INIT_001,-
X        EXEC$INIT_002,-
X        EXEC$INIT_SSTBL_000,-
X        EXEC$INIT_SSTBL_001,-
X        EXEC$INIT_SSTBL_002
X`09
$ CALL UNPACK VDDRIVER.ALPHA_OPT;8 1595338486
$ create 'f'
X$LINK/ALPHA/MAP/full/NATIVE/BPAGE=14/SECTION/NOTRACE/NODEMAND-
X/SHARE/SYSEXE=SELECT/NOSYSSHR VDDRIVERALPHA+vddriver.opt/opt
$ CALL UNPACK VDDRIVER.LNK;11 1161373388
$ create 'f'
X`09.TITLE`09VDDRIVER - VAX/VMS VIRT DISK DRIVER
X`09.IDENT`09'V4f'
X`09.Subtitle`09Documentation
X;
X; Changed by making it fd1 type and adding nodename prefix characteristic
X; so that hopefully it will now work with MSCP.
X;
X; Added save/restore of IRP$L_MEDIA for second I/O completion (by VDDRIVER)
X; so that error path code that assumes this field unaltered will work. 4/14/
V89
X;
X;md$stat=1
X;d$$bug=1
X;x$$$dt=1`09;call xdelta
X; Note: define symbol VMS$V5 to assemble in VMS V5.x or later. Default
X; assembly without this definition produces a VMS V4.x driver.
X; Glenn C. Everhart, 2/2/1989
X; Merged in some of Marty Sasaki's changes
Xvms$v5=1
X; define v5$picky also for SMP operation
Xv5$picky=1
X;USAPADDR=0
X;d$$bug=0
X;
X; FACILITY:
X;`20
X; `09VAX/VMS VIRTUAL DISK DRIVER USING CONTIGUOUS FILES.
X;`20
X; AUTHOR:
X;`20
X; G. EVERHART
X;
X;`20
X; ABSTRACT:
X;`20
X; `09THIS MODULE CONTAINS THE TABLES AND ROUTINES NECESSARY TO
X; `09PERFORM ALL DEVICE-DEPENDENT PROCESSING OF AN I/O REQUEST
X;`09FOR VMS VIRTUAL DISKS ON CONTIG FILES.
X;
X; Note:
X;`09This driver has an FDT table that will look just like other
X;`09disks for everything, but will NOT do buffered I/O.
X;`09In its' FDT routines, which will be dummies, it will just
X;`09modify logical block numbers in the I/O packets, assume
X;`09the buffered bit in irp$w_STS clear (like all disk drivers`20
X;`09except floppy drivers), do a range check to make sure
X;`09the LBN used is in the legal range for this particular unit
X;`09ov VD:, and reset things to call the real driver's FDT
X;`09routines and let IT do the work. It will unbusy itself
X;`09before losing control.
X;`09`09The idea is that only I/O "gets at the physical
X;`09storage", so only that need be munged. Since this happens
X;`09only for read/write logical/physical, we just leave OUR
X;`09FDT routines in there for everything else. In just assuming
X;`09the buffered bit in the I/O we MAY mess up some quotas (this
X;`09will eventually get cleaned up), but won't lose buffers or
X;`09otherwise mess up things. Since most drivers have nonbuffered
X;`09I/O, we'll usually be just fine. (Disk drivers, that is.)
X;`09(In fact only RX01 class real drivers are buffered. Don't
X;`09put vd: units on those!!!)
X;`09`09To call the "real" FDT routines we'll just reset the
X;`09registers (and the IORP) to the real device and return. The
X;`09exec routines that handle FDT routines will take it from there
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-
