	TITLE	'KAYPRO II DOUBLE DENSITY DISK ENABLE'
	PAGE	54
*
*	John S Robison
*	MAY 17, 1983
*
*	THIS PROGRAM WILL DYNAMICALLY MODIFY THE OSBORNE I
*	WITH 1.4 CBIOS AND 1.43 ROM TO PERMIT READ AND
*	WRITE OF KAYPRO II DOUBLE DENSITY DISKETTES.
*
*	KAYPRO II SINGLE SIDED DOUBLE DENSITY DISKETTES
*	ARE FORMATTED AS FOLLOWS:
*
*		40 TRACKS
*		10 BLOCKS PER TRACK
*		512 BYTES PER BLOCK
*		BLOCKS NUMBERED FROM 0 THROUGH 9
*		BLOCKS HARD INTERLACED AS FOLLOWS:
*			0,8,3,6,1,9,4,7,2,5
*		1 SYSTEM TRACK
*		64 ENTRY DIRECTORY
*
*	EQUATES TO 1.4 CBIOS LOCATIONS
*
SIGNON	EQU	0E561H	;LOCATION OF SIGN-ON MESSAGE
DPH0DPB	EQU	0E20AH	;DRIVE 0 DPB ADDRESS POINTER
DPH0CSV	EQU	0E20CH	;DRIVE 0 DPH CHECK SUM VECTOR ADDRESS
DPH0ALV	EQU	0E20EH	;DRIVE 0 DPH ALLOCATION VECTOR ADDRESS
DPH1DPB	EQU	0E21AH	;DRIVE 1 DPB ADDRESS POINTER
DPH1CSV	EQU	0E21CH	;DRIVE 1 DPH CHECK SUM VECTOR ADDRESS
DPH1ALV	EQU	0E21EH	;DRIVE 1 DPH ALLOCATION VECTOR ADDRESS
XTAB6AD	EQU	0E22AH	;ADDRESS FOR USER DEFINED XLATE TABLE
USERDPB	EQU	0E2EEH	;ADDRESS FOR USER DEFINED DPB
NSEKTYP	EQU	0E90CH	;NEW LOCATION FOR SEKTYP
NHSTTYP	EQU	0E90DH	;NEW LOCATION FOR HSTTYP
NXLTKEY	EQU	0E90EH	;NEW LOCATION FOR XLTKEY
ALV0	EQU	0E910H	;NEW ALLOCATION VECTOR DRIVE 0
ALV1	EQU	ALV0+25	;NEW ALLOCATION VECTOR DRIVE 1
CSV0	EQU	ALV1+25	;NEW CHECK VECTOR DRIVE 0
CSV1	EQU	CSV0+16	;NEW CHECK VECTOR DRIVE 1
ACTSEC	EQU	0EF14H	;ACTIVE SECTOR
ACTDSK	EQU	0EF17H	;ACTIVE DISK
*
*	CP/M EQUATES
*
BDOS	EQU	5	;ENTRY TO BDOS
WRSTR	EQU	9	;STRING TO CONSOLE FUNCTION
RESET	EQU	13	;RESET ALL DRIVES
*
	ORG	100H
	MACLIB	Z80		;Z80 MNEMONICS
$*MACRO
	PAGE
*
*	VALIDATE WE ARE USING 1.4 CBIOS
*
	LXI	H,SIGNON	;MESSAGE IN CBIOS
	LXI	D,SIGNMSG	;MESSAGE IN THIS PROGRAM
	MVI	B,SIGNL+1	;LENGTH OF MESSAGE
SIGNLOP	LDAX	D	;GET BYTE FROM PROGRAM
	CMP	M	;DOES CBIOS MATCH?
	JNZ	REJECT	;NO
	INX	H	;YES
	INX	D
	DJNZ	SIGNLOP
	JMP	ACCEPT	;CBIOS IS CORRECT ONE
REJECT	LXI	D,REJMSG	;WRONG VERSION OF CBIOS
	MVI	C,WRSTR	;STRING TO CONSOLE
	CALL	BDOS	;INFORM OPERATOR
	RET		;BACK TO CCP
REJMSG	DB	0DH,0AH,'THIS PROGRAM IS VALID ONLY '
	DB	0DH,0AH
	DB	'FOR THE 1.4 CBIOS AND A 59K SYSTEM$'
ACCEPT	LXI	H,0
	SHLD	XTAB6AD	;NO TRANSLATE TABLE
	LXI	H,DPB	;NEW DISK PARAMETER BLOCK
	LXI	D,USERDPB ;USER DPB IN CBIOS
	LXI	B,16	;BLOCK IS 16 BYTES LONG
	LDIR		;LOAD USER DPB
	LXI	H,ALV0	;NEW ALV0 ADDRESS
	SHLD	DPH0ALV	;PUT IN DPH
	LXI	H,CSV0	;NEW CSV0 ADDRESS
	SHLD	DPH0CSV	;PUT IN DPH
	LXI	H,ALV1	;NEW ALV1 ADDRESS
	SHLD	DPH1ALV	;PUT IN DPH
	LXI	H,CSV1	;NEW CSV1 ADDRESS
	SHLD	DPH1CSV	;PUT IN DPH
	LXI	D,NSEKTYP	;NEW ADDRESS OF SEKTYP
	LXI	H,SEKTYP	;ADDRESS OF TABLE
	MVI	B,SEKTYPN	;LENGTH OF TABLE
	CALL	SPRAY		;TRANSFER VALUES
	LXI	D,NHSTTYP	;NEW ADDRESS OF HSTTYP
	LXI	H,HSTTYP	;ADDRESS OF TABLE
	MVI	B,HSTTYPN	;LENGTH OF TABLE
	CALL	SPRAY		;TRANSFER VALUES
	LXI	D,NXLTKEY	;NEW ADDRESS OF XLTKEY
	LXI	H,XLTKEY	;ADDRESS OF TABLE
	MVI	B,XLTKEYN	;LENGTH OF TABLE
	CALL	SPRAY		;TRANSFER VALUES
	PAGE
*
*	PATCH TO INTERCEPT INCORRECT NUMBER OF BLOCKS
*	PER TRACK (6) AND SUBSTITUTE CORRECT NUMBER (10)
*
	LXI	H,PATCH1	;EXECUTION ADDRESS FOR PATCH 1
	SHLD	CPATCH1+1	;SET INTERCEPT IN CBIOS
	MVI	A,(JMP)
	STA	CPATCH1
	LXI	H,PAT1CODE	;CODE FOR PATCH 1
	LXI	D,PATCH1	;DESTINATION FOR PATCH 1
	LXI	B,LPATCH1	;LENGTH OF PATCH 1
	LDIR			;MOVE PATCH 1
;
*	PATCH TO NOT INCREMENT BLOCK NUMBER IF DRIVE
*	IN QUESTION IS THE KAYPRO DRIVE
*
	LXI	H,PATCH2	;EXECUTION ADDRESS FOR PATCH 2
	SHLD	CPATCH2+1	;SET INTERCEPT IN CBIOS
	MVI	A,(JMP)
	STA	CPATCH2
	LXI	H,PAT2CODE	;CODE FOR PATCH 2
	LXI	D,PATCH2	;DESTINATION FOR PATCH 2
	LXI	B,LPATCH2	;LENGTH OF PATCH 2
	LDIR			;MOVE PATCH 2
	MVI	C,RESET
	CALL	BDOS	;RESET DRIVES
	LXI	D,COMPMSG
	MVI	C,WRSTR
	CALL	BDOS	;ACKNOWLEDGE SUCCESSFUL COMPLETION
	RET		;RETURN TO CCP
COMPMSG	DB	0DH,0AH,'Kaypro II Double Density '
	DB	'Diskettes are now valid.$'
	PAGE
*
*	SUBROUTINE TO PUT NEW VALUE AT ADDRESSES SECURED
*	FROM A TABLE
*
*		DE = NEW VALUE
*		HL = ADDRESS OF TABLE
*		B  = NUMBER OF ENTRIES IN TABLE
*
SPRAY	PUSH	D	;SAVE NEW VALUE
SPRAY1	MOV	E,M	;GET LOW BYTE OF ADDRESS
	INX	H
	MOV	D,M	;GET HIGH BYTE OF ADDRESS
	INX	H
	XTHL		;HL = NEW VALUE, ADDR TABLE ON STACK
	XCHG		;HL = DESTINATION, DE = NEW VALUE
	MOV	M,E	;LOW BYTE OF NEW VALUE TO MEMORY
	INX	H
	MOV	M,D	;HIGH BYTE OF NEW VALUE TO MEMORY
	XCHG		;HL = NEW VALUE
	XTHL		;HL = TABLE ADDRESS, NEW VALUE ON STACK
	DJNZ	SPRAY1	;PROCESS NEXT TABLE ENTRY
	POP	D	;FIX STACK
	RET
*
*	KAYPRO II DISK PARAMETER BLOCK (DPB)
*
DPB	DB	8	;OSBORNE CODE FOR DD 512 BYTE BLOCKS
	DW	40	;40 128 BYTE RECORDS PER TRACK
	DB	3	;1K BLOCK SHIFT FACTOR
	DB	7	;1K BLOCK MASK
	DB	0	;1K EXTENT MASK
	DW	194	;195K - 1 DISK CAPACITY
	DW	63	;64 - 1 DIRECTORY ENTRIES
	DB	0F0H	;ALLOCATION 0 (2 BLKS RESERVED FOR CBIOS)
	DB	0	;ALLOCATION 1
	DW	16	;CHECK VECTOR
	DW	1	;SYSTEM TRACKS
	PAGE
*
*	SIGN-ON MESSAGE FOR 1.4 CBIOS (59K)
*
SIGNMSG	DB	SIGNL	;LENGTH OF MESSAGE
	DB	'Z'-40H
	DB	'Osborne Computer System'
	DB	0DH,0AH
	DB	'59k CP/M vers 2.2'
	DB	0DH,0AH
	DB	'CBIOS 1.4'
	DB	0DH,0AH
SIGNL	EQU	$-SIGNMSG-1
*
*	TABLE OF ADDRESSES USING LABEL SEKTYP WHICH
*	MUST BE MOVED TO MAKE ROOM FOR EXPANDED VECTORS
*
SEKTYP	DW	0E37BH
	DW	0E5DAH
	DW	0E648H
	DW	0E67BH
	DW	0E6B0H
SEKTYPN	EQU	($-SEKTYP)/2	;NUMBER OF ENTRIES
*
*	TABLE OF ADDRESSES USING LABEL HSTTYP WHICH
*	MUST BE MOVED TO MAKE ROOM FOR EXPANDED VECTORS
*
HSTTYP	DW	0E678H
	DW	0E6B3H
	DW	0E6DCH
HSTTYPN	EQU	($-HSTTYP)/2	;NUMBER OF ENTRIES
*
*	TABLE OF ADDRESSES USING LABEL XLTKEY WHICH
*	MUST BE MOVED TO MAKE ROOM FOR EXPANDED VECTORS
*
XLTKEY	DW	0E7BDH
	DW	0E7ECH
XLTKEYN	EQU	($-XLTKEY)/2	;NUMBER OF ENTRIES
	PAGE
*
*	PATCH 1 TO FIX NUMBER OF BLOCKS PER TRACK
*
PAT1CODE CALL	0E490H	;GET DENSITY OF DRIVE
	JNZ	0E48AH	;UNFORMATTED DISKETTE
	MVI	A,6	;IS THIS A KAYPRO II?
	CMP	B
	JNZ	CPATCH1+5	;NO, RELEASE INTERCEPT
	MVI	B,10	;YES, SET CORRECT NUMBER OF BLOCKS
	JMP	CPATCH1+5	;RELEASE INTERCEPT
LPATCH1	EQU	$-PAT1CODE	;LENGTH OF PATCH
CPATCH1	EQU	0E431H	;INTERCEPT LOCATION FOR PATCH 1
PATCH1	EQU	0E980H	;EXECUTION ADDRESS FOR PATCH 1
*
*	PATCH 2 TO MAKE PHYSICAL SECTOR START AT 0 INSTEAD OF 1
*
PAT2CODE PUSH	PSW	;SAVE A & FLAGS
	PUSH	D
	LXI	H,DPH0DPB	;ADDRESS OF DRV 0 DPB POINTER
	LDA	ACTDSK		;GET ACTIVE DISK NUMBER
	CPI	0		;DISK 0?
	JRZ	PAT2C1		;YES, POINTER IS CORRECT
	LXI	H,DPH1DPB	;NO, ADDR OF DRV 1 DPB POINTER
PAT2C1	MOV	E,M		;GET ACTIVE DPB ADDRESS
	INX	H
	MOV	D,M
	LXI	H,USERDPB+1	;ADDR OF KAYPRO DPB
	DSBC	D		;DO THEY MATCH?
	POP	D		;RESTORE DE
	LXI	H,ACTSEC	;POINT TO ACTIVE SECTOR
	JRZ	PAT2C2		;YES, THEY MATCH
	POP	PSW		;NO, NORMAL OSBORNE DISK
	JMP	CPATCH2+3	;RESUME NORMAL PROCESSING
PAT2C2	POP	PSW
	JMP	CPATCH2+4	;KAYPRO, BYPASS SECTOR INCREMENT
LPATCH2	EQU	$-PAT2CODE	;LENGTH OF PATCH
CPATCH2	EQU	0E6EDH	;INTERCEPT LOCATION FOR PATCH 2
PATCH2	EQU	PATCH1+LPATCH1	;EXECUTION ADDRESS FOR PATCH 2
	END
 OF PATCH
CPATCH2	EQU	0E6EDH	;INTERCEPT LOCATION FOR PA