*--------------------------------------------------------------
*  PUTBOOT.ASM
*     FLEX program to install a DSDD capable FLEX loader
*     for the Smoke Signal Broadcasting BFD-68(A) controller
*     onto sector 0, track 0. After running PUTBOOT, run
*     "LINK xxxx.SYS" to point the loader to the FLEX
*     system file.
*
*     Mike Douglas, 03/26/23
*--------------------------------------------------------------

* Flex equates

LOADLOC	equ	$7000		;FLEX boot loader runs here

WARMST	equ	$AD03		;FLEX warm start entry point
GETCHR	equ	$AD15		;get and return character in A
PUTCHR	equ	$AD18		;display character in A
INBUFF	equ	$AD1B		;input line to the line buffer
PSTRNG	equ	$AD1E		;display $04 terminated string
PRCRLF	equ	$AD24		;display CR/LF
GETFIL	equ	$AD2D		;get file spec from line bufer
OUTDEC	equ	$AD39		;display X as decimal value
OUTHEX	equ	$AD3C		;display X as hex value
GETHEX	equ	$AD42		;get hex value in X
INDECM	equ	$AD48		;get decimal value in X

DREAD	equ	$BE80		;disk read sector
DWRITE	equ	$BE83		;disk write sector
DDRVSEL	equ	$BE8C		;disk drive select

* Misc Equates

CR	equ	$0D		;carriage return
LF	equ	$0A		;line feed
EOT	equ	$04		;end of string

*****************************************************************
*
* The PUTBOOT program starts here ($A100)
*
*****************************************************************
	org	$A100

	bra	putBoot		;skip by version number
version	fcb	10		;version 1.0	

putBoot	ldx	#mPrompt	;display confirmation prompt
	jsr	PSTRNG
	
	jsr	GETCHR		;get response
	anda	#$5F		;convert 'y' to 'Y'
	cmpa	#'Y'
	bne	abort		;don't do the update

	jsr	INDECM		;get drive number from cmd line
	bcs	badDrv		;invalid or missing drive number
	tstb			;only a separator present?
	beq	badDrv		;yes, comma or similar found

	stx	drvNumX		;save number entered
	ldaa	drvNumX+1	;use just LSB of drvNumX
	cmpa	#2		;verify 0 or 1
	bcc	badDrv

	ldx	#flxFcb		;point X to the FCB
	jsr	DDRVSEL		;select the drive

	ldx	#flxBoot	;point to the FLEX boot loader
	ldaa	#0		;track 0
	ldab	#0		;sector 0 exists only on track 0
	jsr	DWRITE		;write boot sector
	bne	wrtFail		;write failed

	ldx	#mDone		;display "drive updated" message

dspExit	jsr	PSTRNG		;display message in (X)
	jsr	PRCRLF		;extra CR/LF
	jmp	WARMST		;return to FLEX

wrtFail	ldx	#mFail		;"write to disk failed" then exit
	bra	dspExit		

badDrv	ldx	#mBadDrv	;"invalid drive" then exit
	bra	dspExit

abort	ldx	#mAbort		;"no updates performed" then exit
	bra	dspExit

*--------------------------------------------------------------
* Data Area
*--------------------------------------------------------------
mPrompt	fcb	LF
	fcc	'This program writes a FLEX loader for the Smoke'
	fcb	CR,LF
	fcc	'Signal BFD-68(A) controller to track 0, sector 0'
	fcb	CR,LF,LF
	fcc	'Continue? '
	fcb	EOT

mBadDrv	fcc	'Invalid or missing drive number'
	fcb	EOT

mDone	fcc	'FLEX loader written'
	fcb	CR,LF,LF
	fcc	'Now run LINK xxxx.SYS to point the loader'
	fcb	CR,LF
	fcc	'to the proper FLEX system file'
	fcb	EOT

mFail	fcc	'Write to disk failed - '

mAbort	fcc	'No updates performed'
	fcb	EOT
		
flxFcb	equ	*		;FLEX FCB structure
	fcb	0,0		;drive number at offset 3
drvNumX	rmb	2		;16 bit drive number from X

*--------------------------------------------------------
* FLEXLOAD.ASM
*    Double-sided compatible FLEX 2/3 loader for the
*    Smoke Signal Broadcasting BFD-68(A) floppy disk
*    controller.
*
*    Mike Douglas, 03/25/23
*--------------------------------------------------------
BOOTLOC	equ	$7000		;FLEX loader runs here
STACK	equ	$A070		;stack location (below ROM usage)

* BFD-68 ROM EQUATES

BFDREAD	equ	$8029		;read a sector
BFDREST	equ	$8038		;restore to track 0
BFDTRK	equ	$A07C		;track number
BFDSEC	equ	$A07D		;sector number
BFDBUF	equ	$A07E		;pointer to buffer

*--------------------------------------------------------
* Boot ROM jumps here after loading this from sector 0
*--------------------------------------------------------
	org	BOOTLOC		;boot ROM loads us here

flxBoot	lds	#STACK		;init stack pointer
	bra	loadFlx		;go load Flex

flexTrk	fcb	1		;track for FLEX3.SYS
flexSec	fcb	10		;sector to find FLEX3.SYS
			
pFlex	rmb	2		;pointer to FLEX entry
pDest	rmb	2		;pointer to destination
pSource	rmb	2		;pointer to data in secBuf

*--------------------------------------------------------
* loadFlx - Entry point for loading FLEX from disk. The 
*    drive that loaded this program is used to load FLEX.
*    This allows booting from any drive.
*--------------------------------------------------------
loadFlx	jsr	BFDREST		;restore to track zero
	bsr	read1st		;read first sector of FLEX

load1	bsr	getByte		;get next byte
	cmpa	#$02		;data record header?
	beq	load2		;yes

	cmpa	#$16		;transfer address header?
	bne	load1		;no, keep looking

	bsr	getByte		;get transfer address
	staa	pFlex		;MSB
	bsr	getByte		;LSB
	staa	pFlex+1
	ldx	pFlex		;jump to FLEX
	jmp	0,x

load2	bsr	getByte		;A=load address MSB
	psha
	bsr	getByte		;A=load address LSB
	pulb			;B=load address MSB
	staa	pDest+1		;save load address LSB
	stab	pDest		;MSB

	bsr	getByte		;A=byte count
	tab			;B=byte count
	beq	load1		;byte count was zero

load3	pshb
	bsr	getByte		;get next data byte
	pulb
	ldx	pDest		;X->where to put the data
	staa	0,x
	inx
	stx	pDest
	decb
	bne	load3		;loop for byte count in B

	bra	load1		;get next record

*--------------------------------------------------------
* readSec 
*--------------------------------------------------------
read1st	ldaa	flexTrk		;read 1st sector of Flex
	ldab	flexSec

readSec	staa	BFDTRK		;give track to BFD ROM

	cmpb	#10		;sector show side 0 or 1?
	bls	setSec		;side 0
	orab	#$20		;set BFD side bit
setSec	stab	BFDSEC		;give sector to BFD ROM

	ldx	#secBuf		;give buffer pointer to ROM
	stx	BFDBUF
	jsr	BFDREAD		;read the sector
	bitb	#$1C		;any read errors?
	bne	loadFlx		;yes, start over
	
	ldx	#secBuf+4	;data starts at offset 4
	stx	pSource		;pSource->data in secBuf
	rts

*--------------------------------------------------------
* getByte - Get next byte from sector buffer. Retrieve next
*    sector as needed.
*--------------------------------------------------------
getByte	ldx	pSource		;X->next byte 
	cpx	#secBuf+256	;reached end of sector?
	beq	nextSec		;yes, get the next sector

	ldaa	0,x		;else, return next byte
	inx
	stx	pSource		;save updated pointer
	rts

nextSec	ldaa	secBuf		;A=next track
	ldab	secBuf+1	;B=next sector
	bsr	readSec
	bra	getByte

* Sector buffer starts here

secBuf	equ	*

	end	putBoot
