* Loader for Smoke System Broadcasting DOS-68 Operating System
* I/O Routines for MF68 Floppy Disk
* 
* This program patches SSB DOS-68 to use MF68 instead of 
* the SSB floppy disk controller
*
* C(C) Roberto Sancho, Apr/2022
* Uses BC00-BD00 for loader. Once DOS is started this mem is available for any program
*      BE00-BEFF for MF68 I/O Routines. This mem should not be overwritten/modified
*
* Updated Apr/2023 by Mike Douglas for proper operation on real hardware

SYSFILE	EQU	$8051		TRACK AND SECTOR OF DOS68 SYSTEM FILE
SECBUF	EQU	$7F80		BUFFER FOR READ DISK SECTOR 
MON	EQU	$E0E3		SWTBUG Monitor re-entry point

	ORG	$BC00

START	LDAA	#$FF		Init PBUF     
	STAA	PBUF   
	LDX	#$E0E3		Init jump to SWTBUG monitor as the default
	STX	TA		   transfer address (TA)

	LDAA	#$08		Select drive 0
	STAA	BFDDRG
	JSR	BFDRST		Restore to track 0

	LDX	#SYSFILE	Track and sector for DOS68 file (main OS program)
	STX	SECBUF		Set FWD Link Trk and Sect in sector buffer
	LDX	#SECBUF
	STX	BFDSBU		Set addr where sector is to be read (sector buffer)
RDNEXT	BSR	RDBYTE		read a byte from disk file in B
	CMPB	#$42		is data record?
	BEQ	RDDATR		yes -> branch
	CMPB	#$47		is transfer address record?
	BNE	RDNEXT		no -> skip this byte and read next from disk 
	BSR	RDBYTE		yes -> get transfer addr (TA) hi
	STAB	TA
	BSR	RDBYTE		get transfer addr lo
	STAB	TA+1		save TA address 
	BRA	RDNEXT

* READ A DATA RECORD INTO MEMORY

RDDATR	CLRA
	BSR	RDBYTE		B=Data record last byte used (=len-1)
	INCB	  		B=Data record len
	PSHB
	BSR	RDBYTE		B=Data load addr hi
	STAB	PSTORE
	BSR	RDBYTE		B=Data load addr lo
	STAB	PSTORE+1
RDDATB	BSR	RDBYTE		get record data byte
	LDX	PSTORE		load address for byte 
	STAB	0,X		save data byte at load addr
	INX 
	STX	PSTORE
	PULB			B=Bytes remaining to load
	DECB	
	PSHB
	BNE	RDDATB		continue until all bytes are load
	PULB
	BSR	RDBYTE		get chksum byte  
	INCA
	BEQ	RDNEXT
	JMP	MON		CHKSUM Error -> return to monitor

* READ BYTE FROM DISK FILE, FOLLOWING FWD TRK AND SEC LINKS
* RETRUN B=BYTE READ, A=CHKSUM 

RDBYTE	LDX	PBUF		pointer to next byte to get from sector buffer
	BMI	RDTKSEC		128 bytes already read -> load next sector following FWD LINK
	LDAB	0,X		read byte from sector buffer
	INX 
	STX	PBUF
	ABA			A=A+B=checksum
	RTS 

RDTKSEC	LDX	SECBUF		get FWD Trk and Sect to load
	BEQ	JMPTA		If no FWD link, jumop to Transfer Address
	STX	BFDTRG		TrSect to load
	LDX	#SECBUF+4	init sector buffer data address
	STX	PBUF
	PSHA
	JSR	BFDRDS		read sector into 7f80-7fff (SECBUF)
	PULA
	BEQ	RDBYTE
	JMP	MON		return to monitor if read error

JMPTA	JSR	PATCHD		Patch the loaded system before jumping to it
	LDX	TA		Jump to transfer address to start 
	JMP	0,X		   loaded program 

* PATCH DOS68 TO USE MF68 I/O ROUTINES (AT ADDRESS BEXX) INSTEAD OF 
* CALLING SSB FLOPPY ROM (AT ADDRESS 80XX)
*
* DDE4  7E 8026	 JMP	$8026    SSB INITIALIZE PIA ROUTINE
* DD47  BD 8038	 JSR	$8038    SSB RESTORE
* DDA0  BD 8038	 JSR	$8038    SSB RESTORE
* DD30  CE 802C	 LDX	#$802C   SSB WRITE SECTOR ROUTINE
* DD35  CE 8029	 LDX	#$8029   SSB READ SECTOR ROUTINE 
* DD88  8C 8029	 CPX	#$8029   SSB READ SECTOR ROUTINE
* DD51:	BD 806C	 JSR	$806C    SSB WRITE TRACK REGISTER
* DDB7:	BD 8072	 JSR	$8072    SSB READ TRACK REGISTER

PATCHD	LDAA	#$BE
	STAA	$DDE5
	STAA	$DD48
	STAA	$DDA1
	STAA	$DD31
	STAA	$DD36
	STAA	$DD89
	STAA	$DD52
	STAA	$DDB8
	
* Patch FORTRAN line printer to use the screen
* D2B8:	7E D283 ZLP     JMP  ZWARMS   FORTRAN LINE PRINTER OUTPUT VECTOR (Points to DOS68 WARM START)
*    -> 7E D286 ZOUTCH  JMP  ZOUTEE   

	LDX	#$D286
	STX	$D2B9

	RTS
	
PBUF	RMB	2	   POINTER TO NEXT BYTE TO GET FROM READ DISK SECTOR BUFFER
TA	RMB	2	   TRANSFER ADDRESS (=COLD START ADDR OF OPERATING SYSTEM)
PSTORE	RMB	2	   POINTER WHERE THE BYTE READ FROM DISK IS TO BE STORED IN MEM     
	
*--------------------------------------------------------------
* SSB Smoke Signal Broadcasting BFD-68 disk drive ROM replacement.
* Allows to use MF68 disk drive and DC-x controller.
*
* The following is the original entry for SSB ROM
* as listed in 68'Micro Journal, Volumne 1 issue 1, Feb	1979, p13-20
* 
* BFDCLD EQU $8020  SSB	Cold Start
* BFDWRM EQU $8023  SSB	Warm Start
* BFDINT EQU $8026  SSB	Initialize PIA routine
* BFDRDS EQU $8029  SSB	Read Sector routine 
* BFDWRS EQU $802C  SSB	Write Sector routine
* BFDRDT EQU $802F  SSB	Read Track routine
* BFDWRT EQU $8032  SSB	Write Track routine
* BFDSEK EQU $8035  SSB	Seek routine
* BFDRST EQU $8038  SSB	Restore routine
*
*	    $8060      Send command
*	    $8063      Operation complete
*	    $8066      Clean up & return
*	    $8069      Write sector register
*	    $806C      Write track register
*	    $806F      Write track number
*	    $8072      Read track register
*	    $8075      Step in
*	    $8078      Step out
*	    $807B      Step
*--------------------------------------------------------------
BFDDRG	EQU	$A07B		Drive Register ($08 drive 0, $10 drive 1, $20 drive 2)
BFDTRG	EQU	$A07C		Track Register ($80..$A2)
BFDSRG	EQU	$A07D		Sector Register ($40..$51)
BFDSBU	EQU	$A07E		Sector Buffer Pointer

* THE MEM AREA BE00-BFFF HOLDS THE SSBBFD-68 ROM REPLACEMENT
* SSB ROM ENTRY POINTS STARTS AT $8020
* REPLACEMENT ENTRY POINTS STARTS AT $BE20

	ORG	$BE20

BFDCLD	JMP	MON    		SSB Cold Start
BFDWRM	JMP	MON    		SSB Warm Start
BFDINT	JMP	DUMMY  		SSB Initialize 
BFDRDS	JMP	RDSEC  		SSB Read Sector routine
BFDWRS	JMP	WRSEC  		SSB Write Sector routine
BFDRDT	JMP	MON    		SSB Read Track routine
BFDWRT	JMP	MON   		SSB Write Track routine
BFDSEK	JMP	MON    		SSB Seek routine
BFDRST	JMP	RESTOR  	SSB Restore routine

	ORG	$BE6C

BFDSTRK	JMP	SETTRK		SSB Set track register
BFDSSK	JMP	MON		SSB Set seek destination	
BFDGTRK	JMP	GETTRK		SSB Get track register	

* SWTPC DISK CONTROLLER EQUATES

DRVREG	EQU	$8014		DRIVE SELECT REGISTER
CMDREG	EQU	$8018		1771 COMMAND REGISTER
TRKREG	EQU	$8019		1771 TRACK REGISTER
SECREG	EQU	$801A		1771 SECTOR REGISTER
DATREG	EQU	$801B		1771 DATA REGISTER

FDRSC	EQU	$0B		RESTORE COMMAND
FDSKI	EQU	$1B		SEEK COMMAND
FDRDC	EQU	$8C		READ SECTOR COMMAND
FDWRC	EQU	$AC		WRITE SECTOR COMMAND

*--------------------------------------------------------------
* READ A SECTOR
*
* drive in $A07B: $08=drive 0, $10=drive 1, $20=drive 2
* track in $A07C ($80..$A2)
* sector in $A07D ($40..$51)
* Sector Buffer in $A07E/F
* return B=status register from 1771
*--------------------------------------------------------------
RDSEC	BSR	SELDRV		SELECT DRIVE
	BSR	SEEK		SEEK TO THE PROPER TRACK
	LDAA	#FDRDC		ISSUE READ COMMAND
	STAA	CMDREG
	JSR	DEL56U		DELAY
	LDX	BFDSBU		GET BUFFER ADDRESS

RDLOOP	LDAB	CMDREG		NEW BYTE READY?
	BITB	#$02
	BNE	GETBYTE		YES
	BITB	#$01		STILL BUSY?
	BNE	RDLOOP		YES

	TSTB			TEST STATUS (EXPECTED BY DOS-68)
DUMMY	RTS

GETBYTE	LDAA	DATREG		GET A BYTE
	STAA	0,X		STORE IN BUFFER
	INX
	BRA	RDLOOP		DO AGAIN

*--------------------------------------------------------------
* WRITE A SECTOR
*
* drive in $A07B: $08=drive 0, $10=drive 1, $20=drive 2
* track in $A07C ($80..$A2)
* sector in $A07D ($40..$51)
* Sector Buffer in $A07E/F
* return B=status register from 1771
*--------------------------------------------------------------
WRSEC	BSR	SELDRV 		SELECT DRIVE
	BSR	SEEK		SEEK TO PROPER TRACK
	LDAA	#FDWRC		ISSUE WRITE COMMAND
	STAA	CMDREG
	JSR	DEL56U		DELAY
	LDX	BFDSBU		GET BUFFER ADDRESS

WRTLOOP	LDAB	CMDREG		READY FOR ANOTHER BYTE?
	BITB	#$02
	BNE	PUTBYTE		YES
	BITB	#$01		STILL BUSY?
	BNE	WRTLOOP		YES

	TSTB			TEST RESULT (EXPECTED BY DOS-68)
	RTS

PUTBYTE	LDAA	0,X		GET A BYTE
	STAA	DATREG
	INX
	BRA	WRTLOOP		DO AGAIN
	
*--------------------------------------------------------------
* RESTORE TO TRACK 0
*--------------------------------------------------------------
RESTOR	BSR	SELDRV		SELECT DRIVE
	LDAA	#FDRSC		ISSUE RESTORE COMMAND
	BRA	DOSEEK

*--------------------------------------------------------------
* SETTRK - Set the 1771 track register from BFDTRG
* GETTRK - Return the 1771 track register in B
*--------------------------------------------------------------
SETTRK	LDAA	BFDTRG		WRITE BFDTRG TO TRKREG
	ANDA	#$7F
	STAA	TRKREG
	RTS

GETTRK	LDAB	TRKREG		RETURN TRKREG IN B
	RTS

*--------------------------------------------------------------
* SEEK A=TRACK, B=SECTOR
*--------------------------------------------------------------
SEEK	STAB	SECREG		SET SECTOR FROM B
	CMPA	TRKREG		ALREADY ON RIGHT TRACK?
	BEQ	SEEKRTS		YES, JUST EXIT

	STAA	DATREG		SEEK TO TRACK IN A
	LDAA	#FDSKI		SEEK COMMAND
DOSEEK	STAA	CMDREG
	JSR	DEL56U

WBUSY	LDAB	CMDREG
	BITB	#$01		BUSY?
	BNE	WBUSY		YES

SEEKRTS	RTS

*--------------------------------------------------------------
* SELECT DRIVE, HANDLE SSB STYLE PARAMS
* RETURN A=TRACK, B=SECTOR
*--------------------------------------------------------------
SELDRV	LDAA	BFDDRG		SSB SELECTED DRIVE 
	ASRA			$08->0,$10->1,$20->2
	ASRA
	ASRA
	ASRA
	ANDA	#$03
	STAA	DRVREG		SELECT THE DRIVE

	LDAA	BFDTRG		GET SSB TRACK#	
	ANDA	#$7F		MF68 TRACKS RANGE FROM 0..34
	LDAB	BFDSRG		GET SECTOR 
	ANDB	#$1F		MF68 SECTORS RANGE FROM 0..17
	RTS
	
*--------------------------------------------------------------
* DEL56U- DELAY 56us INCLUDING THE CALL TO DELAY56U
*--------------------------------------------------------------
DEL56U	JSR	DELAY2
DELAY2	JSR	DELAY3
DELAY3	RTS

* SET START ADDRESS FOR "G"O COMMAND

	ORG	$A048
	FDB	START

	END
