;
; CD-ROM Drive Basic SCSI Command Routine
;

;
; Read Physical Block from Disk
;  IN: bx = Physical Block Number (high)
;      dx =     "      "      "    (low)
;      cx = Read Block Count (Max. 32 Block)
;      [ds:si] = Read Memory Address
; OUT: Carry Set -> Error
;      ax = MS-DOS Status Word
;      cx = Read Block Count
;
RedDsk	proc	near
	push	es
	push	di
	push	bx

; Setup SCSI-Pointer
	mov	al,08h		; Read Command
	call	[bp.SetScPtr]	; Setup SCSI-Pointer

; Set CDB Value with SCSI-Pointer
	mov	[si+1],bl
	mov	[si+2],dh
	mov	[si+3],dl
	mov	[si+4],cl

; Go SCSI Phase
RedDsk1:
	mov	ax,[bp.SecCnt]
	mul	[bp.BlkSiz]	; Calc Transfer Byte
	mov	cx,ax
    if  IF_TYPE eq PC9801
	mov	bx,4406h	; for PC9801-55 BIOS
    endif
    if  IF_TYPE eq ASPI
	mov	bx,0806h	; for ASPI (Direction Bits is Read)
    endif
	call	[bp.PhasePtr]
	mov	cx,[bp.SecCnt]	; Read Count for Non-Error
	jnc	RedDsk9

; Set Error Code in AX for MS-DOS
	cmp	al,06h		; Unit Attention ?
	je	RedDsk1		; Yes, Read Retry

; Error Read
	mov	cx,0		; Read Count Zero
	stc
RedDsk9:
	pop	bx
	pop	di
	pop	es
	ret
RedDsk	endp

;
; Test Unit Ready
;   IN: al = Unit Number
;  OUT: al = 00h->Media Insert & Drive Ready
;            01h->Chenge Media
;            02h->Media Not Present
;            03h->Illegal Drive
;       Carry Set ->Drive Not Connect or Hardware Error
;
TestUnit proc	near
	push	dx
	call	TstUnitM	; Call SCSI Test Unit Ready Command
	jc	TstUnit7	; Branch, Hardware Error
	cmp	al,00h		; Ready ?
	je	TstUnit9
	cmp	al,02h		; Not Ready ? (02h)
	je	TstUnit9	; Yes, Branch
	cmp	al,06h		; Unit Attention ? (06h)
	jne	TstUnit7

; One More Call Command
	call	TstUnitM	; Call SCSI Test Unit Ready Command
	jnc	TstUnit8	; Branch, No Error

; Illegal Error
TstUnit7:
	mov	al,03h		; Mark of Illegal Error
	stc
	pop	dx
	ret

; Media Changed
TstUnit8:
	mov	al,01h		; Media Changed or Power-On Drive

; Return
TstUnit9:
	pop	dx
	ret
TestUnit endp

;
; Inner Routine 
;  SCSI "Test Unit Ready" Command
;  OUT: AL = Status byte
;
TstUnitM proc	near
	push	es
	push	di

; Setup SCSI-Pointer & CDB
	mov	si,[bp.TempPtr]	; Dummy
	xor	ax,ax		; Test Unit Ready Command
	call	[bp.SetScPtr]	; Setup SCSI-Pointer

; Go SCSI Phase
	tfrp	0006h,0
	call	[bp.PhasePtr]
;
	pop	di
	pop	es
	ret
TstUnitM endp

;
; Read Capacity (Get Sictor Size)
; OUT: bx:dx = Max. Block Address
;      cx = Block Size
;      Carry Set-> Error
;
ReadCap proc	near
	push	es
	push	di

; Setup SCSI-Pointer & CDB
	mov	si,[bp.TempPtr]	; Buffer
	mov	al,25h		; Read Capacity Command
	call	[bp.SetScPtr]	; Setup SCSI-Pointer

; Go SCSI Phase
RedCap1:
	tfrp	440ah,8
	call	[bp.PhasePtr]
	jc	RedCap9

; Set Max. Block Address
RedCap8:
	mov	si,[bp.TempPtr]	; Buffer
	mov	bh,[si]
	mov	bl,[si+1]
	mov	dh,[si+2]
	mov	dl,[si+3]
;	mov	ch,[si+6]
;	mov	cl,[si+7]
;
RedCap9:
	pop	di
	pop	es
	ret
ReadCap	endp

	include if.asm
;
; INQUIRY
; OUT: ah.bit-7 = Removable Media Flag
;      al = Device Code
;      Carry Set-> Error
;
Inquiry	proc	near
	push	es
	push	di

; Setup SCSI-Pointer & CDB
	mov	si,[bp.TempPtr]	; Buffer
	mov	al,12h		; Inquiry Command
	call	[bp.SetScPtr]	; Setup SCSI-Pointer
	mov	byte ptr [si+4],08h	; 8-Byte

; Go SCSI Phase
	tfrp	4406h,8
	call	[bp.PhasePtr]
	jc	Inquiry9

; Set Inquiry Data
	mov	si,[bp.TempPtr]	; Buffer
	mov	ax,[si]
;
Inquiry9:
	pop	di
	pop	es
	ret
Inquiry	endp
