;*******************************************************
;
;	SCSI Driver 'Open' Filter
;
;	Written by Matt Gulick.		Started June 8,1988
;
;	Copyright Apple Computer, Inc. 1988,89
;
;*******************************************************

;*******************************************************
;
;	This file contains the subroutines needed by the
;	SCSI Driver to respond to the Open call number
;	$0001.  In a Block Device Driver this will return no
;	error and perform no function.  In the case of a
;	Character device however, this will need to prepare
;	the target device for Data I/O that may be sent to
;	it.
;
;*******************************************************

;*******************************************************
;
;	Revision History:
;
;*******************************************************

;	June 8,		1988	File started.
;	June 20		1988	Registers in and out are
;
;	April 11	1989	Added Character Device Code.

				STRING		PASCAL
				BLANKS		OFF
				PAGESIZE	70
				PRINT		NOGEN
				PRINT		NOMDIR
				MACHINE		M65816

				IMPORT		test_unit_rdy
				IMPORT		auto_sense_data
				IMPORT		reserve_unit

				PRINT		OFF

				INCLUDE		'scsihd.equates'
				INCLUDE		'M16.MEMORY'
				INCLUDE		'M16.UTIL'
				PRINT		ON

				EJECT

				IF			block_dvc = true\
				AND			character_dvc = false		THEN
			
;*******************************************************
;
;	This routine is used as the Open code for a Block
;	Device Driver.
;
;	Inputs:		None.
;
;	Outputs:	Acc			=	0
;				Carry		=	0
;				Y register	=	Unspecified
;				X register	=	Unspecified
;				P register	=	0=M=X=e
;				Direct Page	=	GS/OS Direct Page
;				Data Bank	=	Ours
;
;	Errors:		None.
;
;*******************************************************

				ENDIF

;-------------------------------------------------------------------------------

				IF			character_dvc = true\
				AND			block_dvc = false		THEN
             	
;*******************************************************
;
;	This routine is used as the Open code for a
;	Character Device Driver.  This code is commented out
;	so that is available to any one who uses this SCSI
;	Driver Skeleton.
;
;	Inputs:		None.
;
;	Outputs:	Acc			=	Error
;				Carry		=	Set or Clear
;				Y register	=	Unspecified
;				X register	=	Unspecified
;				P register	=	0=M=X=e
;				Direct Page	=	GS/OS Direct Page
;				Data Bank	=	Ours
;
;	Errors:		Already Open Error	$0024
;				For other errors see Spec.
;
;*******************************************************

				ENDIF

;-------------------------------------------------------------------------------

				EXPORT	open
open			PROC

;-------------------------------------------------------------------------------

				IF			block_dvc = true\
				AND			character_dvc = false		THEN
												;
												; Is the device online?
												;
				ldy		#dib.dvcflag

				lda		[dib_ptr],y
				and		#dvc_online
				bne		@open					;Yes.
												;
												; Device is currently offline.
												;
				lda		#drvr_off_line
				sec
				rts
												;
												; Return ok.
												;
@open			lda		#$0000
				clc
				rts

				ENDIF

;-------------------------------------------------------------------------------

				IF			character_dvc = true\
				AND			block_dvc = false		THEN
												;
												; Is the device online?
												;
				ldy		#dib.dvcflag

				lda		[dib_ptr],y
				and		#dvc_online
				bne		@open					;Yes.
												;
												; Device is currently offline.
												;
				lda		#drvr_off_line
				sec
				rts
												;
												; Check if Open.
												;
@open			lda		|open_flag
				bne		@alrdy_opn

;-------------------------------------------------------------------------------

				IF			scsi_dtype = scanner\
				OR			scsi_dtype = appl_laser		THEN
												;
												; It's a character device.  Prepare it
												; for operation.
												;
												; Set flag so that we will do this
												; at most 2 times for this call.
												;
@try_again		lda		#$ffff
				sta		@loop_cnt
												;
												; Is the Unit Ready for
												; communications?
												;
				jsr		|test_unit_rdy
				bcc		@its_ready				;Yes.
												;
												; No.  But why not?
												;
				lda		|auto_sense_data+\
						rqst_sens.sense_key
				and		#$00ff
				beq		@its_ready				;I quess it was only kidding.
												;
												; Is it doing somthing for sombody
												; right now?
												;
				cmp		#$0002
				bne		@check_6				;No.
												;
												; Yes it is. The Device is not yet
												; ready.
												;
@dvc_busy		lda		#drvr_busy
				sec
				rts
												;
												; Was it maybe reset or powered up
												; again?
												;
@check_6		cmp		#$0006
				beq		@handle_6				;Yes.
												;
												; No. The Device has Problems.
												;
@io_error		lda		#drvr_io
				sec
				rts
												;
												; The auto sensing should have cleared
												; this state, so lets try it again.
												; But only a second time.
												;
@handle_6		inc		@loop_cnt
				beq		@try_again
				bra		@io_error

@loop_cnt		dc.w	null					;Loop Counter.
												;
												; The Device is Ready.  Issue a
												; RESERVE UNIT Call to ensure that
												; nobody else can talk to the Scanner
												; while we have it opened.
												;
@its_ready		jsr		reserve_unit
				bcs		@io_error
												;
												; Make sure that it's block size is
												; 1 byte/block. This will make it easy
												; to get what the user requests if at
												; all possible.
												;
				

				ELSE

;-------------------------------------------------------------------------------

				Insert Your Code Here.

				ENDIF

;-------------------------------------------------------------------------------

				inc		|open_flag

				lda		#$0000
				clc
				rts

@alrdy_opn		lda		#drvr_prior_open
				sec
				rts

				ENDIF

;-------------------------------------------------------------------------------

										;
										; Internal Data Area for Open and Close.
										;
				EXPORT	open_flag
open_flag		dc.w	$0000

				ENDP

				END

				EJECT