	TITLE	DISK BOOTSTRAP DRIVER II
	LIST	NOCOND
;****************************************************************************
;
;	DISK CONTROLLER BOOTSTRAP DRIVER
;
;	FOR M5B WITH ZMON MONITOR.
;	(ALSO WILL WORK STAND-ALONE)
;
;****************************************************************************
;
; REVISION STATUS:
;
; 1.0 -	26 FEB 81, Release
; 1.1 -	Fix bug.
; 1.2 -	18 JUL 82, Move DD to high memory, clean up listing.
; 1.3 - 12 FEB 83
;	Add timout if DD not responding, add true recalibrate
;	on boot in case the head is outside track 0.
; 1.4 -	14 FEB 83
;	Make changes for rev C board.
; 1.5 -	23 MAR 83   GRH
;	Fix bug in recal routine to account for phase 1 anded with trk00
;	signal from drive. Causes recal to not work
;
; 1.6 -	3 APR 83   GRH
;	Fix bug in boot routine that assumes the controller window is
;	enabled after requesting it. Found out that if the Z-80 is
;	generating a wait signal, the bus request is never acknowledged!
;	Solution is to output the RESET bit along with the request thus
;	yanking the processor out of it's sleep.
;
; 2.0 -	18 MAR 84   GRH
;	Added hard disk boot option and boot command source disk option.
;
; 2.1 -	18 APR 85   GRH
;	Fix problem with hard disk boot from drive 1. Needs logon. Also
;	Also allow boot from 2nd platter.
;		code	logical	physical
;		42	A	DRIVE 0 HEAD 0
;		52	B	DRIVE 0 HEAD 2
;		62	C	DRIVE 1 HEAD 0
;		72	D	DRIVE 1 HEAD 2
;
; 3.0 -	28 JAN 87   GRH
;	Change Jade DD boot to resident prom version.
;	Implement disk I/O driver functions & vectors and COMIOPB.
;	Add error message output.
;	Add prom # & drive passed in page 0.
;	Drives now assigned the following logical to physical relationship:
;	0..3 =	8" Jade floppy
;	4..7 =	8" ISHA hard disk
;	8..B =	5" Jade floppy
;	C..F =	8" Micromation Doubler (ISIS)  <not implemented yet>
;	10..13= 3" Jade floppy			<not implemented yet>
;
; 3.01	4 JUN 88   GRH
;	Fix bug in ISHAX that prevented the clear controller command from
;	  working.
;
; 3.02	12 JUN 88   GRH
;	Change 'RET'urns in 'H8BOOT' to 'JP ....,DKRET'. Returns caused
;	  system crashes because ROMs not set up.
;
; 3.03	25 JUN 88   GRH
;	Modify floppy boot to include new disk format with disk system tracks
;	  directory like the hard disk has (removed DCM & BLT loader).
;
VERSN	EQU	303
;
;****************************************************************************

	SUBTTL	DECLARATIONS
;============================================================================
;
;				CONSTANTS
;
;============================================================================
FALSE	EQU	0
TRUE	EQU	NOT FALSE
;
DEBUG	EQU	FALSE
;
LF	EQU	0AH
CR	EQU	0DH
;
REV	EQU	'C'		;JADE BOARD REVISION LEVEL
;
BIOSSEC	EQU	13		;START SECTOR OF BIOS
HNGTMO	EQU	10		;HANGUP TIMOUT
SECSIZ	EQU	128		;DISK SECTOR SIZE
;
;   SYSTEM LOCATIONS
;
LOGINBYTE EQU	0004H		;CP/M CURRENT DRIVE & USER BYTE
IOPB	EQU	005CH		;USE DEFAULT FCB AS IOPB AREA
DEFBFR	EQU	0080H		;USE CPM DEFAULT BUFFER FOR BIOS SECTOR 1
PROMST	EQU	0F800H
XOVER	EQU	PROMST + 30H	;ROM CROSS-OVER POINT
PROMSIZ	EQU	2048		;SIZE OF THIS PROM FOR CODE CHECKING


;============================================================================
;
;*INCLUDE MONBOARD.DEF
;*INCLUDE COMIOPB.DEF
;*INCLUDE JDDCONT.DEF
;*INCLUDE ISHA.DEF
;*INCLUDE NAKEDT.DEF
;*INCLUDE HDISK.DEF
;*INCLUDE SYSDIR.DEF
;
;============================================================================
	LIST	OFF
*INCLUDE MONBOARD.DEF
*INCLUDE COMIOPB.DEF
*INCLUDE JDDCONT.DEF
*INCLUDE ISHA.DEF
*INCLUDE NAKEDT.DEF
*INCLUDE HDISK.DEF
*INCLUDE SYSDIR.DEF
	LIST	ON

	SUBTTL	UNINITIALIZED DATA
;############################################################################
;
;			PAGE 0 RESERVED AREA
;
;############################################################################
	ORG	0040H
;
;   BOOT VARIABLES
;
DKPROM	DS	2	;PROM # & DRIVE PASSED TO BIOS
BIOSLN	DS	2	;BIOS LENGTH SAVE/SECTOR COUNT
BIOSNT	DS	2	;BIOS ENTRY


	SUBTTL	MAIN PGM
	ORG	PROMST
;----------------------------------------------------------------------------
;
;	STAND-ALONE ENTRY VECTOR
;
;----------------------------------------------------------------------------
	JP	COLD			;BOOT VECTOR


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	CONSOLE INPUT
;	EXIT -	A= CHAR
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	RET
	NOP
	NOP


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	DISK ROM FUNCTION 
;	ENTRY-	C= FUNCTION #
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	JP	DKFUNC


;****************************************************************************
;
;	CONSOLE OUTPUT SUBR
;	ENTRY-	C= CHAR
;
;****************************************************************************
	JP	CO


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	JADE FLOPPY DISK DRIVER VECTOR
;	ENTRY-	IX= IOPB PTR
;	EXIT -	AF= 0: NO ERRORS
;		BC,DE,HL,IX= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	JP	DSKX


;############################################################################
;
;	PUT VERSION # AT START OF 1ST VECTOR FOR USER ACCESS
;
;############################################################################
	DW	VERSN
	DB	0


;----------------------------------------------------------------------------
;
;	COLD START FROM RESET IN CASE THIS IS ONLY PROM IN SYSTEM
;
;----------------------------------------------------------------------------
COLD:	DI			;DISABLE ROM IMAGE
	OUT	(COLDRES),A
;
	LD	SP,DEFBFR	;SET UP COLD STACK
	LD	B,0		;SELECT OPTIONS
	JR	BEGIN


;----------------------------------------------------------------------------
;
;	SWAP ROMS TO RETURN TO CALLER
;
;----------------------------------------------------------------------------
	DS	XOVER - $		;POSITION CODE
DKRET:	LD	A,XMONROM		;SELECT MONITOR FOR RETURN
	NOP				;ALIGN NEXT INSTRUCTION
	OUT	(ROMSEL),A
;
;	MONITOR ROM CONTINUES EXECUTION NOW
;


;----------------------------------------------------------------------------
;
;	BOOT CALLER HAS SWAPPED ROMS & STARTS EXECUTING HERE.
;	ENTRY-	B= DRIVE #
;			0..3 =	8" JADE FLOPPY
;	   		4..7 =	8" HARD DISK (ISHA)
;			8..B =	5" JADE FLOPPY
;	   		C..F =	8" MICROMATION (INTEL M2FM)
;	   		10..13 = 3" JADE FLOPPY
;
;----------------------------------------------------------------------------
BEGIN:
;
;   SAVE PROM # FOR BIOS
;
	LD	A,C
	AND	A,7
	LD	(DKPROM),A
;
;   SAVE DRIVE
;
	REPT	4		;D4..D11 -> D0..D7
	SRL	B
	RR	C
	ENDM
;
	LD	A,B		;CHECK FOR DRIVE # > 0FFH
	OR	A,A
	JR	NZ,ABORT
;
	LD	A,C		;TELL BIOS WHERE WE'RE AT
	LD	(LOGINBYTE),A
	LD	(DKPROM + 1),A
;
;   NOW VECTOR TO DISK BOOT ROUTINE
;
	CP	A,4		;IF 8" FLOPPY DISK THEN EXIT
	JR	C,F8BOOT
;
	CP	A,8		;IF HARD DISK THEN EXIT
	JP	C,H8BOOT
;
	CP	A,0CH		;IF 5" FLOPPY THEN EXIT
	JP	C,F5BOOT
;
	CP	A,10H		;IF MICROMATION THEN EXIT
	JP	C,M8BOOT
;
	CP	A,14H		;IF 3" FLOPPY THEN EXIT
	JP	C,F3BOOT
;
;   FALL INTO ERROR RETURN TO PRINT MESSAGE
;


;----------------------------------------------------------------------------
;
;	ABORT RETURNS CONTROL TO THE MONITOR ROM
;
;----------------------------------------------------------------------------
ABORT:	SCF			;HAVE MONITOR PRINT ERROR MESSAGE
	JR	DKRET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	3" JADE FLOPPY DISK BOOT
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
F3BOOT:	EQU	ABORT	;UNSUPPORTED


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	5" JADE FLOPPY DISK BOOT
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
F5BOOT:	EQU	ABORT	;UNSUPPORTED


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	8" MICROMATION M2FM BOOT
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M8BOOT:	EQU	ABORT	;UNSUPPORTED

	SUBTTL	JADE BOOT
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	8" JADE FLOPPY BOOT
;	THIS ROUTINE NOW ACCESSES THE NEW JADE CONTROLLER WITH ON-BOARD PROM.
;   THE CODE WILL COMMAND THE CONTROLLER TO READ THE BIOS FROM THE DISK AND
;   EXECUTE THE COLD START ENTRY IN THE BIOS.
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
F8BOOT:
;
;   SET THE PORT #
;
	EXX
	LD	C,DDPORT8
	IN	A,(C)
	AND	A,DDSASW
	RLCA
	OR	A,HIGH DDBASE
	LD	H,A
	LD	L,0
	EXX
;
;   RESET & START THE DISK PROCESSOR
;
	LD	A,DDBGN
	CALL	JWAIT
	JR	NZ,ABORT
;
;   TEST THE SELF TEST STATUS
;
	LD	IX,IOPB
	CALL	JGETRES
	CALL	NZ,DBERR	;DIAGNOSTIC ERROR
;
;   PREPARE IOPB
;
	LD	HL,LOGIOPB
	CALL	IIOPB
;
	LD	A,(LOGINBYTE)	;SET DRIVE
	LD	(IOPB + PBDRVO),A
;
	LD	A,2		;SET SECTOR
	LD	(IOPB + PBSECO),A
;
;   LOG ON DRIVE
;
	CALL	DSKX
	CALL	NZ,DBERR
	JP	NZ,DKRET
;
;   READ THE DIRECTORY SECTOR
;
	LD	(IX + PBSECO),?DIRSEC
	LD	(IX + PBCMDO),DDRDS
	CALL	DSKX
	CALL	NZ,DBERR
	JP	NZ,DKRET
;
;   IF NOT DIRECTORY SECTOR THEN ERROR
;
	LD	A,(DEFBFR)
	CP	A,?NEWDIR
	JP	C,DKRET
;
;   ELSE FETCH THE LOCATION FOR THE BIOS
;
	LD	HL,(DEFBFR + ?DSBIOS)
	LD	A,H
	LD	H,0
	LD	(IOPB + PBSECO),HL
	LD	L,A
	LD	(IOPB + PBTRKO),HL
;
;   READ 1ST BIOS SECTOR INTO BUFFER
;
	CALL	DSKX
	CALL	NZ,DBERR
	JP	NZ,DKRET
;
;   FETCH BIOS LOAD ADDRESS & SIZE PARAMETERS FROM BIOS 1ST SECTOR
;
	CALL	STUPBIOS
	JP	C,DKRET
;
;   READ BIOS
;
JADRDB:
	CALL	DSKX
	CALL	NZ,DBERR
	JP	NZ,DKRET
;
	INC	(IX + PBSECO)		;NEXT SECTOR
;
	LD	HL,(IOPB + PBDMAO)	;BUMP LOAD ADDRESS
	LD	DE,SECSIZ
	ADD	HL,DE
	LD	(IOPB + PBDMAO),HL
;
	LD	HL,BIOSLN		;IF --COUNT != 0 THEN REPEAT
	DEC	(HL)
	JR	NZ,JADRDB
   IF	DEBUG
;
;   RETURN TO MONITOR
;
	OR	A,A			;RETURN NO ERROR
	JP	DKRET
   ELSE
;
;   EXECUTE THE BIOS COLD START ENTRY
;
	LD	HL,(BIOSNT)
	JP	(HL)
   ENDIF

	SUBTTL	DISK IOPB EXECUTOR
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	EXECUTE THE DISK IOPB FUNCTION
;	ENTRY-	IX= IOPB ADDRESS
;	EXIT -	AF= 0: NO ERRORS
;		
;		A,BC,BC',HL,HL',DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DSKX:
;
;   COMMAND OK, COMPUTE CONTROLLER PORT
;
	LD	A,(IX + PBDRVO)
	CP	A,NDRVS		;IF DRIVE # OUT OF RANGE THEN RETURN ERROR
	JP	NC,JSELERR
;
	LD	HL,DRVPRT	;CALULATE DRIVE PORT TABLE ELEMENT
	ADD	A,L
	LD	L,A
	LD	A,0
	ADC	A,H
	LD	H,A
	LD	A,(HL)		;FETCH CONTROLLER PORT
	EXX
	LD	C,A
	EXX
;
	CP	A,HSTATUS	;IF HARD DISK THEN EXIT
	JP	Z,ISHAX
;
	DEC	A		;IF MICROMATION THEN EXIT
	JP	Z,M2X
;
	JP	JADEX		;ELSE MUST BE JADE CONTROLLER
;
;
;   DRIVE PORT TABLE
;
DRVPRT:
	REPT	4		;8" FLOPPY DRIVES
	DB	DDPORT8
	ENDM
	REPT	4		;8" HARD DISK DRIVES
	DB	HSTATUS
	ENDM
	REPT	4		;5" FLOPPY DRIVES
	DB	DDPORT5
	ENDM
	REPT	4		;8" MICROMATION DOUBLER DRIVES
	DB	1
	ENDM
	REPT	4		;3" FLOPPY DRIVES
	DB	DDPORT3
	ENDM
NDRVS	EQU	$ - DRVPRT

	SUBTTL	JADE FLOPPY CONTROLLER PRIMITIVES
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	EXECUTE THE DISK IOPB FUNCTION
;	ENTRY-	IX= IOPB ADDRESS
;		C'= CONTROLLER PORT ADDRESS
;	EXIT -	AF= 0: NO ERRORS
;		
;		A,BC,BC',HL,HL',DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JADEX:
;
;   CHECK FOR CONTROLLER PRESENT
;
	EXX
	IN	A,(C)
	EXX
	INC	A		;0FFH IF NOT THERE
	JR	Z,JCNP
;
;   COMPUTE JADE CONTROLLER BASE ADDRESS
;
	DEC	A		;FETCH ADDRESS SELECT SWITCH DATA
	AND	A,DDSASW
	RLCA
	OR	A,HIGH DDBASE
	EXX
	LD	H,A
	LD	L,0
	EXX
;
;   USE COMMAND TO INDEX INTO DRIVER TABLE
;
	LD	A,(IX + PBCMDO)		;IF UNSUPPORTED COMMAND THEN ERROR
	CP	A,NJCMDS
	JR	NC,DCMDERR
;
	LD	E,A
	LD	D,0
	LD	HL,JADETBL
	ADD	HL,DE
	ADD	HL,DE
	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A
;
;   IF NEEDED, BIAS DRIVE DOWN
;
	LD	A,(IX + PBDRVO)
	PUSH	AF		;SAVE FOR LATER RESTORATION
;
	CP	A,4		;IF 8" THEN NO NEED
	JR	C,JADEOK
;
	SUB	A,8		;SKIP OVER 8" HARD DISK
	CP	A,4		;IF 5" THEN OK
	JR	C,JADEOK
;
	SUB	A,8		;SKIP OVER MICROMATION TO 3", ASSUME OK
;
JADEOK:	LD	(IX + PBDRVO),A

	PUSH	HL
	LD	HL,JADERET
	EX	(SP),HL
	JP	(HL)		;EXECUTE THE DRIVER TYPE
;
;   JADE ROUTINES RETURN HERE
;
JADERET:
	POP	HL		;RESTORE DRIVE BUT SAVE FLAGS (ERROR)
	LD	(IX + PBDRVO),H
	RET
;
;
;############################################################################
;
;			COMMAND TYPE TABLE
;
;############################################################################
JADETBL:
	DW	JTYPE1		;LOGON DISK		RETURN SECTOR DATA
	DW	JTYPE1		;READ SECTOR		"	"	"
	DW	JTYPE2		;WRITE SECTOR		SEND SECTOR DATA
	DW	JTYPE3		;FORMAT TRACK		SEND DRIVER CODE
	DW	JTYPE1		;READ ADDRESS		RETURN SECTOR DATA
	DW	JTYPE4		;EIA OUTPUT		IOPB ONLY
	DW	JTYPE4		;EIA STATUS		"	"
	DW	JTYPE4		;IDLE			"	"
	DW	JTYPE4		;RETURN VERSION		"	"
	DW	JTYPE5		;SET DISK FLAGS		SECTOR DATA BOTH WAYS
	DW	JTYPE4		;LOAD HEAD & IDLE	IOPB ONLY
	DW	JTYPE4		;SEEK TRACK		"	"
	DW	JTYPE5		;SET DRIVE PARAMETERS	SECTOR DATA BOTH WAYS
	DW	JTYPE4		;RETURN DRIVE STATUS	IOPB ONLY
	DW	JTYPE4		;SET EIA BAUD RATE	"	"
	DW	JTYPE4		;CLEAR			"	"
NJCMDS	EQU	($ - JADETBL) / 2


;****************************************************************************
;
;	ILLEGAL COMMAND ERROR
;
;****************************************************************************
DCMDERR:
	LD	(IX + PBSTATO),CMDERR
;
;   COMMON ERROR CODE
;
DSKERR:	LD	A,-1
	OR	A,A
	RET


;****************************************************************************
;
;	ILLEGAL DRIVE REQUESTED
;
;****************************************************************************
JSELERR:
	LD	(IX + PBSTATO),SELERR
	JP	DSKERR


;****************************************************************************
;
;	CONTROLLER NOT SENSED ERROR
;
;****************************************************************************
JCNP:	LD	(IX + PBSTATO),CNPERR
	JP	DSKERR


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;   TYPE 1 JADE COMMAND XFERS SECTOR DATA FROM CONTROLLER
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JTYPE1:
;
;   EXECUTE COMMAND
;
	CALL	JEX
	RET	NZ		;IF ERROR THEN QUIT
;
;   CHECK FOR XFER INHIBIT
;
	BIT	PBFNXB,(IX + PBFLGO)	;IF FLAG == TRUE THEN NO XFER
	JR	NZ,JT1
;
;   XFER DATA FROM CONTROLLER
;
JT1A:	EXX
	LD	A,DDMB0		;SOFTLY GRAB RESOURCES WITHOUT INTERRUPT
	OUT	(C),A
	LD	A,DDMB1		;OPEN WINDOW TO SECTOR BUFFER (BANK 1)
	OUT	(C),A
;
;   FETCH FDC ADDRESS
;
	PUSH	HL
	EXX
	POP	HL
;
;   FETCH DESTINATION ADDRESS
;
	LD	E,(IX + PBDMAO)
	LD	D,(IX + [PBDMAO + 1])
;
;   FETCH XFER COUNT
;
	LD	C,(IX + PBST4O)
	LD	B,(IX + PBST5O)
;
;   CHECK FOR LEGAL COUNT
;
	LD	A,B		;IF COUNT == 0 OR COUNT > 1024 THEN NO XFER
	CP	A,4
	JR	NC,JT1B
;
	OR	A,C
	JR	Z,JT1B
;
	LDIR			;XFER DATA
;
;   REMOVE JADE WINDOW BEFORE RETURNING
;
JT1:	EXX
	XOR	A,A
	OUT	(C),A
	EXX
;
	RET
;
;
;   ILLEGAL IOPB FORMAT ERROR
;
JT1B:	CALL	JT1		;REMOVE CONTROLLER WINDOW
BADIOPB:
	LD	(IX + PBSTATO),IOPBERR	;PASS BACK ERROR
	JP	DSKERR


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN NO ERRORS FUNCTION
;	EXIT -	A= 0
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DSKOK:	XOR	A,A
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;   TYPE 2 JADE COMMAND XFERS SECTOR DATA TO CONTROLLER
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JTYPE2:
;
;   CHECK FOR XFER INHIBIT
;
	BIT	PBFNXB,(IX + PBFLGO)	;IF FLAG == TRUE THEN NO XFER
	JR	NZ,JT2
;
;   OPEN WINDOW TO SECTOR BUFFER
;
	EXX
	LD	A,DDMB1
JT2A:	OUT	(C),A
;
;   FETCH CONTROLLER ADDRESS FOR DESTINATION
;
	PUSH	HL
	EXX
	POP	DE
;
;   FETCH SOURCE ADDRESS FROM IOPB
;
	LD	L,(IX + PBDMAO)
	LD	H,(IX + [PBDMAO + 1])
;
;   FETCH COUNT
;
	LD	C,(IX + PBST4O)
	LD	B,(IX + PBST5O)
;
;   CHECK FOR VALID COUNT
;
	LD	A,B		;IF COUNT == 0 OR COUNT > 1024 THEN NO XFER
	CP	A,4
	JR	NC,JT1B
;
	OR	A,C
	JR	Z,JT1B
;
	LDIR			;XFER DATA
;
JT2:
;
;   FALL INTO THE JADE EXECUTION FUNCTION
;


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;			EXECUTE THE JADE IOPB FUNCTION
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JEX:
;
;   OPEN WINDOW TO COMMAND BUFFER
;
	EXX
	LD	A,DDMB0		;OPEN WINDOW TO COMMAND BUFFER (BANK 0)
	OUT	(C),A
;
;   COMPUTE OFFSET TO CDB
;
	PUSH	HL
	EXX
	POP	HL
	LD	DE,DDCBO
	ADD	HL,DE
	EX	DE,HL
;
;   IOPB ADDRESS IS SOURCE
;
	PUSH	IX		;SET IOPB ADDRESS
	POP	HL
;
;   DOWNLOAD THE IOPB
;
	LD	BC,PBSTATO	;ONLY XFER PERTINENT BYTES
	LDIR
;
;   EXECUTE THE COMMAND
;
	LD	A,DDEXC		;START COMMAND
	CALL	JWAIT		;WAIT FOR COMPLETION
	RET	NZ		;IF ERROR THEN RETURN ERROR
;
;   FALL INTO GET RESULTS FUNCTION
;


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;		COMMAND EXECUTED, XFER RESULTS FUNCTION
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JGETRES:
;
;   SELECT COMMAND BLOCK WINDOW
;
	EXX
	LD	A,DDMB0
	OUT	(C),A
;
;   COMPUTE IOPB LOCATION IN WINDOW
;
	PUSH	HL
	EXX
	POP	HL
	LD	DE,DDCBO + PBSTATO
	ADD	HL,DE
;
;   FETCH IOPB ADDRESS OF STATUS BYTES
;
	PUSH	IX
	POP	DE
	EX	DE,HL
	LD	BC,PBSTATO
	ADD	HL,BC
	EX	DE,HL
;
;   COUNT = REMAINDER
;
	LD	BC,IOPBSZ - PBSTATO
;
;   UPLOAD STATUS BYTES
;
	LDIR
;
;   RELEASE IOPB WINDOW
;
	EXX
	XOR	A,A
	OUT	(C),A
	EXX
;
;   CHECK FOR ERROR
;
	LD	A,(IX + PBSTATO)
	OR	A,A
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;   TYPE 3 JADE COMMAND XFERS FORMAT PGM TO CONTROLLER
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JTYPE3:
;
;   CHECK FOR XFER INHIBIT
;
	BIT	PBFNXB,(IX + PBFLGO)	;IF FLAG == TRUE THEN NO XFER
	JR	NZ,JT2
;
;   SELECT CONTROLLER WINDOW
;
	EXX
	LD	A,DDMB0
	JP	JT2A		;COMMON WITH WRITE SECTOR


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;   TYPE 4 JADE COMMAND XFERS IOPB ONLY TO/FROM CONTROLLER
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JTYPE4:	EQU	JEX


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;   TYPE 5 JADE COMMAND XFERS SECTOR BUFFER BOTH DIRECTIONS
;	ENTRY-	IX= IOPB PTR
;		HL'= CONTROLLER WINDOW PTR
;		C'= CONTROLLER PORT
;	EXIT -	AF= 0: NO ERRORS
;		B, DE, HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JTYPE5:	CALL	JTYPE2		;XFER DATA DOWN AND EXECUTE
	RET	NZ		;IF ERROR THEN RETURN
	JP	JT1A		;XFER DATA BACK


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	WAIT ON JADE CONTROLLER BUSY FUNCTION
;	ENTRY-	A= COMMAND TO OUTPUT
;		C'= PORT OF CONTROLLER
;	EXIT -	AF= 0: OK, /0: ERROR
;		DE,HL= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
JWAIT:
;
;   ISSUE PASSED COMMAND
;
	EXX
	OUT	(C),A
	EXX
;
;   PAUSE A WHILE FOR CONTROLLER TO CATCH UP
;
	EX	(SP),HL
	EX	(SP),HL
;
;   WAIT FOR TASK COMPLETION FOR A WHILE
;
	LD	L,HNGTMO	;SET UP TIMOUT
	LD	DE,0
JWAIT1:	DEC	DE		;IF NOT TIMOUT THEN CONTINUE TO WAIT
	LD	A,E
	OR	D
	JR	NZ,JWAIT2
;
	DEC	L		;IF TIME OUT THEN RETURN TO MONITOR
	OR	L
	JP	Z,DSKERR
;
JWAIT2:	EXX
	IN	A,(C)		;IF NOT DONE THEN WAIT
	EXX
	AND	A,DDSHLT
	JR	NZ,JWAIT1
;
	RET			;RETURN ZF


	IF	($ AND 7FFFH) >= (0FC00H AND 7FFFH)
	CONMSG	*** JADE DEPENDENT CODE OVERLAPS CONTROLLER MAP ***
	ENDIF
	SUBTTL	MICROMATION PRIMITIVES
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	MICROMATION DRIVER
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M2X:	EQU	DSKERR

	SUBTTL	HARD DISK BOOT
;****************************************************************************
;
;	Hard disk boot function.
;	This module reads the BIOS image to the proper system
; address & jumps to the BIOS cold start entry point.
;
;****************************************************************************
H8BOOT:
;
;   INSURE FDC WINDOW REMOVED
;
	LD	BC,0341H
	XOR	A,A
H8B1:	OUT	(C),A
	INC	C
	DJNZ	H8B1
;
;   SET UP IOPB IN RAM
;
	LD	HL,LOGIOPB
	CALL	IIOPB
;
;   FETCH & OFFSET PHYSICAL DRIVE
;
	LD	A,(LOGINBYTE)	;COMPUTE & SET DRIVE
	SUB	A,4
;
;   COMPUTE LOGICAL DRIVE FOR IOPB
;
	SRL	A		;DRIVE = LOGICAL_DRIVE / 2
	PUSH	AF		;BIAS DRIVE UP
	ADD	A,4
	LD	(IOPB + PBDRVO),A
	POP	AF
;
;   COMPUTE SECTOR FROM LOGICAL DRIVE
;
	RRA			;IF ODD DRIVE THEN SECTOR += 128
	AND	A,80H
	EXX			;SAVE SECTOR OFFSET IN C' FOR LATER USE
	LD	B,A		;   EVEN= 0, ODD= 80H (128)
;
	LD	A,1		;IF ODD, THEN USE PLATTER 1
	ADD	A,B
	LD	(IOPB + PBSECO),A
	EXX
;
;   ISSUE CLEAR CONTROLLER IOPB
;
	LD	A,DDCLR
	LD	(IOPB + PBCMDO),A
;
	LD	IX,IOPB
	CALL	ISHAX
;
;   CHECK SELF TEST STATUS
;
	CALL	DQERR
;
;   FORCE HOST ADAPTER LOG-ON
;
	LD	A,DDLOG
	LD	(IOPB + PBCMDO),A
;
	CALL	ISHAX
	CALL	DQERR
	JP	NZ,DKRET
;
;   NOW READ THE DIRECTORY SECTOR
;
	LD	(IX + PBCMDO),DDRDS
;
	EXX
	LD	A,B
	EXX
	LD	HL,?DIRSEC		;SECTOR = SECTOR + (DRV / 2) * 128
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	(IOPB + PBSECO),HL
;
	CALL	ISHAX		;READ THE DIRECTORY SECTOR (IOPB SET UP)
	CALL	DQERR
	JP	NZ,DKRET
;
;   LOAD THE CBIOS
;
	LD	HL,(DEFBFR + HDBIOSS)	;FETCH CBIOS SECTOR FROM DIRECTORY
	LD	H,0
	INC	HL			;CONVERT TO SECTOR FROM SECTOR -1
	EXX				;ADD IN LOGICAL DRIVE OFFSET
	LD	A,B
	EXX
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	(IOPB + PBSECO),HL
;
	CALL	ISHAX		;LOAD IN CBIOS SECTOR #1
	CALL	DQERR		;CHECK FOR ERRORS
	JP	NZ,DKRET
;
	CALL	STUPBIOS	;SET UP IOPB FOR BIOS READ
	JP	C,DKRET
;
HDRDLP:
	CALL	ISHAX
	CALL	DQERR
	JP	NZ,DKRET
;
	LD	HL,(IOPB + PBSECO)	;NEXT SECTOR
	INC	HL
	LD	(IOPB + PBSECO),HL
;
	LD	HL,(IOPB + PBDMAO)	;BUMP DMA ADDRESS
	LD	DE,SECSIZ
	ADD	HL,DE
	LD	(IOPB + PBDMAO),HL
;
	LD	A,(BIOSLN)	;IF NOT DONE THEN LOOP
	DEC	A
	LD	(BIOSLN),A
	JR	NZ,HDRDLP
;
	LD	HL,(BIOSNT)	;BIOS LOADED, GO EXECUTE IT
   IF	NOT DEBUG
	JP	(HL)
   ELSE				;IF DEBUG THEN RETURN NO ERRORS
	OR	A
	JP	DKRET
   ENDIF

	SUBTTL	INTELLIGENT SASI HOST ADAPTER (ISHA) PRIMITIVES
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	ISHA DRIVER
;	ENTRY-	IX= IOPB ADDRESS
;	EXIT -	AF= 0: NO ERRORS
;		BC= SECTOR
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ISHAX:
;
;   CHECK FOR CONTROLLER PRESENT
;
	IN	A,(HSTATUS)
	INC	A
	JP	Z,JCNP
;
;   IF CLEAR COMMAND THEN DO DIFFERENTLY
;
	LD	A,(IX + PBCMDO)
	CP	A,DDCLR
	JR	Z,ISHACLR
;
;   BIAS DOWN DRIVE NUMBER
;
	LD	A,(IX + PBDRVO)
	PUSH	AF			;SAVE DRIVE TO RESTORE IOPB LATER
	SUB	A,4
	LD	(IX + PBDRVO),A
;
;   TEMPORARILY CONVERT LOGICAL SECTOR TO PHYSICAL SECTOR UNTIL ISHA IS CHANGED
;
	LD	C,(IX + PBSECO)
	LD	B,(IX + PBSECO + 1)
	PUSH	BC			;SAVE FOR RESTORE
	DEC	BC			;CONVERT TO LOGICAL SECTOR
	LD	(IX + PBSECO),C
	LD	(IX + PBSECO + 1),B
;
;   PUT IOPB ADDRESS IN BC FOR EASY OUTPUT TO CONTROLLER
;
	PUSH	IX
	POP	BC
;
;   OUTPUT THE IOPB ADDRESS TO HOST ADAPTER
;
	LD	A,C
	OUT	(HDATA),A
	LD	A,HIOPBL
	OUT	(HCMD),A
	CALL	HWBUSY
;
	LD	A,B
	OUT	(HDATA),A
	LD	A,HIOPBH
	OUT	(HCMD),A
	CALL	HWBUSY
;
	XOR	A,A
	OUT	(HDATA),A
	LD	A,HIOPBX
	OUT	(HCMD),A
	CALL	HWBUSY
;
;   OUTPUT THE EXECUTE IOPB COMMAND
;
	LD	A,HEXEC
	OUT	(HCMD),A
	CALL	HWBUSY
;
;   RESTORE THE IOPB
;
	POP	BC
	LD	(IX + PBSECO),C
	LD	(IX + PBSECO + 1),B
;
	POP	AF
	LD	(IX + PBDRVO),A
;
;   RETURN THE ERROR STATUS
;
	LD	A,(IX + PBSTATO)
	OR	A,A
	RET
;
;
;   CLEAR COMMAND ISSUED. RESET THE CONTROLLER
;
ISHACLR:
	LD	A,1 SHL HRESET		;ISSUE CONTROLLER RESET
	OUT	(HCMD),A
	XOR	A,A
	OUT	(HCMD),A
;
CLRWT:	IN	A,(HSTATUS)		;WAIT FOR CONTROLLER READY
	BIT	HBUSYB,A
	JR	NZ,CLRWT
;
	LD	HL,0	;DELAY A WHILE IN CASE ISHA FOOLING WITH STATUS PORT
ISHA2:	DEC	HL
	LD	A,H
	OR	A,L
	JR	NZ,ISHA2
;
	IN	A,(HSTATUS)
	BIT	HBUSYB,A
	JR	NZ,CLRWT	;IF BUSY AGAIN THEN CONTINUE TO WAIT
;
;   IF NO ERRORS THEN RETURN 0
;
	AND	A,(1 SHL HERRB) OR (1 SHL HFERRB)
	LD	(IX + PBSTATO),A
	RET	Z
;
;   ERROR ENCOUNTERED, RETURN FIRMWARE ERROR
;
	IN	A,(HDATA)
	LD	(IX + PBSTATO),A	;RETURN NO ERRORS FOR NOW
	OR	A,A
	RET


;****************************************************************************
;
;	HWBUSY SUBR WAITS UNTIL HOST ADAPTOR GOES NOT BUSY
;	EXIT -	A= STATUS
;		ZF= TRUE
;
;****************************************************************************
HWBUSY:
;
;   IF CONTROLLER BUSY THEN WAIT
;
	IN	A,(HSTATUS)
	BIT	HBUSYB,A
	JR	NZ,HWBUSY
;
;   ELSE RETURN ZF
;
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	COMMON SETUP IOPB FOR BIOS READ SUBR
;	ENTRY-	CBIOS SECTOR #1 IN DEFBFR
;		IX= IOPB PTR
;	EXIT -	CF= ERROR
;		A,HL,DE,BC= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
STUPBIOS:
;
;   FETCH BIOS LOAD PARAMETER OFFSET
;
	LD	A,(DEFBFR + 1)
;
;   IF NOT IN 1ST SECTOR THEN RETURN ERROR
;
	CP	A,SECSIZ
	CCF
	RET	C
;
;   COMPUTE PTR TO PARAMETERS
;
	LD	HL,DEFBFR
	LD	E,A		
	LD	D,0
	ADD	HL,DE
;
;   FETCH LOAD ADDRESS & SAVE
;
	DEC	HL
	LD	D,(HL)
	DEC	HL
	LD	E,(HL)
;
	LD	(BIOSNT),DE
;
;   FETCH BIOS LENGTH & SAVE
;
	DEC	HL
	LD	B,(HL)
	DEC	HL
	LD	C,(HL)
;
	LD	(BIOSLN),BC
;
;   MOVE THIS SECTOR TO PROPER LOCATION
;
	LD	HL,DEFBFR
	LD	BC,SECSIZ
	LDIR
;
;   SET UP FOR NEXT SECTOR READ
;
	LD	(IOPB + PBDMAO),DE	;SET UP NEW DMA ADDRESS
;
	INC	(IX + PBSECO)	;NEXT SECTOR
;
;   COMPUTE SECTOR COUNT FROM LENGTH
;
	LD	HL,(BIOSLN)	;COMPUTE # SECTORS
	LD	A,L		;IF NOT EVEN SECTOR THEN BUMP 1
	AND	A,7FH
	JR	Z,NOBUMP
;
	LD	DE,SECSIZ
	ADD	HL,DE
;
NOBUMP:	LD	A,L
	RLA			;PUT BIT 7 INTO BIT 0 OF H
	RL	H
	LD	A,H
;
	DEC	A		;ALREADY HAVE 1ST SECTOR
;
;   SAVE COUNT IN LENGTH
;
	LD	(BIOSLN),A
;
;   DONE, RETURN NO ERROR
;
	OR	A,A
	RET


;****************************************************************************
;
;	INITIALIZE THE IOPB STRUCTURE IN RAM
;	ENTRY-	HL= IOPB PTR TO INITIALIZE FROM
;	EXIT -	HL, DE, BC= ?
;
;****************************************************************************
IIOPB:
;
;   MOVE THE IOPB
;
	LD	DE,IOPB
	LD	BC,IOPBSZ
	LDIR
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	DISK ERROR OUTPUT SUBR
;	ENTRY-	IX= IOPB BASE
;	EXIT -	AF= 0: NO ERROR
;		HL,DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DQERR:
;
;   IF STATUS == 0 THEN RETURN NO ERROR
;
	LD	A,(IX + PBSTATO)
	OR	A,A
	RET	Z
;
;   ELSE FALL INTO ERROR OUTPUT
;


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	DISPLAY ERROR AND RETURN ERROR FUNCTION
;	ENTRY-	IX= IOPB PTR
;	EXIT -	AF= /0
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DBERR:
;
;   DISPLAY HEADER
;
	LD	HL,DERM
	CALL	PUTS
;
;   DISPLAY IOPB DATA
;
	PUSH	IX
	POP	HL
	LD	B,IOPBSZ
;
DBTE1:	LD	A,(HL)		;OUTPUT BYTE
	CALL	HTOA
;
	CALL	SPACE		;DISPLAY SEPARATOR
;
	INC	HL		;NEXT VALUE
	DJNZ	DBTE1		;IF NOT DONE THEN CONTINUE
;
;   DISPLAY PORT #
;
	CALL	SPACE
	CALL	SPACE		;OUTPUT PORT #
	EXX
	LD	A,C
	EXX
	CALL	HTOA
;
;   DISPLAY CONTROLLER ADDRESS
;
	CALL	SPACE
	EXX			;OUTPUT FDC ADDRESS
	LD	A,H
	EXX
	CALL	HTOA
	EXX
	LD	A,L
	EXX
	CALL	HTOA
;
;   NEW LINE & RETURN ERROR
;
	CALL	CRLF
	JP	DSKERR

	SUBTTL	ASCII CHAR ROUTINES
;****************************************************************************
;
;	CONVERT BINARY NIBBLE TO ASCII-HEX & OUTPUT SUBR
;	ENTRY-	A= BINARY
;
;****************************************************************************
HTOA:
;
;   CONVERT UPPER NIBBLE 1ST
;
	PUSH	AF
	RRCA
	RRCA
	RRCA
	RRCA
	CALL	CONV
;
;   NOW CONVERT LOWER NIBBLE
;
	POP	AF
CONV:	AND	A,0FH		;INSURE ONLY NIBBLE
	ADD	A,90H		;CONVERT
	DAA
	ADC	A,40H
	DAA
	LD	C,A		;OUTPUT
;
;   FALL INTO CONSOLE OUTPUT
;


;****************************************************************************
;
;	CONSOLE OUTPUT SUBR
;	ENTRY-	C= CHAR
;	EXIT -	AF= ?
;
;****************************************************************************
CO:	IN	A,(NTS)		;IF BUSY THEN WAIT
	AND	A,1 SHL NTBSY
	JR	NZ,CO
;
	LD	A,C
	OUT	(NTD),A
	RET


;****************************************************************************
;
;			NEW LINE SUBR
;	EXIT -	AF, C= ?
;
;****************************************************************************
CRLF:	LD	C,0DH
	CALL	CO
	LD	C,0AH
	JR	CO


;****************************************************************************
;
;	PRINT TEXT SUBR
;	ENTRY-	HL= TEXT PTR (LAST CHAR HAS BIT 7 SET)
;	EXIT -	HL, C, A= ?
;
;****************************************************************************
PUTS:	LD	C,(HL)
	RES	7,C
	CALL	CO
;
	BIT	7,(HL)
	RET	NZ
;
	INC	HL
	JR	PUTS


;****************************************************************************
;
;	OUTPUT SPACE TO CONSOLE SUBR
;
;****************************************************************************
SPACE:	LD	C,' '
	JR	CO

	SUBTTL	ROM FUNCTIONS
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	FUNCTION DISPATCHER
;	ENTRY-	C= FUNCTION #
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DKFUNC:
;
;   IF ILLEGAL FUCTION THEN RETURN ERROR
;
	LD	A,C
	CP	A,MAXFUNC
	LD	A,-1
	RET	NC
;
;   ELSE SELECT FUNCTION
;
	PUSH	HL
	LD	HL,FUNCTBL
	LD	A,C
	ADD	A,A
	ADD	A,L
	LD	L,A
	LD	A,0
	ADC	A,H
	LD	H,A
	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A
	EX	(SP),HL
	RET


;############################################################################
;
;	FUNCTION TABLE
;
;############################################################################
FUNCTBL:
	DW	RETVER		;(0) RETURN VERSION #
	DW	DQERR		;(1) TEST FOR IOPB ERROR & QUERY IF ERROR
	DW	DBERR		;(2) DISPLAY IOPB ERROR DATA
MAXFUNC	EQU	($ - FUNCTBL) / 2


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN VERSION #
;	EXIT -	HL= VERSION # IN BINARY
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RETVER:	LD	HL,VERSN
	XOR	A,A
	RET

	SUBTTL	INITIALIZED DATA
;############################################################################
;
;   MESSAGES
;
;############################################################################
DERM:	DB	CR,LF,'Disk Error! IOPB data:'
	DB	CR,LF,'CM DR TL TH SL SH FG AL AH AX ST S1 S2 S3 S4 S5   PT CA'
	DM	CR,LF

;############################################################################
;
;	LOGIN IOPB
;
;############################################################################
LOGIOPB:
	DB	DDLOG		;COMMAND
	DB	0		;DRIVE
	DW	0		;TRACK
	DW	2		;SECTOR/SIDE
	DB	0		;FLAGS
	DW	DEFBFR		;DMA
	DB	0		;EXTENDED DMA
	DB	0,0,0,0		;STATUS
	DW	128		;XFER COUNT


	IF	($ < PROMST) OR ($ > (PROMST + PROMSIZ))
	CONMSG	ERROR!  Code Too Large for PROM!
	ENDIF

	END
