;============================================================
;CP/M Program to a Eject PerSci Disk on the Cromemco 16FDC
;Floppy Disk Controller
;============================================================
;Revision History
; 1.00 123 May 2021  M. Eberhard
;============================================================
;=======
;Equates
;=======

MAXDRV	equ	3		;highest allowed drive number

;------------------------------------------
; BDOS Function Codes, passed in register C
;------------------------------------------
BPRINT	equ	9	;Print $-terminated line at de
;-------------------------
;Page 0 reserved locations
;-------------------------
WBOOTV	equ	0		;CP/M warm boot entry
IOBYTE	equ	3		;Intel IOBYTE location
CDISK	equ	4		;current disk
BDOSV	equ	5		;vector to BDOS

;CP/M Buffers 

COMBUF	equ	80h		;temp buffer used by CP/M
TPA	equ	100h		;transient program area
;------------------------------------
;16FDC floppy disk controller equates
;------------------------------------
ADCMD	equ	4		;Auxiliary disk command
ASTAT	equ	4		;Auxiliary disk status
DSTAT	equ	30h		;disk stat port
DCMMD	equ	DSTAT		;disk command port
DTRCK	equ	DSTAT+1		;track port
DSCTR	equ	DSTAT+2		;sector port
DDATA	equ	DSTAT+3		;data port
DFLAG	equ	DSTAT+4		;disk flag port
DCTRL	equ	DSTAT+4		;disk ctrl port

;WD1793 commands

RSTRCM	equ	00000000b	;(I) restore
SEEKCM	equ	00010000b	;(I) seek
STEPCM	equ	00100000b	;(I) step
STPICM	equ	01000000b	;(I) step-in
STPOCM	equ	01100000b	;(I) step-out
RSECCM	equ	10000000b	;(II) read sector
WSECCM	equ	10100000b	;(II) write sector
RADRCM	equ	11000000b	;(III) read address
RTRKCM	equ	11100000b	;(III) read track
WTRKCM	equ	11110000b	;(III) write track
FINTCM	equ	11010000b	;(IV) force interrupt

;WD1793 command options (1st letter matches WD1793 data sheet)

RS03MS	equ	00000000b	;(I) 3 mS step rate
RS06MS	equ	00000001b	;(I) 6 mS step rate
RS10MS	equ	00000010b	;(I) 10 mS step rate
RS15MS	equ	00000011b	;(I) 15 mS step rate
VERTRK	equ	00000100b	;(I) verify on destination track
HDLOAD	equ	00001000b	;(I) head load
UPDTTR	equ	00010000b	;(I) update track reg
F1SCMP	equ	00000010b	;(II)enable side compare
F2SCS1	equ	00001000b	;(II)side compare, side 1
MULTCM	equ	00010000b	;(II) read/write multiple
ED15MS	equ	00000100b	;(II & III) settling delay

;Control register 1 (DCTRL) output bits

DCDS1	equ	00000001b	;drive select 1
DCDS2	equ	00000010b	;drive select 2
DCDS3	equ	00000100b	;drive select 3
DCDS4	equ	00001000b	;drive select 4
DCMAXI	equ	00010000b	;0=Minidisk, 1=8" disk
DCMDMO	equ	00100000b	;Motor on
DCDDEN	equ	01000000b	;double density enable
DCAUTOW	equ	10000000b	;autowait

;Auxiliary Disk Command (ADCMD) output bits
;(All bits are active-low)

ADSIDE0	equ	00000010b	;0=side 1, 1=side 0
ADCTRL0	equ	00000100b	;-Control Out (test)
ADRSTOR	equ	00001000b	;-Restore (PerSci)
ADFSEKN	equ	00010000b	;-Fast Seek (PerSci)
ADDSO	equ	00100000b	;-Drive Select Override (test)
ADEJECT	equ	01000000b	;-Remote eject (PerSci)


;WD1793 status (DSTAT) after a command

SBUSY	equ	00000001b	;(All) busy
SCRCERR	equ	00001000b	;(All) CRC error
SWRPROT	equ	01000000b	;(All) write protect
SNOTRDY	equ	10000000b	;(All) drive not ready
SINDEX	equ	00000010b	;(I) index
STRACK0	equ	00000100b	;(I) track 0
SSEEKER	equ	00010000b	;(I) seek error
SHEADLD	equ	00100000b	;(I) head loaded
SDATRQ	equ	00000010b	;(II & III) data request
SLOSTD	equ	00000100b	;(II & III) lost data error
SRNFER	equ	00010000b	;(II & III) record not found
SRCTYF	equ	00100000b	;(II & III) record type fault
SWFALT	equ	00100000b	;(II & III) Write fault

;Disk Flag (DFLAG) input bits

DEOJ	equ	00000001b	;WD1793 INTRQ signal, active high
DAWTO	equ	00000010b	;Autowait Timeout
DMOTO	equ	00000100b	;Motor Timeout
DMOTON	equ	00001000b	;Motor On
DINHIN	equ	00010000b	;-Inhibit Init
DFSHLD	equ	00100000b	;WD1793 HLD, active high
DFAUTOB	equ	01000000b	;autoboot jumper, 0=autoboot
DFSDRQ	equ	10000000b	;WD1793 DRQ signal, 1=ready

;Auxiliary Status Register (ASTAT) input bits

BSW8	equ	00000001b	;Switch 8
BSW7	equ	00000010b	;Switch 7
BSW6	equ	00000100b	;Switch 6
BSW5	equ	00001000b	;Switch 5
BSIP	equ	01000000b	;(PerSci) Seek in Progress
BRTC	equ	10000000b	;512 m,Sec reat-time clock
;================
;Start of program
;================
	ORG	TPA

	lda	CDISK		;default to eject
	mov	b,a

;Get drive letter to eject

	lxi	h,COMBUF

	mov	c,m		;1st byte is byte count
	
	inr	c		;for initial dcr c

PLOOP:	inx	h
	dcr	c		;any more characters?
	jz	EJECT		;n: default

	mov	a,m
	cpi	' '		;skip spaces
	jz	PLOOP

	ori	'a'-'A'		;either case is ok
	sui	'a'		;valid disk to eject?
	cpi	MAXDRV+1
	jnc	ERROR
	mov	b,a		;drive to eject
EJECT:
;compute b = select bit for the drive we will eject

	xra	a		;clear carry
	inr	b
	mvi	a,80h		;build select bit pattern
SBLOOP:	rlc
	dcr	b
	jnz	SBLOOP

;select the specified disk

	out	DCTRL

	call	DELAY

;Eject the disk

	mvi	a,(ADEJECT+ADSIDE0) xor 0FFh
	out	ADCMD

	call	DELAY

;end eject pulse

	mvi	a,ADSIDE0 xor 0FFh
	out	ADCMD

;Deselect all drives

	xra	a
	out	DCTRL

	call	DELAY

;Return to CP/M

	jmp	WBOOTV		;to CP/M

;Bogus Entry

ERROR:	mvi	c,BPRINT	;BDOS code
	lxi	d,ERRMSG
	jmp	BDOSV		;return from there


ERRMSG:	db	'Huh?$'

	
Subroutine: ;1/2-second delay

DELAY:	lxi	h,456		;assume 4 MHz

STALUP:	xra	a		;(4)[4]

STALP1:	sui	1		;(7)[7] 17*256=4352 cycles
	jnz	STALP1		;(10)[10]

	dcx	h		;(6)[5]
	mov	a,h		;(4)[5]
	ora	l		;(4)[4]
	jnz	STALUP		;(10)[10] (4+4352+24=4380 cycles/pass)

	ret



