From: gleeve@galaxy.dnet
Newsgroups: comp.os.vms
Subject: DD (720KB) 3.5" floppies on VS3100
Date: 31 Jul 92 18:17:42 GMT
Distribution: world
Organization: The Internet

I noticed a useful feature of DKdriver, that it will allow writes
to DD (720KB) floppies in the RX23S drives if the dd_bypass
bit is set in ucb$l_dk_flags for the driver. This is not
normally done, but does work. I've tried it, and to make it
more convenient took some code and cobbled up the following
utility. IF run with the commands
$ setbyp:==$setbyp ! assuming setbyp.exe is in sys$system
$ setbyp dka500:   ! or whatever your RX23S is called
it will set this bit so you can write as well as read 720K floppies.
This can be very handy where communicating with some machines (in my
case, an Amiga).

Build is simple:
$ macro setbyp
$ link setbyp+sys$system:sys.stb/sel

Glenn Everhart
Everhart@Raxco.com
---------------- cut here -------------
	.TITLE	setbyp	;set BYPASS flag for RX23S
; The dd_bypass flag in ucb$l_dk_flags for dkdriver allows writing to low density
; RX23 disks. This program will set this flag. The values are obtained from VMS 5.4-3 listings
ucb$l_dk_flags=344	;158 hex
dd_bypass=4096		;1000 hex
	.IDENT	/1.0/
vms$v5=1
	.SBTTL	Symbols, Macros, Data

	.LIBRARY	/SYS$LIBRARY:LIB.MLB/

	$TPADEF		; Symbols for LIB$TPARSE.
	$SSDEF		; Symbols for return status.
	$UCBDEF		; Symbols for device ucb.
	$STSDEF		; Symbols for returned status.
	$DVIDEF		; Symbols for $GETDVI service.
	$DCDEF		; Symbols for device type.
	$devdef		; sym. for sdi type device.
; note sdi type devices are NOT scanned by RMS using logical I/O but
; their directories are instead created by the ACP/XQP and scanned
; by the ACP/XQP. While this is slower than doing it with logical
; I/O, it does allow directory access to be trapped by FDT code
; so that directory scans can be fooled as well as other accesses.

	.PSECT	ZDEC_DATA,RD,WRT,NOEXE,LONG,SHR,PIC

CMD_BUF:			; Buffer to hold command line.
	.BLKB	80
CMD_BUF_SIZ = . - CMD_BUF

CMD_BUF_DESC:			; Descriptor to command line.
	.LONG	 CMD_BUF_SIZ
	.ADDRESS CMD_BUF

PROMPT:
	.ASCID	/Device: /

PARSE_BLK:			; Parse block for LIB$TPARSE.
	.LONG	TPA$K_COUNT0
	.LONG	TPA$M_ABBREV	; Permit unambiguous abbreviations.
	.BLKB	TPA$K_LENGTH0-8

OVERRIDE:			; Zero out allocated devices, if set.
	.LONG	0

LOG_DEV_DESC:			; Descriptor for device on command line.
	.BLKQ	1

DEV_BUF:			; Buffer to hold device name.
	.BLKB	40
DEV_BUF_SIZ = . - DEV_BUF

DEV_BUF_DESC:			; Descriptor pointing to device name.
	.LONG	 DEV_BUF_SIZ
	.ADDRESS DEV_BUF

PID:				; Owner of device (if any).
	.BLKL	1

DEV_ITEM_LIST:			; Device list for $GETDVI.
	.WORD	 DEV_BUF_SIZ	; Make sure we a have a physical device name.
	.WORD	 DVI$_DEVNAM
	.ADDRESS DEV_BUF
	.ADDRESS DEV_BUF_DESC
	.WORD	 4		; See if someone has this device allocated.
	.WORD	 DVI$_PID
	.ADDRESS PID
	.LONG	 0
	.WORD	 4
	.WORD	 DVI$_DEVCLASS	; Check for a terminal.
	.ADDRESS DEV_CLASS
	.LONG	 0
	.LONG	 0		; End if item list.

TT_ITEM_LIST:			; Item list if we have a terminal.
	.WORD	 DEV_BUF_SIZ	; Make sure we a have a physical device name.
	.WORD	 DVI$_TT_PHYDEVNAM
	.ADDRESS DEV_BUF
	.ADDRESS DEV_BUF_DESC
	.LONG	 0

DEV_CLASS:
	.LONG	1

K_ARG:				; Argument list for kernel-mode routine.
	.LONG	 1		; Just one argument.
	.ADDRESS DEV_BUF_DESC	; Pass descriptor for device name.

	.SBTTL	State Table
	.PSECT	ZDEC_STATES,RD,NOWRT,EXE,LONG,SHR,PIC

	$INIT_STATE	STATE_TABLE,KEY_TABLE

	$STATE	START
	$TRAN	'/',QUAL
	$TRAN	TPA$_SYMBOL,DEV,,,LOG_DEV_DESC
	$TRAN	TPA$_EOS,TPA$_EXIT

	$STATE	DEV
	$TRAN	TPA$_EOS,TPA$_EXIT
	$TRAN	'/',QUAL
	$TRAN	':',COLON

	$STATE	COLON
	$TRAN	'/',QUAL
	$TRAN	TPA$_EOS,TPA$_EXIT

	$STATE	QUAL
	$TRAN	'OVERRIDE',,,1,OVERRIDE
	$TRAN	'NOOVERRIDE',,CLR_OV

	$STATE
	$TRAN	TPA$_SYMBOL,DEV,,,LOG_DEV_DESC
	$TRAN	TPA$_EOS,TPA$_EXIT

	$END_STATE


	.ENTRY	CLR_OV,^M<>
	CLRL	OVERRIDE
	MOVL	#SS$_NORMAL,R0
	RET

	.SBTTL	Main program
	.PSECT	ZDEC_CODE,RD,NOWRT,EXE,LONG,SHR,PIC
	.ENTRY	ZDEC,^M<R2,R3,R4,R5,R6,R7,R8,R9>

; Get the command line.
;
	PUSHAL	CMD_BUF_DESC		; Return length.
	PUSHAL	PROMPT			; Prompt for device name.
	PUSHAL	CMD_BUF_DESC		; Place to hold line.
	CALLS	#3,G^LIB$GET_FOREIGN
	BLBS	R0,20$			; Error?
	BRW	EXIT
20$:
	MOVL	CMD_BUF_DESC,-		; Set length of string to parse.
		PARSE_BLK+TPA$L_STRINGCNT
	MOVL	CMD_BUF_DESC+4,-	; Set address of string to parse.
		PARSE_BLK+TPA$L_STRINGPTR
	PUSHAL	KEY_TABLE		; Parse the command line for
	PUSHAL	STATE_TABLE		; qualifier and device.
	PUSHAL	PARSE_BLK
	CALLS	#3,G^LIB$TPARSE
	BLBS	R0,30$			; Error?
	BRW	EXIT
30$:

; Get the physical device name, and see if this device has an owner.
;
	$GETDVI_S -
		DEVNAM=LOG_DEV_DESC,-	; Command line has device name.
		ITMLST=DEV_ITEM_LIST
	BLBS	R0,40$
	BRW	EXIT

40$:
	CMPL	#DC$_TERM,DEV_CLASS	; Did we get a terminal?
	BNEQ	50$
	$GETDVI_S -			; Yes, make sure we get the
		DEVNAM=LOG_DEV_DESC,-	; physical device name.
		ITMLST=TT_ITEM_LIST
	BLBS	R0,50$
	BRW	EXIT

50$:
	TSTL	PID
	BEQL	60$
	TSTL	OVERRIDE		; Device is allocated, see if we
	BGTR	60$			; should proceed.
	MOVL	#SS$_DEVALLOC,R0	; Device is allocated, exit with
	BRW	EXIT			; error.
60$:

	$CMKRNL_S -			; Enter k-mode to zero out count.
		ROUTIN=ZERO,-
		ARGLST=K_ARG
	BLBS	R0,80$
	BRW	EXIT
80$:

EXIT:
	RET
; routine to set the bypass bit. Also zeroes error count (this came
; from mark Oakley's original ZDEC program).
	.ENTRY	ZERO,^M<R2,R4>

	.if	ndf,vms$v5
	MOVL	G^SCH$GL_CURPCB,R4	;; Our PCB address is input to SCH
	.iff
	MOVL	G^CTL$GL_PCB,R4		;; Our PCB address is input to SCH
	.endc
					;; routines.
	JSB	G^SCH$IOLOCKW		;; Lock the I/O database.

	MOVL	4(AP),R1		;;; Address of device name descriptor.
	JSB	G^IOC$SEARCHDEV		;;; Get UCB address for device into R1.
	BLBS	R0,60$
	BRW	ZERO_EXIT

60$:
	TSTL	UCB$L_PID(R1)		;;; Make sure device did not become
	BEQL	80$			;;; allocated.
	TSTL	OVERRIDE		;;; Device is allocated, see if we
	BGTR	80$			;;; should proceed.
	MOVL	#SS$_DEVALLOC,R0
	BRW	ZERO_EXIT

80$:
	CLRW	UCB$W_ERRCNT(R1)	;;; Zero out the error count.
; If you want to set the dv.sdi bit, uncomment the next. This forces
; all RMS directory calls to go thru the XQP.
; set dv.sdi bit in ucb$l_devchar. This is bit 4
;	bisl	#dev$m_sdi,ucb$l_devchar(r1)	;set "sdi" bit
	bisl	#dd_bypass,ucb$l_dk_flags(r1)	;set "bypass" flag so driver will allow write on 720K floppies
	MOVL	#SS$_NORMAL,R0

ZERO_EXIT:
	PUSHL	R0			;;; Remember status.
	JSB	G^SCH$IOUNLOCK		;;; Unlock I/O database (drop IPL).
	POPL	R0

	RET

	.END	ZDEC

Newsgroups: comp.os.vms