

	title 'PC 1715 / 1024    DOUBLE density diskette handler'

;    CP/M-80 Version 3     --  Modular BIOS

;	Disk I/O Module based diskette systems

	;	Initial version 0.01,
	;		DOUBLE density floppy only.	- 18.11.1988

	dseg

    ; Disk drive dispatching tables for linked BIOS

	public	fdsd0,fdsd1,fdsd2

	EXTRN	IVDSK1,IVDSK2
	EXTRN	FLOPPY,PFTKOM,PFTADR
	EXTRN	DIOMRK,ITIMEO,LWEXIS,ALWNR,ASPNR,SPNRL

    ; Variables containing parameters passed by BDOS

	extrn	@adrv,@rdrv
	extrn	@dma,@trk,@sect
	extrn	@dbnk
	EXTRN	@CNT

    ; System Control Block variables

	extrn	@ermde		; BDOS error mode

    ; Utility routines in standard BIOS

	extrn	?wboot	; warm boot vector
	extrn	?pmsg	; print message @<HL> up to 00, saves <BC> & <DE>
	extrn	?pdec	; print binary number in <A> from 0 to 99.
	extrn	?pderr	; print BIOS disk error header
	extrn	?conin,?cono	; con in and out
	extrn	?const		; get console status


    ; Port Address Equates

	maclib ports

    ; CP/M 3 Disk definition macros

	maclib cpm3

    ; Z80 macro library instruction definitions

	maclib z80

    ; common control characters

cr	equ 13
lf	equ 10
bell	equ 7

;**************************************************************
; VEREINBARUNGEN
;**************************************************************

MAXDSK	EQU	2

;****************** E/A - VEREINBARUNGEN **********************

; Adressen der Floppykarte

; Steuer-PIO
flcoad	equ	04h		;Port A
flcoac	equ	05h
flcobd	equ	06h		;Port B
flcobc	equ	07h

; Daten-PIO
fldaad	equ	00h		;Port A Schreib-Daten
fldaac	equ	01h
fldabd	equ	02h		;Port B Lese-Daten
fldabc	equ	03h

; Select-Latch
flsel	equ	20h	;Bit 7..4: /Select LW3..0; Bit 3..0: /Lock LW 3..0
flmot	equ	21h	;Bit 7..4: /Motor on (von flsel 7..4 durchgeschaltet)



    ; Extended Disk Parameter Headers (XPDHs)

	dw	fd$write
	dw	fd$read
	dw	fd$login
	dw	fd$init0
	db	0,0		; relative drive zero
fdsd0	dph     0,dpbsd1

	dw	fd$write
	dw	fd$read
	dw	fd$login
	dw	fd$init1
	db	1,0		; relative drive one
fdsd1	dph	0,dpbsd1

	dw	fd$write
	dw	fd$read
	dw	fd$login
	dw	fd$init2
	db	2,0		; relative drive one
fdsd2	dph	0,dpbsd2

	cseg	; DPB must be resident

DPBSD1	DPB	1024,10,80,2048,128,2

DPBSD2	DPB	1024,5,40,1024,64,2

	dseg	; rest is banked


    ; Disk I/O routines for standardized BIOS interface

; Initialization entry point.

;		called for first time initialization.


fd$init0:
;; Port Steuer-B
	lxi	h,diomrk	;; Adressmarken-Interrupt
	shld	ivdsk2
	LXI	H,IVDSK2
	MOV	A,L
	out	flcobc
	mvi	a,0cfh		;; bit E/A
	out	flcobc
	mvi	a,0e3h		;; eeea aaee
	out	flcobc
	mvi	a,00110111b	;; di/oder/high/Maske
	out	flcobc
	mvi	a,11111101b	;; Interrupt bei Marke
	out	flcobc
;; Port Daten-B
	mvi	a,4fh		;; byte-Eingabe
	out	fldabc
;; Port Daten-A
	mvi	a,0fh		;; byte-Ausgabe
	out	fldaac
;; Port Steuer-A
	out	flcoac		;; byte-Ausgabe
	out	flcoad		;; AMF aus
	lxi	h,itimeo
	shld	ivdsk1
	LXI	H,IVDSK1
	MOV	A,L
	out	flcoac		;; Index-Interrupt
	mvi	a,3
	out	flcoac		;; verbieten

;; Select-Latch-Programmierung
	mvi	a,0ffh		;; alle LW ausschalten
	out	flsel
	out	flmot

;; Ermittlung der vorhandenen Laufwerke
	mvi	c,4		;; 4 LAUFWERKE WEGEN VESCH.
	mvi	d,0
	mvi	a,0f7h		;; ohne lock
flka1:	rlc
	out	flsel
	out	flmot
	exaf
	mvi	b,85		;; max 85 mal steppen
flka2:	in	flcobd
	rlc			;; kam Spur0-Signal?
	jrnc	flka4		;; -> ja
	mvi	a,01011111b	;; steppen in Richtung Spur 0
	out	flcoad
	mvi	a,11011111b	;; mit Kopf oben
	out	flcoad
	mvi	h,8		;; Schrittzeit abwarten
flka3:	dcr	l
	jrnz	flka3
	dcr	h
	jrnz	flka3
	djnz	flka2		;; -> weiteren Schritt ausfuehren
;****Laufwerke immer existent melden wegen 8" Beistell-Laufwerken ohne Strom
;***	jr	flka5		;; -> LW nicht existent
;***
flka4:	setb	6,d		;; Laufwerk existent melden
flka5:	dcr	c		;; weiteres LW?
	jrz	flka6		;; -> nein
	rrcr	d
	rrcr	d
	exaf
	jr	flka1		;; -> naechstes LW pruefen

flka6:	mov	a,d
	sta	lwexis

	mvi	a,0ffh		;; alle LW ausschalten
	out	flsel
	out	flmot

	xra	a
	sta	alwnr		;; LW 0 ist das zuletzt benutzte, Motor ist aus
	sta	aspnr		;; steht auf Spur 0
	mvi	b,maxdsk
	lxi	h,spnrl
flka7:	mov	m,a		;; alle alten Spurnr. sind 0
	inx	h
	djnz	flka7

fd$init1:	; all initialization done by drive 0
fd$init2:
	ret

fd$login:
		; This entry is called when a logical drive is about to
		; be logged into for the purpose of density determination.

		; It may adjust the parameters contained in the disk
		; parameter header pointed at by <DE>

	ret	; we have nothing to do in
		;	simple single density only environment.


; disk READ and WRITE entry points.

		; these entries are called with the following arguments:

			; relative drive number in @rdrv (8 bits)
			; absolute drive number in @adrv (8 bits)
			; disk transfer address in @dma (16 bits)
			; disk transfer bank	in @dbnk (8 bits)
			; disk track address	in @trk (16 bits)
			; disk sector address	in @sect (16 bits)
			; pointer to XDPH in <DE>

		; they transfer the appropriate data, perform retries
		; if necessary, then return an error code in <A>

;
; READ UND WRITE UNTER VERWENDUNG DES PHYSISCHEN FLOPYTREIBERS
;
CALC:
	XRÁ	A
	MOÖ	B,Á	ť SIDĹ SELEKÔ AUĆ 0
	STÁ	MSIDAKT
	LDA	@SECT	; 0..9 IST DER BEREICH
	INR	A	; 1..10 STARTSEKTOR DES GEBIETES (1K)
	STA	MSEKAKT
	STA	ASEKAKT	; ANZEIGE SEKTOR ZWISCHENSPEICHERN
	SUI	6	; PRUEFEN OB VORDERSEITE
	JC	CAL1
	INR	A	; RUECKSEITE SEKTOREN AB 1 (1K)
	STA	MSEKAKT
	MVI	A,1	; SIDE SELECT AUF 1
	STA	MSIDAKT
CAL1:	LDA	@RDRV	; LAUFWERK
	cpi	2
	mvi	b,1
	jrnz	cal2
	mvi	b,2
	mvi	a,1	; Laufwerk C ist Laufwerk 1
cal2:
	STA	MDRVAKT
	mov	a,b	; Anzahl Stepimpulse / Spur
	sta	stp
	LDA	@TRK	; SPUR
	STA	MTRKAKT
	LHLD	@DMA
	SHLD	ADR
	RET
;

fd$read:		; EINEN SEKTOR LESEN
	CALL	CALC
	CALL	PHREAD	; SEKTOR LESEN
	JR	RETAUS
;

fd$write:		; SCHREIBEN EINES SEKTORS
	CALL	CALC
	CALL	PHWRITE
;
RETAUS:
	ORA	A
	MVI	A,0
	RZ
	MVI	A,1	; FEHLER AUFGETRETEN
	RET
;
;
; EINBINDEN PHYSISCHER FLOPPYROUTINEN READ / WRITE
;
PHREAD:
	MVI	B,39H	; PFTKOM FUER LESEN
	JMP	PHREWR

PHWRITE:
	MVI	B,3CH	; PFTKOM FUER SCHREIBEN OHNE VERIFY
PHREWR:
	LDA	MSIDAKT
	ORA	A
	MOV	A,B
	JRZ	PH1
	ORI	80H
PH1:	STA	PFTKOM
;
; ANZEIGE LESE- / SCHREIBVORGANG
;
	BIT	2,A
	MVI	A,'R'
	JRZ	ANZREA
	MVI	A,'W'
ANZREA:	STA	ANZRW
	LDA	@rdrv	; mdrvakt
	ADI	41H
	STA	ANZDRV
	LDA	MTRKAKT
	CALL	HEXASC
	SHLD	ANZTRK
	LDA	ASEKAKT
	CALL	HEXASC
	SHLD	ANZSEK
	LXI	H,ANZEIG
	LXI	D,0FFC7H
	LXI	B,9
	LDIR				; ANZEIGE AUF BILDSCHIRM
	LXI	H,ADR
	LXI	D,PFTADR
	LXI	B,10
	LDIR
	JMP	FLOPPY

;
; UNTERPROGRAMM FUR UMRECHNUNG HEX IN ASCII
;
HEXASC:
	MVI	L,'0'
HEXAS1:	CPI	10
	JRC	HEXAS2
	INR	L
	SBI	10
	JR	HEXAS1
HEXAS2:	ADI	'0'
	MOV	H,A
	RET
;
; ANZEIGEPUFFER LESE- / SCHREIBVORGANG
;
ANZEIG:
ANZDRV:	DB	' :'
ANZTRK:	DB	'  /'
ANZSEK:	DB	'   '
ANZRW:	DB	' '
;
; RAM - ZELLEN
;
ASEKAKT:
	DB	0	; SEKTOR 1..10 FUER ANZEIGE

; NACHFOLGENDE TABELLE ( BIS STI ) DARF IN IHREM AUFBAU NICHT
; VERAENDERT WERDEN, DA SIE MITTELS LDIR-BEFEHL DEM PHYSISCHEN
; DISKETTENTREIBER UEBERGEBEN WIRD

ADR:	DW	0	; ADRESSE DES BUFFERS FUER PHYSISCHE
			; FLOPPYROUTINE
MDRVAKT:
	DB	0	; DRIVE, DAS GELADEN IST
MTRKAKT:
	DB	0	; TRACK
MSIDAKT:
	DB	0	; SIDE
MSEKAKT:
	DB	0	; SEKTOR
LEN:	DB	3	; PHYSISCHE BLOCKLAENGE
ANZ:	DB	1	; ANZAHL ZU TRANSFERIERENDER SEKTOREN
STP:	DB	1	; ANZAHL STEPIMPULSE PRO SPUR
STI:	db	5*10
;	DB	4*10	; SCHRITTZEIT FUER STEP

	end

