d 	.TITLE	ACPMNT - MOUNT IMAGE FOR PCACP
 	.IDENT	/V02/
,
;++
;
X; ACPMNT.MAR -- MOUNT IMAGE FOR PAPER TAPE ACP
;
 ;	THIS PROGRAM MOUNTS THE PAPER TAPE ACP (PCACP), AFTER
;	CREATING THE ACP PROCESS.  IT PERFORMS ALL THE APPROPRIATE
;	SYNCHRONIZING CHECKS WITH THE ACP.
L;
; SIDE EFFECTS:
;	
x;	THE PCACP PROCESS MAY BE CREATED.
;
@; PROGRAMMER:
;
;	VIK MUIZNIEKS    JULY--1979
l;
;--
4PC_ACP_TYPE=200					; PAPER TAPE ACP TYPE
;
;	SYMBOL AND OFFSET DEFINITIONS (SOME FROM LIB.MLB)
`	;
		$CCBDEF
(
	$IODEF

	$AQBDEF

	$SSDEF
T	$DYNDEF
	$UCBDEF
	$VCBDEF
	$PQLDEF
	$PRDEF
H	$PSLDEF
;
;	CHARACTER STRING DESCRIPTORS FOR $CREPRC
t;
IMAGE:	.ASCID	/SYS$SYSTEM:PCACP.EXE/
<PROCESS:.ASCID	/PCACP/
INPUT:	.ASCID	/TTA0:/				; NEVER USED BY ACP
UIC:	.WORD	^O01				; ACP UIC MEMBER=001
h	.WORD	^O01				; ACP UIC GROUP=001
						; ACP UIC = [001,001]
0;
;	CHAR. STRING DESCR. FOR PAPER TAPE READER/PUNCH DEVICE
;
\PCAPE:	.ASCID	/PCA1:/
;
$;	QUOTA LIST FOR PCACP PROCESS
;
QLIST:	.BYTE	PQL$_ASTLM
P	.LONG	128
	.BYTE	PQL$_DIOLM
	.LONG	^X00000FFF
|	.BYTE	PQL$_BIOLM
	.LONG	^X00000FFF
D	.BYTE	PQL$_LISTEND
;
;	STORAGE FOR RETURNED PCACP PID
p;
PID:	.BLKL	1
8;
;	30-SECOND DELTA TIME FOR $SETIMR
 ;
dWAIT:	.LONG	-10*1000*1000*30,-1
;
,;	CHANNEL FOR IO$_MOUNT QIO TO PCACP
;
CHAN:	.LONG	0
XSTART:	.WORD	0				; NULL ENTRY MASK
	$CMKRNL_S	B^BEGIN			; CHANGE MODE TO KERNEL
 	RET					; ALL DONE
BEGIN:	.WORD	0				; SAVE NO REGISTERS
;
L;	GET UCB ADDRESS INTO R7
;
	$ASSIGN_S	DEVNAM=PCAPE,CHAN=CHAN,-; ASSIGN CHANNEL TO PCA1
x			ACMODE=#PSL$C_USER	; AT USER LEVEL--SINCE
						; THAT WAS PREVIOUS MODE
@						; (REQUIRED LATER BY
						; IOC$VERIFYCHAN)
 	BLBS	R0,10$				; CHECK FOR ERROR
l 	MOVL	#SS$_DEVOFFLINE,R0		; RETURN ERROR STATUS
 	RET
4!10$:	MOVZWL	W^CHAN,R0			; OBTAIN CHANNEL NUMBER
!	JSB	G^IOC$VERIFYCHAN		; OKAY CHANNEL # AND PUT
!						; CCB ADDRESS IN R1
`"						; (THIS ROUTINE DESTROYS
"						; R0-R3; ALSO, IT CHECKS
(#						; CHANNEL ACCESSIBILITY
#						; FOR THE PREVIOUS MODE-
#						; IN THIS CASE, USER)
T$	BLBS	R0,20$				; CHECK FOR ERROR
$	RET					; AND FINISH UP
%20$:	MOVL	CCB$L_UCB(R1),R7		; GET UCB ADDRESS
%;
%;	IS ACP ALREADY MOUNTED OR MARKED FOR DISMOUNT?
H&;
&	BBS	#DEV$V_MNT,UCB$L_DEVCHAR(R7),30$; ALREADY MOUNTED?
'	BBC	#DEV$V_DMT,UCB$L_DEVCHAR(R7),40$; MARKED FOR DISMOUNT?
t'30$:	MOVL	#SS$_DEVMOUNT,R0		; RETURN ERROR STATUS
'	BRW	EXIT				; USE COMMON EXIT
<(40$:
(;
);	ALLOCATE THE ACP QUEUE BLOCK (AQB)
h);
)	MOVZBL	#AQB$C_LENGTH,R1		; LENGTH OF AQB
0*	JSB	G^EXE$ALONONPAGED		; ALLOCATE AQB
*	BLBS	R0,50$				; ALLOCATION OK?
*	MOVL	#SS$_INSFMEM,R0			; NO, ERROR
\+	BRW	EXIT				; USE COMMON EXIT
+50$:
$,;
,;	INITIALIZE THE AQB (ADDRESS OF AQB RETURNED IN R2 BY EXEC)
,;
P-	MOVZBW	#AQB$C_LENGTH,AQB$W_SIZE(R2)	; RECORD SIZE
-	MOVB	#DYN$C_AQB,AQB$B_TYPE(R2)	; TYPE OF BLOCK
.	MOVL	R2,AQB$L_ACPQFL(R2)		; SET IRP Q FORWD. LINK
|.	MOVL	R2,AQB$L_ACPQBL(R2)		; AND BACKWARD LINK
.	MOVB	#1,AQB$B_MNTCNT(R2)		; INITIALIZE MOUNT COUNT
D/	MOVB	#PC_ACP_TYPE,AQB$B_ACPTYPE(R2)	; MARK ACP AS PT ACP
/	BISB	#AQB$M_CREATING!AQB$M_UNIQUE,-	; START SYNCHRONIZATION
0		AQB$B_STATUS(R2)		; WITH CREATING BIT
p0	PUSHL	R2				; SAVE AQB ADDRESS
0;
81;	ALLOCATE THE VOLUME CONTROL BLOCK (VCB)
1;
 2	MOVL	#SS$_INSFMEM,R6			; ASSUME DEAL. FAILURE
d2	MOVZBL	#VCB$C_LENGTH,R1		; SIZE OF VCB
2	JSB	G^EXE$ALONONPAGED		; ALLOCATE VCB
,3	BLBC	R0,76$				; DEAL. AQB IF FAIL
3	MOVL	R2,R8				; SAVE VCB ADDRESS
3;
X4;	INITIALIZE VCB (ADDRESS RETURNED IN R2 BY THE EXECUTIVE)
4;
 5	MOVB	#DYN$C_VCB,VCB$B_TYPE(R2)	; RECORD TYPE
5	MOVZBW	#VCB$C_LENGTH,VCB$W_SIZE(R2)	; AND SIZE
5	MOVW	#1,VCB$W_TRANS(R2)		; INIT. TRANS. COUNT
L6	MOVL	(SP),VCB$L_AQB(R2)		; LINK TO AQB
6;
7;	INITIALIZE APPROPRIATE UCB FIELDS FOR SYNCHRONIZATION
x7;
7	MOVL	R2,UCB$L_VCB(R7)		; LINK TO VCB
@8	BISW	#UCB$M_MOUNTING,UCB$W_STS(R7)	; NOTE DEVICE MOUNTING
8;
9;	START THE ACP PROCESS (PCACP). NOTE THAT PCACP WILL HAVE THE
l9;	SAME PRIVILEGES AS THE PROCESS STARTING PCACP SINCE THE PRVADR
9;	ARGUMENT IS NOT SPECIFIED IN THE $CREPRC CALL (THAT ARGUMENT IS
4:;	USED TO SPECIFY THE PRIVILEGES THE CREATED PROCESS SHOULD HAVE).
:;
:	$CREPRC_S	PIDADR=PID,-
`;			IMAGE=IMAGE,-
;			INPUT=INPUT,-
(<			QUOTA=QLIST,-		; GIVE LARGE QUOTAS
<			BASPRI=#8,-		; AS WITH MOST ACPS
<			PRCNAM=PROCESS,-
T=			STSFLG=#0,-		; DISABLE RESOURCE WAIT
=			UIC=UIC			; WANT DETACHED PROCESS
>	BLBS	R0,80$				; BR IF SUCCESSFUL
>	MOVL	R0,R6				; SAVE ERROR STATUS
>;
H?;	DEALLOCATE AQB AND VCB ON FAILURE
?;
@	MOVL	R2,R0				; SET ADDR. TO DEAL. VCB
t@75$:	JSB	G^EXE$DEANONPAGED		; RETURN BLOCK
@76$:	POPL	R0				; SET ADDR. TO DEAL. AQB
<A	JSB	G^EXE$DEANONPAGED		; RETURN BLOCK
A	MOVL	R6,R0				; RESTORE ERROR STATUS
B	BRW	EXIT				; USE COMMON EXIT
hB80$:
B;
0C;	PLACE PCACP PID INTO AQB
C;
C	MOVL	(SP),R2				; RESTORE AQB ADDRESS
\D	MOVL	W^PID,AQB$L_ACPPID(R2)		; RECORD PID
D;
$E;	LINK AQB INTO AQB LIST AFTER LOCKING THE I/O DATA BASE
E;
E	MOVAL	G^IOC$GL_MUTEX,R0		; GET I/O DATABASE MUTEX
PF	MOVL	G^SCH$GL_CURPCB,R4		; AND OWN PCB ADDRESS
F	JSB	G^SCH$LOCKW			; AND LOCK MUTEX, NOTE
G						; THAT R2-R5 ARE ALTERED
|G	MOVAB	G^IOC$GL_AQBLIST,R1		; GET AQB LISTHEAD
G	MOVL	(SP),R2				; RESTORE AQB ADDRESS
DH	MOVL	(R1),AQB$L_LINK(R2)		; FORWARD LINK
H	MOVL	R2,(R1)				; PUT AQB AT HEAD
I;
pI;	UNLOCK THE I/O DATA BASE
I;
8J	MOVAL	G^IOC$GL_MUTEX,R0		; GET I/O DATABASE MUTEX
J	MOVL	G^SCH$GL_CURPCB,R4		; AND OWN PCB ADDRESS
 K	JSB	G^SCH$UNLOCK			; UNLOCK MUTEX, NOTE
dK						; THAT R2-R5 ARE ALTERED
K	SETIPL	#0				; AND LOWER IPL
,L;
L;	ISSUE MOUNT QIO TO ACP
L;
XM	$QIO_S	CHAN=CHAN,FUNC=#IO$_MOUNT	; USE EVENT FLAG #0
M;
 N;	WAIT UP TO THIRTY SECONDS
N;
N	$SETIMR_S	EFN=#1,DAYTIM=WAIT	; USE EVENT FLAG #1
LO	$WFLOR_S	EFN=#0,MASK=#^B11	; EITHER EVENT FLAG
O;
P;	TIMEOUT OR MOUNT QIO FINISHED; CHECK SYNCHRONIZATION
xP;
P	POPL	R2				; RESTORE AQB ADDRESS
@Q	BBSC	#AQB$V_CREATING,AQB$B_STATUS(R2),90$ ; ERROR IF SET
Q	BBSC	#UCB$V_MOUNTING,UCB$W_STS(R7),90$    ; ERROR IF SET
R	BBC	#DEV$V_MNT,UCB$L_DEVCHAR(R7),90$     ; ERROR IF CLEAR
lR	MOVZWL	#SS$_NORMAL,R0			; RETURN SUCCESS CODE
R	BRB	EXIT				; USE COMMON EXIT
4S90$:
S;
S;	DELETE THE ACP PROCESS (PCACP)
`T;
T	$DELPRC_S	PIDADR=PID		; AWAY IT GOES
(U	MOVL	#SS$_DEVNOTMOUNT,R6		; ERROR CODE
U;
U;	RESTORE UCB TO ORIGINAL STATE
TV;
V	BICL	#UCB$M_MOUNTING,UCB$W_STS(R7)	; NO LONGER MOUNTING
W	CLRL	UCB$L_VCB(R7)			; NO LONGER HAVE VCB
W;
W;	DELETE AQB AND VCB DATA STRUCTURES--AFTER REMOVING AQB FROM LIST
HX;
X	PUSHL	R2				; SAVE AQB ADDRESS
Y;
tY;	FIRST LOCK THE I/O DATABASE MUTEX
Y;
<Z	MOVAL	G^IOC$GL_MUTEX,R0		; GET I/O DATABASE MUTEX
Z	MOVL	G^SCH$GL_CURPCB,R4		; GET PCB ADDRESS
[	JSB	G^SCH$LOCKW			; LOCK MUTEX
h[;
[;	UNHOOK THE AQB FROM THE AQB LINKED LIST
0\;
\	MOVL	(SP),R2				; GET AQB ADDRESS
\	MOVAB	G^IOC$GL_AQBLIST,R1		; GET AQB LISTHEAD
\]	MOVL	(R1),R0				; GET 1ST AQB POINTER
]	CMPL	R2,R0				; FOUND RIGHT AQB?
$^	BNEQ	97$				; IF NEQ, NO
^	MOVL	AQB$L_LINK(R2),(R1)		; IF FOUND, RELINK
^	BRB	99$				; AND DEALLOCATE AQB
P_97$:	CMPL	AQB$L_LINK(R0),R2		; FOUND AQB?
_	BEQL	98$				; IF EQL, YES
`	MOVL	AQB$L_LINK(R0),R0		; GET NEXT AQB
|`	BRB	97$				; LOOP UNTIL FOUND
`98$:	MOVL	AQB$L_LINK(R2),AQB$L_LINK(R0)	; IF FOUND, RELINK
Da;
a;	UNLOCK THE I/O DATABASE MUTEX
b;
pb99$:	MOVAL	G^IOC$GL_MUTEX,R0		; GET I/O DATABASE MUTEX
b	MOVL	G^SCH$GL_CURPCB,R4		; GET PCB ADDRESS
8c	JSB	G^SCH$UNLOCK			; UNLOCK MUTEX
c	SETIPL	#0				; LOWER IPL
 d;
dd;	DEALLOCATE THE VCB AND AQB DATA STRUCTURES
d;
,e	MOVL	R8,R0				; RESTORE VCB ADDRESS
e	BRW	75$				; DEALLOCATE AQB & VCB
e;
Xf;	COMMON EXIT POINT WHICH DEALLOCATES CHANNEL TO PCA1
f;
 gEXIT:	MOVL	R0,R6				; SAVE ERROR STATUS
g	$DASSGN_S	CHAN=CHAN		; DEASSIGN PC CHANNEL
g	MOVL	R6,R0				; RESTORE ERROR STATUS
Lh	RET					; DONE
h	.END	START
