; This is Version 2.4 of Configure Disk for CDOS(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-- 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,"CDOS Disk Configure Version 2.4 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",cr,lf
		db	"  types of disks. The NEW configuration will remain in effect until the next",cr,lf
		db	"  COLD BOOT. You can read and write the disks. ",cr,lf
		db	cr,lf
		db	"WARNING-CDOS Disks should NOT be written to by CPM.",cr,lf
		db	"WARNING- Some CDOS files can not be seen by CPM.",cr,lf
		db	"WARNING- Use Standard disks (IBM) to tranfer data to/from a CDOS system.",cr,lf
		db	cr,lf
		db	'$'
NoticeIMD
		db	"  NOTE-Selecting an IMD disk image only sets emulator for auto deblocking,",cr,lf
		db	"       sets ORDER, IDM flag and configures BIOS's DPB and XLT.",cr,lf
		db	"       You MUST open an IMD image, FIRST,",cr,lf
		db	"       so the Emulator can process and set all other info.",cr,lf
		db	'$'

DiskNumber 	db	0
DiskType	db	0
Stack$Save	dw	0

OptDiskTable	db	0	;0=regular, 1=IMD
DiskTablePtr	dw	DiskTable
NumberOfDisksPtr	db	NumberOfDisks

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:	
; Get command line option "IMD" is only option

	mvi	a,07	;expect non-imd
	sta	IMDflag

	lxi	hl,0x80
	mov	a,m
	cpi	0
	jz	NoOptions
..skip
	inx	hl	;warning - not testing for all blanks, probably OK
	mov	a,m
	cpi	' '
	jz	..skip
	
	cpi	'I'
	jnz	NotIMD
	inx	hl
	mov	a,m
	cpi	'M'
	jnz	NotIMD
	inx	hl
	mov	a,m
	cpi	'D'
	jnz	NotIMD
;  is IMD so change pointers to disk table and length of table
	mvi	a,2
	sta 	OptDiskTable
	lxi	hl,DiskTableIMD
	shld	DiskTablePtr
	mvi	a,NumberOfDisksIMD
	sta	NumberOfDisksPtr
	mvi	a,08	; set IMD
	sta	IMDflag
	jmp	NextOption
NotIMD:	; test for HD
	cpi	'H'
	jnz	NotHD
	inx	hl
	mov	a,m
	cpi	'D'
	jnz	NotHD
;  is HD so change pointers to disk table and length of table
	mvi	a,1
	sta 	OptDiskTable
	lxi	hl,DiskTableHD
	shld	DiskTablePtr
	mvi	a,NumberOfDisksHD
	sta	NumberOfDisksPtr
	mvi	a,00	;set neither auto-log
	sta	IMDflag
;	jmp	NextOption
NotHD:
NextOption:	;no more options
NoOptions:

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

	lda	OptDiskTable
	cpi	2
	jnz	SkipIMDnotice
	lxi	d,NoticeIMD
	call	PrintDE

SkipIMDnotice:

;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	

	lxi	hl,NumberOfDisksPtr
	cmp	m
	jc	Got$Type

NOT$Type
	call 	NewLine
	jmp 	Get.Type

Got$Type

	sta	DiskType
	call	NewLine

;----------------
; this code simply reads the ID to determine disk type and then falls through to doNormal
	cpi	1
	jnc	doNormal
	lda	IMDflag
	cpi	0	
	jz	doNormal
	call	AutoLogCDOS		; call CDOS log drive.
testLog
	ora	a			;if returned 0 then not supported
	jnz	go.on
	lxi	d,msgNoSupport
	call 	PrintDE
	jmp	exit$here
go.on
	sta	DiskType
	
;-------------------------
doNormal
; 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	

	call	FeedNDI

;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	SetDRM

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	SetDRM

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

SetDRM

; have to fix DRM based on disk label
	lda	DiskType	
	call	GetDPBptr	;hl=internal DPB
	call	FixDRM
; re-inject the DPB with fixed DRM
	lda	DiskType	
	call	GetDPBptr	;hl=internal DPB
	lded	DPB		;de=DPB in bios
	lxi	b,DPBsize	;size of dpb
	ldir

;-------------------------
;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

	lhld	DiskTablePtr
	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
	lxi	hl,NumberOfDisksPtr
	cmp	m
	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	
; 0
	dw	CDOSLogINL,0,0,0	;dummy fields because not used
; 1
	dw 	ibm8L,ibm8P,ibm8D,ibm8X
; 2
	dw 	cdos5SSSD128L,cdos5SSSD128P,cdos5SSSD128D,cdos5SSSD128X
	dw 	cdos5SSDD512L,cdos5SSDD512P,cdos5SSDD512D,cdos5SSDD512X
	dw 	cdos5DSSD128L,cdos5DSSD128P,cdos5DSSD128D,cdos5DSSD128X
	dw 	cdos5DSDD512L,cdos5DSDD512P,cdos5DSDD512D,cdos5DSDD512X
; 6
	dw 	cdos8SSSD128L,ibm8P,ibm8D,ibm8X
	dw 	cdos8SSDD512L,cdos8SSDD512P,cdos8SSDD512D,cdos8SSDD512X
	dw 	cdos8DSSD128L,cdos8DSSD128P,cdos8DSSD128D,ibm8X
	dw 	cdos8DSDD512L,cdos8DSDD512P,cdos8DSDD512D,cdos8DSDD512X

NumberOfDisks	equ 	($-DiskTable)/8
;-----------
DiskTableIMD	
; 0
	dw	CDOSLogINIMDL,0,0,0	;dummy fields because not used
; 1
	dw 	ibm8IMDL,ibm8IMDP,ibm8D,ibm8X
; 2
	dw 	cdos5SSSD128IMDL,cdos5SSSD128IMDP,cdos5SSSD128D,cdos5SSSD128X
	dw 	cdos5SSDD512IMDL,cdos5SSDD512IMDP,cdos5SSDD512D,cdos5SSDD512X
	dw 	cdos5DSSD128IMDL,cdos5DSSD128IMDP,cdos5DSSD128D,cdos5DSSD128X
	dw 	cdos5DSDD512IMDL,cdos5DSDD512IMDP,cdos5DSDD512D,cdos5DSDD512X
; 6
	dw 	cdos8SSSD128IMDL,ibm8IMDP,ibm8D,ibm8X
	dw 	cdos8SSDD512IMDL,cdos8SSDD512IMDP,cdos8SSDD512D,cdos8SSDD512X
	dw 	cdos8DSSD128IMDL,cdos8DSSD128IMDP,cdos8DSSD128D,ibm8X
	dw 	cdos8DSDD512IMDL,cdos8DSDD512IMDP,cdos8DSDD512D,cdos8DSDD512X

NumberOfDisksIMD	equ 	($-DiskTableIMD)/8

;-----------
DiskTableHD	
	dw 	PC4104L,PC4104P,PC4104D,0
	dw 	PC8190L,PC8190P,PC8190D,0

;	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

NumberOfDisksHD	equ 	($-DiskTableHD)/8

;-------------
; IDs
LGDSDD	db	'LGDSDD$',9,9	
LGDSSD	db	'LGDSSD$',8,8	
LGSSDD	db	'LGSSDD$',7,7	
LGSSSD	db	'LGSSSD$',6,6	
SMDSDD	db	'SMDSDD$',5,5	
SMDSSD	db	'SMDSSD$',4,4	
SMSSDD	db	'SMSSDD$',3,3	
SMSSSD	db	'SMSSSD$',2,2	


CDOSLogINL
	db	"Auto LOGIN CDOS disk$"
CDOSLogINIMDL
	db	"Auto LOGIN CDOS disk(IMD)$"
;-------------------------
;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
;----------------------------
; Track 0 has 18 128 byte sectors
; rest of disk has 10 512 byte sectors, 
;     but we make them 40 128 byte sectors and do XLT 4 sectors at a time
cdos5DSDD512L
	db	"CDOS 5.25 512 Double Sided Double Density$"

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

	set16	09ah,0	;IDM flag	0

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

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

	set16	0b2h,1	;#t0
	set8	0b3h,1	;density	(T0) 	Single
	set16	0b4h,18	;SPT		(T0) 
	set8	0b5h,0	;Sector Size	(T0) 	128
	set8	0b6h,3	;clock		(T0)	5inch

	set16	0c2h,1	;#sys
	set8	0c3h,2	;density	(SYS) 	Double
	set16	0c4h,40	;SPT		(SYS) 
	set8	0c5h,0	;Sector Size	(SYS) 	128
	set8	0c6h,3	;clock		(SYS) 	5inch
	
	db	0ffh	;end it

cdos5DSDD512IMDL
	db	"CDOS 5.25 512 Double Sided Double Density(IMD)$"

cdos5DSDD512IMDP:

	set16	09ah,0	;IDM flag 

	set16	0a4h,40	;SPT		(data)  10
	set8	0a5h,0	;Sector Size	(data) 	128
	
	db	0ffh

	
cdos5DSDD512D
	DW    40	;sectors per track
	DB    4		;block shift factor
	DB    15		;block mask
	DB    0		;extent mask
	DW    0xc2	;disk size-1
	DW    127	;directory max
	DB    0c0h	;alloc 0
	DB    0		;alloc 1
	DW    32	;check size
	DW    2		;track offset
	DB    0,0	;physical sector size and shift
;--------------------
cdos5SSDD512L
	db	"CDOS 5.25 512 Single Sided Double Density$"

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

	set16	09ah,0	;IDM flag	0

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

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

	set16	0b2h,1	;#t0
	set8	0b3h,1	;density	(T0) 	Single
	set16	0b4h,18	;SPT		(T0) 
	set8	0b5h,0	;Sector Size	(T0) 	128
	set8	0b6h,3	;clock		(T0)	5inch

	set16	0c2h,1	;#sys
	set8	0c3h,2	;density	(SYS) 	Double
	set16	0c4h,40	;SPT		(SYS) 
	set8	0c5h,0	;Sector Size	(SYS) 	128
	set8	0c6h,3	;clock		(SYS) 	5inch
	
	db	0ffh	;end it

cdos5SSDD512IMDL
	db	"CDOS 5.25 512 Single Sided Double Density(IMD)$"

cdos5SSDD512IMDP:

	set16	09ah,0	;IDM flag 

	set16	0a4h,40	;SPT		(data)  10
	set8	0a5h,0	;Sector Size	(data) 	128
	
	db	0ffh

	
cdos5SSDD512D
	DW    40	;sectors per track
	DB    3		;block shift factor
	DB    7		;block mask
	DB    0		;extent mask
	DW    189	;disk size-1
	DW    63	;directory max
	DB    0xC0	;alloc 0
	DB    0		;alloc 1
	DW    16	;check size
	DW    2		;track offset
	DB    0,0	;physical sector size and shift

;--------------------
; All Tracks have 18 128 byte sectors
cdos5SSSD128L
	db	"CDOS 5.25 128 Single Sided Single Density$"

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

	set16	09ah,0	;IDM flag	0

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

	set8	0a3h,1	;density	(data) 	Single
	set16	0a4h,18	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,3	;clock		(data) 	5inch

	db	0ffh
;----------------------------

cdos5SSSD128IMDL
	db	"CDOS 5.25 128 Single Sided Single Density(IMD)$"

cdos5SSSD128IMDP:

	set16	09ah,0	;IDM flag	0

	db	0ffh
	
cdos5SSSD128D
	DW	18	;sectors per track
	DB	3		;block shift factor
	DB	7		;block mask
	DB	0		;extent mask
	DW	82	;disk size-1
	DW	63	;directory max
	DB	0c0h	;alloc 0
	DB	0		;alloc 1
	DW	16	;check size
	DW   	3		;track offset
	DB	0,0	;physical sector size and shift

;-----------------------
;--------------------
; All Tracks have 18 128 byte sectors
cdos5DSSD128L
	db	"CDOS 5.25 128 Double Sided Single Density$"

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

	set16	09ah,0	;IDM flag	0

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

	set8	0a3h,1	;density	(data) 	Single
	set16	0a4h,18	;SPT		(data) 
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,3	;clock		(data) 	5inch

	db	0ffh
;----------------------------

cdos5DSSD128IMDL
	db	"CDOS 5.25 128 Double Sided Single Density(IMD)$"

cdos5DSSD128IMDP:

	set16	09ah,0	;IDM flag	0

	db	0ffh
	
cdos5DSSD128D 
	DW	18	;sectors per track
	DB	3		;block shift factor
	DB	7		;block mask
	DB	0		;extent mask
	DW	172	;disk size-1
	DW	63	;directory max
	DB	0c0h	;alloc 0
	DB	0		;alloc 1
	DW	16	;check size
	DW   	3		;track offset
	DB	0,0	;physical sector size and shift

;-----------------------
; Tracks have 26 128 byte sectors
;
;----------------------------

cdos8SSSD128IMDL	
	db	"CDOS 8 Inch 128 Single Sided Single Density(IMD)$"

cdos8SSSD128L	
	db	"CDOS 8 Inch 128 Single Sided Single Density$"

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

cdos8DSSD128IMDL	
	db	"CDOS 8 Inch 128 Double Sided Single Density(IMD)$"

cdos8DSSD128IMDP:

	set16	09ah,0	;IDM flag	0

	db	0ffh

cdos8DSSD128L	
	db	"CDOS 8 Inch 128 Double Sided Single Density$"

cdos8DSSD128P:
	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,2	;Heads

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

	db	0ffh

cdos8DSSD128D	
	dw	26		;spt
	db	4		;bsh
	db	15		;blm
	db	1		;exm
	dw	246		;dsm
	dw	127		;drm
	db	0c0h		;al0
	db	0		;al1
	dw	32		;cks
	dw	2		;off
	DB	0,0		;physical sector size and shift


;-----------------------
; Track 0 has 26 128 byte sectors
; rest of disk has 16 512 byte sectors, 
;     but we make them 64 128 byte sectors and do XLT 4 sectors at a time
;----------------------------

cdos8DSDD512L
	db	"CDOS 8 inch 512 Double Sided Double Density$"

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

	set16	09ah,0	;IDM flag	0

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

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

	set16	0b2h,1	;#t0
	set8	0b3h,1	;density	(T0) 	Single
	set16	0b4h,26	;SPT		(T0) 
	set8	0b5h,0	;Sector Size	(T0) 	128
	set8	0b6h,2	;clock		(T0)	8inch

	set16	0c2h,1	;#sys
	set8	0c3h,2	;density	(SYS) 	Double
	set16	0c4h,64	;SPT		(SYS)   16
	set8	0c5h,0	;Sector Size	(SYS) 	128
	set8	0c6h,2	;clock		(SYS) 	8inch

	db	0ffh

cdos8DSDD512IMDL
	db	"CDOS 8 inch 512 Double Sided Double Density(IMD)$"

cdos8DSDD512IMDP:

	set16	09ah,0	;IDM flag 

	set16	0a4h,64	;SPT		(data)  16
	set8	0a5h,0	;Sector Size	(data) 	128
	
	db	0ffh
	
cdos8DSDD512D
	DW    64	;sectors per track
	DB    4		;block shift factor
	DB    15	;block mask
	DB    0		;extent mask
	DW    607	;disk size-1
	DW    255	;directory max
	DB    0f0h	;alloc 0
	DB    0		;alloc 1
	DW    64	;check size
	DW    2		;track offset
	DB	0,0	;physical sector size and shift

;-------------------------
;DPB=64,4,15,0,303,127,192,0,32,1,2,3
cdos8SSDD512L
	db	"CDOS 8 inch 512 Single Sided Double Density$"

cdos8SSDD512P:
	set8	080h,0	;order
	set8	081h,1	;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,64	;SPT		(data)  16
	set8	0a5h,0	;Sector Size	(data) 	128
	set8	0a6h,2	;clock		(data) 	8inch

	set16	0b2h,1	;#t0
	set8	0b3h,1	;density	(T0) 	Single
	set16	0b4h,26	;SPT		(T0) 
	set8	0b5h,0	;Sector Size	(T0) 	128
	set8	0b6h,2	;clock		(T0)	8inch

	set16	0c2h,1	;#sys
	set8	0c3h,2	;density	(SYS) 	Double
	set16	0c4h,64	;SPT		(SYS)   16
	set8	0c5h,0	;Sector Size	(SYS) 	128
	set8	0c6h,2	;clock		(SYS) 	8inch

	db	0ffh

cdos8SSDD512IMDL
	db	"CDOS 8 inch 512 Single Sided Double Density(IMD)$"

cdos8SSDD512IMDP:

	set16	09ah,0	;IDM flag 

	set16	0a4h,64	;SPT		(data)  16
	set8	0a5h,0	;Sector Size	(data) 	128
	
	db	0ffh
	
cdos8SSDD512D
	DW    64	;sectors per track
	DB    4		;block shift factor
	DB    15	;block mask
	DB    0		;extent mask
	DW    303	;disk size-1
	DW    127	;directory max  255
	DB    0c0h	;alloc 0         f0
	DB    0		;alloc 1
	DW    32	;check size	64
	DW    2		;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

ibm8IMDL	db	"Standard 8 IBM 3740 Single Sided Single Density(IMD)$"

ibm8IMDP:

	set16	09ah,0	;IDM flag	0

	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

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

;---------
; XLT tables
;  here's where the magic happens
;IBM ----------
	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

;CDOS5 sssd 128----------
	db	1	; 1 based
cdos5SSSD128X
cdos5DSSD128X
 	db	1,6,11,16,3,8,13,18,5,10,15,2,7,12,17,4,9,14

;CDOS8 DSDD and SDDD 512----------;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	
cdos8SSDD512X	
	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

;CDOS5 SDDD 512-----------;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
cdos5SSDD512X
	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
;-----------------------
msgFound	db	cr,lf,' Configured as $'
msgNotFound	db	cr,lf,' NO id on disk. Did not configure!',cr,lf,'$'
msgReadLogErr	db	cr,lf,' Unable to read ID sector 1 track 0!',cr,lf,'$'
msgNoSupport	db	cr,lf,' Unable to configure that!',cr,lf,'$'
id.size equ	6
;-----------

;return Z if bad login
;return NZ if good and disk type in a
IMDflag	db	0

autoLogCDOS
	call ConfigTRK0
TestIDs
	call ReadID
	jz	OkConfig
	lxi	d,msgReadLogErr
	call 	PrintDE
	xra	a
	ora	a
	ret
	
OkConfig
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,LGDSDD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt80
	lxi	hl,LGDSDD
	jmp	autoOut
nxt80
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,LGDSSD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt81
	lxi	hl,LGDSSD
	jmp	autoOut
nxt81
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,LGSSDD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt82
	lxi	hl,LGSSDD
	jmp	autoOut
nxt82
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,LGSSSD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt5inch
	lxi	hl,LGSSSD
	jmp	autoOut
nxt5inch
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,SMDSDD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt50
	lxi	hl,SMDSDD
	jmp	autoOut
nxt50
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,SMDSSD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt51
	lxi	hl,SMDSSD
	jmp	autoOut
nxt51
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,SMSSDD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	nxt52
	lxi	hl,SMSSDD
	jmp	autoOut
nxt52
	lxi	h,log.buf+0x78	;get address of ID in log buffer
	lxi	d,SMSSSD	;de points to ID
	mvi	b,id.size	;label size
	call	Compare
	jnz	doneAll
	lxi	hl,SMSSSD
	jmp	autoOut
doneAll
	lxi	d,msgNotFound
	call 	PrintDE
	xra	a
	ora	a
	ret
autoOut
	push	hl
	push	de
	lxi	d,msgFound
	call 	PrintDE
	call 	PrintHL
	call	NewLine
	pop	de
	pop	hl

	mvi	d,0
	lda	IMDflag
	mov	e,a
	dad	de
	mov	a,m
	ora	a
	ret
	
; returns NZ if not found Z if found
Compare	ldax	d	;get label character
	cmp	m	;match?
	rnz		;NO check for other ID
	inx	h	;point to next char
	inx	d
	dcr	b	;dec count of characters
	jnz	Compare	;again
	ret
	
ConfigTRK0
	lxi	hl,ibm8P
	call	FeedNDI
	ret

;hl=internal DPB
; have to read disk label (type 0x81) 
FixDRM
	push	hl
	lxi	b,13
	dad	b
	mov	e,m
	inx	hl
	mov	d,m
	sded	bt.trk
	lxi	hl,Rlab
	call	FeedNDI

	call	dsk.sts		; we did a read so get status

	jz	OkChkLab
	lxi	d,msgReadLabErr
	call 	PrintDE
	pop	hl
	jmp	Exit$here
	ret
msgReadLabErr
	db	cr,lf,' Could not Read Label, used default DRM',cr,lf,'$'
msgNoLabErr
	db	cr,lf,' No Label, used default DRM',cr,lf,'$'
msgERRbadSize
	db	cr,lf,' Number of files not supported, used default DRM',cr,lf,'$'
msgLabIS
	db	cr,lf,' Label is $'
OkChkLab
	lda	log.buf
	cpi	0x81
	jz	FoundLabel
	lxi	d,msgNoLabErr
	call 	PrintDE
;	pop	hl
	jmp	retPrintDRM
	
FoundLabel
	lxi	d,msgLabIS
	call 	PrintDE
	mvi	a,'$'
	sta	log.buf+9
	lxi	d,log.buf+1
	call	PrintDE
	call	NewLine

	lda	log.buf+15	;get CKS from label
	mov	e,a
	xra	a
	mov	d,a

	pop	hl
	push	hl
	lxi	bc,11
	dad	bc	;hl points to CKS in DPB
	mov	m,e
	inx	hl
	mov	m,d

	xchg
	dad	hl	;multiply CKS by 4 and subtract 1 to get DRM
	dad	hl
	dcx	hl	;minus 1
	xchg

	pop	hl
	push 	hl

	lxi	bc,7
	dad	bc	;hl points to DRM in DPB
	mov	m,e
	inx	hl
	mov	m,d

	lxi	hl,alvTabOneK
	lda	log.buf+12	;00=1k 80=2k
	cpi	0x80
	jnz	itsLoaded
	lxi	hl,alvTabTwoK

itsLoaded
	lxi	de,log.buf+15	;get CKS from label

search
	mov	a,m	;get CKS from table
	cpi	0	;
	jz	retphl	;finished if end of table
	
	xchg
	cmp	m	;hl is now de->CKS in label
	xchg
	jc	nxtrec

	inx	hl
	mov	e,m
	inx	hl
	mov	d,m	;de contains ALV0/1
	pop	hl	;retrieve hl->DPB
	push	hl

	lxi	bc,9	;point to AL0
	dad	bc
	mov	m,e
	inx	hl
	mov	m,d

retPrintDRM
	lxi	d,msgNUMfiles
	call	PrintDE
	pop	hl	; hl->dpb

	lxi	bc,7
	dad	bc	;hl points to DRM in DPB
	mov	e,m
	inx	hl
	mov	d,m
	inx	de	;DRM+1
	xchg

	call 	showdec

	call	NewLine
	
	ret
msgNUMfiles	db	cr,lf," Number of Directory entries = $"
nxtrec
	inx	hl	;next record
	inx	hl
	inx	hl

	jmp	search
retphl	
	lxi	d,msgERRbadSize
	call 	PrintDE

	pop	hl	; hl->dpb

	ret
;-------------------
alvTabOneK
	db	0x08,0x80,0x00
	db	0x10,0xC0,0x00
	db	0x18,0xE0,0x00
	db	0x20,0xF0,0x00
	db	0x28,0xF8,0x00
	db	0x30,0xFC,0x00
	db	0x38,0xFE,0x00
	db	0x40,0xFF,0x00
	db	0x48,0xFF,0x80
	db	0x50,0xFF,0xC0
	db	0x58,0xFF,0xE0
	db	0x60,0xFF,0xF0
	db	0x68,0xFF,0xF8
	db	0x70,0xFF,0xFC
	db	0x78,0xFF,0xFE
	db	0x80,0xFF,0xFF
	db	0
alvTabTwoK
	db	0x10,0x80,0x00
	db	0x20,0xC0,0x00
	db	0x30,0xE0,0x00
	db	0x40,0xF0,0x00
	db	0x50,0xF8,0x00
	db	0x60,0xFC,0x00
	db	0x70,0xFE,0x00
	db	0x80,0xFF,0x00
	db	0

	

;-------------------
;Z80 Emualator hardware parameters (new Disk interface)

ndi.Lo	equ	0xC8
ndi.Hi	equ	0xC9
ndi.Sel	equ	0xCA

cmd.read	equ	1
cmd.write	equ	2

;macros for setting up NDI IO parmeter tables.

Set8	macro	?Register,?Value,?Label
	db	1,?Register
?Label	db	?Value
	endm

Set16	macro	?Register,?Value,?Label
	db	2,?Register
?Label	dw	?Value
	endm

; this routine feeds data to the New Disk Interface
; the data is in a parameter block as
; size(1) port(1) data (1 or 2) terminated with 0xFF
; entry -  hl points to parameter block
;-------------------------
FeedNDI
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	ndi.Sel	;out to select port
	inx	hl
	mov	a,m	;got value to out to register
	out 	ndi.LO	; out to low reg
	inx	hl
	jmp 	another
do2	inx	hl
	mov	a,m	;got register selector in a
	out	ndi.Sel	;out to select port
	inx	hl
	mov	a,m	;got value to out to low register
	out 	ndi.Lo	; out to low reg
	inx	hl
	mov	a,m	;got value to out to high register
	out 	ndi.Hi	; out to high reg
	inx	hl
	jmp 	another
finished
	ret	

;disk read write format exits 

dsk.ok:	
	xra	a		;clear a to indicate OK
	ret

dsk.er:	
	mvi	a,0FFh		;set a to indicate ERROR
	ret


; disk status

dsk.sts
	mvi	a,8	;select for status register
	out 	ndi.Sel
	in	ndi.Lo
	ana	a	;set status
	ret

;disk login

ReadID
dsk.log
;	lxi	hl,Select	;select is done first only to support 1.0.18-1.0.22
;	call	feedNDI

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

;	lxi	hl,LogData	;set defaults needed to read ID sector
;	call	FeedNDI

	lxi	hl,LIO		; finalize set of parms and read ID sector
	call	FeedNDI

	call	dsk.sts		; we did a read so get status
	
	ret
;-----------------------

; load this to select drv (done separate to allow 1.0.18 - 1.0 22 to work) 
; for 1.0.23 up cnfg parms accumulate until NDI IO command
; 18-22 required you set drive first.

Select
	set8	0x18,0,bt.drv	;drive number
	db	0xff

; load  this to Read Label Dir Ent 0

Rlab
	set16	0x10,log.buf	;DMA address of Log buffer
	set16	0x22,0,bt.trk	;track number
	set16	0x24,1		;sector 1 (XLTs 1 to 1 on all)
	set8	0x00,cmd.read	;NDI command
	db	0xff
; load  this to do IO

;DIO
;	set16	0x10,0,bt.dma	;system tranfer address
;	set16	0x22,0,bt.trk	;track number
;	set16	0x24,0,bt.sec	;sector number
;	set8	0x00,0,bt.cmd	;NDI command
;	db	0xff
; load this to read ID sector 

LIO
	set16	010h,log.buf	;DMA address of Log buffer
	set16	022h,0		;Track 0
	set16	024h,1		;Sector 1
	set8	0x00,cmd.read	;NDI command
	db	0xff

;-----------------------
log.buf	ds	0x78
	db	0,0,0,0,0,0,0,0

;-----------------------
;*	Chout - Character in (a) to console output.
;
;	Preserves all but (a)
;

Chout:
	push	h
	push	b
	push	d
	mov	e,a
	mvi	c,2
	call	bdos			; issue a console-out
	pop	d
	pop	b
	pop	h
	ret

;*	Strout - Output a string following the call to this routine.
;
;	preserves all.
;
;	String is null-terminated.
;

Strout:
	xthl				; get return in (hl)
	push	psw			; save (a)
Strout2:
	mov	a,m
	inx	h
	ora	a
	jz	Strout4			; if done...
	push	d
	push	b
	push	h
	mov	e,a
	mvi	c,2			; console out
	call	bdos
	pop	h
	pop	b
	pop	d
	jmp	Strout2

Strout4:
	pop	psw
	xthl
	ret				; exit...all regs preserved

;*	ShowDec - Show (HL) as a decimal number.
;
;	Output to the console; blank leading zeroes.
;

ShowDec:
	push	h
	push	d
	push	b
	push	psw
	lxi	d,DecTable	; get powers table
	xchg
	mvi	c,0		; say blanking
ShowDec2:
	mov	a,m
	ora	a		; see if last digit
	jz	ShowDec8	; if so
	mvi	b,0
ShowDec4:
	inr	b
	mov	a,e
	sub	m
	mov	e,a
	inx	h
	mov	a,d
	sbb	m
	mov	d,a
	dcx	h
	jnc	ShowDec4	; if oversubtract

;	correct oversubtract.

	mov	a,e
	add	m
	mov	e,a
	inx	h
	mov	a,d
	adc	m
	inx	h
	mov	d,a
	dcr	b
	jz	ShowDec6	; if a zero
	mvi	c,1
ShowDec6:
	inr	c
	dcr	c		; check (c)
	jz	ShowDec2	; loop to next digit
	mov	a,b
	adi	'0'
	call	chout		; character out
	jmp	ShowDec2	; to next digit

;	Do the last digit - do not blank.

ShowDec8:
	mov	a,e
	adi	'0'
	call	chout
	pop	psw
	pop	b
	pop	d
	pop	h
	ret

DecTable:
	dw	10000,1000,100,10,0	; powers of 10


	ds	256
Stack	equ	$
	end	0100h
	