;**********************************
;    HDInstall -- allows changing default Part.
;	
; built: starting Dec 30, 1989	
; author: Paul Bosacki	
;**********************************

	.if (0)

HISTORY:

	RELEASE	NOTES
		1	Quick hack to get multiple         
		partion support. 

Application Notes:

	.endif

;CIA equates:

cia1hours	= $dc0b
cia1minutes	= $dc0a
cia1seconds	= $dc09
cia1tenthsec	= $dc08

;KERNAL ROM equates - pass these to the link for the debug file

LISTEN	== $ffb1
UNLSN	== $ffae
CIOUT	== $ffa8
SECOND	== $ff93

TALK	== $ffb4
TKSA	== $ff96
ACPTR	== $ffa5
UNTALK	== $ffab

;CONSTANTS used:

DRIVE_TYPE	= $24
CMD_TYPE	= 1

InitVector:
	.word Main

Main:	MoveB	curDrive, c_curDrive ;remember boot device
	jsr	GetDiskDriver
	jsr	PurgeTurbo		;get out of the turbo code
	jsr	InitDevice
	jsr	ClearErr
EndMain:
	rts

InitDevice:
	jsr FindDrive		;find the drive's current address
	txa			;on .eq we found the harddrive
	bne 1$	
	ldy curDrive		;mark drive type
	lda #DRIVE_TYPE
	sta driveType-8,y

	.if	RELEASE < 4

	lda activePartion	; this doesn't seem to actually be used
	sta driveData-8,y	; anywhere (but better check)

	.else

		.ifnconst	FD
	lda	#0
		.else
	lda	#$80		; $80 = FD
		.endif

	sta	driveData-8,y	; and mark it (for integrator)

	.endif

	jsr GetClock
	jsr ForceRoot
	jsr InitAllVars
	ldx #0
1$:	rts

GetDiskDriver:
	LoadW r6,fileNmBuf	;locate filetype auto-exec
	LoadB r7L,DISK_DEVICE	;with permanent filename "HardDrive"
	LoadB r7H,1		;grab the first file with this name
	LoadW r10,HDNative	;get diskdriver
	jsr FindFTypes
	txa			;test for error
	bne 1$			;and exit if found

	LoadW r0,fileNmBuf	;open that file
	jsr OpenRecordFile

	lda #1			;open driver record
	jsr PointRecord

	LoadW r7,driverBuff	;and load that record into
	LoadB r2L,$ff		;diskBuf
	sta r2H
	jsr ReadRecord
	txa
	pha			;save the error
	jsr CloseRecordFile	;tidy up
	pla			;get back the error
				;and return with it
1$:	rts

HDNative:
	.ifnconst	FD
	.byte	"HDnative",NULL
	.else
	.byte	"FDnative",NULL
	.endif

FindDrive:
	ldy #8	
	sty a9H
10$:	jsr SetUpPollDrive
	beq foundHD		;on .eq, it's a CMD HD
	inc a9H
	ldy a9H
	cpy #11
	bne 10$
	ldx #DEV_NOT_FOUND	;assume device not found

foundHD:
	rts			;to inform HD not found
		
SetUpPollDrive:
	tya
	jsr OurSetDevice	;otherwise, SetDevice as current
	jsr IsHardDrive		;and poll drive
	txa
	rts

InitAllVars:
	lda ramExpSize
	beq 99$

	LoadW r0,driverBuff
	lda #0
	sta r3L
	ldy curDrive
	lda hiRAMSpace-8,y
	sta r1H
	lda loRAMSpace-8,y
	sta r1L
	LoadW r2,$d80
	jsr StashRAM

	lda c_curDrive
	jsr OurSetDevice
	LoadW r0,$8400
	LoadW r1,$7900
	LoadW r2,$500
	LoadB	r3L,0
	jsr StashRAM
99$:	rts

hiRAMSpace:
	.byte ]$8300,]($8300+$d80)
	.byte ]($8300+(2*$d80)),]($8300+(3*$d80))

loRAMSpace:
	.byte [$8300,[($8300+$d80)
	.byte [($8300+(2*$d80)),[($8300+(3*$d80))

IsHardDrive:
	jsr InitForIO		;map in IO and KERNAL
				;put all interrupts on hold
				;cancel spriteDMA
	LoadB STATUS,0		;init STATUS
	LoadW r0,partionBuffer	;where to put the bytes
	MoveW CMDWhere,MRWhere	;and where they come from
	
	jsr FetchDrvRAM		;fetch 16 bytes from $fea0
	txa			;this is the CMD signature
	bne 2$			;escape for gen_error
	jsr DoneWithIO		;as we are
	
	LoadW r1,partionBuffer
	LoadW r2,CMDSign	
	lda #6			;compare six bytes
	ldx #r2			;source string
	ldy #r1			;destination string
	jsr CmpFString		;compare the strings
	bne MustBeAn81		;returns with .Z flag set if both
				;strings are .eq
	jsr CheckOrMove		;if not in an '81 part, moves to one
	ldx #0
	rts

2$:	jsr DoneWithIO
	rts	

MustBeAn81:
	ldx #DEV_NOT_FOUND
	rts
		
CMDSign:
	.ifnconst	FD
	.byte	"CMD HD",NULL
	.else
	.byte	"CMD FD",NULL
	.endif

CMDWhere:
	.word $fea0
CheckOrMove:
	jsr InitForIO		;and reenter IO routines
	MoveB defaultPart,r2L	;is there a default partition?
	bne makeThisPart	;if so set it up as active

Find81Part:
	LoadB r2L,255		;get current partition first
				;if already in an '81 part	
3$:	jsr GetInfo		;start getting partition info
	txa
	bne makeThisPart

	.ifconst	FD

	lda	fmtType
	and	#%10100000	; check disk in drive & CMD format
	cmp	#%10100000
	bne	exitPartition	; if not, exit now

	.endif

	lda partType
	cmp #CMD_TYPE		;have we found an 81 partition
	beq makeThisPart	;on .eq, yes

	inc r2L
	lda r2L

	.ifnconst	FD
	cmp	#255
	.else
	cmp	#32
	.endif

	bne 3$
	ldx #DEV_NOT_FOUND
	bne exitPartition

makeThisPart:
	lda r2L
	cmp #255
	beq exitPartition
	jsr OpenNewPartion	;returns with .X .eq 0

exitPartition:
	jsr DoneWithIO
	txa
	rts

GetInfo:
	MoveB r2L,InfoOnPart	;get info on this part #
	ldx #]GPCmnd 		;address of command to send
	lda #[GPCmnd
	jsr GiveCmnd		;if GiveCmnd errs out
	txa			;it returns with UNLSN called
	bne 22$			;end error in .X

	jsr UNLSN		;get ready to command drive to talk

	lda curDrive		;get curDrive
	jsr TALK		;and tell it to talk
	lda #$ff		;secondary address 15
	jsr TKSA

	jsr ACPTR		;get a byte
	sta partType
	jsr ACPTR		;get a byte
	sta	fmtType
	jsr ACPTR		;get a byte
	sta activePartion
	jsr UNTALK		;and tell the drive all done
	ldx #0			;return no error

2$:	rts

22$:	jsr UNTALK		;and tell the drive all done
	LoadB r2L,255
	rts			;return with NULL part error

GPCmnd:
	.byte "G-P"
InfoOnPart:
	.byte 0,13	;which partion
CPSyntax:
	.byte "C"
	.byte 208	;petascci shifted P
partionValue:
	.byte 0,13,NULL

OpenNewPartion:	
InitSend:
	MoveB activePartion,partionValue
	ldx #]CPSyntax
	lda #[CPSyntax
	jsr GiveCmnd
	txa
	bne 99$

	jsr UNLSN
	ldx #0

99$:	rts

ForceRoot:
	jsr InitForIO
	ldx #]CDcmnd
	lda #[CDcmnd
	jsr GiveCmnd
	txa
	bne 99$
	lda #0
	jsr CIOUT
	jsr UNLSN
	ldx #0
99$:	jmp DoneWithIO

CDcmnd:	.byte "CD//",CR,NULL

FetchDrvRAM:
	ldx #]MRSyntax		;address of command to send
	lda #[MRSyntax
	jsr GiveCmnd		;if GiveCmnd errs out
	txa			;it returns with UNLSN called
	bne 2$			;end error in .X

	lda #16	;number of bytes wanted
	jsr CIOUT

	jsr UNLSN		;get ready to command drive to talk

	lda curDrive		;get curDrive
	jsr TALK		;and tell it to talk
	lda #$ff		;secondary address 15
	jsr TKSA

	ldy #0			;init counter
1$:	jsr ACPTR		;get a byte
	sta (r0),y		;now put it there
	iny			;inc counter
	cpy #16			;have we got all the bytes needed
	bcc 1$			;on .cc, no

	jsr UNTALK		;and tell the drive all done
	ldx #0			;return no error

2$:	rts

MRSyntax:	.byte "M-R"
MRWhere:	.word $00	;where in drive ram

OurSetDevice:
	sta curDrive
	sta curDevice
	rts

GiveCmnd:
	stx r4H			;address of command
	sta r4L
	LoadB STATUS,0		;clear STATUS

	lda curDrive		;command HardDrive to listen
	jsr LISTEN
	bit STATUS		;device not present
	bmi 1$

	lda #$ff
	jsr SECOND
	bit STATUS
	bmi 1$

	ldy #0			;init index into buffer
2$:	lda (r4),y
	jsr CIOUT
	iny
	cpy #5			;command length
	bcc 2$

	ldx #0			;return no error
	rts

1$:	jsr UNLSN
	ldx #$0d		;error: device not present
	rts

ClearErr:
	jsr	InitForIO

	LoadB	STATUS,0
	lda	curDrive
	jsr	TALK
	lda	#$FF
	jsr	TKSA

10$:	jsr	ACPTR		; keep reading until no more available
	bit	STATUS
	bpl	10$

	jsr	UNLSN

	jsr	DoneWithIO
	rts


;*************************************************
;local variables
;*************************************************

defaultPart:
	.byte 0		;do not move from psect
			;region

	seg.u	ramsect
	rorg	MOD_0_END

c_curDrive:	.block 1
fileNmBuf:	.block 17
activePartion:	.block 1
partType:	.block 1
fmtType:	.block 1
partionBuffer:	.block 32
driverBuff:	.block $d80

HDTimeEnd:

	seg	code
