; This is Version 2.3 of Configure Disk (requires Z80 Emulator 1.0.28 and up)
;	it no longer sets all parameters. 
;	old configure disk set all disk parameters whether they were used or not
;
; for use with bios22Dv22 and bios22Dv23, so chk vectors for hard disks are set to (drm+1)/4
;
; WARNING-- BIOS22Dv22 is modified to prevent older versions of this program from working
; The magic has changed.... (location)like-wise this program wont work on old BIOS22D
;
; This program will configure the Z80 Emulator to access various Disk Images
; from OTHER emulator Packages... 
; IT DOES NOT CONFIGURE THE EMULATOR TO RUN THE DISKS
;   YOU CAN READ/WRITE THE CONTENTS OF THE DISKS, 
;   BUT THE SOFTWARE ON THOSE DISKS WILL NOT RUN ON THE EMULATOR, 
; 	UNLESS THEY ARE FOR A MACHINE SUPPORTED BY THE Z80 EMULATOR
;
; WARNING----IMD disks are NOT processed correctly by this program..
;     use configure disk for IMD files.
;
;WARNING-- this program requires a Custom BIOS(BIOS22Dv22.asm) and works with CPM2.2 only, 
;   which reserves extra space for the XLTs, DPBs, ALL, CHK vectors
;WARNING--do not define formats that use more than the available space in 
; XLT tables, CHK vectors and allocation Vectors..
;
;	XLT	CHK	ALL
; A:-P:	256	512	512
;   this provides room for up to 8mb and 2048 directory entries.
; XLT is always at 0xFA00 for every drive
;  because, each drives parameters is kept in a differrent bank.
; A: in bank 0, B: in bank 1, etc, etc P: in bank 15
;
; Changing Drive A: is possible.... but dangerous, 
;   you can change it if you know enough.
;
;	XLTs can be 1 or zero based, will convert 0 to 1 base during injection
;
;(note-most BIOSes put a pointer to a shared DPB for disks that are Identical)
;
; This program can be modified to work with ANY BIOS that uses separate DPBs
;   for each disk
; Or if you want to change multiple disks at a time, it will work
;   with ANY BIOS whether or NOT there's individual DPBs.
; The program simply writes new DPB info into the DPB 
;   pointed to by the DPH (returned after SELDSK)
; It then writes new data to the an area for the XLT and 
;   then puts that address in the DPH
; It then reprograms the Z80 Emulator's Disk Controller for the type disk
; IT is designed to run with BIOS22Dv2.ASM. BIOS22Dv2.ASM has areas reserved 
;   specifically for this program
;
; This program sets sector size to 128 and then uses a modified XLT 
;        to access large sectors as 128 bytes, using the z80 emulator's auto-deblock
;
;This program requires AS8080 to assemble (symbols violate ASM/MAC rules)

	org 	100h

true	equ	-1
false	equ	not true

AS8080		equ	true

	if 	AS8080
		z80
	else
		maclib	z80
	endif

bdos	equ	05h

	jmp	start

;Storage used for testing OS version

bdos$ver 	dw	0
mpm$ver		dw	0
dir$bio		db	0	; direct bios bdos-0=no-1=yes
run$msg		db	'Running under $'
cpm$msg		db	'CP/M $'
mpm$msg		db	'MP/M $'
II$msg		db	'II $'
pri$msg		db	'Prior to 2.0$'
ukn$msg		db	'Unknown System$'
ext$msg		db	'Exiting$'
bds$msg 	db	'BDOS $'
msd$msg		db	'0.'
lsd$msg		db	'0 $'
noDB$msg 	db	'No '
DB$msg 		db	'BDOS Direct BIOS Support$'
bad$msg		db	'Can not run on this configuration$'
msg.die		db	CR,LF,LF
		db	"Requires Z80 Emulator Version 1.0.28 or higher$"
msg.cpu		db	CR,LF,LF
		db	"Requires Z80 CPU$"
NO$MAGIC	db	CR,LF,LF
		db	"NO MAGIC Requires Special BIOS22Dv22.ASM or v23 to run$"

BS.DSK	EQU	01BH

DSK$REG$SEL	equ	0cah
DSK$REG$LOW	equ	0c8h
DSK$REG$HI	equ	0c9h

CR		equ	13
LF		equ	10

crlf		db	CR,LF,'$'

; Storage for Program

Opening		db	cr,lf,"Configure Disk Version 2.3 for Z80 Emulator 1.0.28 and up$"
Trm$Msg		db	"Finished",CR,LF,'$'
Ask$disk	db	"Select Disk to be reconfigured(letter only)....B through P - $"
Ask$Type	db	"Select Disk type (two hex characters)- $"
Notice		db	cr,lf
		DB	"This program will temporarily reconfigure a disk drive to access specific"
		db	cr,lf
		db	"  types of disks. The NEW configuration will remain in effect until the next"
		db	cr,lf
		db	"  COLD BOOT. You can read and write the disks. "
		db	cr,lf,cr,lf
		db	"NOTE- CDOS disk images are supported by DCC.COM"
		db	cr,lf
		db	"NOTE- Correct Jade disk images are supported by DCJ.COM"
		db	cr,lf,'$'

DiskNumber 	db	0
DiskType	db	0
Stack$Save	dw	0

DPB		dw	0
DPH		dw	0
XLT		dw	0
SPT		dw	0

;-------------------------
start:
	sspd	Stack$Save
	lxi	sp,Stack
	lxi	d,run$msg
	call	print

;-------------------------
; check for proper CPM/MPM version

; Check for CPM prior to 2, we can not use CPM prior to 2

	mvi	c,0ch		;get CPM/bdos version
	call	bdos
	shld	bdos$ver

chk$old	xra	a
	cmp	l		;L=0 for cpm prior to 2.0
	jnz	chk$cpm
	lxi	d,cpm$msg	;CPM
	call	print
	lxi	d,pri$msg	;old CPM
	call 	print
badexit call 	printNL
	lxi	d,bad$msg	;Can not run on old CPM
	call	print
	call	printNL		;newline
exit:	lxi	d,ext$msg	;tell them about exit
	call 	print
	call	Exit$PGM
	jmp	0		;warm boot
	
chk$cpm	xra	a
	cmp	h		;H=0 for CPM
	jnz	chk$mpm
	lxi	d,cpm$msg	;CPM 
	call	print
	lda	bdos$ver	;get saved bdos version
	call	cnv$htd		;convert to ascii
	lxi	d,msd$msg
	call	print
	lda	bdos$ver	;get saved bdos version
	cpi	030h		;>=3.0 has direct bios in bdos
	jnc	no$dbios
	mvi	a,1
	sta	dir$bio		;set direct bios flag
no$dbios:
	jmp	GOT$CPM2or3

; check for MPM, but can not run on MPM

chk$mpm	mvi	a,01h		;H=1 for MPM
	cmp	h
	jnz	unknown		;something's weird
	lxi	d,mpm$msg	
	call	print
	mvi	c,0a3h		;get MPM version
	call	bdos
	shld	mpm$ver
	xra	a		;H=0 for MPM 1
	cmp	h
	jnz	chk$mII
	jmp	badexit		;MPM
chk$mII
	mvi	a,1		;H=1 for MPM 2
	cmp	h
	jnz	unknown
	lxi	d,II$msg	;MPM II
	call 	print
	lda	mpm$ver
	call	cnv$htd		;convert to ascii
	lxi	d,msd$msg	;print MPM version
	call	print

	lxi	d,bds$msg	;print bdos indicator
	call	print
	lda	bdos$ver	;get saved bdos version
	call	cnv$htd		;convert to ascii
	lxi	d,msd$msg	;print bdos version
	call	print
	jmp	badexit

unknown	lxi	d,ukn$msg	;unknown OS
	call	print
	jmp	badexit

;Got something we can use CPM 2 or 3 (both require special bios)

GOT$CPM2or3:
	call	printNL		;newline
	lda 	dir$bio		;get saved direct bios flag
	ana	a
	jz	noDB
	lxi	d,nodb$msg	;tell no direct bios
	jmp	yesDB
noDB:
	lxi	d,db$msg	;tell direct bios available
yesDB:	call	print

;-------------------------
; check for proper emulator version

; if major and minor and rev = 0 then bad
; if rev=0xff then bad
; z80 Emulators prior to 1.0.17 return unused port value of 0 or 0xff

	in 	0xc4		;read major number
	cpi 	0		;port c4 not implemented in wrong vers
	jnz	NOT_000
	in 	0xc5		;read minor number
	cpi 	0		;port c5 not implemented in wrong vers
	jnz	NOT_000
	in 	0xc6		;read revision number
	cpi 	0		;port c6 not implemented in wrong vers
	jz	Ver.Bad
NOT_000	cpi	0xff		;returns either 0 or ff if bad
	jz	Ver.Bad

; Versioning ports available so find out what version
; We can run on Version 1.0.22 or greater using NEW disk interface

	in 	0xc4		;read major number
	cpi	1
	jc	Ver.Bad
	in 	0xc5		;read minor number
	cpi	0
	jc	Ver.Bad
	in 	0xc6		;read minor number
	cpi	28
	jc	Ver.Bad
	jmp	Ver.OK
Ver.Bad	lxi	de,msg.die	;death message
	call	PrintDE		;out message
	call	Exit$PGM	;exit if bad so disks dont get trashed
	jmp	0			
Ver.OK

;-------------------------
; check CPU (we need z80)

	in 	0c2h
	cpi	0
	jz	cpu.OK
	lxi	de,msg.cpu	;death message
	call	PrintDE		;out message
	call	Exit$PGM	;exit if bad so disks dont get trashed
	jmp	0			

cpu.Ok

;-------------------------
; check for correct BIOS
;  Correct Bios contains Magic 76,'2','1' at BIOS+036h

	LDA	BS.PAG
	MOV	H,A
	mvi	L,036h
	mov	a,m
	CPI	076H
	JNZ	GotNoMagic
	inx	hl
	mov	a,m
	CPI	'2'
	JNZ	GotNoMagic
	inx	hl
	mov	a,m
	CPI	'2'
	JNZ	GotNoMagic
	jmp	RunPGM

GotNoMagic
	lxi	de,NO$MAGIC
	call	PrintDE
	call	Exit$PGM
	jmp 	0
;-------------------------

RunPGM:	

	call	NewLine
	lxi	d,Opening
	call 	PrintDE
	call	NewLine
	lxi	d,Notice
	call 	PrintDE

;find out what disk user wants to configure

Get.SelDisk:
	call	NewLine
	LXI 	d,Ask$disk
	CALL	PrintDE
	CALL	ReadOne

	cpi	'a'
	jc 	notLC	;LT a
	cpi	'q'
	jnc	notLC	;GTE q or GT p

	jmp	Got$diskLC
notLC
	cpi	'A'
	jc 	notUC	;LT A
	cpi	'Q'
	jnc	notUC	;GTE Q or GT Q
	
	jmp 	Got$disk
notUC
	call 	NewLine
	jmp 	Get.SelDisk

Got$diskLC
	sui	'a'-'A'
Got$disk
	sui	'A'
	sta	DiskNumber
	

;-------------------------
;Find out what the user wants to configure disk as
; supports two digit hex value-- 0-9 and a-f ..
	call	NewLine
	call 	PrintMenu

Get.Type:
	Call	NewLine
	LXI 	d,Ask$Type
	CALL	PrintDE

	CALL	ReadOne		;read first char
	call	CHK.Valid
	
	cpi	0ffh
	jz	NOT$Type

	rlc
	rlc
	rlc
	rlc
	
	mov b,a

	CALL	ReadOne		;read second char
	call	CHK.Valid
	
	cpi	0ffh
	jz	NOT$Type

	ora	b	

	cpi	NumberOfDisks
	jc	Got$Type

NOT$Type
	call 	NewLine
	jmp 	Get.Type

Got$Type

	sta	DiskType

;-------------------------
; Get pointers to internal data in BIOS for disk config

;get DPH
	lda	DiskNumber
	mov	c,a
	call	SelDisk		; bios call returns DPH in HL
	shld	DPH
;get XLT (not needed, we use predefined locations for all, since could be 0000h)
	mov	e,m		;First entry in DPH points to XLT
	inx	hl
	mov	d,m
	sded	XLT
;get DPB
	lhld	DPH		;DPH + 10 points to DPB
	lxi	de,10
	dad	de
	mov	e,m
	inx	hl
	mov	d,m
	sded	DPB

;get SPT for XLT length 

;get SPT
	lhld	DPB		;First entry in DPB is SPT
	mov	e,m
	inx	hl
	mov	d,m
	sded	SPT

;-------------------------
; load disk config from EDP table
; this routine writes new disk config data from programs data tables
;   to the Z80 Emulator's Disk Controller config registers
	
;select drive
	lda	DiskType	
	call 	GetEDPptr	;get HL=EDPptr

	mvi	a,018h	;select
	out	DSK$REG$SEL
	lda	DiskNumber	
	out	DSK$REG$LOW

; config the disk

;hl should be ED pointer	

another	mov	a,m	;got size 1=low 2=low/high and FF=finished
	cpi	0ffh
	jz	finished
	cpi	2
	jz	do2
do1	inx	hl
	mov	a,m	;got register selector in a
	out	0cah	;out to select port
	inx	hl
	mov	a,m	;got value to out to register
	out 	0c8h	; out to low reg
	inx	hl
	jmp 	another
do2	inx	hl
	mov	a,m	;got register selector in a
	out	0cah	;out to select port
	inx	hl
	mov	a,m	;got value to out to low register
	out 	0c8h	; out to low reg
	inx	hl
	mov	a,m	;got value to out to high register
	out 	0c9h	; out to high reg
	inx	hl
	jmp 	another
finished


;set parameters
	mvi	a,000h	;select command Reg
	out	DSK$REG$SEL
	mvi	a,07fh	;command is NULL but causes parameters to be set
	out	DSK$REG$LOW

;-------------------------
;inject DPB from internal program area to DPB in BIOS
; assume CPM 2
; NEEDs work to run on CPM 3 (plus special BIOS)

DPBsize	equ	15	;17 for CPM3

	lda	DiskType	
	call	GetDPBptr	;hl=internal DPB
	lded	DPB		;de=DPB in bios
	lxi	b,DPBsize	;size of dpb
	ldir

; get SPT from internal DPB

	lda	DiskType	
	call	GetDPBptr	;hl=internal DPB
	mov	e,m		;SPT is first entry in DPB
	inx	hl
	mov	d,m
	sded	SPT		;SPT = new SPT

;get XLT pointer from internal table

	lda	DiskType	
	call	GetXLTptr
	mov	a,h
	ora	l
	jz	no$XLT		;zero if no XLT used
	
	lxi	d,0xFA00
	lhld	DPH		;set DPH's XLT to value in DE
	mov	m,e
	inx	hl
	mov	m,d

;DE=pointer to XLT in Bios
	lda	DiskType
	call	GetXLTptr	;HL=internal XLT, a= 0 or 1 based
	lbcd	SPT		;count of sectors/bytes in XLT
	cpi	0
	jz	ZeroBase
OneBase	ldir
	jmp	Exit$Here

ZeroBase
	mov	a,m
	inr	a		; for zero based XLTs
	stax	d
	inx	h
	inx	d
	dcx	b
	mov	a,b
	ora	c
	jnz	ZeroBase

	jmp	Exit$Here

no$XLT	lhld	DPH		;set DPH's XLT to 0
	mvi	m,0
	inx	hl
	mvi	m,0

;-------------------------
;Must exit here if after SELDISK Call
Exit$here
	mvi	c,13		;reset disk system
	call	bdos

	call	Exit$PGM
	jmp 	0		;should never happen

;-------------------------
; this get entered by Cntrl-C check in ReadOne
; also by normal Exit$Here
; it does NOT return to PGM
; Can exit here only if before SELDSK call

Exit$PGM:
	call	NewLine
	lxi	de,Trm$Msg
	call	PrintDE
	lspd	Stack$Save
	ret			; this should return to CPM
;-------------------------
;Entry	
;	C=disk
;Return
;	HL=ptr to DPH

SelDisk
	push	de
	push	bc
	push	a
	mvi	L,bs.dsk
	call	bios
	pop	a
	pop	bc
	pop	de
	ret

;-------------------------
BS.PAG	EQU	02H

;BIOS TRANSFER ROUTINE

BIOS	LDA	BS.PAG
	MOV	H,A
	PCHL
;-------------------------

; CONSOLE LINKAGE - BDOS CALLS

CNS.RD	EQU	1
CNS.WR	EQU	2

CNTL.C	EQU	3
REBOOT	EQU	0

ReadOne:
	push	b
	push	d
	push	h
	MVI	C,CNS.RD
	CALL	BDOS
	pop	h
	pop	d
	pop	b
	ANI	07FH
	CPI	CNTL.C
	CZ	Exit$PGM
	RET
	
WriteOne:
	PUSH	H
	MOV	E,A
	MVI	C,CNS.WR
	CALL	BDOS
	POP	H
	RET
	
;-------------------------
;entry 
;	A=char
;return 
;	HEX character value or FF if bad

Valid$Chars
	db	'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
	db	'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
;   YES it checks 0-9 twice, but i dont care
CHK.valid	
	push	b
	push	h
	lxi	h,Valid$Chars+31
	mvi	b,16
..loop	
	cmp	m		;match?
	jz	Char$OK		;OK
	dcx	h		;point to next chars
	dcr	b		;dec count of characters
	jnz	..loop		;again

;	lxi	h,Valid$Chars+15
	mvi	b,16
..loop	
	cmp	m		;match?
	jz	Char$OK		;OK
	dcx	h		;point to next chars
	dcr	b		;dec count of characters
	jnz	..loop		;again
	
Char$OK	
	dcr	b
	mov	a,b
	pop	h
	pop	b
	ret

;-------------------------
;convert Binary in A to Hex 
HEX2:
HEX2H	db	030h
HEX2L	db	030h
	db	'$'
BIN2HEX:	
	push	a		
	push	a
	ani	0f0h
	rrc
	rrc	
	rrc
	rrc
	cpi	0ah
	jc	notA_FH
	adi	041h-03ah
notA_FH	adi	030h
	sta	HEX2H
	pop	a
	ani	0fh
	cpi	0ah
	jc	notA_FL
	adi	041h-03ah
notA_FL	adi	030h
	sta 	HEX2L
	pop	a
	ret

;-------------------------
PrintHEX2:
	push	de
	call	BIN2HEX
	lxi	de,HEX2
	call	PrintDE
	pop	de
	ret
;-------------------------

GetDiskEntryPtr:

;Entry
;	A=Disk Number
;Returns 
;	DE=entry size
;	HL=ptr to disk entry
;	A=0

	lxi	hl,DiskTable
	lxi	de,8
..loop	ora	a
	rz
	dad	d
	dcr	a
	jmp	..loop
;-------------------------
GetHLDEptr:

;Entry
;	DE= offset
;	HL=PTR
;Returns
;	hl=ptr at HL + DE

	dad	de
	mov	e,m
	inx	hl
	mov	d,m
	mov	h,d
	mov	l,e
	ret
;-------------------------
GetLABptr:

;Entry
;	A=Disk Number
;Returns
;	hl=ptr to disk LABEL

	push	de
	push	a
	call	GetDiskEntryPtr
	lxi	de,0
	call 	GetHLDEptr	
	pop	a
	pop	de
	ret
;-------------------------
GetDPBptr:

;Entry
;	A=Disk Number
;Returns
;	hl=ptr to disk DPB

	push	de
	push	a
	call	GetDiskEntryPtr
	lxi	de,4
	call 	GetHLDEptr	
	pop	a
	pop	de
	ret
;-------------------------
GetEDPptr:

;Entry
;	A=Disk Number
;Returns
;	hl=ptr to disk Emu Disk Configuration

	push	de
	push	a
	call	GetDiskEntryPtr
	lxi	de,2
	call 	GetHLDEptr	
	pop	a
	pop	de
	ret

;-------------------------
GetXLTptr:

;Entry
;	A=Disk Number
;Returns
;	hl=ptr to disk Emu Disk Configuration
;	a=0 or 1 based

	push	de
	call	GetDiskEntryPtr
	lxi	d,6
	call 	GetHLDEptr
	dcx	h
	mov	a,m
	inx	h
	pop	de
	ret
;-------------------------
PrintHL:
	push	de
	mov	e,l
	mov	d,h
	call	PrintDE
	pop 	de
	ret
;-------------------------
PrintDE:
	push	hl
	push	bc
	push	a
	mvi	c,9
	call	bdos
	pop	a
	pop	bc
	pop	hl
	ret
;-------------------------
NL	db	13,10,'$'
NewLine:
	push	de
	lxi	de,NL
	call	PrintDE
	pop	de
	ret
;-------------------------
SP	db	' ','$'
PrintSpace:
	push	de
	lxi	de,SP
	call	PrintDE
	pop	de
	ret
;-------------------------


PrintMenu:
	call	NewLine
	mvi	a,0
..loop	call	PrintHex2
	call	PrintSpace
	call	GetLABptr
	call	PrintHL
	call	NewLine
	inr	a
	cpi	NumberOfDisks
	jnz	..loop
;	call	NewLine
	ret
	
;-------------------------
;Print NewLine and Print

printNL	lxi	d,crlf
print:	
	mvi	c,09h
	jmp	bdos

;-------------------------
;convert to bcd
cnv$htd:			
	push	psw
	ani	0f0h
	rrc
	rrc	
	rrc
	rrc
	adi	030h
	sta	msd$msg
	pop	psw
	ani	0fh
	adi	030h
	sta	lsd$msg
	ret
;-------------------------
;DPBs/DISK configuration
;-------------------------

; Label,EMU Disk Parameters,DPB,XLT

DiskTable	
	dw 	PC1440L,PC1440P,PC1440D,0
	dw 	PC4104L,PC4104P,PC4104D,0
	dw 	PC8190L,PC8190P,PC8190D,0
	dw 	ibm8L,ibm8P,ibm8D,ibm8X
	dw 	jadeDDL,jadeDDP,jadeDDD,0
	dw	AppleIIL,AppleIIP,AppleIID,AppleIIX
	dw 	F1440L,F1440P,F1440D,0
	dw	mits2L,mits2P,mits2D,mitsX	;uses 137 byte sectors
	dw	mitsL,mitsP,mitsD,mitsX		;uses 137 byte sectors
	dw	mithdL,mithdP,mithdD,0 
	dw	UMHD4L,UMHD4P,UMHD4D,0
	dw	LBLD2N1,EPBD2N,DPBD2N1,0 
	dw	LBLD2N2,EPBD2N,DPBD2N2,0 
	dw	LBLD2N3,EPBD2N,DPBD2N3,0 

;	dw	UMHD512L,UMHD512P,UMHD512D,0 	;too big for CPM 2

NumberOfDisks	equ 	($-DiskTable)/8
;-------------------------
;the parameters used to configure the z80 emulator's disk controller 
;  may not be completly correct, but work with auto deblock to read and write disks...
; we always use a sector size of 128...
; we set XLT 4 at a time (for 512 byte sectors).. 
; we multiply number of real sectors by 4 (for 512 byte sectors)
;  and allow the z80 emulator to do the deblocking
; only disk images that require pre/post have the real sector size set,
;   but then only for deblocking , 
;   CPM still uses 128 byte sector size but emulator knows it is 512
;-------------------------

Set8	macro	?Register,?Value
	db	1,?Register,?Value
	endm
Set16	macro	?Register,?Value
	db	2,?Register
	dw	?Value
	endm
;----------------------------

; This format is wrong.. it uses 48 sectors for track 0 when it should be 26
; but this was the only way to do Jade disks prior to Z80 emulator version 1.0.17
jadeDDL
	db	"Jade Z80 Emulator- old Double Density format$"

jadeDDP:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,77	;Cylinders
	set8	0a1h,1	;Heads

	set8	0a3h,2	;density	(data) 	Double
	set16	0a4h,48	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,2	;clock		(data) 	8inch

	db	0ffh

jadeDDD
	DW    48	;sectors per track
	DB    4		;block shift factor
	DB    15	;block mask
	DB    1		;extent mask
	DW    224	;disk size-1
	DW    63	;directory max
	DB    080h	;alloc 0
	DB    0		;alloc 1
	DW    16		;check size
	DW    2		;track offset
	DB	0,0	;physical sector size and shift

;-------------------------
;  for Udo Munk's Z80SIM 4MB HD

UMHD4L	db	"Z80SIM 4MB HD$"

UMHD4P:
	set8	080h,0		;order
	set8	081h,0		;formatType
	set8 	082h,0		;DONT use prepost

	set16	09ah,0		;IDM flag	0

	set16	0a0h,255	;Cylinders
	set8	0a1h,1		;Heads

	set8	0a3h,0		;density	(data) 	Don't care
	set16	0a4h,128	;SPT		(data) 
	set8	0a5h,0		;Sector Size	(data) 	128
	set8	0a6h,1		;clock		(data) 	HD

	db	0ffh

UMHD4D	DW	128	;sectors per track
	DB	4	;block shift factor
	DB	15	;block mask
	DB	0	;extent mask
	DW	2039	;disk size-1
	DW	1023	;directory max
	DB	255	;alloc 0
	DB	255	;alloc 1
	DW	256	;check size
	DW	0	;track offset
	DB	0,0	;physical sector size and shift

;-------------------------
; not done - not used(to big for CPM 2.2)
UMHD512L	db	"Z80SIM 512MB HD$"

UMHD512P:
	set8	080h,0		;order
	set8	081h,0		;formatType
	set8 	082h,0		;DONT use prepost

	set16	09ah,0		;IDM flag	0

	set16	0a0h,256	;Cylinders
	set8	0a1h,1		;Heads

	set8	0a3h,0		;density	(data) 	Don't care
	set16	0a4h,16384	;SPT		(data) 
	set8	0a5h,0		;Sector Size	(data) 	128
	set8	0a6h,1		;clock		(data) 	HD

	db	0ffh

UMHD512D
	DW    16384	;sectors per track
	DB    7		;block shift factor
	DB    127	;block mask
	DB    0		;extent mask
	DW    7FFFH	;disk size-1
	DW    8191	;directory max
	DB    255	;alloc 0
	DB    255	;alloc 1
	DW    0H	;check size	
;	DW    8000H	;check size	CPM 3
	DW    0		;track offset
	DB    0,0	;physical sector size and shift
;-------------------------	
;default drive parametr block for IBM 3740

ibm8L	db	"Standard 8 IBM 3740 Single Sided Single Density$"

ibm8P:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,77	;Cylinders
	set8	0a1h,1	;Heads

	set8	0a3h,1	;density	(data) 	Single=1
	set16	0a4h,26	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,2	;clock		(data) 	8inch=2

	db	0ffh

ibm8D	dw	26		;spt
	db	3		;bsh
	db	7		;blm
	db	0		;exm
	dw	242		;dsm
	dw	63		;drm
	db	0c0h		;al0
	db	0		;al1
	dw	16		;cks
	dw	2		;off
	DB	0,0		;physical sector size and shift

;default drive parametr block for 3$5" pc1440

;-------------------------
PC1440L	db	"Z80 Emulator 3.5 PC1440$"

PC1440P:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,80	;Cylinders
	set8	0a1h,2	;Heads

	set8	0a3h,2	;density	(data) 	Double=2
	set16	0a4h,72	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128=0
	set8	0a6h,4	;clock		(data) 	3inch=4

	db	0ffh


PC1440D	dw	72		;spt
	db	4		;bsh
	db	15		;blm
	db	0		;exm
	dw	710		;dsm
	dw	255		;drm
	db	0f0h		;al0
	db	0		;al1
	dw	64		;cks
	dw	2		;off
	DB	0,0		;physical sector size and shift

;default drive parametr block for pc4104

;-------------------------
PC4104L	db	"Z80 Emulator PC4104$"

PC4104P:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,228	;Cylinders
	set8	0a1h,2	;Heads

	set8	0a3h,2	;density	(data) 	Double=2
	set16	0a4h,72	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128=0
	set8	0a6h,4	;clock		(data) 	3inch=4

	db	0ffh


PC4104D	dw	72		;spt
	db	4		;bsh
	db	15		;blm
	db	0		;exm
	dw	2042		;dsm
	dw	1023		;drm
	db	0ffh		;al0
	db	0ffh		;al1
	dw	256		;cks
	dw	2		;off
	DB	0,0		;physical sector size and shift

;default drive parametr block for pc8190

;-------------------------
PC8190L	db	"Z80 Emulator PC8190$"

PC8190P:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,445	;Cylinders
	set8	0a1h,2	;Heads

	set8	0a3h,2	;density	(data) 	Double=2
	set16	0a4h,72	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128=0
	set8	0a6h,4	;clock		(data) 	3inch=4

	db	0ffh


PC8190D	dw	72		;spt
	db	5		;bsh
	db	31		;blm
	db	1		;exm
	dw	2042		;dsm
	dw	2047		;drm
	db	0ffh		;al0
	db	0ffh		;al1
	dw	512		;cks
	dw	2		;off
	DB	0,0		;physical sector size and shift

;-------------------------
; NOTE order is 0,159,1,158,2,157 .... 77,82,78,81, 79,80
F1440L	db	"CPM-86 3.5 F144$"

F1440P:
	set8	080h,1	;order = cylinders, not sides
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,80	;Cylinders
	set8	0a1h,2	;Heads

	set8	0a3h,2	;density	(data) 	Double=2
	set16	0a4h,72	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128=0
	set8	0a6h,4	;clock		(data) 	3inch=4

	db	0ffh

F1440D	dw	72		;spt
	db	5		;bsh
	db	31		;blm
	db	1		;exm
	dw	354		;dsm
	dw	255		;drm
	db	0c0h		;al0
	db	0		;al1
	dw	64		;cks
	dw	2		;off
	DB	0,0		;phys and m

;-------------------------
AppleIIL	db	"Apple II$"

; NOTE these parameters work, but do not properly match the real parameters
; Works with IMage file from ALTAIRZ80 
; MAY NOT WORK WITH OTHER IMAGE FILES FOR APPLE II
; The Real disk had 16 256 byte sectors, 
;    but the Z80 Emu will auto deblock if the image file is just-right
; the trick is in the XLT table and setting SPT to 32 128 byte sectors

AppleIIP:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,35	;Cylinders
	set8	0a1h,1	;Heads

	set8	0a3h,0	;density	(data) 	dont care
	set16	0a4h,32	;SPT		(data) 	16
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,0	;clock		(data) 	dont care

	db	0ffh

AppleIID
	dw	32		; spt, sectors per track
	db	3		; allocation block shift factor, bsh
	db	7		; data allocation block mask, blm, allocation size (bls) = 2048
	db	0		; extent mask
	dw	0x7f		; dsm, maximum data block number
	dw	0x2f		; drm, number of directory entries - 1
	db	0C0h,0		; al0, al1, 4 blocks reserved to hold all entries
				; 256 * 32 = 4 * 2048
				; (drm+1) * 32 = (number of bits in al0 and al1) * bls
	dw	0Ch		; cks = (drm + 1)/4
	dw	3		; off, number of tracks skipped at beginning of disk
	db	0		; PSH
	db	0		; PHM
;-------------------------
mithdL	db	"AltairZ80 8MB SIMulated HD$"
mithdP	
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,0	;DONT use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,2048	;Cylinders
	set8	0a1h,1	;Heads

	set8	0a3h,0	;density	(data) 	Don't care
	set16	0a4h,32	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,1	;clock		(data) 	HD

	db	0ffh

mithdD	dw	32		; SPT, sectors per track
	db	5		; BSH, data allocation block shift factor, for BLS=4,096
	db	31		; BLM, data allocation block mask, for BLS=4,096
	db	1		; extent mask for BLS=4,096 and DSM>255
	dw	2047-6		; DSM, maximum data block number
	dw	1023		; DRM, number of directory entries - 1
	db	0ffh,0		; AL0, AL1, 8 blocks reserved to hold all entries
				; 1024 * 32 = 8 * 4096
	dw	256		; CKS, set 0 since hard disk is fixed
	dw	6		; OFF, number of tracks skipped at beginning of disk
	db	0		; PSH
	db	0		; PHM

;-------------------------	
;The following formats for the MITS fdc uses 137 byte sectors.
;-------------------------
; This disk has 128 byte sectors for CPM stored in 137 byte sectors with 9 extra bytes
mits2L	db	"AltairZ80 mits2$"

mits2P:
	set8	080h,0		;order
	set8	081h,0		;formatType
	set8 	082h,1		;use prepost

	set16	09ah,0		;IDM flag	0

	set16	0a0h,254	;Cylinders
	set8	0a1h,1		;Heads

	set8	0a3h,2		;density	(data) 	Double
	set16	0a4h,32		;SPT		(data) 
	set8	0a5h,0		;Sector Size	(data) 	128
	set8	0a6h,2		;clock		(data) 	8inch
	set8	0a8h,0		;pSector Size	(data) 	128

	set16	0d0h,0	;disk pre
	set16	0d1h,0	;disk post
	set16	0d2h,0	;track pre
	set16	0d3h,0	;track post
	set16	0d8h,3	;sector pre
	set16	0d9h,6	;sector post

	db	0ffh


mits2D	dw	32		; spt, sectors per track
	db	4		; allocation block shift factor, bsh
	db	15		; data allocation block mask, blm, allocation size (bls) = 2048
	db	0		; extent mask
	dw	0x1ef		; dsm, maximum data block number
	dw	255		; drm, number of directory entries - 1
	db	0f0h,0		; al0, al1, 4 blocks reserved to hold all entries
				; 256 * 32 = 4 * 2048
				; (drm+1) * 32 = (number of bits in al0 and al1) * bls
	dw	32		; cks = (drm + 1)/4
	dw	6		; off, number of tracks skipped at beginning of disk
	db	0		; PSH
	db	0		; PHM

;-------------------------
; This disk has 128 byte sectors for CPM stored in 137 byte sectors with 9 extra bytes
mitsL	db	"AltairZ80 mits$"
mitsP:
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,1	;use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,35	;Cylinders
	set8	0a1h,2	;Heads

	set8	0a3h,2	;density	(data) 	Double
	set16	0a4h,32	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,3	;clock		(data) 	5inch
	set8	0a8h,0	;pSector Size	(data) 	128

	set16	0d0h,0	;disk pre
	set16	0d1h,0	;disk post
	set16	0d2h,0	;track pre
	set16	0d3h,0	;track post
	set16	0d8h,3	;sector pre
	set16	0d9h,6	;sector post

	db	0ffh


mitsD	dw	32		; spt, sectors per track
	db	3		; allocation block shift factor, bsh
	db	7		; data allocation block mask, blm, allocation size (bls) = 1024
	db	0		; extent mask
	dw	254		; dsm, maximum data block number
	dw	255		; drm, number of directory entries - 1
	db	0ffh,0		; al0, al1, 8 blocks reserved to hold all entries
				; 256 * 32 = 8 * 1024
				; (drm+1) * 32 = (number of bits in al0 and al1) * bls
	dw	32		; cks = (drm + 1)/4
	dw	6		; off, number of tracks skipped at beginning of disk
	db	0		; PSH
	db	0		; PHM

;-------------------------------

;-------CompuPro 8-1024---
lblF8D6	db	"(MUST open IMD file first) CompuPro 8 - 1024$"

; this assumes that IMD file has been processed by emulator(opened)
; we only need to change SPT and Logical sector size for Data tracks

EPBF8S6:

	set16	09ah,0	;IDM flag	0

	set16	0a4h,64	;SPT		(data)  64/8
	set8	0a5h,0	;Sector Size	(data) 	128
	
	db	0ffh

;---------

LBLD2N1	db "CompuPro Fujitsu 20MB drive 8MB Logical Disk 1$"
LBLD2N2	db "CompuPro Fujitsu 20MB drive 8MB Logical Disk 2$"
LBLD2N3	db "CompuPro Fujitsu 20MB drive 4MB+ Logical Disk 3$"
;sectors have 3 prebyte
EPBD2N
	set8	080h,0	;order
	set8	081h,0	;formatType
	set8 	082h,1	; use prepost

	set16	09ah,0	;IDM flag	0

	set16	0a0h,243	;Cylinders
	set8	0a1h,8	;Heads

	set8	0a3h,0	;density	(data) 	Don't care
	set16	0a4h,88	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,1	;clock		(data) 	HD
	set8	0a8h,3	;pSector Size	(data) 	1024

	set16	0d0h,0	;disk pre
	set16	0d1h,0	;disk post

	set16	0d2h,0	;track pre
	set16	0d3h,0	;track post

	set16	0d8h,3	;sector pre
	set16	0d9h,0	;sector post
	
	db	0ffh

;---------
; XLT tables
;  here's where the magic happens
;---------
	db	1	; 1 based
mitsX:	db	01,18,03,20,05,22,07,24
	db	09,26,11,28,13,30,15,32
	db	17,02,19,04,21,06,23,08
	db	25,10,27,12,29,14,31,16
;----------
	db	1	; 1 based
ibm8X	db	01h,07h,0dh,13h,19h,05h
	db	0bh,11h,17h,03h,09h,0fh
	db	15h,02h,08h,0eh,14h,1ah
	db	06h,0ch,12h,18h,04h,0ah
	db	10h,16h
;----------
	db	1	; 1 based
cdos5SSSD128X
 	db	1,6,11,16,3,8,13,18,5,10,15,2,7,12,17,4,9,14
;----------;512 byte sectors
;	1 base 01,12,07,02,13,08,03,14,09,04,15,10,05,16,11,06
;	0 base 00,11,06,01,12,07,02,13,08,03,14,09,04,15,10,05
;	 x4    00,44,24,04,48,28,08,52,32,12,56,36,16,60,40,20	
; set skew for 4 128 byte sectors at a time(1 base)
	db	1	; 1 based
cdos8DSDD512X	
	db	01,02,03,04,45,46,47,48,25,26,27,28,05,06,07,08
	db	49,50,51,52,29,30,31,32,09,10,11,12,53,54,55,56
	db	33,34,35,36,13,14,15,16,57,58,59,60,37,38,39,40
	db	17,18,19,20,61,62,63,64,41,42,43,44,21,22,23,24
;-----------;512 byte sectors
;	0 base	00 04 08 02 06 01 05 09 03 07 	
;	 x4	00,16,32,08,24,04,20,36,12,28
; set skew for 4 128 byte sectors at a time(1 base)
	db	1	; 1 based
cdos5DSDD512X
	db	01,02,03,04,17,18,19,20,33,34,35,36,09,10,11,12,25,26,27,28
	db	05,06,07,08,21,22,23,24,37,38,39,40,13,14,15,16,29,30,31,32
;------------;256 byte sectors
;	0 base 	0,6,12,3,9,15,14,5,11,2,8,7,13,4,10,1	
;  set skew for 2 128 byte sectors at a time(1 base)
	db	1	; 1 based
AppleIIX
	db	1,2,13,14,25,26,7,8,19,20,31,32,29,30,11,12
	db	23,24,5,6,17,18,15,16,27,28,9,10,21,22,3,4

;------------
;these are compupro (already blocked but zero based)
;------------
	db	0	;  0 based
XLT8S0:	DB	0,6,12,18,24,4,10,16,22,2,8,14,20
	DB	1,7,13,19,25,5,11,17,23,3,9,15,21
;---------
	db	0	; this indicates 0 based
XLT8D1:	DB	 0, 1,18,19,36,37, 2, 3,20,21,38,39
	DB	 4, 5,22,23,40,41, 6, 7,24,25,42,43
	DB	 8, 9,26,27,44,45,10,11,28,29,46,47
	DB	12,13,30,31,48,49,14,15,32,33,50,51
  	DB	16,17,34,35
;----------
	db	0	;  0 based
XLT8D2:	DB	 0, 1, 2, 3,16,17,18,19
	DB	32,33,34,35,48,49,50,51
	DB	 4, 5, 6, 7,20,21,22,23
	DB	36,37,38,39,52,53,54,55
	DB	 8, 9,10,11,24,25,26,27
	DB	40,41,42,43,56,57,58,59
	DB	12,13,14,15,28,29,30,31
  	DB	44,45,46,47
;---------
	db	0	;  0 based
XLT8D3:	DB	 0, 1, 2, 3, 4, 5, 6, 7
	DB	24,25,26,27,28,29,30,31
	DB	48,49,50,51,52,53,54,55
	DB	 8, 9,10,11,12,13,14,15
	DB	32,33,34,35,36,37,38,39
	DB	56,57,58,59,60,61,62,63
	DB	16,17,18,19,20,21,22,23
	DB	40,41,42,43,44,45,46,47
;-------
	db	0	;  0 based
XLT5S0:	DB	 0, 5,10,15, 4, 9,14, 3		; 0, 5,10,15, 2, 7,12,17
        DB	 8,13, 2, 7,12, 1, 6,11		; 4, 9,14, 1, 6,11,16, 3
	DB	00,00				; 8,13
;-------
	db	0	;  0 based
XLT5D1:	DB	 0, 1,10,11,20,21,30,31		; 0, 1,10,11,20,21,30,31
	DB	 8, 9,18,19,28,29		; 4, 5,14,15,24,25,34,35
   	DB	 6, 7,16,17,26,27		; 8, 9,18,19,28,29
 	DB	 4, 5,14,15,24,25		; 2, 3,12,13,22,23,32,33
   	DB	 2, 3,12,13,22,23,00,00,00,00	; 6, 7,16,17,26,27
;-------
	db	0	;  0 based
XLT5D2:	DB	 0, 1, 2, 3,16,17,18,19
     	DB	12,13,14,15,28,29,30,31
       	DB	 8, 9,10,11,24,25,26,27
      	DB	 4, 5, 6, 7,20,21,22,23
       	DB	00,00,00,00,00,00,00,00	
;------
	db	0	;  0 based
XLT5D3:	DB	 0, 1, 2, 3, 4, 5, 6, 7
      	DB	16,17,18,19,20,21,22,23
 	DB	32,33,34,35,36,37,38,39
     	DB	 8, 9,10,11,12,13,14,15
      	DB	24,25,26,27,28,29,30,31

;------
; these DPBs already are configured to deblock
; apparently Compupro did the deblocking BIOS unaware..

;	MAKEDPB	F8S0,	00h,	1,26,1,	  2,77,	1024,	 64, 64

DPBF8S0	DW 	26 
 	DB 	3
	db	7
	db	0
 	DW 	0xf3,63
   	DB 	0xc0,0
  	DW 	16,2
;F8S0CSVZ EQU (64+3)/4
;F8S0ALVZ EQU (f4+7)/8

;       MAKEDPB	F8S1,	01h,	2,26,1, 2*2,77,	1024,	128,128

DPBF8S1	DW 	26 
  	DB 	3,7,0
 	DW 	0x1e7,127
 	DB 	0xf0,0
 	DW 	32,4
	DB	0,0
 ;F8S1CSVZ EQU (128+3)/4
 ;F8S1ALVZ EQU (0x1e8+7)/8

;       MAKEDPB	F8D2,	02h,	1,26,2,   2,77,	2048,	128,128, 0 ;16K extents

DPBF8D2	DW 	26 * 2
 	DB 	4,15,0
  	DW 	0xf3,128-1
   	DB 	0xc0,0
  	DW 	32,2
	DB	0,0
;F8D2CSVZ EQU (128+3)/4
;F8D2ALVZ EQU (0xf4+7)/8

;       MAKEDPB	F8D3,	03h,	2,26,2, 2*2,77,	2048,	256,256

DPBF8D3	DW 	26 * 2
   	DB 	4,15,0
  	DW 	0x1e7,255
    	DB 	0xf0,0
  	DW 	64,2*2
	DB	0,0
;F8D3CSVZ EQU (256+3)/4
;F8D3ALVZ EQU (1e8+7)/8

;        MAKEDPB	F8D4,	04h,	1,15,4,	  2,77,	2048,	128,128

DPBF8D4	DW 	15 * 4
    	DB 	4,15,0
  	DW 	0x119,127
     	DB 	0xc0,0
  	DW 	32,2
	DB	0,0
;F8D4CSVZ EQU (128+3)/4
;F8D4ALVZ EQU (0x11a+7)/8

;       MAKEDPB	F8D5,	05h,	2,15,4, 2*2,77,	2048,	256,256

DPBF8D5	DW 	15 * 4
    	DB 	4,15,0
  	DW 	0x232,255
      	DB 	0xf0,0
  	DW 	64,2*2
	DB	0,0
;F8D5CSVZ EQU (256+3)/4
;F8D5ALVZ EQU (0x233+7)/8

;       MAKEDPB	F8D6,	06h,	1, 8,8,	  2,77,	2048,	128,128

DPBF8D6	DW 	8 * 8
    	DB 	4,15,0
  	DW 	0x12b,127
    	DB 	0xc0,0
  	DW 	32,2
	DB	0,0
;F8D6CSVZ EQU (128+3)/4
;F8D6ALVZ EQU (0x12c+7)/8

;      MAKEDPB	F8D7,	07h,	2, 8,8, 2*2,77,	2048,	256,256

DPBF8D7	DW 	8 * 8
    	DB 	4,15,0
  	DW 	0x257,255
      	DB 	0xf0,0
  	DW 	64,2*2
	DB	0,0
;F8D7CSVZ EQU (256+3)/4
;F8D7ALVZ EQU (DSMC+7)/8

;FD8CSVZ	EQU  64	;Max checksum vector size (4 dir entries / record)
;FD8ALVZ	EQU  0x4b	;Max allocation vector size (bytes = blocks / 8 bits)
                ;
;Memorex (Fujitsu) 20 Mbyte drive
; note- ALVs are wrong
;       MAKEDPB	D2N1,	43h,	8,11,8,	  8*1, 94,  4096,  1024,0	;First 8M

DPBD2N1	DW 	88
    	DB 	5,31,1
  	DW 	0x7fd,1023
      	DB 	0xff,0xff
  	DW 	256,8
	DB	0,0
;D2N1CSVZ EQU (0+3)/4
;D2N1ALVZ EQU (0x7fe+7)/8

;       MAKEDPB	D2N2,	43h,	8,11,8,	 8*94,187,  4096,  1024,0	;Second 8M

DPBD2N2	DW 	88
  	DB 	5,31,1
  	DW 	0x7fd,1023
    	DB 	0xff,0xff
 	DW 	256,8*94
	DB	0,0
;D2N2CSVZ EQU (0+3)/4
;D2N2ALVZ EQU (0x7fe+7)/8

;      MAKEDPB	D2N3,	43h,	8,11,8,	8*187,243,  4096,  1024,0	;Third 4M+

DPBD2N3	DW 	88
    	DB 	5,31,	1
  	DW 	0x4cf,1023
      	DB 	0xff,0xff
 	DW 	256,8*187
	DB	0,0
;D2N3CSVZ EQU (0+3)/4
;D2N3ALVZ EQU (0x4d0+7)/8



	ds	256
Stack	equ	$
	end	0100h
	