
TITLE	' CP/M-SYSTEM FUER PC 1715 '
; VERSION 1.1
; STAND 15.09.88

	MACLIB	Z80
	MACLIB	DISKDEF

	PUBLIC	BIOS
	PUBLIC	INTEND,UHRPUF

	EXTRN	FLOPPY,PFTKOM,PFTADR
	EXTRN	DIOMRK,ITIMEO,LWEXIS,ALWNR,ASPNR,SPNRL
	EXTRN	BDOS,CCP
	EXTRN	TASINI,TASABF,TAB,TABMER

;**************************************************************
; VEREINBARUNGEN
;**************************************************************

CDISK	EQU	4

intvec	EQU	0F700H		; INTERRUPTTABELLE
IVDSK1	EQU	0E0H
IVDSK2	EQU	IVDSK1+2
IVCTC	EQU	0E8H

TASTP	EQU	0FF80H
TASTPE	EQU	TASTP+30H

MAXDSK	EQU	2

;****************** E/A - VEREINBARUNGEN **********************


CTC	EQU	08H
CTCK3	EQU	CTC+3		; CTC-KANAL FUER UHR


SIO	EQU	0CH		; SIO-BAUSTEIN
CTC	EQU	08H		; CTC-BAUSTEIN
LSTDAT	EQU	SIO+1		; LST-KANAL DER SIO
LSTCRT	EQU	SIO+3
LSTCTC	EQU	CTC+1

CRTPAR	EQU	18H		; CRT-CONTROLLER-PARAMETERREG.
CRTBEF	EQU	19H		; CRT-CONTROLLER-STEUERREGISTER
CRTBWS	EQU	34H		; BWS-ANFANGSADRESSENREGISTER


; 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)



;**************************************************************
;********************* PROGRAMMBEGINN *************************
;**************************************************************

BIOS:

;**************************************************************
;******************* BIOS-SPRUNGVERTEILER *********************
;**************************************************************

	JMP	BOOT		; EINTRITT NACH LADEPROGRAMM
WBOOTE:	JMP	WBOOT		; EINTRITT NACH PROGRAMMABAR-
				; BEITUNG
	JMP	CONST		; KONSOLENSTATUS (TASTATUR)
	JMP	CONIN		; KONSOLENEINGABE (TASTATUR)
	JMP	CONOUT		; KONSOLENAUSGABE (BILDSCHIRM)
	JMP	LIST		; DRUCKERAUSGABE
	JMP	PUNCH		; STANZERAUSGABE (DUMMYROUTINE)
	JMP	READER		; LESEREINGABE (DUMMYROUTINE)

;**************************************************************
;******************** DISKETTENSTEUERUNG **********************
;**************************************************************

	JMP	HOME
	JMP	SELDSK
	JMP	SETTRK
	JMP	SETSEC
	JMP	SETDMA
	JMP	READ
	JMP	WRITE
	JMP	LISTST		; LSTSTATUS (DRUCKER)
	JMP	SECTRAN

;**************************************************************

SYSSIG:	DB	0CH,'CP/M - SYSTEM FUER PC 1715 ',0

;**************************************************************
; VEREINBARUNGEN FUER DISKETTEN
;**************************************************************

	DISKS	2

	DISKDEF	0,1,80,0,2048,390,128,128,2

	DISKDEF	1,0

;**************************************************************

BOOT:	DI

;************* SYSTEMGRUNDEINSTELLUNGEN VORNEHMEN *************

	LXI	SP,80H		; SPEICHERSEITE 0 LOESCHEN
	LXI	H,0F800H	; UND BILDSCHIRM
	LXI	B,800H
BOOT1:	MVI	M,' '
	INX	H
	DCX	B
	MOV	A,B
	ORA	C
	JRNZ	BOOT1
	MVI	B,80H
BOOT2:	MVI	M,0
	INX	H
	DJNZ	BOOT2

;**************** INITIALISIEREN CRT-CONTROLLER ***************

	MVI	A,3EH
	OUT	CRTBWS
	XRA	A		; STOP DISPLAY / RESET
	OUT	CRTBEF
	MVI	A,4FH		; PARAMETER 1
	OUT	CRTPAR
	MVI	A,58H		; PARAMETER 2
	OUT	CRTPAR
	MVI	A,6BH		; PARAMETER 3
	OUT	CRTPAR
	MVI	A,6DH		; PARAMETER 4
	OUT	CRTPAR
	MVI	A,20H		; START DISPLAY
	OUT	CRTBEF

;******************** FLOPPY INITIALISIEREN *******************

;; Port Steuer-B
	lxi	h,diomrk	;; Adressmarken-Interrupt
	shld	(intvec+ivdsk2)
	mvi	a,ivdsk2
	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	(intvec+ivdsk1)
	mvi	a,ivdsk1
	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

BOOT5:
	MVI	A,HIGH(INTVEC)	; INITIALISIERUNG INTERRUPT
	STAI
	IM2
	MVI	C,LSTCTC	; DRUCKERINITIALISIERUNG
	MVI	B,2
	LXI	H,LSTTAB
	OUTIR
	MVI	C,LSTCRT
	MVI	B,9
	OUTIR

	CALL	TASINI		; INITIALISIEREN DER TASTATUR

;______________________________________________________________
; INITIALISIEREN DES UHRINTERRUPTES / ABFRAGE DER TASTATUR
;______________________________________________________________

	LXI	H,UHRPUF	; UHRPUFFER FREIMACHEN
	MVI	B,4
SC:	MVI	M,0
	INX	H
	DJNZ	SC
	MVI	M,5
	LXI	H,TASTP		; FREIMACHEN TASTATURPUFFER
	MVI	B,TASTPE-TASTP+6
SC1:	MVI	M,0
	INX	H
	DJNZ	SC1
	LXI	H,TIMINT	; EINSTELLEN INT-TABELLE KANAL 2
	SHLD	INTVEC+IVCTC+6
	MVI	A,IVCTC		; INT-VEKTOR CTC LADEN
	OUT	CTC
	MVI	A,0A5H		; ZEITGEBERMODUS KANAL 2
	OUT	CTCK3
	MVI	A,0C0H		; ZEITKONSTANTE 20 ms
	OUT	CTCK3
	EI

;******************** SYSTEMMELDUNG AUSGEBEN ******************

	LXI	H,SYSSIG	; SYSTEMMELDUNG AUSGEBEN
	CALL	PRMMSG

;********** INITIALISIEREN DER GRUNDEINSTELLUNGEN *************

	XRA	A
	STA	CDISK		; LAUFWERK A WIRD ANGEWAEHLT
	STA	MWRTFLG		; KEIN SCHREIBVORGANG
	DCR	A
	STA	MDRVAKT		; LAUFWERK IST UNDEFINIERT

;********************* WARMSTART AUSFUEHREN *******************

	JR	GOCPM

;********************** WARMSTARTROUTINE **********************

WBOOT:
	LXI	SP,80H

;******************* CCP-LADUNG VON SPUR 0 ********************

	LDA	MWRTFLG		; WENN NOCH EIN ALTER PUFFER
	ORA	A		; ZUM SCHREIBEN, DANN ZURUECK
	JRZ	NOTBAC		; SONST WEITER
	CALL	PUTTRK		; NORMALERWEISE IST SCHREIB-
				; VORGANG NACH EINEM DIRECTORY-
				; ZUGRIFF ABGESCHLOSSEN
NOTBAC:				; ALLE TRACKS UNGUELTIG
	MVI	A,0FFH
	STA	MDRVAKT
;
	MVI	C,5		; ANZAHL DER VERSUCHE
	PUSH	B		; UND DANN ANFANGEN ZU BOOTEN
WBOOT0:
	LXI	B,CCP		; BOOT VON MINIDISK
	CALL	SETDMA		; AUF DER STARTADRESSE DES CP/M
	MVI	C,0		; LAUFWERK A AUSWAEHLEN
	CALL	SELDSK
	MVI	C,0		; SPUR 0 AUSWAEHLEN
	CALL	SETTRK
	MVI	C,1		; AB SEKTOR 2 (128 BYTE ZAEHL.)
	CALL	SETSEC		; STEHT BEI PC 1715 DAS CP/M
	POP	B		; UND VON DA AN CCP UND BDOS
	MVI	B,2CH		; EINLESEN, BIOS ABER NICHT
				; UEBERSCHREIBEN FUER PATCH'S
RDSEC:	PUSH	B		; ANZAHL MERKEN
	CALL	READ		; LESEN AUSFUEHREN
	JNZ	BOOTERR		; FEHLER DEFEKTER SEKTOR
	LHLD	IOD		; ZIELADRESSE LADEN
	LXI	D,128		; UM LOGISCHE SEKTORADRESSE ZU
	DAD	D		; ERHOEHEN, DAZUADDIEREN
	SHLD	IOD		; UND DANN WIEDER ZURUECKSP.
	LDA	IOS		; SEKTOR LADEN
	CPI	79		; MINI 0..79 SEKTOREN A 128 BY.
	JC	RD1		; SOLANGE AUF GLEICHER SPUR
	LDA	IOT		; DANN NAECHSTE SPUR
	INR	A
	STA	IOT
	MVI	A,0FFH		; SEKTOR NACH INCR. 0
RD1:	INR	A
	STA	IOS		; NEUEN SEKTOR
	POP	B		; SCHLEIFENZAEHLER ZURUECK
	DCR	B		; UND WEITER LESEN
	JNZ	RDSEC

;******** SPEICHERSEITE 0 MIT CP/M-STANDARDWERTEN LADEN *******

GOCPM:
	MVI	A,JMP
	STA	0
	LXI	H,WBOOTE
	SHLD	1
	STA	5
	LXI	H,BDOS
	SHLD	6

	LXI	B,80H		; BUFFER AUF DEFAULT
	CALL	SETDMA		; SO WIE ES CP/M BRAUCHT
	LDA	CDISK		; DAS ZULETZT VERWENDETE LW
	MOV	C,A		; LADEN UND DAMIT SELEKTIEREN

;********** INITIALISIERUNG FERTIG UEBERGANG ZUM CCP **********


	JMP	CCP

;**************** BEHANDLUNG BEI BOOT ERROR *******************

BOOTERR:			; IM FEHLERFALLE BAD SEKTOR
	POP	B		; ERST NOCH EINMAL VERSUCHEN
	DCR	C
	JZ	BOOTER0		; BIS HOFFNUNGSLOS
	PUSH	B
	JMP	WBOOT0		; WIEDERHOLUNG

BOOTER0:			; FEHLERMELDUNG AUSGEBEN
	LXI	H,BOOTMSG	; UND WBOOT NEU STARTEN
	CALL	PRMMSG
BOOTER1:
	CALL	CONIN		; WARTEN AUF TASTE
	CPI	3		; MUSS ^C SEIN
	JRNZ	BOOTER1
	JMP	WBOOT		; DANN NEU VERSUCHEN

BOOTMSG:
	DB	0DH,0AH,'?BOOT',0DH,0AH,0

;**************************************************************
; INITIALISIERUNGSTABELLE FUER DRUCKER
;**************************************************************

LSTTAB:	DB	5		; CTC
	DB	1
	DB	0		; SIO
	DB	19H		; REG. 1
	DB	0		; KEIN INTERRUPT
	DB	3		; REG. 3
	DB	0C1H		; 8 BIT EMPFANGEN
	DB	4		; REG. 4
	DB	45H		; VT=16, 1 STOPBIT, UNGER. PAR.
	DB	5		; REG. 5
	DB	68H		; 8 BIT SENDEN

;**************************************************************
; CONSOLSTATUS
;**************************************************************

CONST:
	LHLD	TABMER
	MOV	A,H
	ORA	L
	JRNZ	CONST1
	LDA	TASTP
	ORA	A
	RZ			; KEINE TASTE
CONST1:	MVI	A,0FFH		; TASTE DA
	RET

;**************************************************************
; CONSOLEINGABE
;**************************************************************

CONIN:
	LHLD	TABMER
	MOV	A,H
	ORA	L
	JRNZ	NEXZEI
CONIN1:	LDA	TASTP
	ORA	A
	JRZ	CONIN1
	LXI	D,TASTP
	LXI	H,TASTP+1
	LXI	B,TASTPE-TASTP+5
	DI
	LDIR
	PUSH	PSW
	XRA	A
	LDAX	D
	POP	PSW
	EI
	LXI	H,TAB
	MOV	B,A
SUCH:	MOV	A,M
	ORA	A
	JRZ	NOTFOU
	INX	H
	CMP	B
	JRZ	SUCHE
WEIT:	INX	H
	MOV	A,M
	ORA	A
	JRNZ	WEIT
	INX	H
	JR	SUCH
SUCHE:
NEXZEI:	MOV	B,M
	INX	H
	MOV	A,M
	ORA	A
	JRNZ	MEHRZE
NOTFOU:	LXI	H,0
MEHRZE:	SHLD	TABMER
	MOV	A,B
	CPI	80H
	RC
	XRA	A
	RET

;**************************************************************
; INTERRUPTROUTINE UHRZEIT
;**************************************************************

TIMINT:	SSPD	RETTSP
	LXI	SP,TIMSTE
	PUSH	PSW
	PUSH	H
	PUSH	B

;______________________________________________________________

	LXI	H,UHRPUF+4
	DCR	M

;______________________________________________________________
; 20-ms ZAEHLER
;______________________________________________________________

	DCX	H
	INR	M
	MVI	A,50		; 50 * 20 ms
	SUB	M
	JNZ	TASABF
	MOV	M,A

;______________________________________________________________
; SEKUNDEN
;______________________________________________________________

	DCX	H
	MOV	A,M
	INR	A
	DAA
	MOV	M,A
	SUI	60H
	JRNZ	TIMOUT
	MOV	M,A

;______________________________________________________________
; MINUTEN
;______________________________________________________________

	DCX	H
	MOV	A,M
	INR	A
	DAA
	MOV	M,A
	SUI	60H
	JRNZ	TIMOUT
	MOV	M,A
	MVI	A,42H
	STA	UHRPUF+3

;______________________________________________________________
; STUNDEN
;______________________________________________________________

	DCX	H
	MOV	A,M
	INR	A
	DAA
	MOV	M,A
	SUI	24H
	JRNZ	TIMOUT
	MOV	M,A

;______________________________________________________________
; ZEIT AUSGEBEN AUF BSE
;______________________________________________________________

TIMOUT:	PUSH	D
	LXI	D,0FFBBH
	LXI	H,UHRPUF
	MVI	B,3
NEXZEO:	CALL	BYTOUT
	MVI	A,':'
	STAX	D
	INX	D
	INX	H
	DJNZ	NEXZEO
	DCX	D
	MVI	A,' '
	STAX	D
	POP	D
	JMP	TASABF

;______________________________________________________________

BYTOUT:	MOV	A,M
	RRC
	RRC
	RRC
	RRC
	CALL	BYTOU1
	MOV	A,M
BYTOU1:	ANI	0FH
	ADI	'0'
	STAX	D
	INX	D
	RET

;______________________________________________________________
; ENDE TASTATURABFRAGE / UHREINSTELLUNG
;______________________________________________________________

INTEND:	POP	B
	POP	H
	POP	PSW
	LSPD	RETTSP
	EI
	RETI

;______________________________________________________________

TIMST:	DS	20H		; STACK FUER TIMINT
TIMSTE:
RETTSP:	DW	0		; STACKPOINTER MERKEN

;______________________________________________________________


;**************************************************************
; CONSOLAUSGABE
;**************************************************************

CONOUT:	LXI	H,00FFH		; CLEAR CURSOR
	CALL	SETCU3
	LHLD	CURS
	INR	H
	DCR	H
	JRNZ	CON1
	MVI	H,0F8H		; SETZEN KURSOR AUF BILDANFANG
	MVI	M,' '
	SHLD	CURS
CON1:
	PUSH	PSW
	LDA	ESCMER		; WAR ESC-FOLGE ?
	ORA	A
	JRZ	NOESC		; -> NEIN
	DCR	A
	STA	ESCMER
	JRZ	ESC2		; -> 2.BYTE DER ESC-FOLGE
	LXI	H,0F800H	; BEHANDLUNG 1.BYTE DER ESC-FO.
	MOV	A,C		; ALS ZEILENANGABE
	ANI	7FH
	ORA	A
	JRZ	SETCUR
	CPI	18H
	JRC	ESC11
	LXI	H,0F800H
	JR	SETCUR
ESC11:	MOV	B,A
	LXI	D,0050H
ESC12:	DAD	D
	DJNZ	ESC12
	JR	SETCUR
ESC2:	MOV	A,C		; BEHANDLUNG 2.BYTE DER ESC-FO.
	ANI	7FH		; ALS SPALTENANGABE
	CPI	50H
	LXI	D,004FH
	JRNC	ESC22
ESC21:	MOV	E,A
ESC22:	DAD	D
	JR	SETCUR
NOESC:
	MOV	A,C		; AUSWERTUNG STEUERZEICHEN
	CPI	7FH
	JRZ	CHRDEL
	CPI	20H
	JRC	CRTCRTL
CRTZEI:	ANI	7FH
	MOV	M,A		; ZEICHEN AUF BILDSCHIRM
	CALL	CRTCRI
;
SETCUR:
	SHLD	CURS
	CALL	SETCUS
	POP	PSW
	RET
;
SETCUS:
	XRA	A
	LXI	D,0F800H
	DSBC	DE		; SBC HL,DE
	MVI	C,0
	LXI	D,50H
SETCU1:
	DSBC	DE		; SBC HL,DE
	JRC	SETCU2
	INR	A
	JR	SETCU1
SETCU2:
	DAD	D
	MOV	H,A
SETCU3:
	MVI	A,80H		; CURSOR SETZEN
	OUT	CRTBEF
	MOV	A,L		; SPALTE
	OUT	CRTPAR
	MOV	A,H		; ZEILE
	OUT	CRTPAR
	RET

CHRDEL:	CALL	CRTDCH
CRTCRTL:
	CPI	0DH		; STEUERZEICHEN AUSWERTEN
	CZ	CRTCR
	CPI	0AH
	CZ	CRTLF
	CPI	15H
	CZ	CRTCRI
	CPI	08H
	CZ	CRTCLE
	CPI	0CH
	CZ	CRTFF
	CPI	01H
	CZ	CRTHOM
	CPI	14H
	CZ	CRTDRB
	CPI	18H
	CZ	CRTDZE
	CPI	16H
	CZ	CRTDCZ
	CPI	1AH
	CZ	CRTCHO
	CPI	1BH
	CZ	CRTESC
	JMP	SETCUR
CRTDCH:	MVI	M,' '		; DEL
CRTCLE:	DCX	H		; BACKSPACE
	MOV	A,H
	CPI	0F7H
	RNZ
	INX	H
	RET
CRTFF:	LXI	H,0F800H	; FORM FEED
	MVI	M,' '
	LXI	D,0F801H
	LXI	B,077FH
	LDIR
CRTHOM:	LXI	H,0F800H	; HOME POSITION
	RET
CRTLF:	LXI	D,0050H		; LINE FEED
	DAD	D
	MOV	A,H
	CPI	0FFH
	RNZ
	MOV	A,L
	CPI	80H
	RC
	DSBC	DE		; SBC HL,DE
	JR	CRTPO1
CRTCRI:	INX	H		; NAECHSTE KURSORPOSITION
	MOV	A,H		; WENN NOETIG BILD ROLLEN
	CPI	0FFH
	RNZ
	MOV	A,L
	CPI	80H
	RC
	LXI	H,0FF30H
CRTPO1:	PUSH	H
	LXI	B,0730H
	LXI	H,0F850H
	LXI	D,0F800H
	LDIR
	MVI	A,' '
	MVI	B,50H
CRTPO2:	DCX	H
	MOV	M,A
	DJNZ	CRTPO2
	POP	H
	RET
CRTCR:	MOV	B,H		; CARRIAGE RETURN
	MOV	C,L
	LXI	H,0FF80H
	LXI	D,0050H
	ORA	A
CRTCR1:	DSBC	DE		; SBC HL,DE
	PUSH	H
	DSBC	BC		; SBC HL,BC
	POP	H
	RZ
	JRNC	CRTCR1
	RET
CRTESC:	MVI	A,02H		; BEHANDLUNG ESC-FOLGE
	STA	ESCMER		; BEGINNEN
	RET
CRTDRB:	XCHG			; LOESCHEN AB CURSOR BIS
	LXI	H,0FF7FH	; BILDENDE
	DSBC	DE		; SBC HL,DE
	MOV	B,H
	MOV	C,L
CRTDR1:	MOV	H,D
	MOV	L,E
	INX	D
	MVI	M,' '
	LDIR
	LHLD	CURS
	RET
CRTDZE:	CALL	CRTCR		; LOESCHEN KURSORZEILE UND
				; SETZEN KURSOR AN ZEILEN-
				; ANFANG
CRTDCZ:	LXI	D,004FH		; LOESCHEN AB KURSORPOSITION
	DAD	D		; BIS ZEILENENDE
	LDED	CURS		; LD DE,(CURS)
	ORA	A
	DSBC	DE
	MOV	B,H
	MOV	C,L
	JR	CRTDR1
CRTCHO:	LXI	D,0050H		; KURSOR EINE ZEILE HOCH
	DSBC	DE
	MVI	A,0F7H
	CMP	H
	RC
	LHLD	CURS
	RET

CURS:	DW	0F800H		; KURSORMERKER
ESCMER:	DB	0		; ESC - MERKER

;**************************************************************

LIST:	CALL	LISTST
	ORA	A
	JZ	LIST		; LIST NOT READY
	MOV	A,C
	ANI	7FH		; MASKIEREN ALS 7 BIT AUSGABE
	OUT	LSTDAT
	RET

;**************************************************************
; DRUCKERSTATUS
;**************************************************************

LISTST:	MVI	A,10H
	OUT	LSTCRT
	IN	LSTCRT
	CMA
	BIT	5,A		; CTS FREI ?
	JRNZ	LISTS1		; NEIN
	BIT	2,A		; SENDER FREI ?
LISTS1:	MVI	A,0
	RNZ			; LIST NOT READY
	DCR	A
	RET			; LIST READY

;**************************************************************
; STANZERAUSGABE (DUMMY)
;**************************************************************

PUNCH:	MOV	A,C
	RET

;**************************************************************
; LESEREINGABE (DUMMY)
;**************************************************************

READER:	MVI	A,1AH
	RET

;**************************************************************
; UNTERPROGRAMM ZEICHENKETTENAUSGABE
;**************************************************************

PRMMSG:	MOV	A,M
	ORA	A
	RZ
	PUSH	H
	MOV	C,A
	CALL	CONOUT
	POP	H
	INX	H
	JR	PRMMSG

;**************************************************************
; DISKETTENSTEUERUNG
;**************************************************************

SELDSK:			; LAUFWERK AUSWAEHLEN
	LXI	H,0	; UND PRUEFEN OB GUELTIG
	MOV	A,C	; WENN GROESSER ALS NDISK
	CPI	MAXDSK	; DANN NICHT OK
	RNC		; NUMMER 0 BIS N-1 ERSCHEINT IN A
	STA	DBANK	; DANN ZUSAETZLICH DIE
	MOV	L,C	; LAUFWERKSTABELLE AUSRECHNEN
	MVI	H,0	; DAZU NUMMER MIT 16 MLTIPLIZIEREN
	REPT	4
	DAD	H
	ENDM
	LXI	D,DPBASE ; UND BASISADRESSE DRAUF ADDIEREN
	DAD	D
	RET
; 
HOME:			; Laufwerk auf Spur 0 anfahren
	MVI	C,0	; nur anwaehlen, aber nicht ausfuehren
;
SETTRK:			; Spur merken, dazu in Speicherzelle
	LXI	H,IOT	; laden
	MOV	M,C
	RET
;
SETSEC:			; SEKTOR MERKEN
	LXI	H,IOS	; DAZU IN SPEICHERZELLE LADEN
	MOV	M,C
	RET
;
SECTRAN:		; SEKTOR UMSETZEN
	MOV	A,D	; WENN EIN SKEWFAKTOR VERWENDET WIRD,
	ORA	E	; WIE Z.B. BEI 8 ZOLL UEBLICH.
	JZ	SE1	; =0, DANN KEIN SKEW VERWENDET,
	MVI	B,0	; SONST IN DE ADRESSE DER SKEW-TABELLE
	XCHG		; DAZU SEKTOR IN C ADDIEREN
	DAD	B	; UND WERT ALS NEUEN SEKTOR
	MOV	A,M	; FESTLEGEN UND
	STA	IOS	; SPEICHERN.
	MOV	L,A
	RET
SE1:	MOV	L,C	; SONST NUR EINFACHEN WERT
	MOV	A,C	; UEBERNEHMEN, OHNE UMRECHNUNG.
	STA	IOS	; AUCH MERKEN
	MVI	H,0	; SE 0.. 255 MAX
	RET
;
SETDMA:			; ADRESSE FUER FLOPPYZUGRIFF FESTLEGEN
	MOV	L,C
	MOV	H,B
	SHLD	IOD
	RET
;
; READ UND WRITE UNTER VERWENDUNG DES PHYSISCHEN FLOPYTREIBERS
; FUER 1 K BYTE BLOECKE
;
CALC:			; RECHNET IOS IN SEKTORBUFFERNR UM
	XRA	A
	MOV	B,A	; SIDE SELEKT AUF 0
	STA	SIDE
	LDA	IOS	; 0..79 IST DER BEREICH
	RRC		; X000NNNN 0..15
	RRC
	RRC		; 0..9
	ANI	0FH	; MAX
	INR	A	; 1..10 STARTSEKTOR DES GEBIETES (1K)
	MOV	E,A	; IN E ALS PARAMETER
	STA	SIDIOS	; ANZEIGE SEKTOR ZWISCHENSPEICHERN
	SUI	6	; PRUEFEN OB VORDERSEITE
	JC	CAL1
	INR	A	; RUECKSEITE SEKTOREN AB 1 (1K)
	MOV	E,A
	MVI	A,1	; SIDE SELECT AUF 1
	MOV	B,A
	STA	SIDE
CAL1:	LDA	DBANK	; LAUFWERK
	MOV	C,A
	LDA	IOT	; SPUR
	MOV	D,A
	RET		; TRACK=D , SEKTOR=E , DRIVE=C
;
READ:			; EINEN SEKTOR LESEN
	LDA	DBANK	; DAZU LAUFWERK BESTIMMEN
;
; HIER EINFUEGEN ZUKUENFTIGEN TEST AUF RAMFLOPPY
;
; 8" LAUFWERKE WERDEN NICHT UNTERSTUETZT
;
MINIRD:			; FUER VERGLEICH,
	CALL	CALC	; LAUFWERKSDATEN UMRECHNEN
	LDA	MDRVAKT	; UND NUN AKTUELLES LAUFW. VERGLEICHEN
	CMP	C	; WENN NICHT GLEICH, DANN NEU LADEN
	JNZ	RLOAD
	LDA	MTRKAKT	; SONST SPUR VERGLEICHEN
	CMP	D	; UND
	JNZ	RLOAD
	LDA	MSIDAKT	; SONST SIDE VERGLEICHEN
	CMP	B
	JNZ	RLOAD
	LDA	MSEKAKT	; SONST SEKTOR
	CMP	E	; WENN GLEICH, DANN SEKTOR IM SPEICHER
	JNZ	RLOAD
R1RD:			; OK, SEKTOR IST IM PUFFER
	LXI	H,BUFFER ; ADRESSE BERECHNEN
	LDA	IOS	; 0..39 * 128 + BUFFER
	ANI	7	; 0,1,..,7
	MOV	D,A	; SEKTOR * 256 / 2
	MVI	E,0	; SCHIEBEN MIT Z80 BEFEHLEN
	DB	0CBH,2AH ; SRA D
	DB	0CBH,1BH ; RR  E = * 256 / 2
	DAD	D	; + BUFFER
	XCHG		; NACH DE IST ZIEL
	LHLD	IOD	; DMA ADRESSE QUELLE HIER
	XCHG		; ZIEL DE
	LXI	B,128	; LAENGE
	DB	0EDH,0B0H ; LDIR
	XRA	A
	RET		; OK ENDE

RLOAD:			; NEUEN LADEN, GGF ALTEN ZURUECKSCHR.
	LDA	MWRTFLG
	ORA	A
	JZ	R1LOAD
	CALL	PUTTRK	; ALTEN ZURUECKSCHREIBEN
	JC	ERRIO
R1LOAD:	CALL	CALC	; BERECHNEN
	MOV	A,C
	STA	MDRVAKT
	MOV	A,B
	STA	MSIDAKT
	MOV	A,E
	STA	MSEKAKT
	MOV	A,D
	STA	MTRKAKT
	LDA	SIDIOS	; ANZEIGE SEKTOR AKTUALISIEREN
	STA	ASEKAKT
	CALL	GETTRK	; NEUEN SEKTOR LESEN
	JC	ERRIO	; FEHLER AUFGETRETEN
	JMP	R1RD	; ENDE
;

WRITE:			; SCHREIBEN EINES SEKTORS
	LDA	DBANK	; DAZU LAUFWERK BESTIMMEN
;
; HIER EINFUEGEN ZUKUENFTIGEN TEST AUF RAMFLOPPY
;
; 8" LAUFWERKE WERDEN NICHT UNTERSTUETZT
;
MINIWR:			; SCHREIBEN EINES SEKTORS
	MOV	A,C
	STA	ALLOC	; INFORMATION 1=DIRECTORYWRITE
	CALL	CALC	; FUER VERGLEICH, BERECHNUNG AUSFUEHREN
	LDA	MDRVAKT	; UND WIE BEI MINIRD
	CMP	C
	JNZ	WLOAD
	LDA	MTRKAKT
	CMP	D
	JNZ	WLOAD
	LDA	MSIDAKT
	CMP	B
	JNZ	WLOAD
	LDA	MSEKAKT
	CMP	E
	JNZ	WLOAD
			; LADEN UNNOETIG, DA SEKTOR SCHON DA
W1WR:			; OK IST SCHON IN BUFFER
	LXI	H,BUFFER
	LDA	IOS	; 0..79 * 128 + BUFFER
	ANI	7	; 0,1,2,3,4,5,6,7
	MOV	D,A	; SEKTOR * 256
	MVI	E,0	; SCHIEBEN MIT Z80 BEFS
	DB	0CBH,2AH ; SRA D
	DB	0CBH,1BH ; RR  E = * 256 / 2
	DAD	D	; + BUFFER
	XCHG		; NACH DE IST ZIEL
	LHLD	IOD	; DMA ADRESSE IST QUELLE HIER
	LXI	B,128	; LAENGE
	DB	0EDH,0B0H ; LDIR
	MVI	A,1
	STA	MWRTFLG	; NUN BESCHRIEBEN
	LDA	ALLOC	; =1 DANN SOFORT ZURUECKSCHREIBEN
	CPI	1	; WEIL DIRECTORYZUGRIFF
	JNZ	W2WR
	CALL	PUTTRK
	JC	ERRIO	; FEHLER AUFGETRETEN, BAD SEKTOR
W2WR:
	XRA	A	; KEIN FEHLER
	RET		; OK ENDE
;
WLOAD:			; NEUEN LADEN, GGF ALTEN ZURUECKSCHR.
	LDA	MWRTFLG
	ORA	A
	JZ	W1LOAD
	CALL	PUTTRK	; ALTEN ZURUECKSCHREIBEN
	JC	ERRIO
W1LOAD:	CALL	CALC	; BERECHNEN
	MOV	A,C
	STA	MDRVAKT
	MOV	A,B
	STA	MSIDAKT
	MOV	A,E
	STA	MSEKAKT
	MOV	A,D
	STA	MTRKAKT
	LDA	SIDIOS	; ANZEIGE SEKTOR AKTUALISIEREN
	STA	ASEKAKT
	LDA	ALLOC
	CPI	2
	JZ	W1WR	; OHNE VORHERIGES LESEN
	CALL	GETTRK
	JC	ERRIO
	JMP	W1WR
;
ERRIO:	MVI	A,1	; FEHLER AUFGETRETEN
	ORA	A
	RET
;
; BUFFER VERWALTUNG
;
GETTRK:			; TRKAKT,SEKAKT,DRVAKT,SIDE ENTHALTEN
			; NEUE BUFFERADRESSE

; HIER KOPPLUNG PHYSISCHEN TREIBER EINBINDEN
; BUFFER LESEN

	CALL	PHREAD

	JC	ERRX
	XRA	A
	RET

ERRX:	STC
	RET

PUTTRK:			; TRKAKT,SEKAKT,DRVAKT,SIDE ENTHALTEN
			; NEUE BUFFERADRESSE
	XRA	A	; BUFFER FREI MELDEN, WIRD
	STA	MWRTFLG	; ZURUECKGESCHRIEBEN

; HIER KOPPLUNG PHYSISCHEN TREIBER EINBINDEN
; BUFFER SCHREIBEN

	CALL	PHWRITE

	JC	ERRX
	XRA	A
	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	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
	CALL	FLOPPY
	ORA	A
	RZ
	STC
	RET
;
; 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
;
UHRPUF:	DS	6	; 4 BYTE UHRPUFFER

ASEKAKT:
	DB	0	; SEKTOR 1..10 FUER ANZEIGE
MWRTFLG:
	DB	0	; <> 0 IST BESCHRIEBEN

; NACHFOLGENDE TABELLE ( BIS STI ) DARF IN IHREM AUFBAU NICHT
; VERAENDERT WERDEN, DA SIE MITTELS LDIR-BEFEHL DEM PHYSISCHEN
; DISKETTENTREIBER UEBERGEBEN WIRD

ADR:	DW	BUFFER	; 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	4*10	; SCHRITTZEIT FUER STEP

ALLOC:
	DB	0	; MERKER 1= DIRECTORY WRITE
;
SIDIOS:	DB	0	; MERKER FUER SEKTOR PHYSISCH
;
DBANK:	DB	0
IOT:	DB	0	; SPUR
IOS:	DB	0	; SEKTOR
SIDE:	DB	0	; SIDE SELECT
IOD:	DW	0	; DMA


BUFFER:	DS	1024

	ENDEF
