;BDISK.Z80	TRiPsoft 02/04/88
;
;Programme to patch the Amstrad CPM+ XDPB to access 80 trk DS DD
;drives connected as Drive B:
;
;NOTE: The EMS file must be patched using one of the routines
;BPAT.SUB or BCPAT.SUB prior to running this programme
;Also discs must be formatted with FM.COM prior to use
;
;Feel free to use the programme for non-commercial use.
;No reposability is accepted for loss or damage arising from
;the use of these programmes.
;
WRMLOC	EQU	1		;location of warmboot vector
INSLEN	EQU	3
BDOS	EQU	5		;BDOS jump
BDSLOC	EQU	6		;location of BDOS jump table
CR	EQU	13
LF	equ	10
DPBLEN	EQU	001BH		;length of Disk Parameter Block
USROFF	EQU	0057H		;offset to warm boot for USERF function
dbuff	equ	05Dh		;FCB1 for command tail
DDSETP	EQU	0083H
COMMON	EQU	0C000H		;address of common memory in CPM +
XDPBB	EQU	0FF7FH		;address of drive B: XDPB
COL	EQU	12		;colour for border change after
				;format change


	ORG	0100H		;start programme at TPA
START:
	JP	BEGIN
	DEFB	'TRiPsoft 020488.$'
BEGIN:
	LD	SP,NEWSTK	;set up stack for programme

;...... standard routine to check for CPM version

CPMCHK:
	LD	C,0CH
	CALL	BDOS
	LD	A,'0'		; 30
	SUB	L
	JR	C,OVER		;ok then get on with it
	LD	DE,PLUSMSG
	CALL	PSTRIN
	RST	0		;quit to re-boot if not CPM+
OVER:
;...	Check for command tail argument

	LD	A,(dbuff)
	CALL	UPCAS		;make uppr case
	CP	'A'
	JR	C,goask		;char too low
	CP	'C'
	JR	NC,goask	;char	too high
	JP	MAKSEL		;go and select it
goask:
	LD	DE,OPTMSG	;option message
	CALL	PSTRIN		;and print it

;......routine to get key choice from keyboard and selet appropriate XDPB

GETKEY:
	LD	C,01H
	CALL	BDOS
	CALL	UPCAS
MAKSEL:
	PUSH	AF
	LD	DE,SETMSG
	CALL	PSTRIN
	POP	AF
	CP	'A'		; 31
	JR	Z,SDP1
	CP	'B'		; 32
	JR	Z,SDP2
	CP	'C'		; 33
	JR	Z,SDP3
	ld	c,09H
	ld	de,badkey
	call	bdos
	JR	GETKEY

SDP1:	ld	de,FM1MSG
	CALL	PSTRIN
	LD	HL,DPB1
	JP	ALTDPB

SDP2:	LD	DE,FM2MSG
	CALL	PSTRIN
	LD	HL,DPB2
	JP	ALTDPB

SDP3:	LD	DE,FM3MSG
	CALL	PSTRIN
	LD	HL,DPB3

;.... install patch into XDPB

ALTDPB:				;patch the dpb with the chosen parameters
	LD	DE,XDPBB	;destination
	LD	BC,DPBLEN	;length
	LDIR			;moveit

;routine to check for RSX's or other memory conflicts
;
CHKRSX:
	LD	HL,(BDSLOC)
	LD	BC,COMMON+6
	OR	A
	SBC	HL,BC
	JR	NC,OVER2	;all ok so get on with it again
	LD	DE,RSXMSG
	CALL	PSTRIN
	RST	0		;quit to cpm re-boot

OVER2:
	LD	HL,(WRMLOC)	;get address of BDOS warm boot vector
	LD	BC,USROFF	;offset for USERF
	ADD	HL,BC		;add them
	LD	DE,JMPLOC	;and store in this code for future use
	LD	BC,INSLEN	;3 bytes (for call XX XX)
	LDIR
	LD	HL,DDSETP	;move address into jump location
	LD	(DSKPARM),HL	
	LD	HL,DATTBL	;data to be put in common memory
	LD	B,07H		;length of data
	LD	DE,COMMON	;destination
	PUSH	DE		;save dest on stack
	LDIR			;move data
	POP	HL		;and get dest into HL
	CALL	JMPLOC		;execute function as inline parameter
DSKPARM:
	NOP
	NOP

;routine to set order to inform of disk format change

	ld	ix,(001)	;warm boot
	ld	de,87		;userf offset
	add	ix,de
	ld	b,12
	ld	c,12
	call	jump
	defw	00ceh		;te set_border
;
	jp	0		;quit to cpm
;
jump:	jp	(ix)
	ret
;
JMPLOC:
	NOP
	NOP
	NOP

	RET
;....	parameter table for disk setup command via rom

DATTBL:				;parameters in 100 millisecond units
	DB	0AH		;motor on timeout
	DB	'2'		;motor off timeout
				;parameter in 10 millisecond units
	DB	0AFH		;write current off time
				;parameters in 1 millisecond units
	DB	1EH		;head settle time
	DB	0AH		;step rate
				;parameter in 32 millisecond units
	DB	0FH		;head unload delay
	DB	3		;bits 7-1 head load delay
				;bit 0 dma mode as in
				;SPECIFY command

;...	disk parameter blocks for the three formats
;	these are constucted as follows
;
	DEFB	80		;TRACKS
	DEFB	9		;SECTORS/TRACK
	defb	0c1h		;FIRST SEC NO
	DEFB	00,02		;SECTOR SIZE
	DEFB	42,82		;TIMING R/W & FORMAT
	DEFB	060H		;MFM MODE BYTE
	defb	0FFh		;freeze byte to allow auto 
				;format selection
DPB1:
	DB	028h,00		;spt
	DB	4		;bsh
	db	0FH		;blm
	db	0		;exm
	db	7FH,1		;dsm
	db	7FH,0		;drm
	db	0C0H,0		;al0,al1
	DB	020h,00		;cks
	DB	0,0		;off
	db	2		;psh
	db	3		;phm
	db	1		;sidedness
	DB	50H		;tracks
	DB	0AH		;sectors/track
	DB	041H		;first sect no
	DB	0,2		;sector size
	DB	9		;gap length read/write
	db	011H		;gap length format
	DB	060H		;MFM mode flag
	DB	0FFH		;freeze flag
DPB2:
	DB	028H,0
	DB	4,0FH,0
	db	8FH,1
	db	7FH,0
	db	0C0H,0
	DB	020h,0
	DB	0,0
	db	2,3
	db	1
	DB	50H
	DB	0AH
	DB	041H
	DB	0,2
	db	9
	db	011H
	DB	060H
	DB	0FFH
DPB3:
	DB	028H,0
	DB	4,0FH,0
	db	8FH,1
	db	0FFH,0
	db	0F0H,0
	DB	020H,0
	DB	0,0
	db	2,3
	db	1
	DB	050H
	DB	0AH
	DB	041H
	DB	0,2
	DB	9
	db	011H
	DB	060H
	DB	0FFH

;..... Utility subroutines

PSTRIN:	PUSH	BC
	LD	C,09
	CALL	BDOS
	POP	BC
	RET

;....	check for uppercase and convert if necessary
UPCAS:	CP	'Z'+7
	JR	C,UPOK		;already upper case
	AND	05FH		;convert to upper case
UPOK:	RET


;......Message area

OPTMSG:
	DB	'BDISK.COM V 1.0 for Amstrad CP/M Plus ',cr,lf
	DB	'Disk format changer for 80 track B: drives',CR,LF,lf
	DB	'Formats available:',cr,lf
	DB	'A - 764K with 128 directory entries',CR,LF
	DB	'B - 796k with 128 directory entries',CR,LF
	DB	'C - 792k with 256 directory entries',CR,LF
	db	cr,lf,'Usage BDISK<return> will show this menu',cr,lf
	db	'BDISK x<return> where x is A B or C will auto-',cr,lf
	db	'select the format required',cr,lf
	DB	CR,LF,'Press A B or C to select format:',cr,lf,'$'

;.....	error messages

PLUSMSG:
	DB	'BDISK.COM will not run in this evironment',cr,lf
	DB	'CP/M + (3.1) required',7,cr,lf,lf,'$'
RSXMSG:
	DB	'Not Enough Free Common memory available for BDISK',cr,lf
	DB	'Clear RSX',02CH,'s etc before running BDISK',7,cr,lf,'$'
BADKEY:	DB	' Bad key pressed - incorrect choice ',7,CR,'$'


;...	format messages

SETMSG:	DB	cr,lf,'Setting Drive B: for - $'
FM1MSG:	DB	'764K with 128 directory entries',CR,LF,'$'
FM2MSG:	DB	'796k with 128 directory entries',CR,LF,'$'
FM3MSG:	DB	'792k with 256 directory entries',CR,LF,'$'


	DS	64		;space for stack
NEWSTK:
	END
ctory entries',CR,LF,'$'
FM3MSG:	DB	'792k with 256 directory entries'