;*******************************************************
;
;	SCSI Driver 'Close' 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 Close call number
;	$0004.  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 reset
;	the state of the target device to what it was prior
;	to the Open Call..
;
;*******************************************************

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

;	June 8,		1988	File started.
;	June 20		1988	Registers in and out are
;						described and changes from Code
;						review inserted.
;	April 11,	1989	Added Code for Scanner.

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

				IMPORT		test_unit_rdy
				IMPORT		auto_sense_data
				IMPORT		release_unit
				IMPORT		open_flag

				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 Close 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 Close 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:		Device not open Error	$0023
;				For other errors see Spec.
;
;*******************************************************

				ENDIF

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

				EXPORT	close
close			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		@close					;Yes.
												;
												; Device is currently offline.
												;
				lda		#drvr_off_line
				sec
				rts
												;
												; Return to caller
												;
@close			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		@close					;Yes.
												;
												; Device is currently offline.
												;
				lda		#drvr_off_line
				sec
				rts
												;
												; Check if Open.
												;
@close			lda		|open_flag
				beq		@dvc_closed
												;
												; Clear Open Flag Now incase we
												; terminate from an I/O Problem.
												;
				lda		#$0000
				sta		|open_flag

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

				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
												; RELEASE UNIT Call.
												;
@its_ready		jsr		release_unit
				bcs		@io_error
				

				ELSE

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

				Insert Your Code Here.

				ENDIF

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

				lda		#$0000
				clc
				rts

@dvc_closed		lda		#drvr_not_open
				sec
				rts

				ENDIF

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

				ENDP

				END

				EJECT