;fast bootable seek/read, slot 6 version
;copyright (c) Peter Ferrie 2011-2012

; Translated to ca64 by Vince Weaver

		chksum    = 0		;otherwise safer but 12 bytes larger
		secldr2   = $0e		;14th sector is fastest when loaded from bootsector but can be any of them
		seekback  = 0		;set to 1 to enable seek backwards

		adrlo     = $26		;constant from boot prom
		adrhi     = $27		;constant from boot prom
		slot      = $2b		;constant from boot prom
		tmpsec    = $3c		;constant from boot prom
		tmpadr    = $41
		partial2  = $f9		;copy of partial1
		partial1  = $fa		;sectors to read from one track
		total     = $fb		;total sectors to read
		step      = $fc		;state for stepper motor
		tmptrk    = $fd		;temporary copy of current track
		curtrk    = $fe		;current track (must initialise before calling seek)
		phase     = $ff		;current phase for seek
		addrtbl   = $50		;requires 16 bytes
		nibtbl    = $2d6	;constant from boot prom
		bit2tbl   = $200	;hard-coded (uses $2aa-$2ff)

		maxsec    = $10		;sectors per track, usually 10 but 0b for Olympic Decathlon, 0c for Karateka

		;this section is specific to bootsectors
		;load second stage sector to $900, enabling track seek
		tax			;1 sector
		lda #secldr2
		ldy #9
		jsr seekread
		jmp ldr2
		;

seekread:	stx total
		sta addrtbl
		sty tmpadr
calcpart:	sec
		lda #maxsec
		sbc addrtbl
		cmp total
		bcs L1
		tax
L1:		stx partial1
		stx partial2
callseek:	jsr seek - 1		;(seekret) disabled during boot, increment to enable
		ldy addrtbl
		ldx #$0f
		lda #0
L2:		sta addrtbl, x
		dex
		bpl L2
L3:		lda tmpadr
		ldx sectbl, y
		sta addrtbl, x
		inc tmpadr
		iny
		dec partial1
		bne L3

read:		ldx #0
read1:
L4:		jsr readnib
L5:		cmp #$d5
		bne L4
		jsr readnib
		cmp #$aa
		bne L5
		tay			;we need Y=#$AA later
		jsr readnib
		eor #$ad		;zero A if match
		beq check_mode

		;if not #$AD, then #$96 is assumed

		ldy #2			;high 8 bits of bit2tbl
		sty adrhi		;store 2-bits array at $2xx
L6:		jsr readnib
		rol			;set carry
		sta tmpsec
		jsr readnib
		and tmpsec
		dey
		bpl L6
.if chksum
		sta tmpsec
		tay
		ldx addrtbl, y
		stx step
.else
		tay
		lda addrtbl, y
		sta step
		stx addrtbl, y
		tax
.endif
		bcs read1
check_mode:	cpx #0			;set carry if non-zero
		beq read1
		.byte $90
L7:		clc
L8:		ldx $c0ec
		bpl L8
		eor nibtbl, x
		sta (adrlo), y		;$2xx initially, and then the real address
		iny
		bne L8
		ldx step
		stx adrhi		;set real address
		bcs L7			;carry is set on first pass, clear on second, loops one time
.if chksum
L9:		ldx $c0ec
		bpl L9
		eor nibtbl, x
		bne read
		ldx tmpsec
		sta addrtbl, x
.endif
L10:		ldx #$a9
L11:		inx
		beq L10
		lda (adrlo), y
		lsr bit2tbl, x
		rol
		lsr bit2tbl, x
		rol
		sta (adrlo), y
		iny
		bne L11
		dec total
		dec partial2
		bne read		;read all requested sectors in one track
		ldx total
		beq seekret
		inc phase
		inc phase		;update current track
		jmp calcpart

sectbl:		.byte 0, $0d, $0b, 9, 7, 5, 3, 1, $0e, $0c, $0a, 8, 6, 4, 2, $0f

readnib:
L12:		lda $c0ec
		bpl L12
seekret:	rts			;hard-coded relative to seek

seek:		lda #0
		sta step
copy_cur:	lda curtrk
		sta tmptrk
		sec
		sbc phase
		beq seekret
.if seekback
		bcs L13
.endif
		eor #$ff
		inc curtrk
.if seekback
		bcc L14
L13:		adc #$fe
		dec curtrk
L14:
.endif
		cmp step
		bcc L15
		lda step
L15:		cmp #8
		bcs L16
		tay
		sec
L16:		lda curtrk
		ldx step1, y
		bne L18
L17:		clc
		lda tmptrk
		ldx step2, y
L18:		stx tmpsec
		and  #3
		rol
		tax
		sta $c0e0, x
L19:		ldx #$13
L20:		dex
		bne L20
		dec tmpsec
		bne L19
		lsr
		bcs L17
		inc step
		bne copy_cur

step1:		.byte 1, $30, $28, $24, $20, $1e, $1d, $1c
step2:		.byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c

		newtrk    = $42		;track*2 for main stage
		newnum    = $1f		;number of sectors in main stage
		newsec    = 1		;first sector in main stage
		newadr    = $61		;load address for main stage
		newstart  = $6100	;start address for main stage

ldr2:		jmp ldr2
		;replace with something like the following:
		;inc callseek + 1
		;sty curtrk
		;lda #newtrk
		;sta phase
		;ldx #newnum
		;lda #newsec
		;ldy #newadr
		;jsr seekread
		;jmp newstart
