NEW
  AUTO 3,1
*/--------------------------------------
*\--------------------------------------
D2.MotorControl	>PULLB D2.MotorOn
				>PULLB D2.DrvSlt
				jsr D2.CheckDiskII
				bcs .9

				lda D2.MotorOn
				asl

				lda #IO.D2.DrvOff
				adc D2.Slotn0
				tax
				lda $C000,x

				clc

.9				rts
*/--------------------------------------
*\--------------------------------------
D2.Recalibrate	>PULLB D2.DrvSlt
				jsr D2.CheckDiskII
				bcs .9

				ldy D2.Slotn0
				lda IO.D2.Ph0On,y

				lda #IO.D2.SeekTimeR
				jsr D2.Wait100usecA

				lda #160				40 x 4 Qtracks

				php
				sei

.1				dec
				dec

				pha

				phy
				plx
				jsr D2.SeekPhOnY

				lda #IO.D2.SeekTimeR
				jsr D2.Wait100usecA

				lda IO.D2.Ph0Off,x

				lda #IO.D2.SeekTimeR
				jsr D2.Wait100usecA

				pla
				bne .1

				jsr D2.Wait25600usec

				lda IO.D2.Ph0Off,y

				plp

*				clc

				jmp D2.Wait25600usec

.9				rts
*/--------------------------------------
*\--------------------------------------
D2.HeadSelect	>PULLB D2.HeadNum
				>PULLB D2.DrvSlt

				jsr D2.CheckDiskII
				bcs .9

				lda D2.HeadNum			A = 0/1

				asl						A = 0/2

				ora D2.Slotn0
				tax						x=n0/n2

				lda IO.D2.Ph0On,x
				lda IO.D2.Ph0On+4,x

				lda #1
				jsr D2.Wait100usecA

				lda IO.D2.Ph0Off,x
				lda IO.D2.Ph0Off+4,x

.9				rts
*/--------------------------------------
*\--------------------------------------
D2.MoveHead		>PULLB D2.TargetQTrack
				>PULLB D2.CurrentQTrack
				>PULLB D2.DrvSlt
				jsr D2.CheckDiskII
				bcs .99

				php
				sei

				lda D2.CurrentQTrack

				bit #1					A = Current QT
				beq .2					we are on 0/4 or 2/4 track

				pha

				cmp	D2.TargetQTrack		we are on 1/4 or 3/4 track
				bcc .1					if CC, C < T, must move in

				inc						move out: X = Ph(N+1)

.1				jsr D2.SeekPhOnY		move in : X = Ph(N)

				tya
				tax

				pla

				bcs .2					if CS, C > T, must move out

				inc						move in : Y = Ph(N+1)

.2				jsr D2.SeekPhOnY		move out: Y = Ph(N)

				bra .9					Ph ON to go to 0/4 or 2/4, no wait
*--------------------------------------
.3				bcs	.4					if CS, C > T, must move out

				inc						CC: C < T, ON next PH

				.HS B0					BCS

.4				dec						CS: C > T, ON prev PH

				sta D2.CurrentQTrack

				bit #1
				bne .5

				lda IO.D2.Ph0Off,x		we must go to 0/4 or 2/4 : Off Prev Ph
				bra .8					go wait....

.5				phy						we must go on 1/4 or 3/4
				plx						Y already ON, -> X for Ph0Off,x

				bcs	.6					if CS, C > T, must move out

				inc						CC: C < T, ON next PH

.6				jsr D2.SeekPhOnY		now X and Y on

.8				lda #IO.D2.SeekTimeF

				jsr D2.Wait100usecA		...wait...

.9				lda D2.CurrentQTrack
				cmp	D2.TargetQTrack
				bne .3

*				lsr						CS if X,Y on

				jsr D2.Wait25600usec

				ldy D2.Slotn0
				lda IO.D2.Ph0Off,y
				lda IO.D2.Ph0Off+2,y
				lda IO.D2.Ph0Off+4,y
				lda IO.D2.Ph0Off+6,y

*				lda IO.D2.Ph0Off,y

*				bcc .10

*				lda IO.D2.Ph0Off,x
*				clc
*				lda IO.D2.Ph0Off,y

*.10				jsr D2.Wait25600usec

				plp
				clc
.99				rts
*--------------------------------------
D2.SeekPhOnY	and #6
				ora D2.Slotn0
				tay
				lda IO.D2.Ph0On,y
				rts
*/--------------------------------------
* # D2TrkFmt16s
* Write a track (16 sectors)
*  PUSHB DSSS0000
*  PUSHB VolNum
*  PUSHB HeadNum (0,1)
*  PUSHB TrackNum
* ## RETURN VALUE
*  CC : success
*  CS : A = Error
*\--------------------------------------
D2.TrkFmt16s	>PULLB D2.TrkNum
				>PULLB D2.VolNum
				>PULLB D2.DrvSlt

				jsr D2.CheckDiskII
				bcs .99

				php
				sei

				lda D2.VolNum
				sta X.TRKFMT.VolNum

				lda D2.TrkNum
				sta X.TRKFMT.TrkNum

				ldy #D2.TrkFormat.Size

.1				lda D2.TrkFormat-1,y
				sta $1ff,y
				dey
				bne .1

				ldx D2.Slotn0
				lda IO.D2.ReadProt,x
				lda IO.D2.ReadMode,x
				bmi .9					Write protected

				jsr $200

				plp
				clc
				rts

.9				lda #MLI.E.WRTPROT

				plp
				sec
.99				rts
*/--------------------------------------
* # D2TrkRead16s
* Write a track (16 sectors)
*  PUSHB DSSS0000
*  PUSHB TrackNum
*  PUSHW Ptr to 16*256 buffer
* ## RETURN VALUE
*  CC : success, A = VolNum
*  CS : A = Error
*\--------------------------------------
D2.TrkRead16s	>PULLW ZPPtr1
				>PULLB D2.TrkNum
				>PULLB D2.DrvSlt

				jsr D2.CheckDiskII
				bcs .9

				lda D2.VolNum
				clc
.9
D2.TrkRead16s.RTS
				rts
*/--------------------------------------
* # D2TrkWrite16s
* Write a track (16 sectors)
*  PUSHB DSSS0000
*  PUSHB VolNum
*  PUSHB TrackNum
*  PUSHW = Ptr to 16*256 buffer
* ## RETURN VALUE
*  CC : success
*  CS : A = Error
*\--------------------------------------
D2.TrkWrite16s	>PULLW ZPPtr1
				>PULLB D2.TrkNum
				>PULLB D2.VolNum
				>PULLB D2.DrvSlt

				jsr D2.CheckDiskII
				bcs D2.TrkRead16s.RTS

				>LDYAI TRACK16.LEN+256+1
				>SYSCALL2 GetMem
				bcs D2.TrkRead16s.RTS

				>STYA ZPPtr2
				stx D2.hTrkBuf

				stz D2.SectNum

				ldy #0					put 256 FF sync bytes for slooooow drives
				jsr D2.PutSyncBytePtr2

				ldy #TRACK16.GAP1
				jsr D2.PutSyncBytePtr2

.1				jsr D2.PutAddrHeadPtr2

				jsr D2.HeaderCheckSum

				ldy #3

.2				lda D2.Checksum,y
				jsr D2.PutByte44Ptr2
				dey
				bpl .2

				jsr D2.PutTailPtr2

				ldy #TRACK16.GAP2
				jsr D2.PutSyncBytePtr2

				jsr D2.PutDataHeadPtr2

				lda ZPPtr1+1
				bne .7

				ldy #$57
				ldx #2
				lda #$96

.3				sta (ZPPtr2)
				inc ZPPtr2
				bne .4
				inc ZPPtr2+1

.4				dey
				bne .3
				dex
				bne .3

				bra .8

.7				jsr D2.PutData
				inc ZPPtr1+1

.8				jsr D2.PutTailPtr2
				ldy #TRACK16.GAP3
				jsr D2.PutSyncBytePtr2

				inc D2.SectNum
				lda D2.SectNum
				cmp #16
				bne .1

				lda #0
				sta (ZPPtr2)

				jsr D2.HeadSelect

				jsr D2.WriteTrackPtr2

				php
				pha
				lda D2.hTrkBuf
				>SYSCALL2 FreeMem
				pla
				plp

				rts
*/--------------------------------------
*\--------------------------------------
D2.TrkReadNIB
*/--------------------------------------
* # D2TrkWriteNIB
* Write a track (NIBBLE)
* ## ASM
*  PUSHB = DSSS0000
*  PUSHW = Ptr to NIBBLE buffer (0 ended)
* ## RETURN VALUE
*  CC : success
*  CS : A = Error
*       A=0, currently starting/seeking...
*\--------------------------------------
D2.TrkWriteNIB	>PULLW ZPPtr1
				>PULLB D2.DrvSlt

				jsr D2.CheckDiskII		was it a DISK II ?
				bcs .99

.99				rts
*--------------------------------------
* A=DSSS0000
*--------------------------------------
D2.CheckDiskII	pha
				and #$70				only 0SSS
				sta D2.Slotn0
				lsr
				lsr
				lsr
				lsr
				ora #$C0				make Cn
				sta ZPPtr3+1
				stz ZPPtr3

				ldx #3					4 bytes to check

.1				ldy DiskII.OFS,x

.2				lda (ZPPtr3),y
				cmp DiskII.SIG,x
				bne .9

				dex
				bpl .1

				pla						all bytes match, Disk II
				asl
				lda #0
				adc #IO.D2.DrvSel1
				adc D2.Slotn0
				tax
				lda $C000,x

				ldx D2.Slotn0

				lda IO.D2.ReadMode,x
				lda IO.D2.RData,x

				clc
				rts

.9				pla
				lda #MLI.E.NODEV
				sec
				rts
*--------------------------------------
* A=DSSS0000
*--------------------------------------
D2.DrvSpinCheck	ldy #0

				lda IO.D2.RData,x

.1				pha
				pla

				cmp IO.D2.RData,x
				bne .8					spinning

				dey
				bne .1

				clc						CC:not spinning
				rts

.8				sec
				rts
*--------------------------------------
D2.Wait25600usec
				lda #0

D2.Wait100usecA phx

.1				ldx #19					(2)

.2  			dex						(2)
				bne .2					(3)

				dec						(2)
				bne .1					(3)

				plx

				rts						(6)
*--------------------------------------
D2.PutSyncBytePtr2
				lda #$7f

.1				sta (ZPPtr2)
				inc ZPPtr2
				bne .2

				inc ZPPtr2+1

.2				dey
				bne .1

				rts
*--------------------------------------
D2.PutAddrHeadPtr2
				ldy #2

.1				lda ADDR.Head,y
				jsr D2.PutBytePtr2
				dey
				bpl .1

				rts
*--------------------------------------
D2.PutDataHeadPtr2
				ldy #2

.1				lda DATA.Head,y
				jsr D2.PutBytePtr2
				dey
				bpl .1

				rts
*--------------------------------------
D2.PutTailPtr2	ldy #2

.1				lda TAIL,y
				jsr D2.PutBytePtr2
				dey
				bpl .1

				rts
*--------------------------------------
D2.HeaderCheckSum
				lda D2.VolNum
				eor D2.TrkNum
				eor D2.SectNum

				sta D2.Checksum
				rts
*--------------------------------------
D2.PutData		stz D2.Checksum

				lda ZPPtr1
				ldy ZPPtr1+1

				clc
				adc #86
				bcc .1

				iny
				clc

.1				sta ZPPtr3
				sty ZPPtr3+1

				adc #86
				bcc .2

				iny

.2				sta ZPPtr4
				sty ZPPtr4+1

				ldy #85

.3				lda (ZPPtr1),y
				and #3
				tax
				lda D2.XX000000,x
				pha

				lda (ZPPtr3),y
				and #3
				tax
				pla
				ora D2.00XX0000,x
				pha

				lda (ZPPtr4),y
				and #3
				tax
				pla
				ora D2.0000XX00,x

				tax

				eor D2.Checksum
				sta D2.Checksum

				lda FC2Nib,x

*				jsr D2.PutBytePtr2

				sta (ZPPtr2)
				inc ZPPtr2
				bne .31

				inc ZPPtr2+1

.31				dey
				bpl .3

				ldy #0

.4				lda (ZPPtr1),y
				and #$FC

				tax

				eor D2.Checksum
				sta D2.Checksum

				lda FC2Nib,x

*				jsr D2.PutBytePtr2

				sta (ZPPtr2)
				inc ZPPtr2
				bne .41

				inc ZPPtr2+1

.41				iny
				bne .4

				ldx D2.Checksum
				lda FC2Nib,x
				bra D2.PutBytePtr2
*--------------------------------------
D2.PutByte44Ptr2
				pha
				ror
				jsr .1

				pla

.1				ora #$AA
*--------------------------------------
D2.PutBytePtr2	sta (ZPPtr2)
				inc ZPPtr2
				bne .8

				inc ZPPtr2+1

.8				rts
*--------------------------------------
D2.WriteTrackPtr2
				lda D2.hTrkBuf
				>SYSCALL2 GetMemPtr
				>STYA ZPPtr1

				php
				sei

				ldy #D2.TrkWriter.Size

.1				lda D2.TrkWriter-1,y
				sta $1ff,y
				dey
				bne .1

				ldx D2.Slotn0

				jsr $200

				bcs .9

				plp
				clc
				rts

.9				plp
				sec
				rts
*--------------------------------------
MAN
SAVE usr/src/lib/libblkdev.s.d2
LOAD usr/src/lib/libblkdev.s
ASM
