	TITLE	'Sorcim ColdStart Boot for GBC DISK1.'
;BOOT	ColdStart Boot load for CompuPro DISK1 controller.
;
;	+-----------------------+
;	|			|
;	|	D i s k		|
;	|	B O O T 	|
;	|			|
;	+-----------------------+
;	Copyright 1981, Sorcim Corp.
;
;	This product is a copyright program product of
;	SORCIM and is supplied for use with the GBC 171
;	series controllers.
;
;	CompuPro			Sorcim Corp.
;	Oakland, CA			Santa Clara, CA
;
;
;	Version number:	2.2 or 1.0
;	Level	F	81-03-31
;		G	81-04-17	support CPm-86
;		H	81-05-04	Load CPm-86 per Group heading
;		J	81-10-31	Initialize stack pointer
;
;	The following code is supplied to customers who
;	purchase a hard/floppy disk system from CompuPro.
;	The following code is written onto track 0 sector 0
;	of the disk.  This routine is read into memory
;	at location 100h by the user's PROM.   This routine then
;	loads the rest of the system into memory.
;
;
;	The format of the Floppy Disk Boot sectors are as follows:
;
;			Routine
;	T  Sector	Name
;
;	0  1 thru 4	Boot program (this routine)
;
;	   5 thru 24	BIOS-80	|  LdBios86
;	  25			|  Group Header
;	  26			|  ReStart88
;
;	1  1 thru 8	CCP	|	0 .. 3	LdCpm86
;	   9 thru 22	BDOS-80	|	4 .. 18 =	LdBDOS 86
;
;	  23 thru 26	reserved
	
OPARM:	EQU	*o		;Capture O parameter
@TARG:	EQU	4		;select 8088 to boot
LEVEL:	EQU	8		;Level x.xH
	CPU	'8085'		;Boot executes in 8085 always


K:	EQU	1024
OPTS:	EQU	40h		;Option selections byte
N$TRK:	EQU	26		;sectors in Track 0
N$BOOT:	EQU	4		;sectors for Boot
	space	4,10
;	CPm-80 location symbols.
.85	IF	@TARG = 0
VERS:	EQU	22		;Version = CPm-80 v2.2
BIOLEN:	EQU	0E00h
	IF	OPARM < (64+2)	;If absolute
MSIZE:	EQU	OPARM		;Size of CP/M memory
CBIOS:	EQU	MSIZE*K-BIOLEN	;Start of CP/M jump table
	ENDIF
	IF	OPARM > (64+1)	;If PRL generation
MSIZE:	EQU	(OPARM+BIOLEN)/K	;Size of CP/M memory
CBIOS:	EQU	OPARM		;Start of CP/M jump table
	ENDIF
BDOS:	EQU	CBIOS-BIOLEN+6	;Start of BDOS
CCP:	EQU	CBIOS-1600h	;Start of CCP
CBANK:	EQU	0		;CPm-80 always in low bank
.85	endif


;	CPm-86 location symbols.
.86	IF	@TARG = 4
VERS:	EQU	10		;Version = CPm-86 v1.0
LDRSEG:	EQU	0FC00h		;Loader at FC000
LDRBIO:	EQU	1200h		;LdBios offset
CBANK:	EQU	(LDRSEG+LDRBIO/16) shr 12
CBIOS:	EQU	( (LDRSEG+LDRBIO/16) and 0FFFh) * 16
XFER:	EQU	400h
I#JMPL:	EQU	0EAh
.86	endif



;	Assembly Constants
FDPORT	EQU	0C0H		;Base port address for Controller
FDCS	EQU	FDPORT		;Status register
FDCD	EQU	FDPORT+1	;Data register
DMA	EQU	FDPORT+2	;Dma address (when write)
INTS	EQU	FDPORT+2	;Status Register (when read)
;				Input on port disables boot rom.
SER	EQU	FDPORT+3	;Serial port

MMGR:	EQU	0FDh		;IN on this swaps processors

DELCNT	=	5*1000		;Delay count for 5 MHz processor

;	Controller function definitions
;	Specify (00) command
NSEC	=	0		;Sect verify number
F.RTK	=	02		;Read track
F.SPEC	=	03		;Specify
F.DSTS	=	04		;Drive status
F.RDAT	=	06		;Read data
F.RECA	=	07		;recalibrate
F.RSTS	=	08		;Read status
F.SEEK	=	0Fh		;Seek

SRT	=	16-8		;= Shuggart 800s
;		16-3		;= Shuggart 850s
;		16-3		;= Remex
HUT:	=	240/16		;Head unload = 240 ms
HLT:	=	(35+1)/2	;Head load = 35 ms
ND:	=	00		;Set DMA mode
	space	4,10
;	Bootstrap load.
;	Do not change any addresses from here to START:
;	Entry	C= Board switches from ROM (0 .. 3)
	ORG	100h
BOOT:
	JMP	START		;invariance
	ds	6
stack:
	space	4,10
;	Function data for controller to boot
DATA	DB	CBANK		;Extended
ENTRY:	VFD	16\ CBIOS
LDMA	EQU	*-DATA

READ:	DB	F.RDAT
	DB	0		;hds,ds1,ds0
	DB	0		;C = sector ID info
	DB	0		;Head
	DB	N$BOOT+1	;Record (sector) of BIOS
	DB	0		;N
	DB	N$TRK-2		;Read most of track
	DB	7		;GPL
	DB	128		;DTL
LREAD	=	*-READ


;	8088 Reset startup routine is kept in last sector.
.88	IF	@TARG <> 0
	DB	00Fh, 0FFh, 080h
	DB	F.RDAT
	DB	0		;hds,ds1,ds0
	DB	0		;C = sector ID info
	DB	0		;Head
	DB	N$TRK		;Record (sector) of Restart
	DB	0		;N
	DB	N$TRK		;EOT
	DB	7		;GPL
	DB	128		;DTL
ENDCMD:


;	Read CPm86 Group Header.
RGHDR:
	VFD	8\0, 16\ RGBUF
	DB	F.RDAT
	DB	0		;hds,ds1,ds0
	DB	0		;C = sector ID info
	DB	0		;Head
	DB	N$TRK-1		;Record (sector) of Group
	DB	0		;N
	DB	N$TRK-1		;EOT
	DB	7		;GPL
	DB	128		;DTL

.88	else
ENDCMD:
.88	endif


;	Disk setup command strings.
SPEC	DB	F.SPEC
	VFD	4\SRT,4\HUT
	VFD	7\HLT,1\ND
LSPEC	=	*-SPEC

RECAL	DB	F.RECA,0
LRECAL	=	*-RECAL
	space	4,10
;	Start of Boot code.
;	Save board option value.
;	Load bios.
;	If 8088, load Restart.
START:
	lxi	sp,stack
	MOV	A,C		;save board options
	STO	A,OPTS

RETRY:
;	Load Specify Command
	LDK	DE,SPEC
	LDK	B,LSPEC
	CALL	DFCN		;direct function

;	Recalibrate drive

	LDK	B,LRECAL
	CALL	DFCN		;Recalibrate

RCAL2:	IN	INTS
	ORA	A
	JP	RCAL2		;If not complete

	MVI	A,F.RSTS
	OUT	FDCD

	LDK	BC,250		;Leave lite on for 1/4 second
	CALL	DELAY

RCAL3:	IN	FDCS
	ORA	A
	JP	RCAL3
	IN	FDCD
	SUI	20h
	MOV	C,A
RCAL4:	IN	FDCS
	ORA	A
	JP	RCAL4
	IN	FDCD
	ORA	C
	JNZ	ERROR		;if error in recalibrate


;	Now set-up read command & DMA address.
;	If CPm-86, read Group Header to find destination.

.86	IF	@TARG <> 0
	LDK	DE,RGHDR
	CALL	DREAD	;read header
	JNZ	ERROR	;if problems
	LDK	A,I#JMPL
	STO	A,XFER
	LDK	HL,LdrBio	;set up Far Jump to bios
	STO	HL,XFER+1
	LD	HL,RGBUF+3
	STO	HL,XFER+3
	LDK	BC,LdrBio / 16
	ADD	HL,BC		;HL-> fwa bios (paragraphs)
	MOV	A,L
	AND	0Fh
	RAL ! RAL ! RAL ! RAL
	STO	A,DATA+2
	MOV	A,H
	AND	0F0h
	RAR ! RAR ! RAR ! RAR
	STO	A,DATA+0
	ADD	HL,HL
	ADD	HL,HL		;shift by 4
	ADD	HL,HL
	ADD	HL,HL
	MOV	A,H
	STO	A,DATA+1
.86	ENDIF

	LDK	DE,DATA
READB:
	CALL	DREAD		;direct read
	JNZ	ERROR		;if problems

	MOV	A,E
	CMP	low ENDCMD
	JNZ	READB		;if more Read commands to do

;	Jump to enter the BIOS.
.85	IF	@TARG = 0
	LD	HL,ENTRY
	MOV	D,H
	MOV	H,L		;reverse
	MOV	L,D
	JMP	[hl]		;enter CBIOS
.85	endif

.88	IF	@TARG <> 0
	IN	MMGR		;let 8088 run
.88	endif
	space	4,10
;	Function drive.
;	Entry	DE-> Command bytes.
;		B= length of command.
;	Exit	DE-> Lwa+1 of command.
DFCN:
DFCN1:	IN	FDCS
	OR	A
	JP	DFCN1		;if no master ready bit
	LD	A,[de]		;load command byte
	OUT 	FDCD		;to controller
	INC	DE
	DEC	B
	JNZ	DFCN1		;if more bytes
	RET
	space	4,10
;	Disk Read.
;	Entry	DE-> (3)DMA, (9)Command
;	Exit	DE-> Lwa+1 of Command.
;		Zbit=> successful read
DREAD:	proc
	LDK	B,LDMA
:ADR:	LD	A,[de]
	OUT	DMA		;set DMA
	INC	DE
	DEC	B
	JNZ	:ADR		;if NOT all 3 bytes

	LDK	B,LREAD
:1:	IN	FDCS
	OR	A
	JP	:1		;if no master ready bit
	LD	A,[de]		;load command byte
	OUT 	FDCD		;to controller
	INC	DE
	DEC	B
	JNZ	:1		;if more bytes

:2:	IN	INTS
	ORA	A
	JP	:2		;If not complete

:3:	IN	FDCS
	ORA	A
	JP	:3
	IN	FDCD
	SUI	40h
	MOV	L,A
:4:	IN	FDCS
	ORA	A
	JP	:4
	IN	FDCD
	SUI	80h
	MOV	H,A

	LDK	B,7-2
:5:	IN	FDCS
	OR	A
	JP	:5		;if not ready
	IN	FDCD		;read status
	DEC	B
	JNZ	:5		;wait until all done

	MOV	A,L
	ORA	H
	RET
	space	4,10
;	Disk error handler.
ERROR:
	LDK	BC,2000		;wait 2 seconds
	CALL	DELAY
	JMP	RETRY
	space	4,10
;	Delay process.
;	Entry	BC= delay count (nominal milliseconds).
;	Uses	AF, BC.
DELAY:
	LDK	A,DELCNT/26
DELY1:
	INC	BC
	DEC	BC
	DEC	A
	JNZ	DELY1	;if not one millisecond
	DEC	BC
	MOV	A,B
	OR	C
	JNZ	DELAY	;if not requested time
	RET


;	ASSERT	* < BOOT+N$BOOT*128	;only 4 sectors available
RGBUF:	EQU	BOOT + N$BOOT*128
	END
