;******************************************************************
;***                                                            ***
;***  PROF-80 Monitor Version: 1.6                              ***
;***                                                            ***
;***  letzte Aenderung am: 18.11.1985      (c) Joachim Hanst    ***
;***                                                            ***
;******************************************************************
;
		TITLE	'PROF-80 MONITOR VERSION 1.6'
;
;
;
		MACLIB	Z80
		MACLIB	CDEF	;BENUTZE CDEF.LIB FUER ALLE C-SYSTEM MODULE
;
BELL		EQU	07H
CNGPRMT		EQU	'-'
;
;
		ORG     EPROM
MONITOR:
		;SPRUNGVEKTOR FUER MONITOR SERVICE-ROUTINEN
		;
		JMP	INIT		;MONITOR-EINGANG NACH RESET
		JMP	START		;MONITOR WARM-START
CS		JMP	UMLEIT$CONST	;CONSOLEN STATUS,EIN-UND AUSGABE
CI		JMP	UMLEIT$CONIN	;GEHEN ERST UEBER SPRUNG IM RAM
CO		JMP	UMLEIT$CONOUT	;AUF IHRE VERTEILER
		JMP	SETSEC$CNT	;SETZE ANZAHL DER SEKTOREN
		JMP	BOOTERR		;DRUCKE FEHLERMELDUNG
		JMP	SETCMDT		;SETZE CMDTAB ENTSPRECHEND TEST
		JMP	RECAL		;SETZE AUSGEWAEHLETES DRIVE AUF TRACK 0
		JMP	SELDSK		;WAEHLE DRIVE AUS
		JMP	SETTRK		;SETZE SPUR FUER AUSGEWAEHLTES DRIVE
		JMP	SETSEC		;SETZE SEKTOR FUER AUSGEWAEHLTES DRIVE
		JMP	SETDMA		;SETZE DMA ADRESSE FUER READ/WRITE
		JMP	READ		;LESE DISK
		JMP	WRITE		;SCHREIBE DISK
		JMP	START		;IN ALTEN VERSIONEN WAR HIER GETMINIMAX
		JMP	START		;
;
		JMP	CONST		;CONSOLEN STATUS-VERTEILER
SERNR		DW	18116		;SERIEN NUMMER
RSTART7		JMP	RST$VERTEILER	;RST 7 EINSPRUNG (MUSS 38H SEIN)
		JMP	CONIN		;CONSOLEN EINGABE-VERTEILER
		JMP	CONOUT		;CONSOLEN AUSGABE-VERTEILER
		JMP	TEST		;TESTE DISK-FORMAT
		JMP	MOTO		;WARTE AUF READY UND GEBE DISK-BEFEHL
		JMP	CMFD		;SENDE DISK-BEFEHL OHNE READY
		JMP	RESULT		;ERGEBNISPHASE DES UPD 765
		JMP	SEEK		;POSITIONIERE AUF SPUR
		JMP	NEXT		;LESE EIN RESULT-BYTE AUS UPD 765
		JMP	MULTIP		;MULTIPLIKATION
		JMP	DIVIDE		;DIVISION
		JMP	INT$SERVICE	;EINLESEN EINES ZEICHENS NACH INT.
		JMP	GRAFIN		;VIDEO KARTE EINGABE
		JMP	GRAFOUT		;VIDEO KARTE AUSGABE
		JMP	GRAFIST		;VIDEO KARTE EIN STATUS
VERSIONNR	DB	16H		;VERSIONS NUMMER
		JMP	UMLEIT$NMI	;SPRUNG AUF NMI ROUTINE
		JMP	GRAFOST		;VIDEO KARTE AUS STATUS
		JMP	SOFTIN		;SOFT SCHNITTSTELLE EINGABE
		JMP	SOFTOUT		;SOFT SCHNITTSTELLE AUSGABE
		JMP	SOFTIST		;SOFT SCHNITTSTELLE EIN STATUS
		JMP	SOFTOST		;SOFT SCHNITTSTELLE AUS STATUS
USER1IN		JMP	SAIN		;UNIO-SIO-A EINGABE
USER1OUT	JMP	SAOUT		;UNIO-SIO-A AUSGABE
USER1IST	JMP	SAIST		;UNIO-SIO-A EIN STATUS
USER1OST	JMP	SAOST		;UNIO-SIO-A AUS STATUS
USER2IN		JMP	SBIN		;UNIO-SIO-B EINGABE
USER2OUT	JMP	SBOUT		;UNIO-SIO-B AUSGABE
USER2IST	JMP	SBIST		;UNIO-SIO-B EIN STATUS
USER2OST	JMP	SBOST		;UNIO-SIO-B AUS STATUS
USERINIT	RET			;BENUTZER INITIALISIERUNG
		NOP			;
		NOP			;
		JMP	DISKERR		;FLOPPY-FEHLERMELDUNG
		JMP	SOFTPRNTOUT	;SIMPLEX SCHNITTSTELLE
		JMP	SOFTPRNTOST	;SIMPLEX BEREIT
		JMP	SET$PHYS$TIME	;SETZE ZEIT
		JMP	READ$PHYS$TIME	;LESE ZEIT
		JMP	SET$SHIFT	;SETZE SHIFT-REGISTER
		JMP	SET$DUPLEX$BAUD	;SETZE BAUDRATE DUPLEX
		JMP	SET$SIMPLEX$BAUD;SETZE BAUDRATE SIMPLEX
		JMP	SPECD		;SETZE DISKPARAMETER
					;
					;DIE NACHFOLGENDEN DATEN WERDEN
					;NACH EINEM RESET IN DIE
					;SYSTEMPAGE UEBERNOMMEN.
					;DIE DATEN BEFINDEN SICH AB VERS 1.4
					;IMMER AN DEN GLEICHEN EPROM
					;ADRESSEN, SO DASS SIE VOM
					;BENUTZER LEICHT GEPATCHT WERDEN
					;KOENNEN.
					;
XSPECD$WORD	DW	HLOS*256+256+SRTS*16+HUTS	;STEPRATE, HLT, HUT
					;DIESE DATEN GEBEN DIE DEFAULT
					;EINSTELLUNG AN, SIE WERDEN DURCH
					;DEN U-BEFEHL UEBERDECKT
XSEEKNR		DB	000H		;DOUBLESTEPVEKTOR
XREADY$BYTE	DB	0FFH		;READYBYTE KANN VORDEFINIERT WERDEN.
XTE$TIME	DB	010H		;WARTEZEIT NACH WRITE-DISK (IN 100 US)
XPRNT$BAUD	DB	003H		;BAUDRATE SIMPLEX
STIBAUD		DB	003H		;BAUDRATE UNIO-STI
XSTEP$WAIT	DB	000H		;WARTEZEIT VOR STEP WENN MOTOR AUS WAR
					;
					;SPRUNGVEKTOR FORTSETZUNG
CENT1OUT	JMP	C1OUT		;
CENT1OST	JMP	C1OST		;
CENT2OUT	JMP	C2OUT		;
CENT2OST	JMP	C2OST		;
STIIN		JMP	STIN		;
STIOUT		JMP	STOUT		;
STIIST		JMP	STIST		;
STIOST		JMP	STOST		;
STIINIT		JMP	STINIT		;
SIOAINIT	JMP	SAINIT		;
SIOBINIT	JMP	SBINIT		;
;
;
;
RST$VERTEILER:
	;PRUEFT OB INTERRUPT-BETRIEB DER SOFT-SCHNITTSTELLE
	;WENN NEIN, DANN SPRUNG ZUM MONITOR, SONST EINLESEN
	;DES SERIELLEN ZEICHENS
	;
	PUSH	PSW		;RETTE AKKU
	LDA	IO$JUMPERBYTE	;IST INT.-BETRIEB
	DCR	A		;
	JRNZ	RST$V1		;SPRUNG WENN KEIN INT.-BETRIEB
	POP	PSW		;
	JMP	INT$SERVICE	;SPRUNG ZUR INTERUPTROUTINE
RST$V1	POP	PSW		;SPRUNG ZUM MONITOR
	JMP	START		;
;
;	
;
START: 
;----------------------------------------------ANFANG REGISTER RETTEN-----
	SHLD	LSAVE
	POP	H
	SHLD	PSAVE
	SSPD	SSAVE	;RETTE STACKPOINTER
	LXI	SP,LSAVE;JETZT RETTEN DURCH PUSHBEFEHLE MOEGLICH
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSHIX	;ZUSAETZLICH Z80 REGISTER
	PUSHIY
	EXAF
	EXX	;SCHALTE REGISTER  UM
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	EXX	;REGISTER ZURUECK SCHALTEN
	EXAF
	LDAI	;SAVE I UND R REGISTER
	MOV	B,A
	LDAR
	MOV	C,A
	PUSH	B
;--------------------------------------------------ENDE REGISTER RETTEN----
;
;
	LXI	H,SGNON		;GEBE MONITOR-MELDUNG AUS
	CALL	SOUT		;
				;				
GETCM: 				;
	LXI	H,MSTAK		;
	SPHL			;
	MVI	C,':'		;
	CALL	ECHO		;
GTC03: 				;
	CALL	GETCH1		;
	CALL	ECHO		;
	MOV	D,C		;SAVE COMMAND
	LXI	H,CMDMSG	;ZEIGE AUF TEXT
GTC01	MOV	A,D		;
	CMP	M		;GLEICH
	JRZ	GTC04		;
GTC02	INX	H		;
	MOV	A,M		;GLEICH 00H
	CPI	0		;
	JZ	ERROR		;DANN FEHLER
	CPI	'$'		;
	JRNZ	GTC02		;SUCHE $
	INX	H		;VERGLEICHE NAECHSTES KOMMANDO
	JR	GTC01		;
GTC04	INX	H		;GEFUNDEN GEBE AUS
	CALL	SOUT		;
	MOV	A,D		;
	MOV	C,D		;
	LXI 	B,NCMDS		;C ENTHAELT SCHL.U.INDEXZAEHLER
	LXI	H,CTAB		;
GTC05:				;
	CMP	M		;
	JZ	GTC10		;
	INX	H		;
	DCR	C		;
	JNZ	GTC05		;
	JMP	ERROR		;
GTC10:				;
	LXI	H,CADR		;
	DAD	B		;
	DAD	B		;
	MOV	A,M		;
	INX	H		;
	MOV	H,M		;
	MOV	L,A		;
	PCHL			;
;
;
;
DCMD:
	CALL	GETHX		;LESE STARTADRESSE
	MOV	H,B		;
	MOV	L,C		;
	MOV	A,D		;
	JRC	DCM30		;
	CPI	0DH		;
	LHLD	DISPADR		;
	JRNZ	DCM33		;SPRUNG WENN NOCH ENDADRESSE KOMMT
DCM31	LXI	D,00FFH		;KEINE ENDADRESSE, 100H WEITER
	PUSH	H		;SAVE ANFAANG
	DAD	D		;
	XCHG			;
	POP	H		;
	JR	DCM05		;AUSGABE KANN BEGINNEN
DCM30	CPI	0DH		;
	JRZ	DCM31		;KEINE ENDADRESSE
DCM33	CALL	GETHX		;LESE ZWEITE ADRESSE
	MOV	A,D		;
	CPI	0DH		;
	JNZ	ERROR		;
	MOV	D,B		;
	MOV	E,C		;
	CALL	HILO		;
	JRNC	DCM05		;HL>DE
	MOV	D,H		;
	MOV	E,L		;
DCM05:				;
	CALL	CROUT		;
	MOV	A,H		;
	CALL	NMOUT		;
	MOV	A,L		;
	CALL	NMOUT		;
	MVI	B,000H		;ZAEHLER FUER ASCII AUSGABE
DCM10:				;
	INR	B		;EIN ZEICHEN WEITER
	MVI	C,' '		;
	CALL	ECHO		;
	MOV	A,M		;
	CALL	NMOUT		;
	CALL	BREAK		;
	JC	DCM12		;
	CALL	HILO		;
	JNC	DCM15		;
DCM12: 				;
	INX	H		;
	CALL	DCM20		;
	CALL	CROUT		;
	SHLD	DISPADR		;
	JMP	GETCM		;
DCM15: 				;
	INX	H		;
	MOV	A,L		;
	ANI	0FH		;
	JNZ	DCM10		;
	CALL	DCM20		;
	JR	DCM05		;
				;
DCM20	PUSH	D		;SAVE D
	PUSH	H		;SAVE H
	MVI	C,' '		;
	CALL	CO		;
	MVI	C,'>'		;
	CALL	CO		;
	MOV	C,B		;
DCM23	DCX	H		;
	DJNZ	DCM23		;
	MOV	B,C		;
DCM21	MOV	A,M		;
	CPI	20H		;
	JRC	DCM22		;
	CPI	07FH		;
	JRNC	DCM22		;
	JR	DCM24		;
DCM22	MVI	A,'.'		;DEFAULT FOR NON ASCII
DCM24	MOV	C,A		;
	CALL	CO		;
	INX	H		;
	DJNZ	DCM21		;
	POP	H		;
	POP	D		;
	RET			;
;
;
;
GCMD: 
	CALL	GETHX
	JNC	GCM05
	MOV	A,D
	CPI	0DH
	JNZ	ERROR
	LXI	H,PSAVE
	MOV	M,C
	INX	H
	MOV	M,B
	JMP	GCM10
GCM05: 
	MOV	A,D
	CPI	0DH
	JNZ	ERROR
GCM10: 
	JMP	RSTTF
;
;
;
MCMD: 
	MVI	C,3
	CALL	GETNM
	POP	B
	POP	H
	POP	D
MCM05:
	PUSH	H
	MOV	H,D
	MOV	L,E
	MOV	A,M
	MOV	H,B
	MOV	L,C
	MOV	M,A
	INX	B
	MOV	A,B
	ORA	C
	JZ	GETCM
	INX	D
	POP	H
	CALL	HILO
	JNC	GETCM
	JMP	MCM05
;
;
;
SCMD: 
	CALL	GETHX
	PUSH	B
	POP	H
SCM05: 
	MOV	A,D
	CPI	' '
	JZ	SCM10
	CPI	','
	JNZ	GETCM
SCM10:
	MOV	A,M
	CALL	NMOUT
	MVI	C,CNGPRMT
	CALL	ECHO
	CALL	GETHX
	JNC	SCM15
	MOV	M,C
SCM15:
	INX	H
	JMP	SCM05
;
;
;
XCMD: 
	CALL	GETCH
	MOV	C,A
	CALL	ECHO
	MOV	A,C
	CPI	0DH
	JNZ	XCM05
	CALL	REGDS
	JMP	GETCM
XCM05: 
	MOV	C,A
	CALL	RGADR
	PUSH	B
	POP	H
	MVI	C,' '
	CALL	ECHO
	MOV	A,C
	STA	TEMP
XCM10:
	LDA	TEMP
	CPI	' '
	JZ	XCM15
	CPI	','
	JNZ	GETCM
XCM15: 
	MOV	A,M
	ORA	A
	JNZ	XCM18
	CALL	CROUT
	JMP	GETCM
XCM18:
	PUSH	H
	MOV	E,M
	MVI	D,(REGS AND 0FF00H) SHR 8	;SAVE ADRESSE
	INX	H
	MOV	B,M
	PUSH	D
	PUSH	D
	POP	H
	PUSH	B
	MOV	A,M
	CALL	NMOUT
	POP	PSW
	PUSH	PSW
	ORA	A
	JZ	XCM20
	DCX	H
	MOV	A,M
	CALL	NMOUT
XCM20:
	MVI	C,CNGPRMT
	CALL	ECHO
	CALL	GETHX
	JNC	XCM30
	MOV	A,D
	STA	TEMP
	POP	PSW
	POP	H
	ORA	A
	JZ	XCM25
	MOV	M,B
	DCX	H
XCM25: 
	MOV	M,C
XCM27: 
	LXI	D,3
	POP	H
	DAD	D
	JMP	XCM10
XCM30:
	MOV	A,D
	STA	TEMP
	POP	D
	POP	D
        JMP	XCM27
;
;
;
CCMD:			
	;TESTET PLATTE IM ANGEGEBENEN LAUFWERK
	;UND GIBT ERGEBNISSE AUF DEM BILDSCHIRM AUS
	;
	CALL	DISKDA		;BEFEHL ERLAUBT?
	CALL	SPECD		;SETZE DISK-TIMING
	CALL	GETCH1		;WELCHES LAUFWERK?
	CALL	ECHO		;GEBE ZEICHEN AUF CONSOLE
	MOV	A,C		;ZEICHEN IN AKKU
	SUI	'A'		;WANDLE LW. CHR. IN NUMMER
	JC	ERROR		;WENN KLEINER, FEHLER
	CPI	4		;GROESSER 'D'
	JNC	ERROR		;SPRUNG WENN JA
	MOV	C,A		;RETTE ALTE UNIT
	LDA	UNIT		;
	PUSH	PSW		;
	MOV	A,C		;
	STA	UNIT		;ZU TESTENDES LAUFWERK
	MVI	B,5		;ANZAHL DER VERSUCHE
CCMD1	PUSH	B		;
	LHLD	UNIT		;RETTE UNIT UND TRACK
	PUSH	H		;
	CALL	TEST		;
	POP	H		;
	SHLD	UNIT		;
	POP	B		;GET ZAEHLER
	ORA	A		;FEHLER AUFGETRETEN?
	JRZ	CCMD2		;SPRUNG, WENN OK
	DJNZ	CCMD1		;NOCH EIN VERSUCH?
				;
	POP	PSW		;HOLE ALTE UNIT
	STA	UNIT		;
CCMD5:				;HIER AUCH EINSPRUNG FUER BOOT ERROR
	LXI	H,CHKERR	;DRUCKE FEHLERMELDUNG
	CALL	SOUT		;
	JMP	GETCM		;NEUE EINGABE
				;
CHKERR	DB	0DH,0AH,BELL
	DB	' Disk not correct'
	DB	0DH,0AH,24H
				;
CCMD2:				;
				;GEBE ART DER PLATTE AUS
	POP	PSW		;SETZE STACK RICHTIG
	LXI	H,CTXT1		;
	CALL	SOUT		;
	LDA	TEST$TYPE	;
	ANI	20H		;MINI ODER MAXI
	LXI	H,CTXT11	;
	JRZ	CCMD3		;
	LXI	H,CTXT12	;
CCMD3	CALL	SOUT		;
				;
	LXI	H,CTXT2		;
	CALL	SOUT		;
	LDA	TEST$TYPE	;NUMBER OF SURFACES
	RLC			;
	ANI	01H		;
	ADI	'1'		;WANDLE IN ASCII
	MOV	C,A		;
	CALL	CO		;UND GEBE SEITENZAHL AUS
				;
	LXI	H,CTXT3		;
	CALL	SOUT		;
	LDA	TEST$TYPE	;
	LXI	H,CTXT31	;
	ANI	040H		;
	JRZ	CCMD4		;
	LXI	H,CTXT32	;
CCMD4	CALL	SOUT		;
				;
	LXI	H,CTXT4		;GEBE SEKTORGROESSE AUS
	CALL	SOUT		;
	LDA	TEST$TYPE	;
	ANI	0FH		;
	MVI	H,0		;
	MOV	L,A		;
	DAD	H		;
	DAD	H		;
	DAD	H		;
	LXI	D,SEKTXT	;
	DAD	D		;
	CALL	SOUT		;
				;
	LXI	H,CTXT5		;GEBE SEKTOREN/SPUR AUS
	CALL	SOUT		;
	LDA	TEST$MSEK	;
	CALL	DEZOUT		;
				;
	LXI	H,CTXT6		;GEBE AUS OB DAS LAUFWERK
	CALL	SOUT		;DAS READY SIGNAL LIEFERT
	CALL	READY$MASK	;
	ANI	0FH		;
	LXI	H,CTXT62	;
	JRNZ	CCMD6		;
	LXI	H,CTXT61	;
CCMD6	CALL	SOUT		;
				;SETZE CMDTAB
	CALL	SETCMDT		;
				;
	CALL	CROUT		;
	JMP	GETCM		;
;
CTXT1	DB	0DH,0AH,' Disk format...: $'
CTXT2	DB	0DH,0AH,' Heads.........: $'
CTXT3	DB	0DH,0AH,' Density.......: $'
CTXT4	DB	0DH,0AH,' Sector size...: #$'
CTXT5	DB	0DH,0AH,' Sectors/Track.: #$'
CTXT6	DB	0DH,0AH,' Ready signal..: $'
CTXT31	DB	'single$'
CTXT32	DB	'double$'
SEKTXT	DB	'128    $'
	DB	'256    $'
	DB	'512    $'
	DB	'1024   $'
CTXT11	DB	'maxi$'
CTXT12	DB	'mini$'
CTXT61	DB	'yes$'
CTXT62	DB	'simulated by index$'
;
;
;
OCMD:
	CALL	GETHX	;LESE PORTADRESSE
	MOV	A,D	;WAR TRENNZEICHEN CR?
	CPI	0DH
	JZ	ERROR	;FEHLER WENN JA
	PUSH	B	;SAVE INTEGER
	CALL	GETHX	;LESE DATA BYTE
	MOV	A,D	;WAR TRENNZEICHEN CR?
	CPI	0DH
	JNZ	ERROR	;FEHLER WENN NEIN
	MOV	L,C
	POP	B	;RESTORE PORTADR.
	OUTP	L	;GEBE AUS
	JMP	GETCM
;
RCMD:
		;LIEST AB IN CMDTAB ANGEGEBENEN SEKTOR
	CALL	DISKDA
	CALL	PRINT$DRIVE
	CALL	RWINP	;SETZE DMA ADRESSE UND LAENGE
	CALL	READ	;LESE
	JMP	GETCM
;
WCMD:
	CALL	DISKDA
	CALL	PRINT$DRIVE
	CALL	RWINP
	CALL	WRITE
	JMP	GETCM
;
ICMD:
	MVI	C,1
	CALL	GETNM
	POP	B	;IN C STEHT PORT
	INP	A	;LESE NACH A
	MVI	C,' '	;GEBE BLANK AUS
	PUSH	PSW
	CALL	CO
	POP	PSW
	PUSH	PSW
	CALL	NMOUT	;GEBE HEX AUS
	MVI	C,' '	;GEBE BLANK AUS
	CALL	CO
	POP	PSW
	MOV	D,A	;IN D FUER BITOUT
	CALL	BITOUT
	CALL	CROUT
	JMP	GETCM
;
;
;
ACMD:
	;ZEIGT UND VERAENDERT TRACK, SECTOR UND HEAD
	;DES EINGELOGTEN LAUFWERKS
	CALL	DISKDA	;BEFEHL ERLAUBT?
	CALL	PRINT$DRIVE
;
	LXI	H,ATXT1	;DISPLAY TRACK
	CALL	SOUT
	LDA	TRACK
	CALL	NMOUT
	CALL	ACMD4	;LESE NEUEN WERT
	JRNC	ACMD1	;KEINE EINGABE?
	STA	TRACK
ACMD1	CALL	ACMD5
;
	LXI	H,ATXT2	;DISPLAY HEAD
	CALL	SOUT
	LDA	HEAD
	CALL	NMOUT
	CALL	ACMD4
	JRNC	ACMD2
	ANI	03H	;MASK UPPER 6 BITS
	STA	HEAD
ACMD2	CALL	ACMD5
;
	LXI	H,ATXT3	;DISPLAY SECTOR
	CALL	SOUT
	LDA	SECTOR
	CALL	NMOUT
	CALL	ACMD4
	JRNC	ACMD3
	STA	SECTOR
ACMD3	CALL	ACMD5
;
	CALL	CROUT	;NEXT LINE FOR MONITOR
	JMP	GETCM
;
ACMD4	MVI	C,CNGPRMT
	CALL	ECHO
	CALL	GETHX
	MOV	A,C
	RET
;
ACMD5	MOV	A,D
	CPI	0DH
	JZ	GETCM
	RET
;
ATXT1	DB	0DH,0AH,' Track..: $'
ATXT2	DB	0DH,0AH,' Head...: $'
ATXT3	DB	0DH,0AH,' Sector.: $'
;
;
;
BCMD:
	;EINSPRUNG BOOTROUTINE
	;
	CALL	DISKDA		;BEFEHL ERLAUBT?
	XRA	A		;
	STA	TEST$TRACK	;ERSTE TESTSPUR IST 0
BCMD2:	STA	UNIT		;OK, IN CMDTAB
	CALL	SPECD		;SETZT DISK TIMING
	MVI	B,5		;TESTE PLATTE MAX. 5 MAL
BCMD3	PUSH	B		;
	CALL	TEST		;SETZT CONTROLLER AUF MINI ODER MAXI
	POP	B		;
	ORA	A		;FEHLER AUFGETRETEN?
	JRZ	BCMD4		;SPRUNG WENN NEIN
	DJNZ	BCMD3		;NOCH EIN VERSUCH?
	JMP	CCMD5		;GEBE FEHLER MELDUNG AUS
BCMD4:				;
	CALL	SETCMDT		;SETZE CMDTABELLE
	XRA	A		;SETZE SPUR NULL
	STA	TRACK		;
	STA	HEAD		;HEAD NULL
	INR	A		;
	STA	SECTOR		;SEKTOR EINS
	LXI	H,BOOTADR	;
	SHLD	DMAADR		;
	MVI	A,01H		;UEBERTRAGE EINEN SECTOR
	STA	SECTCNT		;
				;OK, ALLE WERTE SIND GESETZT
	CALL	READ		;LESE
	ORA	A		;FEHLER AUFGETRETEN?
	JNZ	BOOTERR		;
	LXI	H,BOOTADR	;KOPIERE DIE ERSTEN 128 BYTE
	LXI	D,BOOTADR+380H	;NACH HINTEN
	LXI	B,128		;
	LDIR			;
	JMP	BOOTADR+380H	;
;
;
;
LCMD:
	;ZEIGE DATUM UND ZEIT AN
	LDA	CLKFLG		;IST DIE UHR UEBERHAUPT DA?
	ORA	A
	JZ	GCMD1
	CALL	DISP$TIME
	JMP	GETCM
;
GCMD1:	LXI	H,CLKERR$TXT
	CALL	SOUT
	JMP	GETCM
;
CLKERR$TXT:
	DB	0DH,0AH,BELL,' Clock failure',0DH,0AH,'$'
;
;
;
NCMD:
	;SETZE UHRZEIT UND DATUM
	LDA	CLKFLG
	ORA	A
	JZ	GCMD1
	LXI	H,CITXT1	;LESE DATUM EIN
	CALL	SOUT
	CALL	GETDEZ
	CPI	'/'
	JNZ	ERROR		;FALSCHES TRENNZEICHEN
	MOV	A,L
	CALL	DEZHEX
	RLC			;IN RICHTIGE POSITION
	RLC
	RLC
	RLC
	ANI	0F0H
	CPI	0		;MONAT ZWISCHEN 1 UND 12
	JZ	ERROR
	CPI	0C1H
	JNC	ERROR
	STA	PHYS$TIME+4	;MONAT WEG
	CALL	GETDEZ
	CPI	'/'
	JNZ	ERROR
	MOV	A,L
	CPI	0
	JZ	ERROR
	CPI	32H
	JNC	ERROR
	STA	PHYS$TIME+3	;TAG WEG
	CALL	GETDEZ
	CPI	0DH
	JNZ	ERROR
	MOV	A,L
	CPI	80H
	JC	ERROR
	CPI	9AH
	JNC	ERROR
	STA	TEMP		;JAHR ZWISCHEN SPEICHERN
;
	;UHRZEIT EINLESEN
	LXI	H, CITXT2
	CALL	SOUT
	CALL	GETDEZ
	CPI	':'
	JNZ	ERROR
	MOV	A,L
	CPI	24H
	JNC	ERROR
	STA	PHYS$TIME+2
	CALL	GETDEZ
	CPI	':'
	JNZ	ERROR
	MOV	A,L
	CPI	60H
	JNC	ERROR
	STA	PHYS$TIME+1
	CALL	GETDEZ
	CPI	0DH
	JNZ	ERROR
	MOV	A,L
	CPI	60H
	JNC	ERROR
	STA	PHYS$TIME
;
	;SETZE DIE ZEIT
	LXI	H,CITXT3
	CALL	SOUT
	CALL	GETCH		;WARTE AUF IRGEND EIN ZEICHEN
	CALL	SET$PHYS$TIME	;
	LDA	TEMP		;SETZE NOCH JAHR
	CALL	DEZHEX		;WANDLE IN DEZIMALZAHL
	SUI	80		;ZIEHE 80 AB
	ANI	1FH		;MASKIERE
	MOV	B,A		;
	LDA	SHIFT$CONT+4	;
	ANI	0E0H		;
	ORA	B		;
	STA	SHIFT$CONT+4	;
	CALL	SET$SHIFT	;
	CALL	CROUT		;
	CALL	CROUT		;
	JMP	GETCM		;
				;
CITXT1:	DB	0DH,0AH,0AH,' Enter today''s date (MM/DD/YY): $'
CITXT2:	DB	' Enter the time (HH:MM:SS):     $'
CITXT3:	DB	' Press any key to set time$'
;
;
;
FCMD:
	MVI	C,3	;HOLE 3 WERTE VON DER CONSOLE
	CALL	GETNM
	POP	B	;FUELL BYTE
	POP	D	;END WERT
	POP	H	;ANFANGSWERT
FCMD1	MOV	M,C	;FUELLE BYTE
	CALL	HILO	;ENDE ERREICHT?
	JC	GETCM
	INX	H
	JMP	FCMD1
;
;
;
VCMD:
	;VERGLEICHT ZWEI SPEICHERBEREICHE MITEINANDER
	MVI	C,3	;LESE DREI ADRESSEN EIN
	CALL	GETNM
	POP	B	;ZWEITER BLOCKANFANG
	POP	D	;ERSTES BLOCKENDE
	POP	H	;ERSTER BLOCKANFANG
VCMD1	LDAX	B	;LESE BYTE AUS BLOCK 2
	CMP	M	;VERGLEICHE MIT ERSTEM BLOCK
	CNZ	VCMD2	;GEBE UNGLEICHE ADDRESSEN AUS
	CALL	HILO	;ENDE ERREICHT ?
	JC	GETCM	;OK, ENDE
	INX	H
	INX	B
	JMP	VCMD1	;VERGL. NAECHSTES BYTE
;
;
;
TCMD	MVI	C,2	;LESE ANFANG UND ENDADDRESSE
	CALL	GETNM
	POP	D
	POP	H
TCMD1	MOV	C,M
	MOV	A,C	;LESE SPEICHERSTELLE
	CMA		;NEGIERE
	MOV	M,A	;SCHREIBE IN ZELLE
	MVI	B,15	;WARTE ETWAS
TCMD2	DJNZ	TCMD2	;
	MOV	A,M	;LESE WIEDER
	MOV	M,C	;ORGINAL BYTE ZURUECK
	CMA		;A SOLL GLEICH C SEIN
	XRA	C	;SETZE ALL UNGLEICHEN BITS
	CNZ	FBYTOUT	;GEBE FEHLERHAFTES BYTE AUS
	CALL	HILO	;ENDE?
	JC	GETCM	;SPRUNG WENN JA
	INX	H	;TESTE NAECHSTES BYTE
	JR	TCMD1	;LOOP
;
;
;
;
;
;
VCMD2	PUSH	H
	PUSH	D
	PUSH	B	;RETTE ALLE ADRESSEN
	CALL	DISPMEM
	MVI	C,' '
	CALL	ECHO
	POP	H
	PUSH	H
	CALL	DISPMEM
	CALL	CROUT
	CALL	BREAK
	JC	GETCM
	POP	B
	POP	D
	POP	H
	RET
;
DISPMEM:
	;INPUT: HL
	;ZEIGT HL UND (HL) AUF DEM BILDSCHIRM AN
	;ZERSROERT A,B,C,FF'S
	MOV	A,H
	CALL	NMOUT
	MOV	A,L
	CALL	NMOUT
	MVI	C,'='
	CALL	ECHO
	MOV	A,M
	CALL	NMOUT
	RET
;
;
;
FBYTOUT	PUSH	H		;
	PUSH	D		;
	MOV	D,A		;RETTE AKKU
	MOV	A,H		;
	CALL	NMOUT		;
	MOV	A,L		;
	CALL	NMOUT		;
	MVI	C,' '		;GEBE NACH ADRRESE TRENNZEICHEN AUS
	CALL	CO		;
	CALL	BITOUT		;GEBE BITFOLGE AUS
	CALL	CROUT		;
	CALL	BREAK		;ABBRUCH
	JC	GETCM		;SPRUNG ZUM MONITOR WENN JA
	POP	D		;
	POP	H		;
	RET			;
;
;
;
BITOUT:
	;GIBT 8 BIT IN REG.D AUS
	;ZERSTOERT A,B,C,D,E
	MVI	B,8	;GEBE 8 BIT AUS
BITOUT1	RLCR	D	;SCHIEBE IN CARRY
	MVI	A,'0'	;ASSCI 0
	MVI	E,0
	ADC	E
	MOV	C,A
	CALL	CO
	DJNZ	BITOUT1
	RET
;
;
;
HCMD:
	;HELP-BEFEHL, GIBT EINE UEBERSICHT UEBER ALLE
	;EINGEBAUTEN BEFEHLE
	;
	LXI	H,HELPTXT	;GEBE KOPF-MELDUNG AUS
	CALL	SOUT		;
				;GEBE LISTE DER
	LXI	H,CMDMSG-1	;EINGEBAUTEN BEFEHLE AUS
HCMD2	INX	H		;ZEIGER AUF NAECHSTEN-BEFEHLSTEXT
	CALL	CROUT		;GEBE ERST RETURN-LINEFEED AUS
	MOV	A,M		;ENDE DER LISTE?
	ORA	A		;
	JZ	GETCM		;DANN WIEDER AUF KOMMANDO-EBENE
	MVI	B,5		;GEBE FUENF BLANKS AUS
	MVI	C,' '		;
HCMD3	CALL	ECHO		;
	DJNZ	HCMD3		;
	CALL	SOUT		;GEBE TEXT AUS
	JRZ	HCMD2		;BIS KEINER MEHR DA IST
				;
HELPTXT	DB	0DH,0AH,0AH
	DB	'following commands are available:',0H,0AH,'$'
;
;
;
ECMD:
	;GIBT DEN WERT DER LETZTEN BENUTZTEN EPROMADRESSE AUS
	;GEBE EPROM-PRUEFSUMME AUS
	;
	LXI	H,ECMDTXT
	CALL	SOUT
	MVI	A,(LASTADD/256) AND 0FFH
	CALL	NMOUT
	MVI	A,LASTADD AND 0FFH
	CALL	NMOUT
	LXI	H,ECMDTXX
	CALL	SOUT
	LXI	H,0		;BERRECHNE PRUEFSUMME
	MVI	D,0
	LXI	B,0
ECMD1	LDAX	B
	MOV	E,A
	DAD	D
	INX	B
	MOV	A,B
	CPI	20H
	JRNZ	ECMD1
	MOV	A,H
	CALL	NMOUT
	MOV	A,L
	CALL	NMOUT
	CALL	CROUT
	JMP	GETCM
;
ECMDTXT	DB	0DH,0AH,'              end location.: $'
ECMDTXX	DB	0DH,0AH,'              checksum.....: $'
;
;
;
KCMD:
	;GIBT ALLE KONSOLENEINGABEN UNVERAENDERT AUS
	;ESCAPE MIT CONTROL-C
	LXI	H,KCMDTXT
	CALL	SOUT
KCMD1:	CALL	CI		;LESE ZEICHEN
	CPI	3		;CONTROL-C?
	JRZ	KCMD2		;DANN ENDE
	MOV	C,A		;
	CALL	CO		;SONST GEBE ZEICHEN AUS
	JR	KCMD1		;
KCMD2:	CALL	CROUT		;
	JMP	GETCM
;
KCMDTXT	DB	' (escape with ^C)',0dh,0ah,0dh,0ah,'$'
;
;
;
UCMD:				;SETZE DISK-TIMING
				;UND ANZAHL DER STEP-IMPULSE
	LXI	H,UTXT1		;LESE STEPRATE
	CALL	SOUT		;
	CALL	UCMD3		;
	DCR	A		;
	MOV	C,A		;
	ANI	0F0H		;TESTE OB KLEINER 10H
	JNZ	ERROR		;GROESSER, DANN FEHLER
	MOV	A,C		;
	CMA			;BILDE KOMPLEMENT
	PUSH	PSW		;RETTE AKKU
	LXI	H,UTXT2		;LESE HEADUNLOAD TIME
	CALL	SOUT		;
	CALL	UCMD3		;
	RRC			;
	RRC			;
	RRC			;
	RRC			;
	ANI	0FH		;MASKIERE
	MOV	C,A		;RETTE IN C
	POP	PSW		;GET STEPRATE
	RLC			;
	RLC			;
	RLC			;
	RLC			;
	ANI	0F0H		;MASKIERE
	ORA	C		;UNLOAD TIME DAZU
	STA	SHIFT$CONT+2	;
	LXI	H,UTXT3		;LESE HEAD LOAD TIME
	CALL	SOUT		;
	CALL	UCMD3		;
	ANI	0FEH		;
	STA	SHIFTCONT+3	;
	LXI	H,UTXT4		;DOPPELSTEP VEKTOR UND
	CALL	SOUT		;TWOSIDED BITS
	CALL	UCMD3		;
	STA	SHIFT$CONT+1	;
	LDA	SHIFT$CONT+4	;
	ORI	1FH		;BERECHNE PRUEFSUMME
	LXI	H,SHIFT$CONT+3	;
	MVI	B,3		;
UCMD1	ADD	M		;
	DCX	H		;
	DJNZ	UCMD1		;
	CMA			;BILDE KOMPLEMENT
	INR	A		;
	MOV	M,A		;
	CALL	UCMD2		;
	CALL	SPECD		;
	CALL	SET$SHIFT	;
	CALL	CROUT		;
	JMP	GETCM		;
				;
UCMD2:	LHLD	SHIFT$CONT+2	;SETZE DISKTIMING NEU
	MOV	A,H		;
	ORI	1		;
	MOV	H,A		;
	SHLD	SPECD$WORD	;
	LDA	SHIFT$CONT+1	;SETZE SEEKNR (ANZAHL DER STEPIMPULSE)
	STA	SEEKNR		;UND TWO-SIDED-BITS
	RET			;
				;
UCMD3:	CALL	GETHX		;
	MOV	A,D		;
	CPI	0DH		;
	JZ	ERROR		;
	MOV	A,C		;
	RET			;
;
UTXT1	DB	10,13,' Steprate ...........: $'
UTXT2	DB	10,13,' Head unload time ...: $'
UTXT3	DB	10,13,' Head load time .....: $'
UTXT4	DB	10,13,' Double step vector .: $'
;	
;
;
;-------------------------------------------------------INITIALISIERUNG------
;
INIT:
					;
;***	
	LXI	H,6000			;VERZOEGERUNG ZUM WARM WERDEN
INIT7	DCX	H			;
	MVI	A,PAD$TX OR 1		;SETZE TX DUPLEX LEITUNG AUF 1
	OUT	P$LS259			;
	MVI	A,PAD$RTS OR 1		;SETZE RTS INAKTIV
	OUT	P$LS259			;
	MVI	A,PAD$TXP OR 1		;SETZE TX SIMPLEX LEITUNG AUF 1
	OUT	P$LS259			;
	MVI	A,PAD$POLEN OR 80H	;AKTIVIERE DRIVE DECODER
	OUT	P$LS259			;
	MVI	A,5			;UNIO STROBE 1 HIGH
	OUT	CONTR			;
	MVI	A,7			;UNIO STROBE 2 HIGH
	OUT	CONTR			;
	MVI	A,9			;UNIO INIT HIGH
	OUT	CONTR			; 
	MOV	A,H			;
	ORA	L			;
	JNZ	INIT7			;
					;
;***
	MVI	A,PAD$MOTOR OR 80H
	OUT	P$LS259
	MVI	A,PAD$MOTAB OR 1
	OUT	P$LS259
;***
				;
	MVI	B,00		;INITIALISIERE EPROM
	MVI	C,P$RAM$TABLE	;PORTADRESSE DER RAM-TABELLE
	MVI	D,16		;
	MVI	E,0		;EPROM BANK-ADRESSE
	OUTP	E		;GEBE BANKADRESSE FUER KACHEL 0 AUS
	MOV	A,D		;NAECHSTE KACHEL
	ADD	B		;
	MOV	B,A		;
	OUTP	E		;
				;OK, EPROM-KACHELN AKTIV
	MOV	A,D		;JETZT LOGISCHE RAM-BANK 0
	ADD	B		;
	MOV	B,A		;
	MVI	E,02H		;PHYS.-BANK 13 IST LOG.-BANK 0
INIT8	OUTP	E		;INITIALISIERE RESTL. KACHELN
	MOV	A,D		;
	ADD	B		;
	MOV	B,A		;
	CPI	80H		;
	JRNZ	INIT16		;
	MVI	E,0AH		;
INIT16	ORA	A		;
	JRNZ	INIT8		;
				;RAM-TABELLE OK
	MVI	A,PAD$INIT OR 1	;AKTIVIERE-BANKLEITUNGEN
	OUT	P$LS259		;
				;OK, RAM IST AKTIV
				;TESTE BANK 0
	LXI	H,MSTAK-80	;SCHREIBE 256 BYTES
	XRA	A		;IN STACK
INIT13	MOV	M,A		;
	INX	H		;
	INR	A		;
	JRNZ	INIT13		;
	LXI	H,0		;VERZOEGERE ETWAS
INIT15	DCX	H		;
	MOV	A,H		;
	ORA	L		;
	JRNZ	INIT15		;
	LXI	H,MSTAK-80	;
	XRA	A		;
INIT12	CMP	M		;UND VERGLEICHE WIEDER
	JRNZ	INIT9		;UNGLEICH, SETZE FLAG
	INX	H		;EINEN WERT HOEHER
	INR	A		;
	JRNZ	INIT12		;
	XRA	A		;FLAG FUER BANK 0 OK
	JR	INIT10		;
INIT9	MVI	A,01H		;FLAG FUER BANK 0 NICHT OK
INIT10	STAI			;RETTE FLAG IN INT.REGISTER
				;
	MVI	B,20H		;SCHALTE BANK 1 EIN
	MVI	C,P$RAM$TABLE	;
	MVI	D,16		;
	MVI	E,03H		;
INIT11	OUTP	E		;SETZE KACHEL
	MOV	A,D		;EINS WEITER
	ADD	B		;
	MOV	B,A		;
	CPI	80H		;OBERE HAELFTE
	JRNZ	INIT27		;
	MVI	E,0BH		;DANN E NEU SETZEN
INIT27	ORA	A		;IST AKKU GLEICH NULL
	JRNZ	INIT11		;ALLES BANK1 VOLLSTAENDIG EINGESCHALTET
				;
	LXI	H,MSTAK-80	;TESTE BANK 1
	XRA	A		;
INIT17	MOV	M,A		;SCHREIBE 256 BYTES VOLL
	INX	H		;
	INR	A		;
	JRNZ	INIT17		;
	LXI	H,0		;WARTE ETWAS
INIT18	DCX	H		;
	MOV	A,H		;
	ORA	L		;
	JRNZ	INIT18		;
	LXI	H,MSTAK-80	;UND VERGLEICHE WIEDER
	XRA	A		;
INIT19	CMP	M		;
	JRNZ	INIT20		;FEHLER
	INX	H		;
	INR	A		;
	JRNZ	INIT19		;
	MVI	B,0		;FLAG FUER KEIN FEHLER
	JR	INIT21		;
INIT20	MVI	B,02H		;FLAG FUER FEHLER
INIT21	LDAI			;LADE FLAG VON BANK 0
	ORA	B		;UND PACKE FLAK VON BANK 1 DAZU
	STAI			;WIEDER IN INTERRUPT REGISTER
				;
	CPI	3		;SPRUNG WENN KEINE BANK
	JRZ	BLINK$LOOP	;IN ORDNUNG IST
	CPI	1		;LASSE BANK 1 EINGESCHALTET
	JRZ	INIT22		;WENN BANK 0 FEHLERHAFT IST
				;
	MVI	B,20H		;ANSONSTEN SCHALTE
	MVI	C,P$RAM$TABLE	;WIEDER BANK 0 EIN
	MVI	D,16		;
	MVI	E,02H		;
INIT23	OUTP	E		;
	MOV	A,D		;
	ADD	B		;
	MOV	B,A		;
	CPI	80H		;OBERE HAELFTE
	JRNZ	INIT24		;
	MVI	E,0AH		;
INIT24	ORA	A		;ALLES EINGESCHALTET?
	JRNZ	INIT23		;
INIT22	JR	INIT14		;DANN WEITER
				;
BLINK$LOOP:
	MVI	B,80H		;BESETZE
	MVI	C,PAD$INUSE	;REGISTER
	LXI	H,0		;VOR
	EXX			;
	MVI	B,MASK$RX	;
	MVI	C,MASK$CTS	;
	MVI	D,PAD$TX	;
	MVI	E,PAD$RTS	;
	MVI	H,01H		;
	MVI	L,0FFH		;
	EXX			;
BLINK$LOOP1:
	DCX	H		;HL EINS WENIGER
				;
	MOV	A,H		;
	ADD	A		;
	ADD	A		;
	ANA	B		;SETZE LED GLEICH
	ORA	C		;DEM DRITTHOECHSTEN
	OUT	P$LS259		;BIT DES H-REGISTERS
				;
	EXX			;
				;
	IN	P$IN$LS258$A	;SETZE TX-LEITUNG
	ANA	B		;AUF DEN
	ADD	L		;PEGEL DER
	CMC			;RX-LEITUNG
	RAL			;
	ANA	H		;
	ORA	D		;
	OUT	P$LS259		;
				;
	IN	P$IN$LS258$A	;SETZE RTS-LEITUNG
	ANA	C		;AUF DEN
	ADD	L		;PEGEL DER
	CMC			;CTS-LEITUNG
	RAL			;
	ANA	H		;
	ORA	E		;
	OUT	P$LS259		;
				;
	IN	P$IN$LS258$A	;SETZE TXP-LEITUNG
	ANI	MASK$CTSP	;AUF DEN
	ADD	L		;PEGEL  DER
	CMC			;CTSP-LEITUNG
	RAL			;
	ANA	H		;
	ORI	PAD$TXP		;
	OUT	P$LS259		;
				;
	EXX			;
				;
	JR	BLINK$LOOP1	;
				;
INIT14:				;OK, MONITOR KANN LAUFEN
				;
;***				
	LXI	SP,MSTAK	;SETZE STACKPOINTER
;***
	LXI	H,DISKPAGE	;COPIERE ALS ALLERERSTES NACH RAM EIN
	LXI	D,SYSTEMPAGE	;DIE DISKPAGE AUF DIE SYSTEMPAGE
	LXI	B,256		;
	LDIR			;
;***
	LDAI			;SPEICHER BANKFEHLERBYTE IN
	STA	BANK$ERR$BYTE	;SYSTEMPAGE
;***
	CALL	FLOPPY$RESET	;SETZE FLOPPY-CONTROLER
				;ZURUECK
;***
				;SETZE UMLEITUNGS SPRUENGE IM RAM
	MVI	A,0C3H		;JUMP BEFEHL IN AKKU
	LXI	H,GETCM		;UMLEITUNGSADRESSE IN HL
	STA	UMLEIT$GETCM	;
	SHLD	UMLEIT$GETCM+1	;
	LXI	H,CONST		;
	STA	UMLEIT$CONST	;
	SHLD	UMLEIT$CONST+1	;
	LXI	H,CONIN		;
	STA	UMLEIT$CONIN	;
	SHLD	UMLEIT$CONIN+1	;
	LXI	H,CONOUT	;
	STA	UMLEIT$CONOUT	;
	SHLD	UMLEIT$CONOUT+1	;
	LXI	H,START		;
	STA	UMLEIT$NMI	;
	SHLD	UMLEIT$NMI+1	;
;***
				;BESETZE SPEICHERZELLEN VOR
				;
	XRA	A		;BESETZE BYTE MIT 0
	STA	HEAD		;
	STA	DERMSG		;FLOPPY-FEHLERMELDUNG AKTIV
	MVI	A,1		;BESETZE BYTE MIT 1
	STA	TEST$TRACK	;
	STA	TRACK		;
	STA	SECTOR		;
	MVI	A,2		;
	STA	WRITE$PRECOM	;PRECOMPENSATIONSZEIT AUF FESTEN WERT
	MVI	A,10		;
	STA	RWRETRY		;ANZAHL VERSUCHE FUER FLOPPY R/W
	LXI	H,0		;BESETZE WORT MIT 0
	SHLD	DISPADR		;
	LXI	H,IN$BUFF$ZEIG	;SETZE ZEIGER FUER SOFTIN BUFFER
	SHLD	IN$BUFF$ZEIG	;
				;
	LDA	XSEEKNR		;VORBESTZUNG WIE IM EPROM EINGEPATCHT
	STA	SEEKNR		;
	LDA	XREADY$BYTE	;
	STA	READY$BYTE	;
	LDA	XTE$TIME	;
	STA	TE$TIME		;
	LDA	XSTEP$WAIT	;
	STA	STEP$WAIT	;
	LHLD	XSPECD$WORD	;
	SHLD	SPECD$WORD	;
				;
	LXI	D,KENNUNG	;SETZE KENNUNGSTEXT
	LXI	H,KENNUNGSTEXT	;
	LXI	B,7		;
	LDIR			;
	LDA	VERSIONNR	;SETZE MONITOR VERSIONSNUMMER
	STA	MON$VERS	;IM RAM
				;
;***
	CALL	USERINIT	;INITIALISERE BENUTZER SCHNITSTELLEN
;***
	CALL	GET$SPEED	;IST UHR DA? UND WELCHE TAKTRATE IM SYS.
	STA	CLKFLG		;FLAG FUER UHR DA, NICHT DA
				;WENN KEINE UHR DA, WIRD 4MHZ SYS.TAKT
	IF	NOT ACHTMHZ	;ANGENOMMEN.
	ORA	A		;
	JRNZ	INIT3		;DIES ENTSPRICHT 8MHZ BEI
	ENDIF			;ACHTMHZ=JA.
	LXI	H,40000		;
INIT3:	SHLD	SYSTEMTAKT	;LEGE SYSTEMTAKT AB
				;
;***
	CALL	GET$JUMPER	;SETZE BEIDE JUMPERBYTE
	CALL	SET$SOFT$BAUD	;SETZE DIE VERZOEGERUNGSZEIT IN SOFTVERZ
				;IN ABHAENIGKEIT VON BAUD$JUMPER$BYTE
				;UND DEN EINTRAEGEN IN SOFT$BAUD$TAB
	LDA	XPRNT$BAUD		;
	CALL	SET$SIMPLEX$BAUD	;SETZE SIMPLEX VERZOEGERUNG
					;
	CALL	UNIOINIT	;INITIALISIERE UNIO
				;
;***
				;
	LXI	H,INITXT0	;GEBE KOPFTEXT AUS
	CALL	SOUT		;
	LDA	VERSIONNR	;GEBE VERSIONS NUMMER AUS
	RLC			;ERSTE ZIFFER
	RLC			;
	RLC			;
	RLC			;
	ANI	0FH		;
	ADI	30H		;
	MOV	C,A		;
	CALL	ECHO		;
	MVI	C,'.'		;GEBE PUNKT AUS
	CALL	ECHO		;
	LDA	VERSIONNR	;ZWEITE ZIFFER
	ANI	0FH		;
	ADI	30H		;
	MOV	C,A		;
	CALL	ECHO		;
	LXI	H,INITXT8	;
	CALL	SOUT		;
	LHLD	SERNR		;GEBE SERIENNUMMER AUS
	CALL	PDEC		;ALS DEZIMALZAHL AUS
	CALL	CROUT		;
				;
;***
	LDA	BANK$ERR$BYTE	;GEBE GROESSE DES RAMBEREICHES AUS
	LXI	H,INITXT9	;128K
	CPI	0		;
	JRZ	INIT26		;
	LXI	H,INITXT6	;64K (NUR BANK 1)
	CPI	1		;
	JRZ	INIT26		;
	LXI	H,INITXT7	;64K (NUR BANK 0)
INIT26	CALL	SOUT		;
				;
;***
	LDA	CLKFLG		;GEBE TAKTRATE AUS, WENN
	ORA	A		;UHR UEBERHAUPT DA?
	JRZ	NOCLK		;GEBE MELDUNG AUS, WENN UHR DA
	LXI	H,INITXT1	;
	CALL	SOUT		;
	IF	NOT ACHTMHZ	;
	LHLD	SYSTEMTAKT	;GEBE ERMITTELTE TAKT FREQUENZ AUS
	CALL	PDEC		;
	LXI	H,INITXT2	;
	CALL	SOUT		;
	ENDIF			;
	CALL	DISP$TIME	;GEBE UHRZEIT AUS
	JR	NOCLK2		;
NOCLK:
	IF	ACHTMHZ		;
	LXI	H,INITXT1	;
	CALL	SOUT		;
	ENDIF			;
	LXI	H,INITXT4	;GEBE MELDUNG AUS
	CALL	SOUT		;WENN UHR NICHT DA
NOCLK2:
				;
				;
;***
	IM1			;INTERRUPT MODE 1
	EI			;ENABLE INTERRUPTS
	LDA	IO$JUMPERBYTE	;INTERRUPTBETRIEB DER SOFT-EINGABE?
	DCR	A		;WENN JA GEBE RTS FREI
	JRNZ	INIT28		;
	MVI	A,PAD$RTS	;
	OUT	P$LS259		;
INIT28:				;
				;
;***
	LDA	CLKFLG		;SETZE DISKTIMING NEU, WENN
	ORA	A		;A) UHR OK UND B) CHECKSUMME
	JZ	INIT29		;DES SCHIFTREGISTERS STIMMT.
	LXI	H,SHIFT$CONT+4	;BERECHNE PRUEFSUMME
	MOV	A,M		;
	ORI	00011111B	;MASKIERE JAHRESZAHL
	MVI	B,4		;ADDIERE DIE RESTLICHEN 4 BYTE
INIT30	DCX	H		;
	ADD	M		;
	DJNZ	INIT30		;
	ORA	A		;PRUEFSUMME MUSS 0 SEIN
	MVI	A,0		;FALLS SPRUNG, DANN A=0
	JNZ	INIT29		;SONST DEFAULT WERTE
	CALL	UCMD2		;SETZE NEUES TIMING
	MVI	A,0FFH		;FLAG FUER PROMT
INIT29:	STA	TEMP		;
				;
;***
				;
	CALL	INIFDC		;IST FLOPPY CONTROLLER IN ORDNUNG?
				;WENN JA SETZE SOFT RESET
	LDA	DISKFLG		;WAR ZUGRIFF AUF FLOPY CONTROLER MOEGLICH?
	ORA	A		;
	JRZ	INIT4		;SPRUNG WENN FLOPY NICHT OK
	CALL	SPECD		;SET DRIVE PAR. + DMA-MODE
	JR	INIT5		;
INIT4:				;
	LXI	H,INITXT5	;GEBE MELDUNG FUER FLOPPY FEHLER AUS
	CALL	SOUT		;
	JMP	START		;KEIN BOOT MOEGLICH, ZUM MONITOR
INIT5:				;
				;
;***
				;
	LDA	TEMP		;GEBE MELDUNG AUS OB NON-DEFAULT
	LXI	H,INITXTA	;DISKTIMING
	INR	A		;
	CZ	SOUT		;
				;
;***
				;
	LXI	H,INITXT3	;MONITOR ODER BOOT
	CALL	SOUT		;
	CALL	GETCH1		;
	PUSH	PSW		;
	CALL	CROUT		;GEBE AUF JEDEN FALL CR LF AUS
	POP	PSW		;
	CPI	0DH		;MONITOR?
	JNZ	BCMD		;NEIN BOOT
				;
	JMP	START
				;
;***
				;
INITXT0	DB	0CH,0DH,0AH,'PROF-80, EPROM version $'
INITXT8	DB	'   serial no. #$'
	IF	ACHTMHZ
INITXT1	DB	0DH,0AH,'System speed 8.00 MHz assumed',0DH,0AH,'$'
	ELSE
INITXT1	DB	0DH,0AH,'System speed $'
INITXT2	DB	'00 (Hz)',0DH,0AH,'$'
	ENDIF
INITXTA	DB	0DH,0AH,'                      user defined disk timing',0Dh,0Ah,'$'
INITXT3	DB	0DH,0AH,'press <RETURN> for MONITOR or insert disk into'
	DB	0DH,0AH,'drive A  and push any other key for  CP/M boot$'
INITXT4	DB	0DH,0AH,'Clock failure'
	IF	NOT ACHTMHZ
	DB	', 4 MHz system speed is assumed'
	ENDIF
	DB	0DH,0AH,'$'
INITXT5	DB	0DH,0AH,'Floppy failure, no CP/M boot possible',0DH,0AH,'$'
INITXT6	DB	0DH,0AH,'    64K RAM (Bank 1 only)',0DH,0AH,'$'
INITXT7	DB	0DH,0AH,'    64K RAM (Bank 0 only)',0DH,0AH,'$'
INITXT9	DB	0DH,0AH,'    128K RAM',0DH,0AH,'$'
;
;----------------------------------------------------ENDE INITIALISIERUNG----
;
;----------------------------------------------------EIN-AUSGABEROUTINEN-----
;
;
;
GRAFIST:
		;TERMINAL EINGABE STATUS
		;AKKU 0 UND Z WENN KEIN ZEICHEN
		;AKKU FF UN NZ WENN ZEICHEN
	IN	GRIPC
	ANI	GRIPIN$MASK
	RZ
	MVI	A,0FFH
	ORA	A	;RESET ZERROFLAG
	RET
;
;
;
GRAFOST:
		;TERMINAL AUSGABE STATUS
	IN	GRIPC
	ANI	GRIPOUT$MASK
	RZ
	MVI	A,0FFH
	ORA	A
	RET
;
;
;
GRAFIN: 
		;TERMINAL EINGABE
	IN	GRIPC
	ANI	GRIPIN$MASK	;ZEICHEN DA ?
        JRZ	GRAFIN   	;WARTE AUF ZEICHEN
        IN      GRIPD
	RET
;
;
GRAFOUT: 
 		;TERMINAL AUSGABE
	IN	GRIPC
	ANI	GRIPOUT$MASK
        JRZ     GRAFOUT	;WARTE BIS BUFFER LEER
        MOV     A,C     ;AUSGABE ZEICHEN NACH A
        OUT     GRIPD
	RET
;
;
;
	;EIN-AUSGABE FUER DIE DUPLEX SCHNITTSTELLE AUF DER CPU-KARTE
	;
	;
SOFTOUT:
	; GEBE INHALT VON REGISTER C IM SERIELLEN FORMAT AUS
	;
	PUSH	B		;RETTE BC
	PUSH	D		;RETTE DE
	PUSH	H		;RETTE HL
SOFTOUT4:			
	IN	P$IN$LS258$A	;WARTE AUF FREIGABE
	ANI	MASK$CTS	;
	JRZ	SOFTOUT4	;
	MVI	A,PAD$RTS OR 1	;SPERRE EINGABE
	OUT	P$LS259		;
	DI			;SPERRE INTERRUPTS
	RLCR	C		;BITS RICHTIG FUER AUSGABE
	MVI	D,PAD$TX	;ADRESSE DES TXD BITS AM LS259
	XRA	A		;STARTBIT IN AKKU
	MVI	B,9		;GEBE 9 BITS AUS
SOFTOUT1:
	ANI	001H		;MASKIERE BIT FUER AUSGABE <7>
	ORA	D		;PACKE ADRESSE DAZU <4>
	OUT	P$LS259		;GEBE BIT AUS <11>
	LHLD	SOFTVERZ	;LADE VERZOEGERUNGSZEIT <16>
SOFTOUT2:
	DCX	H		;VERZOEGERUNG <6>
	MOV	A,H		;GLEICH NULL? <4>
	ORA	L		; <4>
	JNZ	SOFTOUT2	; <10>
				;
	RRCR	C		;SCHIEBE C UM EIN BIT NACH RECHTS <8>
	MOV	A,C		; <4>
	DJNZ	SOFTOUT1	; <13>
				;
	MVI	A,PAD$TX OR 1	;GEBE STOPBIT AUS
	OUT	P$LS259		;
	LHLD	SOFTVERZ	;
	DAD	H		;ZWEI STOPBITS
SOFTOUT3:
	DCX	H		;VERZOEGERUNG FUER
	MOV	A,H		;STOPBIT
	ORA	L		;
	JNZ	SOFTOUT3	;
				;
	EI			;GEBE INTERRUPTS FREI
	LDA	IO$JUMPERBYTE	;KANN EINGABE FREI GEGEBEN WERDEN?
	DCR	A		;JA WENN INT.BETRIEB
	JRNZ	SOFTOUT5	;
	MVI	A,PAD$RTS	;GEBE EINGABE FREI
	OUT	P$LS259		;
SOFTOUT5:
	POP	H		;RETTE HL
	POP	D		;RETTE DE
	POP	B		;RETTE BC
	MOV	A,C		;ZEICHEN IN AKKU
	RET
;
;
;
SOFTIN:
	;EINLESEN EINES ZEICHENS SOWOHL IM INTERRUPT
	;BETRIEB (INTERRUPT BETRIEB IST DANN, WENN DIE 
	;SOFTSCHNITTSTELLE DIE KONSOLE TREIBT)
	;ALS AUCH IM NICHT INTERRUPT BETRIEB
	;
	PUSH	B
	PUSH	D
	PUSH	H
	LDA	IO$JUMPERBYTE	;IST INTERRUPT-BETRIEB?
	DCR	A		;INT. WENN A=1
	JRZ	SOFTIN8		;SPRUNG BEI INTERRUPT
	MVI	A,PAD$RTS	;GEBE RTS FREI
	OUT	P$LS259		;
	CALL	SOFTIN1		;ANSONSTEN WARTE AUF STARTBIT UND LESE EIN
	PUSH	PSW		;
	MVI	A,PAD$RTS OR 1	;
	OUT	P$LS259		;
	POP	PSW		;
	POP	H		;
	POP	D		;
	POP	B		;
	RET			;
				;
SOFTIN8:			;IM INTERRUPT-BETRIEB WIRD GEWARTET BIS
				;DIE INTERRUPT SERVICE ROUTINE EIN ZEICHEN
				;IN DEN BUFFER SCHREIBT
				;
	EI			;VORSICHTSHALBER INT. ENABLE
	MVI	A,PAD$RTS	;
	OUT	P$LS259		;
	MVI	C,IN$BUFF$ZEIG AND 0FFH
SOFTIN9	LDA	IN$BUFF$ZEIG	;WARTE BIS EIN ZEICHEN KOMMT
	CMP	C		;WENN GLEICH, DANN NOCH KEIN ZEICHEN
	JRZ	SOFTIN9		;
	MVI	A,PAD$RTS OR 1	;RTS INAKTIV
	OUT	P$LS259		;
	DI			;OK, ZEICHEN DA, SPERRE INT.
	LDA	IN$BUFF$ZEIG-1	;LADE ZEICHEN IN AKKU
	LHLD	IN$BUFF$ZEIG	;
	INX	H		;UND ERHOEHE ZEIGER
	SHLD	IN$BUFF$ZEIG	;
	LXI	D,IN$BUFF$ZEIG-1;SCHIEBE ZEICHEN EINS HOCH
	LXI	H,IN$BUFF$ZEIG-2;
	LXI	B,IN$BUFF$ZEIG-1-IN$BUFF$END	;
	LDDR			;
	EI			;INTERRUPTS ENABLE
	PUSH	PSW		;
	MVI	A,PAD$RTS	;GEBE EINGABE FREI
	OUT	P$LS259		;
	POP	PSW		;
	POP	H		;
	POP	D		;
	POP	B		;
	RET			;
;
;
;
INT$SERVICE:
	;NACH EINEM INTERRUPT UND WENN DIE SOFTSCHNITTSTELLE DIE KONSOLE
	;BEDIENT, WIRD DIESE INTERRUPT-SERVIE-ROUTINE ANGESPROCHEN.
	;SIE LIEST EIN ZEICHEN IN DIE SPEICHER ZELLE UNTER DIE IN$BUFF$ZEIG
	;ZEIGT. IST DER BUFFER VOLL (11 BYTES), WIRD KEIN ZEICHEN
	;MEHR EINGELESEN.
	;
	PUSH	PSW		;
	PUSH	B		;
	PUSH	D		;
	PUSH	H		;
	CALL	SOFTIN2		;LESE ZEICHEN EIN
	MOV	C,A		;RETTE ZEICHEN IN C
	LHLD	IN$BUFF$ZEIG	;LADE BUFFER-ZEIGER
	MVI	A,IN$BUFF$END AND 0FFH
	CMP	L		;ZEIGER SCHON AM ENDE?
	JRZ	INT$SERVICE1	;DANN GEHT ZEICHEN VERLOREN
	DCX	H		;SONST LEGE ZEICHEN IN BUFFER
	MOV	M,C		;
	SHLD	IN$BUFF$ZEIG	;UND SETZE ZEIGER NEU
INT$SERVICE1:			;
	POP	H		;
	POP	D		;
	POP	B		;
	POP	PSW		;
	EI			;GEBE INT. FREI
	RET			;
;
;
;
SOFTIN1:
	;LESE ZEICHEN UEBER 74LS258 EIN
	;
	IN	P$IN$LS258$A	;
	ANI	MASK$RX		;WARTE AUF STARTBIT
	JRZ	SOFTIN1		;DER LS258 NEGIERT
SOFTIN2:			;
	LHLD	SOFTVERZ	;LADE VERZOEGERUNG
	SRLR	H		;TEILE DURCH ZWEI
	RARR	L		;UM IN DER BIT MITTE ABZUTASTEN
SOFTIN5	DCX	H		;VERZOEGERUNGSSCHLEIFE
	MOV	A,H		;FUER EIN HALBES BIT
	ORA	L		;
	JNZ	SOFTIN5		;
				;
	MVI	B,8		;LESE 8 BITS EIN
SOFTIN3:
	LHLD	SOFTVERZ	;ERST EIN BIT VERZOEGERN <16>
SOFTIN4	DCX	H		;VERZOEGERUNGSSCHLEIFE
	MOV	A,H		;
	ORA	L		;
	JNZ	SOFTIN4		;
				;
	IN	P$IN$LS258$A	;LESE BIT EIN <11>
	ANI	MASK$RX		; <7>
	ADI	0FFH		;SETZE CARRY WENN EINS <7>
	RARR	C		;UND LEGE IN CHARPUF. <8>
	DJNZ	SOFTIN3		;LESE 8 BITS EIN <13>
				;
	MOV	A,C		;ERGEBNISS IN AKKU
	CMA			;NEGIERE, DA LS258 AUCH NEGIERT
SOFTIN7	ANI	7FH		;STRIPP OF PARITY
				;
	PUSH	PSW		;
	LHLD	SOFTVERZ	;WARTE STOP BIT AB
SOFTIN10:
	DCX	H		;
	MOV	A,H		;
	ORA	L		;
	JNZ	SOFTIN10	;
	POP	PSW		;
				;
	RET
;
;
;
SOFTIST:
	;PRUEFE, OB IM INT.-BETRIEB EIN ZEICHEN IM BUFFER IST
	;WENN EINS GEKOMMEN IST, SETZE A AUF FF
	;SONST AUF 0
	;IST KEIN INTERRUPT BETRIEB, DANN AKKU IMMER 0
	;
	PUSH	H
	PUSH	D
	PUSH	B
	LDA	IO$JUMPERBYTE	;INT.  BETRIEB?
	DCR	A		;
	JRNZ	SOFTST1		;SPRUNG WENN KEIN INT.-BETRIEB
	LDA	IN$BUFF$ZEIG	;LADE ZEIGER
	MVI	C,IN$BUFF$ZEIG AND 0FFH
	CMP	C		;VERGLEICHE
	JRZ	SOFTST1		;SPRUNG WENN KEIN ZEICHEN DA
	MVI	A,0FFH		;
	JR	SOFTST2		;
SOFTST1	MVI	A,0		;
SOFTST2	POP	H
	POP	D
	POP	H
	ORA	A		;SETZE ZEROFLAG
	RET
;
;
;
SOFTOST:
	IN	P$IN$LS258$A	;LESE CTS EIN
	ANI	MASK$CTS	;MASKIERE
	RZ			;RETURN WENN NICHT BEREIT
	MVI	A,0FFH		;SONST BEREIT
	ORA	A		;RESET ZERRO-FLAG
	RET			;
;
;
;
SOFTPRNTOST:
	IN	P$IN$LS258$A	;LESE CTSP EIN
	ANI	MASK$CTSP	;
	RZ			;
	MVI	A,0FFH		;
	ORA	A		;
	RET
;
;
;
SOFTPRNTOUT:
	; GEBE INHALT VON REGISTER C IM SERIELLEN FORMAT 
	; AUF DER SIMPLEX SCHNITTSTELLE AUS
	;
	PUSH	B		;RETTE BC
	PUSH	D		;RETTE DE
	PUSH	H		;RETTE HL
SOFTPRNTOUT4:			
	IN	P$IN$LS258$A	;WARTE AUF FREIGABE
	ANI	MASK$CTSP	;
	JRZ	SOFTPRNTOUT4	;
	MVI	A,PAD$RTS OR 1	;SPERRE EINGABE VON DUPLEX SCHNITTSTELLE
	OUT	P$LS259		;
	DI			;SPERRE INTERRUPTS
	RLCR	C		;BITS RICHTIG FUER AUSGABE
	MVI	D,PAD$TXP	;ADRESSE DES TXD BITS AM LS259
	XRA	A		;STARTBIT IN AKKU
	MVI	B,9		;GEBE 9 BITS AUS
SOFTPRNTOUT1:
	ANI	001H		;MASKIERE BIT FUER AUSGABE <7>
	ORA	D		;PACKE ADRESSE DAZU <4>
	OUT	P$LS259		;GEBE BIT AUS <11>
	LHLD	SOFTPRNTVERZ	;LADE VERZOEGERUNGSZEIT <16>
SOFTPRNTOUT2:
	DCX	H		;VERZOEGERUNG <6>
	MOV	A,H		;GLEICH NULL? <4>
	ORA	L		; <4>
	JNZ	SOFTPRNTOUT2	; <10>
				;
	RRCR	C		;SCHIEBE C UM EIN BIT NACH RECHTS <8>
	MOV	A,C		; <4>
	DJNZ	SOFTPRNTOUT1	; <13>
				;
	MVI	A,PAD$TXP OR 1	;GEBE STOPBIT AUS
	OUT	P$LS259		;
	LHLD	SOFTPRNTVERZ	;
	DAD	H		;ZWEI STOPBITS
SOFTPRNTOUT3:
	DCX	H		;VERZOEGERUNG FUER
	MOV	A,H		;STOPBIT
	ORA	L		;
	JNZ	SOFTPRNTOUT3	;
				;
	EI			;GEBE INTERRUPTS FREI
	MVI	A,PAD$RTS	;GEBE EINGABE FREI DUPLEX
	OUT	P$LS259		;SCHNITTSTELLE FREI
	POP	H		;RETTE HL
	POP	D		;RETTE DE
	POP	B		;RETTE BC
	MOV	A,C		;ZEICHEN IN AKKU
	RET
;
;
;
GET$JUMPER:
		LXI	H,PATAB		;
	LXI	B,PDTAB		;
	MVI	E,P$LS259	;
	MVI	D,P$IN$LS258$B	;
	CALL	JUMPIN		;
	STA	BAUD$JUMPERBYTE	;SPEICHERE AB
	MOV	A,D		;
	STA	IO$JUMPERBYTE	;
	RET
;
;
;
JUMPIN:				;DIESES PROGRAMM LIEST DIE BEIDEN
				;JUMPER AUF DER UNIO- BZW PROF-KARTE
				;EIN. FOLGENDE REGISTER MUESSEN BELEGT SEIN
				;E=PORTADRESSE DES 74 LS259
				;D=PORTADRESSE DES EINGANGS PORTS
				;BC=ADRESSE DER DECODER TABELLE
				;HL=ADRESSE DER AUSGANGS BITS
				;AUSGABE
				;AKKU=JUMPER 1, D=JUMPER2
				;
	PUSH	B		;RETTE DECODER TABELLE
	MOV	C,E		;
	MVI	B,3		;ERSTES BITMUSTER AUSGEBEN
	OUTIR			;
	MOV	A,C		;TAUSCHE PORTADRESSE
	MOV	C,D		;
	MOV	D,A		;
	INP	A		;LESE ERSTES BITPAAR EIN
	RAR			;SCHIEBE BITS NACH RECHTS
	RAR			;
	RAR			;
	RAR			;
	ANI	00000011B	;MASKIERE
	MOV	E,A		;UND NACH E
				;
	MOV	A,C		;TAUSCHE PORTADRESSE
	MOV	C,D		;
	MOV	D,A		;
	MVI	B,2		;ZWEITES BITMUSTER AUSGEBEN
	OUTIR			;
	MOV	A,C		;TAUSCHE PORTADRESE
	MOV	C,D		;
	MOV	D,A		;
	INP	A		;LESE ZWEITES BITPAAR EIN EIN
	RAR			;EINMAL NACH RECHTS SCHIEBEN
	RAR			;
	ANI	00001100B	;MASKIEREN
	ORA	E		;UND ZU E PACKEN
	MOV	E,A		;
				;
	MOV	A,C		;TAUSCHE PORTADRESSE
	MOV	C,D		;
	MOV	D,A		;
	MVI	B,2		;DRITTES BITMUSTER AUSGEBEN
	OUTIR			;
	MOV	A,C		;TAUSCHE PORTADRESSE
	MOV	C,D		;
	MOV	D,A		;
	INP	A		;LESE DRITTES BITPAAR EIN
	ANI	00110000B	;MASKIEREN UND ZU E PACKEN
	ORA	E		;
	MVI	B,3		;TRENNE BEIDE JUMPERFELDER
JUMPI1	RAR			;
	RALR	D		;
	RAR			;
	RALR	E		;
	DJNZ	JUMPI1		;
	POP	H		;HOLE DECODER TABELLE
	PUSH	H		;
	MVI	B,0		;
	MOV	A,D		;
	ANI	00000111B	;
	MOV	C,A		;
	DAD	B		;
	MOV	D,M		;
	POP	H		;HOLE DECODER TABELLE
	MOV	A,E		;
	ANI	00000111B	;
	MOV	C,A		;
	DAD	B		;
	MOV	A,M		;
	RET			;
;
;
;

UDTAB	DB	6,8,12,14	;DECODIER TABELLE FUER UNIO JUMPER
	DB	10,14,14,14	;
;
PDTAB	DB	0,0,0,2		;DECODIER TABELLE FUER PROF JUMPER
	DB	0,3,4,1		;
;
UATAB	DB	0BH,0CH,0EH	;
	DB	0AH,0DH		;
	DB	0CH,0FH		;
;
PATAB	DB	080H,010H,020H	;
	DB	000H,090H	;
	DB	010H,0A0H	;
;
;
;
; ES FOLGEN UNIO TREIBER-ROUTINEN
;
;
;
UNIOINIT:	;DIESE ROUTINE WIRD BEI INITIALISIERUNG DES MONITORS
		;AUFGERUFEN. STROBE UND INIT FUER UNIO-CENTRONICS
		;WURDEN VON INIT SCHON AUF HIGH GESETZT.
		;UNIOINIT LIEST DIE BEIDEN SIO-BAUDRATEN-JUMPER EIN
		;UND INITIALISIERT BEIDE SIO- UND DEN STI KANAL.
		;
	LXI	H,UATAB		;LESE UNIO BAUD JUMPER
	LXI	B,UDTAB		;
	MVI	E,CONTR		;
	MVI	D,STAT		;
	CALL	JUMPIN		;
	STA	SIOBBAUD	;
	MOV	A,D		;
	STA	SIOABAUD	;
				;
	LDA	STIBAUD		;INITIALISIERE STI
	CALL	STINIT		;
	LDA	SIOABAUD	;
	CALL	SAINIT		;
	LDA	SIOBBAUD	;
	CALL	SBINIT		;
	RET
;
;
;
; STI INITIALISIEREN, IN AKKU STEHT NUMMER FUER BAUDRATE
; FALLS OBERE 4 BIT VON AKKU .NE. 0 DANN WIRD BAUDRATE FUER
; RECEIVER UND TRANSMITTER GETRENNT EINGESTELLT
;
STINIT:
	PUSH	PSW		;RETTE AKKU
	ANI	0FH		;NUR TRANSMITTER BAUDRATE
	CALL	STITINIT	;
	POP	PSW		;JETZT RECEIVER BAUDRATE
	MOV	B,A		;
	ANI	0F0H		;WENN OBERES HALBBYTE = 0
	JRZ	STINIT1		;DANN GLEICHE BAUDRATE
	MOV	A,B		;
	ANI	0FH		;38400 BAUD NUR AUF BEIDEN KANAELEN
	JRZ	STINIT2		;GLEICHZEITIG MOEGLICH
	MOV	A,B		;
	RAR			;
	RAR			;
	RAR			;
	RAR			;
STINIT3	ANI	0FH		;
	CALL	STIRINIT	;
	RET			;
STINIT1	MOV	A,B		;
	JR	STINIT3		;BEIDE KANAELE GLEICHE BAUDRATE
STINIT2	XRA	A		;
	JR	STINIT3		;BEIDE KANAELE 38400 BAUD		
;
STITINIT:
	LXI	H,SERTAB	;ZEIGER FUER TABELLE BERECHNEN
	MOV	C,A		;
	MVI	B,0		;
	DAD	B		;
	DAD	B		;
	MVI	A,2		;POINTER AUF TIMER C DATA
	OUT	STI8		;
	MOV	A,M		;TIMER C DATA
	OUT	STI0		;
	INX	H		;
	MVI	A,7		;TIMER C UND D CONTROL
	OUT	STI8		;
	MOV	A,M		;PRESCALE
	ANI	0F0H		;NUR OBERES HALBBYTE
	MOV	B,A		;
	IN	STI0		;TIMER C CONTROL LOESCHEN
	ANI	0FH		;
	ORA	B		;
	OUT	STI0		;
	RET			;
;
STIRINIT:
	LXI	H,SERTAB	;
	MOV	C,A		;
	MVI	B,0		;ZEIGER FUER TABELLE BERRECHNEN
	DAD	B		;2 EINTRAEGE PRO WERT
	DAD	B		;
	MVI	A,1		;POINTER AUF TIMER D DATA
	OUT	STI8		;
	MOV	A,M		;TIMER D DATA
	OUT	STI0		;
	INX	H		;
	MVI	A,7		;TIMER C UND D CONTROL
	OUT	STI8		;
	MOV	A,M		;PRESCALE
	ANI	0FH		;NUR UNTERES HALBBYTE
	MOV	B,A		;
	IN	STI0		;ALTE TIMER C UND D CONTROL DATEN
	ANI	0F0H		;TIMER D CONTROL LOESCHEN
	ORA	B		;NEUES TIMER D CONTROL EINTRAGEN
	OUT	STI0		;
	MOV	A,C		;
	ORA	A		;
	MVI	A,10001000B	;USART CONTROL: 8 DATA BIT, NO PAR, 1 STOP
	JRNZ	STINIT4		;
	ANI	01111111B	;SCALE/1 BEI 38.4 BAUD
STINIT4	OUT	STIC		;
	MVI	A,1		;
	OUT	STID		;RECEIVER ENABLE
	MVI	A,95H		;
	OUT	STIE		;TRANSMITTER ENABLE
	RET			;
;
;
;
; SIO A INITIALISIERUNG, IN AKKU STEHT NUMMER FUER BAUDRATE
;
SAINIT:
	LXI	H,SERTAB	;
	MOV	E,A		;
	MVI	D,0		;ZEIGER FUER TABELLE BERRECHNEN
	DAD	D		;2 EINTRAEGE PRO WERT
	DAD	D		;
	MOV	A,M		;TIMER B DATA
	OUT	STIA		;
	INX	H		;
	MOV	A,M		;PRESCALE
	ANI	0FH		;NUR UNTERES HALBBYTE
	MOV	B,A		;
	IN	STI9		;ALTE TIMER A UND B CONTROL DATEN
	ANI	0F0H		;TIMER B CONTROL LOESCHEN
	ORA	B		;NEUE TIMER B CONTROL DATEN
	OUT	STI9		;
	LXI	H,SIOTAB	;TABELLE FUER SIO INITIALISIERUNG
	MOV	B,M		;TABELLEN LAENGE
	INX	H		;
	MVI	C,SIOAC		;
	OUTIR			;TABELLE AN SIO UEBERGEBEN
	MOV	A,E		;
	ORA	A		;
	MVI	A,01000100B	;SIO WR-REG.4: CLOCK/16, 1 STOP, NO PAR.
	JRNZ	SAINIT1		;
	ANI	10111111B	;CLOCK/1 BEI 38.4 BAUD
SAINIT1	OUT	SIOAC		;
	RET			;
;
;
;
; SIO B INITIALISIERUNG, IN AKKU STEHT NUMMER FUER BAUDRATE
;
SBINIT:
	LXI	H,SERTAB	;
	MOV	E,A		;
	MVI	D,0		;ZEIGER FUER TABELLE BERRECHNEN
	DAD	D		;2 EINTRAEGE PRO WERT
	DAD	D		;
	MOV	A,M		;TIMER A DATA
	OUT	STIB		;
	INX	H		;
	MOV	A,M		;PRESCALE
	ANI	0F0H		;NUR OBERES HALBBYTE
	MOV	B,A		;
	IN	STI9		;ALTE TIMER A UND B CONTROL DATEN
	ANI	0FH		;TIMER A CONTROL LOESCHEN
	ORA	B		;NEUE TIMER A CONTROL DATEN
	OUT	STI9		;
	LXI	H,SIOTAB	;TABELLE FUER SIO INITIALISIERUNG
	MOV	B,M		;TABELLEN LAENGE
	INX	H		;
	MVI	C,SIOBC		;
	OUTIR			;TABELLE AN SIO UEBERGEBEN
	MOV	A,E		;
	ORA	A		;
	MVI	A,01000100B	;SIO WR-REG.4: CLOCK/16, 1 STOP, NO PAR.
	JRNZ	SBINIT1		;
	ANI	10111111B	;CLOCK/1 BEI 38.4 BAUD
SBINIT1	OUT	SIOBC		;
	RET			;
;
;
;
; STI OUT
;
STOUT	CALL	STOST		;BEREIT ?
	JRZ	STOUT		;
	MOV	A,C		;
	OUT	STIF		;
	RET			;
;
;
;
; STI OUT STATUS
;
STOST	IN	STIE		;
	ANI	10000000B	;
	RZ			;
	ORI	0FFH		;
	RET			;
;
;
;
; STI IN
;
STIN	CALL	STIST		;
	JRZ	STIN		;
	IN	STIF		;
	RET			;
;
;
;
; STI INPUT STATUS
;
STIST	IN	STID		;
	ANI	10000000B	;
	RZ			;
	ORI	0FFH		;
	RET			;
;
;
;
; SIO A OUT
;
SAOUT	CALL	SAOST		;
	JRZ	SAOUT		;NOCH NICHT BEREIT
	MOV	A,C		;
	OUT	SIOAD		;ZEICHEN SENDEN
	RET			;
;
;
;
; SIO A OUT STATUS
;
SAOST	IN	SIOAC		;LESE STATUS
	ANI	00000100B	;
	RZ			;
	ORI	0FFH		;
	RET
;
;
;
; SIO A IN
;
SAIN	CALL	SAIST		;
	JRZ	SAIN		;NOCH KEIN ZEICHEN EMPFANGEN
	IN	SIOAD		;
	RET			;
;
;
;
; SIO A IN STATUS
;
SAIST	IN	SIOAC		;LESE STATUS
	ANI	00000001B	;
	RZ			;
	ORI	0FFH		;
	RET			;
;
;
;
; SIO B OUT
;
SBOUT	CALL	SBOST		;
	JRZ	SBOUT		;NOCH NICHT BEREIT
	MOV	A,C		;
	OUT	SIOBD		;ZEICHEN SENDEN
	RET			;
;
;
;
; SIO B OUT STATUS
;
SBOST	IN	SIOBC		;LESE STATUS
	ANI	00000100B	;
	RZ			;
	ORI	0FFH		;
	RET
;
;
;
; SIO B IN
;
SBIN	CALL	SBIST		;
	JRZ	SBIN		;NOCH KEIN ZEICHEN EMPFANGEN
	IN	SIOBD		;
	RET			;
;
;
;
; SIO B IN STATUS
;
SBIST	IN	SIOBC		;LESE STATUS
	ANI	00000001B	;
	RZ			;
	ORI	0FFH		;
	RET			;
;
;
;
; CENTRONICS 1 OUT
;
C1OUT	CALL	C1OST		;BEREIT FUER NAECHSTES ZEICHEN?
	JRZ	C1OUT		;
	MOV	A,C		;
	OUT	CENT1		;
	MVI	A,4		;/STB1 = LOW
	OUT	CONTR		;
	MVI	A,5		;/STB1 = HIGH
	OUT	CONTR		;
	MOV	A,C		;GESENDETES ZEICHEN IN A
	RET			;
;
;
;
; CENTRONICS 1 OUT STATUS
;
C1OST	IN	STAT		;CENTRONICS 1 STATUS
	CMA			;
	ANI	01000000B	;
	RZ			;
	ORI	0FFH		;
	RET			;
;
;
;
; CENTRONICS 2 OUT
;
C2OUT	CALL	C2OST		;BEREIT FUER NAECHSTES ZEICHEN?
	JRZ	C2OUT		;
	MOV	A,C		;
	OUT	CENT2		;
	MVI	A,6		;/STB2 = LOW
	OUT	CONTR		;
	MVI	A,7		;/STB2 = HIGH
	OUT	CONTR		;
	MOV	A,C		;GESENDETES ZEICHEN IN A
	RET			;
;
;
;
; CENTRONICS 2 OUT STATUS
;
C2OST	IN	STAT		;CENTRONICS 2 STATUS
	CMA			;
	ANI	10000000B	;
	RZ			;
	ORI	0FFH		;
	RET			;
;
;
;
;
SERTAB:
	DB	8,11H		;38400 	 BAUD
	DB	96,33H		;   50   BAUD
	DB	64,33H		;   75   BAUD
	DB	175,11H		;  110   BAUD
	DB	143,11H		;  134.5 BAUD
	DB	128,11H		;  150   BAUD
	DB	64,11H		;  300   BAUD
	DB	32,11H		;  600	 BAUD
	DB	16,11H		; 1200   BAUD
	DB	11,11H		; 1745   BAUD
	DB	8,11H		; 2400   BAUD
	DB	5,11H		; 3840   BAUD
	DB	4,11H		; 4800	 BAUD
	DB	3,11H		; 6400   BAUD
	DB	2,11H		; 9600   BAUD
	DB	1,11H		;19200   BAUD
;
;
;
SIOTAB:
	DB	SIOTAL-SIOTAB-1
	DB	1,0
	DB	3,11100001B
	DB	5,11101010B
	DB	4
SIOTAL	EQU	$
;
;
;
;-------------------------------------------------ENDE DER E/A-ROUTINEN-----
;
;
;
CONST:
	;VERTEILER FUER CONSOLEN STATUS
	;DIE ROUTINEN MUESSEN A=FF UND KEIN ZERO-FLAG SETZEN
	;FALLS EIN ZEICHEN DA IST SONST AKKU= 0 UND ZERO-FLAG
	;
	LDA	IO$JUMPERBYTE		;LESE JUMPERBYTE EIN
	CALL	VERTEILER		;
	DW	GRAFIST			;
	DW	SOFTIST			;
	DW	USER1IST		;
	DW	USER2IST		;
	DW	DUMMYIST		;
;
;
;
CONIN:
	;VERTEILER FUER CONSOLEN EINGABE
	;DIE ROUTINE MUSSEN AUF EIN ZEICHEN VON DER KONSOLE WARTEN
	;UND DIESES IM AKKU UEBERGEBEN
	;ALLE ANDEREN REGISTER BLEIBEN UNVERAENDERT
	;
	LDA	IO$JUMPERBYTE		;
	CALL	VERTEILER		;
	DW	GRAFIN			;
	DW	SOFTIN			;
	DW	USER1IN			;
	DW	USER2IN			;
	DW	DUMMYIN			;
;
;
;
CONOUT:
	;VERTEILER FUER CONSOLEN AUSGABE
	;DAS ZEICHEN IN REG C. WIRD VON DEN ROUTINEN AUSGEGEBEN
	;UND IN AKKU KOPIERT, ALLE ANDEREN REGISTER BLEIBEN UNVERAENDERT
	;
	LDA	IO$JUMPERBYTE		;
	CALL	VERTEILER		;
	DW	GRAFOUT			;
	DW	SOFTOUT			;
	DW	USER1OUT		;
	DW	USER2OUT		;
	DW	DUMMYOUT		;
;
;
;
VERTEILER:
	;VERZEIGT AUF EINE DER ADRESSEN DIE DER RETURNADRESSE FOLGEN
	;
	XTHL			;LEGE RETURNADRESSE IN HL
VERTEILER1:
	DCR	A		;WAR AKKU NULL?
	JM	VERTEILER2	;DANN ZEIGT HL AUF DIE RICHTIGE RETURN ADR.
	INX	H		;ANSONSTEN EINE ADRESSE WEITER
	INX	H		;
	JR	VERTEILER1	;
VERTEILER2:
	MOV	A,M		;LADE ADRESSE DER ROUTINE IN HL
	INX	H		;
	MOV	H,M		;
	MOV	L,A		;
	XTHL			; LADE ALTES HL UND LEGE ADRESSE DER ROUTINE
				; AUF DEN STACK
	RET			; SPRINGE IN DIE RICHTIGE ROUTINE
;
;
;
DUMMYIST:
	MVI	A,0FFH
	ORA	A
	RET
;
;
;
DUMMYIN:
	MVI	A,'7'
	RET
;
;
;
DUMMYOUT:
	MOV	A,C
	RET
;
;
;
BREAK:
	;PRUEFT OB EIN ZEICHEN EINGELESEN WURDE
	;
	CALL	CS		;
	JZ	FRET		;
	CALL	CI		;LESE ZEICHEN
	ANI	7FH		;
	CPI	1BH		;GLEICH ESCAPE
	JZ	SRET		;JA ENDE
BREAK1	CALL	CS		;WARTE AUF NEUES ZEICHEN
	JRZ	BREAK1		;
	CALL	CI		;LESE NEUES ZEICHEN
	ANI	7FH		;
	CPI	1BH		;
	JZ	SRET		;WAR BREAK
	JMP	FRET		;WAR ETWAS ANDERES
;
;
;
CNVBN: 
	MOV	A,C		;
	SUI	'0'		;
	CPI	0AH		;
	RM			;
	SUI	7		;
	RET
;
;
;
SOUT:				;GEBE STRING AUS
				;ANFANG IN HL, ENDE DURCH 24HEX
	MOV	A,M		;LESE ZEICHEN
	CPI	'$'		;STRING ENDE
	RZ			;RETURN WENN $
	MOV	C,A		;IN C FUER AUSGABE
	CALL	CO		;GEBE ZEICHEN AUF CONSOLE
	INX	H		;ZEIGER AUF NAECHSTES ZEICHEN
	JR	SOUT		;WIEDERHOLE
;
;
;
CROUT: 
	PUSH	B		;
	MVI	C,0DH		;
	CALL	ECHO		;
	POP	B		;
	RET
;
;
;
ECHO: 
	PUSH	B		;
	MOV	B,C		;
	MVI	A,1BH		;
	CMP	B		;
	JRNZ	ECH05		;
	MVI	C,'$'		;
ECH05:	CALL	CO		;
	MVI	A,0DH		;
	CMP	B		;
	JRNZ	ECH10		;
	MVI	C,0AH		;
	CALL	CO		;
ECH10:	POP	B		;
	MOV	A,C		;
	RET
;
;
;
ERROR:
	LXI	H,SYNERRTXT
	CALL	SOUT
JMP	GETCM
;
SYNERRTXT	DB	' What?',BELL,0DH,0AH,'$'
;
;
;
FRET: 
	STC
	CMC
	RET
;
;
;
;
GETCH1:	;LESE EIN ZEICHEN VON KONSOLE, UND WANDLE IN GROSSBUCHSTABEN
	CALL	CI
	ANI	7FH
	MOV	C,A
	CPI	'a'
	RC
	SUI	'a'-'A'
	MOV	C,A
	RET
;
;
;
GETCH: 
	CALL	CI
	ANI	7FH
	MOV	C,A
	RET
;
;
;
GETHX: 
	PUSH	H
	LXI	H,0
	MVI	E,0
L0228: 
	CALL	GETCH1
	MOV	C,A
	CALL	VALDL
	JNC	L0241
	CALL	ECHO
	MOV	D,C
	PUSH	H
	POP	B
	POP	H
	MOV	A,E
	ORA	A
	JNZ	SRET
	JZ	FRET
L0241: 
	CALL	VALDG
	JNC	L0228
	CALL	ECHO
	CALL	CNVBN
	MVI	E,0FFH
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	MVI	B,0
	MOV	C,A
	DAD	B
	JMP	L0228
;
;
;
GETDEZ:
	;LESE DEZIMALZAHLEN NACH HL
	;ALS TRENNZEICHEN WERDEN '/',':' UND <CR> ERKANNT
	;TRENNZEICHEN WIRD IN AKKU UEBERGEBEN
	;
	MVI	B,0
	LXI	H,0	;LOESCHE AKKU
GETDEZ1	CALL	GETCH1	;LESE ZEICHEN
	CPI	'/'
	JRZ	GETDEZ2
	CPI	':'
	JRZ	GETDEZ2
	CPI	0DH
	JRZ	GETDEZ2
	SUI	'0'	;ZAHL ?
	JRC	GETDEZ1
	CPI	0AH
	JRNC	GETDEZ1
	MOV	C,A
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	DAD	B
	MVI	A,'0'	;GEBE ZAHL AUS
	ADD	C
	MOV	C,A
	CALL	ECHO
	JR	GETDEZ1
GETDEZ2	MOV	C,A
	CALL	ECHO
	MOV	A,C
	RET
;
;
;
DEZHEX:
	;WANDELT DEZIMAL ZAHL IM AKKU IN HEXWERT UM
	PUSH	B
	CPI	0	;IST SCHON 0?
	JRZ	DEZHEX1
	MVI	B,0
DEZHEX2 INR	B
	DCR	A
	DAA
	JNZ	DEZHEX2
	MOV	A,B
DEZHEX1	POP	B
	RET
;
;
;
GETNM:
	MVI	L,3
	MOV	A,C
	ANI	3
	RZ
	MOV	H,A
L025E: 
	CALL	GETHX
	JNC	ERROR
	PUSH	B
	DCR	L
	DCR	H
	JZ	L0273
	MOV	A,D
	CPI	0DH
	JZ	ERROR
	JMP	L025E
L0273: 
	MOV	A,D
	CPI	0DH
	JNZ	ERROR
	LXI	B,0FFFFH
	MOV	A,L
	ORA	A
	JZ	L0286
L0281: 
	PUSH	B
	DCR	L
	JNZ	L0281
L0286: 
	POP	B
	POP	D
	POP	H
	CALL	HILO
	JNC	L0291
	MOV	D,H
	MOV	E,L
L0291: 
	XTHL
	PUSH	D
	PUSH	B
	PUSH	H
L0295: 
	DCR	A
	RM
	POP	H
	XTHL
	JMP	L0295
HILO : 
	PUSH	B
	MOV	B,A
	PUSH	H
	MOV	A,D
	ORA	E
	JZ	L02BD
	INX	H
	MOV	A,H
	ORA	L
	JZ	L02BD	;02BDH
	POP	H
	PUSH	D
	MVI	A,0FFH
	XRA	D
	MOV	D,A
	MVI	A,0FFH
	XRA	E
	MOV	E,A
	INX	D
	MOV	A,L
	ADD	E
	MOV	A,H
	ADC	D
	POP	D
	MOV	A,B
	POP	B
	RET
L02BD: 
	POP	H
	MOV	A,B
	POP	B
	JMP	SRET
;
;
;
PDEC:
	;GEBE HL REGISTER AL DEZIMALZAHL AUS
	LXI	B,TABLE10
	LXI	D,-10000
PNEXT:	MVI	A,'0'-1
PDECL:	PUSH	H
	INR	A
	DAD	D
	JRNC	STOPLOOP
	INX	SP
	INX	SP
	JR	PDECL
STOPLOOP:
	PUSH	D
	PUSH	B
	MOV	C,A
	CALL	ECHO
	POP	B
	POP	D
NEXTDIGIT:
	POP	H
	LDAX	B
	MOV	E,A
	INX	B
	LDAX	B
	MOV	D,A
	INX	B
	MOV	A,E
	ORA	D
	JRNZ	PNEXT
	RET
;
TABLE10:
	DW	-1000,-100,-10,-1,0
;
;
;
DEZOUT:	;WANDLE AKKU IN DEZIMALZAHL UND GEBE AKKU AUS
	ORA	A	;AKKU NULL
	JRZ	DEZOUT2	;DANN IST SCHON ALLES OK
	MOV	B,A
	XRA	A
DEZOUT1:
	INR	A
	DAA
	DJNZ	DEZOUT1
DEZOUT2:
	CALL	NMOUT
	RET
;
;
;
NMOUT: 
	PUSH	H
	PUSH	B
	PUSH	PSW
	RRC
	RRC
	RRC
	RRC
	ANI	0FH
	MOV	C,A
	CALL	PRVAL
	CALL	ECHO
	POP	PSW
	ANI	0FH
	MOV	C,A
	CALL	PRVAL
	CALL	ECHO
	POP	B
	POP	H
	RET
;
;
;
SET$SOFT$BAUD:
	;SETZE DIE BAUDRATE DER SOFT-SCHNITTSTELLE
	;ENTSPRECHEND DER STELLUNG VON BAUD$JUMPERBYTE
	;NEHME DAZU DEN ENTSPRECHENDEN WERT AUS
	;SOFT$BAUD$TAB UND KORRIGIERE  IHN MIT DER
	;SYSTEMFREQUENZ
	;
	LDA	BAUD$JUMPERBYTE	;STELLUNG VON BAUD$JUMPER
SET$DUPLEX$BAUD:		;EINSPRUNG ZUM NEU SETZEN
	MVI	H,0		;SOFT$BAUD$TAB EINTRAG
	MOV	L,A
	LXI	D,SOFT$BAUD$TAB
	DAD	H		;MAL ZWEI
	DAD	D
	MOV	E,M		;SOFT$BAUD$TAB-EINTRAG IN DE
	INX	H
	MOV	D,M
	LBCD	SYSTEMTAKT	;SYSTEMTAKT IN BC
	CALL	MULTIP		;MULTIPLIZIERE
	SHLD	SOFTVERZ	;UND TEILE DURCH 65536
				;DA NUR DIE OBEREN 16 BITS GENUTZT WERDEN
	RET
;
;
;
SET$SIMPLEX$BAUD:
	;BERRECHNE DIE VERZOEGERUNGSZEIT FUER DIE SIMPLEX SCHNITTSTELLE
	;DER WERT IM AKKU GIBT DEN LISTEN-EINTRAG DER SOFT$BAUD$TAB AN
	;
	MVI	H,0		;SOFT$BAUD$TAB EINTRAG
	MOV	L,A		;
	LXI	D,SOFT$BAUD$TAB	;
	DAD	H		;MAL ZWEI
	DAD	D		;
	MOV	E,M		;TABELLEN EINTRAG IN DE
	INX	H		;
	MOV	D,M		;
	LBCD	SYSTEMTAKT	;KORRIGIERE MIT SYSTEMTAKT
	CALL	MULTIP		;MULTIPLIZIERE
	SHLD	SOFTPRNTVERZ	;TEILE DURCH 65536 UND LEGE AB
	RET
;
;
;
MULTIP:
	;MULTIPLIZIERT BC*DE 32BIT ERGEBNIS IN HLDE
	LXI	H,0	;INITIALISIERE HL
	MVI	A,-16	;SCHLEIFENZ[HLER
MUL7	DAD	H	;SCHIEBE DEHL UM 1BIT
	XCHG		;NACH LINKS
	DADC	H	;LSB=0
	XCHG
	JRNC	MUL2	;1AUS DE
	DAD	B	;DANN ADDIERE BC
	JRNC	MUL2	;]BERTRAG ENTSTANDEN?
	INX	D	;DANN DE EINS HOEHER
MUL2	INR	A	;16 DURCHLAEUFE?
	JM	MUL7	;SPRUNG WENN NEIN
	XCHG		;DIE HOEHEREN BITS IN HL
	RET
;
;
;
DIVIDE:
	;DIVIDIERT HLBC/DE
	;CARRY IST GESETZT, WENN QUOTIENT GROESSER ALS FFFF HEX
	;QUOTIENT STEHT IN HL, REST IN BC
	;BENUTZT STACK ALS ZWISCHENSPEICHER
	;
	PUSH	H
	LXI	H,1
	XTHL
	MOV	A,D	;FORM 2 COMPLEMENT OF DIVISOR	
	CMA
	MOV	D,A
	MOV	A,E
	CMA
	MOV	E,A
	INX	D
	PUSH	H
	DAD	D
	JRC	DIV1
DIV2:	POP	H
	JRC	DIV3
	RALR	C	;ROTATE HLBC 1 BIT LEFT
	RALR	B
	RALR	L
	RALR	H
	JRC	DIV4
	PUSH	H
	DAD	D
	INX	SP
	INX	SP
	JRC	DIV5
	POP	H
	DAD	H
DIV6	PUSH	H
	DCX	SP
	DCX	SP
	JR	DIV2
DIV4	DAD	D
DIV5	PUSH	H
	INX	SP
	INX	SP
	POP	H
	DAD	H
	INX	H
	JR	DIV6
DIV3	XTHL
	POP	B
	XRA	A
	RET
DIV1	POP	H
	INX	SP
	INX	SP
	RET
;
;
;
PRVAL: 
	PUSH	PSW
	MOV	A,C
	ORI	0F0H
	DAA
	ADI	0A0H
	ACI	040H
	MOV	C,A
	POP	PSW
	RET
;
;
;
RWINP:
		;LIEST DMA ADRESSE UND ANZAHL DER SEKTOREN EIN
	CALL	GETHX	;LESE DMA ADRESSE
	JNC	ERROR
	MOV	A,D	;KEIN CR
	CPI	0DH
	JZ	ERROR	;SPRUNG WENN DOCH
	SBCD	DMAADR	;ABSPEICHERN
	CALL	GETHX	;LESE ANZAHL DER SEKTOREN
	JNC	ERROR
	MOV	A,D
	CPI	0DH	;MUSS CR SEIN
	JNZ	ERROR
	MOV	A,C
	STA	SECTCNT	;ABSPEICHERN
	RET
;
;
;
PRINT$DRIVE:
		;GIBT DEN LAUFWERK BUCHSTABEN UND EIN BLANK AUF DER
		;KONSOLE AUS
	LDA	UNIT	;WELCHES LAUFWERK?
	ANI	03H	;MASKIERE OBER 6 BITS
	ADI	'A'	;WANDLE IN ASCII
	MOV	C,A
	CALL	CO
	MVI	C,' '
	CALL	CO
	RET
;
;
;
REGDS: 
	LXI	H,RTAB
L02E9:
	MOV	C,M
	MOV	A,C
	ORA	A
	JNZ	L02F3
	CALL	CROUT
	RET
L02F3: 
	CPI	'a'	;SOLL NEUE ZEILE ANFANGEN?
	JRNZ	REGDS1	;SPRUNG WENN NEIN
	PUSH	PSW
	PUSH	B
	CALL	CROUT
	POP	B
	POP	PSW
REGDS1:
	CALL	ECHO
	MVI	C,'='
	CALL	ECHO
	INX	H
	MOV	E,M
	MVI	D,(REGS AND 0FF00H) SHR 8
	INX	H
	LDAX	D
	CALL	NMOUT
	MOV	A,M
	ORA	A
	JZ	L030E
	DCX	D
	LDAX	D
	CALL	NMOUT
L030E: 
	MVI	C,' '
	CALL	ECHO
	INX	H
	JMP	L02E9
;
;
;
RGADR: 
	LXI	H,RTAB
	LXI	D,3	;LAENGE DER TABELLEN EINTRAEGE
L031D: 
	MOV	A,M
	ORA	A
	JZ	ERROR
	CMP	C
	JZ	L032A
	DAD	D
	JMP	L031D
L032A: 
	INX	H
	MOV	B,H
	MOV	C,L
	RET
; 
;-----------------------------------------------REGISTER ZURUECKLADEN------
;
RSTTF:
	DI
	LXI	SP,MSTAK
	POP	B	;LADE I UND R REGISTER
	MOV	A,C
	STAR
	MOV	A,B
	STAI
	EXX
	EXAF	;ERST ZWEITREGISTERSATZ LADEN
	POP	H
	POP	D
	POP	B
	POP	PSW
	EXAF
	EXX	;JETZT NORMALER REGISTERSATZ
	POPIY
	POPIX
	POP	D
	POP	B
	POP	PSW
	LSPD	SSAVE
	LHLD	PSAVE
	PUSH	H
	LHLD	LSAVE
	EI
;----------------------------------------ENDE REGISTER ZURUECKLADEN--------
	RET
;
;
;
SETCMDT:
	;NEHME WERTE AUS TEST$TYPE UND TEST$MSEK
	;UND TRAGE SIE IN CMDTAB EIN
	;
	LDA	TEST$MSEK	;ANZAHL DER SEKTOREN/SPUR
	STA	EOT		;
	LDA	TEST$TYPE	;LADE TEST$TYPE
	MOV	C,A		;UND RETTE IN C
	ANI	40H		;MASKIERE UND
	STA	CMDTAB		;SETZE MFM BIT IN CMDTAB
	MOV	A,C		;
	ANI	0FH		;SETZE SEKTORGROESSE
	STA	SECSZ		;
	ORA	A		;
	MVI	A,0FFH		;SETZE DTL AUF 80 BEI 128 BYTES/SEKTOR
	JRNZ	CMDS1		;SONST AUF 0FFH
	MVI	A,80H		;
CMDS1	STA	DTLL		;
	MOV	A,C		;SETZE GAP-LAENGE IN ABHAENGIGKEIT
	ANI	0FH		;VON DER SEKTORGROESSE
	MOV	C,A		;
	MVI	B,0		;
	LXI	H,GAPTAB	;
	DAD	B		;
	MOV	A,M		;
	STA	GAPLL		;
	RET			;
				;
GAPTAB:				;DIESE TABELLE GIBT DIE GAPLAENGE FUER JEDE
				;SEKTORGROESE AN
	DB	007H		; GAPLAENGE FUER  128 BYTES/SEKTOR
	DB	00EH		; GAPLAENGE FUER  256 BYTES/SEKTOR
	DB	01BH		; GAPLAENGE FUER  512 BYTES/SEKTOR
	DB	035H		; GAPLAENGE FUER 1024 BYTES/SEKTOR
;
;
;
SRET: 
	STC
	RET
;
;
;
VALDG: 
	MOV	A,C
	CPI	'0'
	JM	FRET
	CPI	'9'
	JM	SRET
	JZ	SRET
	CPI	'A'
	JM	FRET
	CPI	'G'
	JP	FRET
	JMP	SRET
;
;
;
VALDL: 
	MOV	A,C
	CPI	','
	JZ	SRET
	CPI	0DH
	JZ	SRET
	CPI	' '
	JZ	SRET
	JMP	FRET
;
;
;
DISP$TIME:
	;GEBE UHRZEIT UND DATUM AUF DEN BILDSCHIRM
	CALL	READ$PHYS$TIME	;LESE ZEIT AUS UHR
	LXI	H,TIMTXT1	;DATUM TEXT AUS
	CALL	SOUT
	LDA	PHYS$TIME+4	;MONAT
	RRC
	RRC
	RRC
	RRC
	ANI	0FH
	DCR	A
	CPI	12		;MONAT UNGUELTIG
	JRC	DISP$TIME1
	XRA	A		;DANN LOESCHE AKKU
DISP$TIME1:
	MOV	L,A
	MVI	H,0
	DAD	H
	DAD	H
	LXI	B,MONTXT
	DAD	B
	CALL	SOUT
	MVI	C,' '
	CALL	ECHO
	LDA	PHYS$TIME+3	;TAG
	CALL	NMOUT
	MVI	C,' '		;GEBE 19 AUS
	CALL	ECHO
	MVI	A,19H
	CALL	NMOUT
	LDA	SHIFT$CONT+4	;JAHRESZAHL
	ANI	1FH		;NUR DIE UNTEREN 5 BIT
	MVI	B,80		;ADDIERE 80 DAZU
	ADD	B
	CALL	DEZOUT		;GEBE AUS
;
	LXI	H,TIMTXT2	;GEBE TIME AUS
	CALL	SOUT
	LDA	PHYS$TIME+2	;STUNDE
	CALL	NMOUT
	MVI	C,':'
	CALL	ECHO
	LDA	PHYS$TIME+1	;MINUTE
	CALL	NMOUT
	MVI	C,':'
	CALL	ECHO
	LDA	PHYS$TIME	;SEKUNDE
	CALL	NMOUT
	CALL	CROUT
	LDA	IO$JUMPERBYTE	;IST GRIP ALS KONSOLE DEFINIERT?
	ORA	A
	RNZ			;RETURN WENN NICHT
	LXI	H,SETTT		;SONST, SETZE GRIP-UHR
	CALL	SOUT		
	LDA	PHYS$TIME+2
	ADI	20H
	MOV	C,A
	CALL	ECHO
	LDA	PHYS$TIME+1
	ADI	20H
	MOV	C,A
	CALL	ECHO
	LDA	PHYS$TIME
	ADI	20H
	MOV	C,A
	CALL	ECHO 	
	RET
;
SETTT	DB	27,27,'U$'
TIMTXT1	DB	0DH,0AH,'              Date  $'
TIMTXT2	DB	0DH,0AH,'              Time  $'
MONTXT	DB	'Jan$'
	DB	'Feb$'
	DB	'Mar$'
	DB	'Apr$'
	DB	'May$'
	DB	'Jun$'
	DB	'Jul$'
	DB	'Aug$'
	DB	'Sep$'
	DB	'Oct$'
	DB	'Nov$'
	DB	'Dec$'
;
;
;
;************************************************************
;
;ES FOLGEN NUN SERVICE ROUTINE FUER BOOT ROUTINE
;
;************************************************************
;
;
;
SETSEC$CNT:
	;SETZE ANZAHL DER ZU UEBERTRAGENDEN SEKTOREN
	MOV	A,C
	STA	SECTCNT
	RET
;
SELDSK:
	;SETZT UNIT BYTE
	MOV	A,C
	STA	UNIT
	RET
;
SETTRK:
	;SETZT TRACK BYTE
	MOV	A,C
	STA	TRACK
	RET
SETSEC:
	;SETZT SECTOR BYTE
	MOV	A,C
	STA	SECTOR
	RET
;
SETDMA:
	SBCD	DMAADR
	RET
;
GETMINIMAX:
	;WENN AKKU=0 DANN MAXI
	;WENN AKKU=0FFH DANN MINI
	LDA	TEST$TYPE
	ANI	20H
	RZ
	MVI	A,0FFH
	RET
;
;
;
;************************************************************
;
;ES FOLGEN NUN DISK ROUTINEN FUER UPD 765
;
;************************************************************
;
;
;
BOOTERR:
	;GEBE FEHLERMELDUNG BEI BOOT AUS
	;UND GEHE ZUM MONITOR ZURUECK
	LXI	H,BERMSG
	CALL	SOUT
	JMP	GETCM
;
BERMSG	DB	' Can not boot',0DH,0AH,24H
;
;
;
SPECD:
	;SETZT DISK PARAMETER FUER NON DMA BETRIEB
	LHLD	UNIT
	PUSH	H	;RETTE CMDTAB
	LHLD	SPECD$WORD
	MVI	A,1
	ORA	H
	MOV	H,A
	LXI	B,0303H
	SHLD	UNIT
	CALL	CMFD
	POP	H
	SHLD	UNIT
	RET
;
;
;
FLOPPY$RESET:
			;GEBE HARDWARE-RESET
			;AUF FLOPPY-CONTROLER
	PUSH	B
	MVI	A,PAD$RESF OR 1
	OUT	P$LS259
	MVI	B,20
FLOPPY$RESET1:
	DJNZ	FLOPPY$RESET1
	MVI	A,PAD$RESF
	OUT	P$LS259
	POP	B
	RET
;
;
;
INIFDC:
			;SOFT RESET DES UPD 765
			;FALS KEIN FLOPPY CONTROLLER VORHANDEN IST,
			;WIRD DISKFLG AUF 00H GESETZT, SONST AUF FFH
	MVI	A,0FFH	;DEFAULT FUER FLOPPY-C DA
	STA	DISKFLG
	LXI	H,0000H	;SETZE ZAEHLER
INIFDC1	DCR	H	;ERNIEDRIGE ZAEHLER
	IN	FDC	;
	CPI	80H	;REQUEST FOR MASTER
	RZ		;OK CONTROLLER DA
	IN	FDD	;LESE DATEN
	MOV	A,H	;IST ZAEHLER NULL
	ORA	L
	JRNZ	INIFDC1	;NEIN, NEUER VERSUCH
	STA	DISKFLG	;KEIN FLOPPYCONTROLLER DA, DISKFLG=00H
	RET
;
;
;
RECAL:
	XRA	A		;AKKU=0
	STA	ALT$TRACK	;VORSICHTSHALBER SPUR AUF NULL
	MVI	B,4		;VIER VERSUCHE
RECAL2:	PUSH	B		;
	CALL	RECAL1		;
	CALL	SENSD		;
	ANI	10H		;TRACK NULL ERREICHT?
	POP	B		;
	RNZ			;RUECKSPRUNG WENN EREICHT
	DJNZ	RECAL2		;
	RET
;
;
;
RECAL1:
	LXI	B,0207H
        CALL    MOTO 
        JMP	SENS
;
;
;
NODISK	DB	0DH,0AH,BELL
	DB	' Drive access not possible$'
;
;
;
DISKDA:
	;GIBT MELDUNG AUS, WENN DISKZUGRIF OHNE KONTROLLER VERSUCHT WIRD
	;UND KEHRT AUF DIE EINGABEEBENE ZURUECK
	LDA	DISKFLG	;LADE FLAG
	ORA	A	;=NULL?
	RNZ		;ZURUECK ZUM RUFENDEN PROGRAMM
	LXI	H,NODISK;GEBE MELDUNG AUS
	CALL	SOUT
	CALL	CROUT
	JMP	GETCM	;AUF KOMMANDOEBENE ZURUECK
;
;
;
READY$MASK:
	;HOLT AUS READY$BYTE DIE WERTE FUER LW
	;SCHON AUF READY GETESTET UND LW KANN READY LIEFERN
	;ODER NICHT
	CALL	UNIT$MASK	;HOLE MASKE FUER EINGELOGGTES LW
	LDA	READY$BYTE	;UND MASKIERE READY$BYTE
	ANA	B		;
	RET
;
;
;
UNIT$MASK:
	;ERZEUGE AUS EINGELOGGTEM LW MASKE FUER OBER UND UNTERE 4 BIT
	LDA	UNIT
	ANI	00000011B
	INR	A
	MOV	B,A
	MVI	A,88H
UNIMASK	RLC
	DJNZ	UNIMASK
	MOV	B,A
	RET
;
;
;
SEEK3:
	CALL	UNIT$MASK
	LDA	SEEKNR
	ANA	B
	ANI	0FH
	RET
;
SEEK:
	LHLD	UNIT		;LADE NEUES LAUFWERK UND NEUER TRACK
	LBCD	ALT$UNIT	;LADE ALTES LAUFWERK UND ALTER TRACK
	MOV	A,B		;VERGLEICHE
	CMP	H		;
	JRNZ	SEEK4		;SPRUNG WENN UNGLEICH
	MOV	A,C		;
	CMP	L		;
	RZ			;RETURN WENN KEIN SEEK NOTWENDIG
SEEK4:	SHLD	ALT$UNIT	;ALTES:=NEUES
	IN	P$IN$LS258$B	;
	ANI	MASK$MOT	;
	MVI	A,PAD$MOTOR	;AUFJEDEN FALL MOTOR JETZT EINSCHALTEN
	OUT	P$LS259		;
	JRZ	SEEK5		;WENN MOTOR SCHON LIEF, DANN KEIN WARTEN
	LDA	STEP$WAIT	;LADE WARTEZEIT
SEEK6	ORA	A		;WENN WARTEZEIT NULL, DANN WEITER
	JRZ	SEEK5		;
	DCR	A		;
	PUSH	PSW		;
	LXI	H,2300		;
SEEK7	DCX	H		;
	MOV	A,H		;
	ORA	L		;
	JRNZ	SEEK7		;
	POP	PSW		;
	JR	SEEK6		;
SEEK5:	CALL	SEEK3		;
	JRZ	SEEK1		;
	LDA	TRACK		;
	PUSH	PSW		;
	ADD	A		;
	STA	TRACK		;
SEEK1:				;
	LXI	B,030FH		;SEEK TRACK
        CALL    MOTO 		;
	CALL	SEEK3		;
	JRZ	SEEK2		;
	POP	PSW		;
	STA	TRACK		;
SEEK2:				;
                     		;SEEK FINISHD ?
SENS:	LXI     B,0108H 	;SENS DRIVE
        CALL    CMFD		;
        CALL    NEXT		;
	PUSH	PSW		;SAVE RESULT
        CPI     080H    	;INVALID COMMAND ?
        CNZ     NEXT    	;NO => NEXT RESULT
        POP     PSW     	;FIRST RESULT
	ANI	020H		;ISOLIERE BIT 5
        JZ      SENS		;
	MVI	A,PAD$MOTOR OR 80H	;SCHALTE MOTOR AUF JEDEN
	OUT	P$LS259			;FALL AB
        RET
;
;
;
RESULT:		;FETCH RESULT OF READ WRITE OPERATION
		;AND CHECK THEM FOR R/W ERRORS
                ;Z+A=00 IF NO ERRORS
                ;NZ,A=? IF ERRORS
	MVI	B,006H		;7RESULTS
        CALL    NEXT		;
        LXI     H,REST		;RESULT TABLE
        MOV     M,A     	;STORE RESULT
        ANI     0C0H    	;ERROR ?
	MOV	C,A		;SAVE
RESLOP  CALL    NEXT		;
	INX	H		;
        MOV     M,A     	;STORE RESULT
	DJNZ	RESLOP		;
				;
	MVI	A,PAD$READY	;SCHALTE READY AUF JEDEN FALL WEG
	OUT	P$LS259		;
	MVI	A,PAD$MOTOR OR 80H	;SCHALTE MOTOR NACH DELAY AB
	OUT	P$LS259		;
				;
        MOV     A,C		;RESTORE RESULT 0
        ORA     A		;IN AKKU
        RET
;
;
;
READY$TEST:
	;ERMITTELT, OB EIN LAUFWERK DAS READY-SIGNAL LIEFERN
	;KANN UND SETZT ENTSPRECHEND DAS READY-BYTE
	;
	CALL	SPEED$CONST	;WARTE BIS DREHZAHL KONSTANT
	JRNZ	RTST1		;SPRUNG WENN DREHZAHL KONSTANT
	CALL	NRDYERR		;GEBE FEHLERMELDUNG AUS UND LESE ZEICHEN
	JRNZ	READY$TEST	;NOCH EIN VERSUCH
	JMP	UMLEIT$GETCM	;SONST ZURUECK
RTST1	CALL	SENSD		;LIEFERT LW READY?
	ANI	20H		;
	PUSH	PSW		;RETTE ZERO-FLAG
	CALL	UNIT$MASK	;TRAGE IN READY$BYTE EIN
	CMA			;
	MOV	B,A		;RETTE MASKE
	POP	PSW		;HOLE ZERO-FLAG
	MVI	A,0FH		;KEIN READY
	JRZ	RTST2		;SPRUNG WENN KEIN READY
	MVI	A,0		;
RTST2	ORA	B		;
	MOV	B,A		;SETZE READY$BYTE
	LDA	READY$BYTE	;
	ANA	B		;
	STA	READY$BYTE	;
	RET
;
;
;
SPEED$CONST:
	;WARTE BIS DREHZAHL KONSTANT, DANN RETURN MIT ZERO-FLAG=0
	;WENN DREHZAHL NICHT KONSTANT WIRD DANN ZERO-FLAG=1
	;
TOLERANZ	EQU	64	;TOLERANZ FUER DREHZAHL KONSTANT
				;
	LXI	B,0204H		;SELEKTIERE LAUFWERK
	CALL	CMFD		;
	MVI	A,PAD$MOTOR	;SCHALTE MOTOR EIN
	OUT	P$LS259		;
	LXI	D,0		;BESETZE VOR
	MVI	B,10		;ZEHN VERSUCHE
SPEEDC1	XCHG			;ADDIERE ZU DE TOLERANZ
	LXI	D,TOLERANZ	;
	DAD	D		;
	XCHG			;
	CALL	CDRIVE$SPEED	;MESSE DREHZAHL
	JRZ	SPEEDC3		;ZURUECK WENN LAUFWERK STEHT
	XCHG			;BILDE DIVERENZ ZU VORHER
	DSBC	D		;
	MOV	A,H		;
	CPI	0		;IM TOLERANZBEREICH?
	JRNZ	SPEEDC2		;SPRUNG WENN NEIN
	MOV	A,L		;
	CPI	TOLERANZ*2	;
	JRNC	SPEEDC2		;SPRUNG WENN DREHZAHL NOCH NICHT KONSTANT
	CALL	CDRIVE$SPEED	;WARTE NOCH ZWEI UMDREHUNGEN
	CALL	CDRIVE$SPEED	;
				;
	CALL	NEXT		;DESELEKTIERE LAUFWERK
	MVI	A,PAD$MOTOR OR 80H
	OUT	P$LS259		;
	MVI	A,0FFH		;ZURUECK MIT ZERO = 0
	ORA	A		;
	RET			;
				;
SPEEDC2	DJNZ	SPEEDC1		;MAXIMAL 10 VERSUCHE
SPEEDC3	CALL	NEXT		;DESELEKTIERE LAUFWERK
	MVI	A,PAD$MOTOR OR 80H
	OUT	P$LS259		;
	XRA	A		;SONST ZURUECK MIT ZERO=1
	RET			;
;
;
;
CDRIVE$SPEED:
	;MESSE GESCHWINDIGKEIT DES LAUFWERKS
	;WENN SICH DISKETTE NICHT DREHT IST DAS ZERO-FLAG GESETZT
	;SONST ZERO-FLAG=0 UND GESCHWINDIGKEIT IN HL
	;
	IN	P$IN$LS258$A	;LESE INDEX-SIGNAL
	ANI	MASK$INDEX	;UND MASKIERE
	JRZ	DSPEED1		;WENN INDEX DA, ERSTE SCHLEIFE
				;UEBERSPRINGEN
				;
	LXI	H,0		;WARTE BIS INDEX KOMMT
DSPEED2	INX	H		;ERHOEHE HL
	MOV	A,H		;OUT OF TIME?
	ORA	L		;
	RZ			;DANN RETURN
	IN	P$IN$LS258$A	;LESE INDEX-SIGNAL
	ANI	MASK$INDEX	;UND MASKIERE
	JRNZ	DSPEED2		;WARTE BIS LOW
				;
DSPEED1	LXI	H,0		;WARTE BIS INDEX WEGGEHT
DSPEED3	INX	H		;ERHOEHE HL
	MOV	A,H		;OUT OF TIME?
	ORA	L		;
	RZ			;DANN RETURN
	IN	P$IN$LS258$A	;LESE INDEX-SIGNAL
	ANI	MASK$INDEX	;UND MASKIERE
	JRZ	DSPEED3		;WARTE BIS HIGH
				;
	LXI	H,0		;EIGENTLICHER ZAEHLER
DSPEED4	INX	H		;ERHOEHE HL
	MOV	A,H		;OUT OF TIME?
	ORA	L		;
	RZ			;
	IN	P$IN$LS258$A	;LESE INDEX UND WARTE
	ANI	MASK$INDEX	;BIS WIEDER LOW
	JRNZ	DSPEED4		;
	MVI	A,0FFH		;RESET ZERO-FLAG
	ORA	A		;
				;
	RET			;ZURUECK MIT DRIVE-SPEED
;
;
;
NOREADY$MOTO:
	IN	P$IN$LS258$B	;LAEUFT MOTOR SCHON ?
	ANI	MASK$MOT	;
	JRZ	NREDY1		;SPRUNG WENN MOTOR SCHON LAEUFT
NREDY2	CALL	SPEED$CONST	;WARTE BIS LW AUF TOUREN
	JRNZ	NREDY1		;SPRUNG WENN DREHZAHL KONSTANT
	CALL	NRDYERR		;GEBE ERROR-TEXT AUS
	JRNZ	NREDY2		;WIEDERHOLUNG
	JMP	UMLEIT$GETCM	;
NREDY1	MVI	A,PAD$MOTOR	;NEUER MOTOR TRIGGER
	OUT	P$LS259		;
	MVI	A,PAD$READY OR 80H	;SETZE READY$LEITUNG
	OUT	P$LS259		;
	JMP	MOTO1
;
;
;
MOTO:				;WAITS UNTIL DISK READY AND THEN
                		;TRANSMITS COMMAND TO FDC
				;
	PUSH	B		;SAVE COMMAND
	CALL	READY$MASK	;LW SCHON GETESTET?
	ANI	0F0H		;STEHT IN DEN OBEREN 4 BITS
	CNZ	READY$TEST	;WENN NOCH NICHT, DANN TESTE AUF READY
	CALL	READY$MASK	;KANN READY GELIEFERT WERDEN?
	ANI	0FH		;STEHT IN DEN UNTEREN 4 BITS
	JNZ	NOREADY$MOTO	;WENN NICHT SPRUNG
				;SONST WEITER WIE GEHABT
				;
	MVI	A,PAD$MOTOR	;SCHALTE MOTOR EIN
	OUT	P$LS259		;
				;
MOTO2	LXI	H,00FFFH	;SET TIMER
MOTO3	PUSH	H		;SAVE TIMER
	LXI	B,0204H		;SENSE DRIVE
	CALL	CMFD
	CALL	NEXT		;FETCH RESULT
	POP	H		;GET TIMER VALUE
	ANI	20H		;DISK READY ?
	JRNZ	MOTO1		;OK, READY
	DCX	H		;TIMER=TIMER-1
	MOV	A,H		;= ZERO?
	ORA	L		;
	JRNZ	MOTO3		;NO, TRY AGAIN
	CALL	NRDYERR		;DRIVE NOT READY TEXT
	JRNZ	MOTO2		;NO, AGAIN
	MVI	A,PAD$MOTOR OR 80H
	OUT	P$LS259		;
	JMP	UMLEIT$GETCM	;ENTWEDER MONITOR ODER WARM-BOOT
				;
				;
NRDYERR:
	;GEBE FEHLERMELDUNG FUER DRIVE NOT READY AUS
	;UND VERGLEICHE EINGEGEBENES ZEICHEN MIT N
	;
	LXI	H,NREADY1	;PRINT ERROR TEXT
	CALL	SOUT		;
	CALL	PRINT$DRIVE	;GEBE LW BUCHSTABE AUS
	LXI	H,NREADY2	;GEBE REST TEXT AUS
	CALL	SOUT		;
	CALL	GETCH1		;AGAIN?
	MOV	C,A		;ECHO
	CALL	ECHO		;
	CALL	CROUT		;LINE FEED
	MOV	A,C		;
	CPI	'N'		;
	RET			;
	;
NREADY1	DB	0DH,0AH,BELL,' Drive $'
NREADY2	DB	'not ready, retry (Y/N) ? $'
;
;
MOTO1:	POP	B
;
;
CMFD:		;TRANSMIT COMMAND TO FDC
		;IN B STEHT ANZAHL DER BYTES
		;IN C STEHT BEFEHL
                ;
	LXI     H,CMDTAB	;
CMFD1	MVI	A,30		;WAIT FOR MASTER
CMFD2	DCR	A		;
	JRNZ	CMFD2		;
	IN      FDC		;REQUEST FOR MASTER
        ANI     0C0H		;
        CPI     080H		;
        JRNZ	CMFD1		;NO => WAIT
        MOV     A,C     	;YES =>
        OUT     FDD     	;SEND BYTE
        INX     H       	;POINT TO NEXT BYTE
        MOV     C,M		;
        DJNZ	CMFD1		;SEND NEXT BYTE
        RET             	;ALL BYTES TRANSFERRED
;
;
;
NEXT:		;READ NEXT RESULT FROM FDC
                ;
	MVI	A,6	;WAIT FOR MASTER READY
NEXT1	DCR	A	;
	JRNZ	NEXT1	;
	IN	FDC	;REQUEST FOR MASTER
        ANI     0C0H    ;TRANSFER TO MASTER
        CPI     0C0H	;
        JNZ     NEXT    ;NO =>WAIT
	IN	FDD	;YES => FETCH RESULT
        RET  
;
;
;
WRITE:
	MVI	A,5			;WRITE COMMANDO
	LXI	H,TXTWR			;WRITE ERROR TEXT
	JMP	RWCOM
;
;
;
READ:
	MVI	A,06H			;READ COMMANDO
	LXI	H,TXTRD			;READ ERROR TEXT
	JMP	RWCOM
	;
	;
	;
RWCOM:
	;VOR EINTRITT IN DIESE ROUTINE MUESSEN CMDTAB
	;SECTCNT UND DMAADR GESETZT SEIN.
	;IN A MUSS READ ODER WRITE COMMANDO STEHEN,
	;IN HL MUSS DIE ADRESSE DER ERROR MSSG. STEHEN.
	;ES WERDEN DIE ANGEGEBENE ANZAHL SECTCNT
	;VON/NACH DMAADR UEBERTRAGEN.
	;HD BIT WIRD ENTSPRECHEND DEM H BIT GESETZT.
	;DAS IN CMDTAB STEHENDE MFM BIT WIRD UEBERNOMMEN.
	;ES WIRD DIE PRECOMPENSATION ZEIT AUS WRITE$PRECOM
	;UEBERNOMMEN.
	;
	;
	STA	RWCMD		;LEGE COMMANDO AB
	SHLD	ERMSG		;LEGE ADR FUR ERR.TEXT AB
	LDA	SECTCNT		;WIEVIEL SECTOREN SOLLEN UEBERTRAGEN WERDEN?
	DCR	A		;EINS WENIGER FUER ADDITION
	CPI	0FFH		;
	RZ			;RETURN WENN NULL GEWESEN
	MOV	C,A		;RETTE AKKU
	LDA	EOT		;RETTE EOT
	STA	EOTSAVE		;
	MOV	B,A		;
	LDA	SECTOR		;BERRECHNE NEUES EOT
	ADD	C		;
	STA	EOT		;
	MOV	C,A		;SOLL UEBER SPUR ENDE UEBERTRAGEN WERDEN?
	MOV	A,B		;
	MVI	B,0		;
	SUB	C		;
	JRNC	RW5		;
	MVI	B,080H		;
	LDA	EOTSAVE		;WENN UEBER SPUR ENDE UEBERTRAGEB WERDEN SOLL
	STA	EOT		;DANN EOT GLEICH ALTES EOT
RW5:	MOV	A,B		;SAVE FLAG
	STA	EOTFLG		;FUER FEHLERMELDUNG
	MVI	A,PAD$RTS OR 1	;SPERRE TASTATUR INTERRUPT
	OUT	P$LS259		;
	DI			;
	CALL	SEEK		;POSITIONIERE
	CALL	SETHEAD		;TRAGE HEAD BIT IN UNIT EIN
	LDA	WRITE$PRECOM	;SETZE PRECOMPENSATION
	CALL	SEND$PRECOM	;
	LDA	RWRETRY		;LADE
	MOV	B,A		;ANZAHL DER VERSUCHE NACH B
RW4	PUSH	B		;SAVE RETRY
	MVI	B,9		;9 BYTES ZU UEBERTRAGEN
	LDA	RWCMD		;LADE COMMANDO
	MOV	C,A		;NACH C
	LDA	CMDTAB		;TRAGE MFM BIT EIN
	ANI	040H		;ISOLIERE MFM BIT
	ORA	C		;COMMAND DAZU
	MOV	C,A		;ZURUECK INC
	CALL	MOTO		;SEND COMMAND TO UPD 765
				;BEREITE REGISTER VOR
	EXX			;LADE DMA ADRESSE IN ZWEITREGISTER SATZ
	LHLD	DMAADR		;
	MVI	C,FDD		;UEBERTRAGUNGSADRESSE
	EXX			;
	LXI	H,SYSTEMPAGE	;PAGE DER MASTER ABHNG. SPRUENGE
	MVI	C,FDC		;
				;
	CALL	RWPOLL		;UEBERTRAGE VON/ZU DISK
				;
	CALL	RESULT		;HOLE ERGEBNIS
	LDA	REST+1		;BLENDE END OF TRACK BIT AUS
	ANI	7FH		;
	STA	REST+1		;
	MOV	C,A		;
	LDA	REST+2		;
	ORA	C		;SONSTIGES FEHLER BIT GESETZT
	POP	B		;RESTORE RETRY COUNTER
	JRZ	RW7		;KEINE FEHLER
	DJNZ	RW4		;NOCH VERSUCHE FREI?
RW7:				;
	LDA	EOTFLG		;WURDE WIRKLICH UEBER SPURGRENZE GELESEN?
	MOV	C,A		;
	LDA	REST+1		;
	ORA	C		;
	STA	REST+1		;
	MOV	C,A		;	
	LDA	REST+2		;
	ORA	C		;SET ZERO FLAG
	PUSH	PSW		;RETTE FLAGS UND AKKU FUER FEHLERMELDUNG
	CNZ	DISKERR		;DRUCKE FEHLER
	LDA	EOTSAVE		;LADE ORG EOT
	STA	EOT		;ZURUECK
	EI			;
	LDA	IO$JUMPERBYTE	;MUSS EINGABE FREIGEGEBEN WERDEN?
	DCR	A		;
	JRNZ	RW1		;
	MVI	A,PAD$RTS	;GEBE EINGABE FREI
	OUT	P$LS259		;
RW1:				;
	LDA	RWCMD		;WAR DISK WRITE ?
	CPI	06H		;
	JRZ	RW2		;SPRUNG WENN NEIN
	LDA	TE$TIME		;SONST VERZOEGERUNG
	ORA	A		;WENN NULL DANN ENDE
	JRZ	RW2		;
	MOV	B,A		;
RW3:	LXI	H,22		;<10>
RW6:	DCX	H		;<6>
	MOV	A,H		;<4>
	ORA	L		;<4>
	JRNZ	RW6		;<12/7>
	DJNZ	RW3		;<13/8>
RW2:				;
	POP	PSW		;LADE AKKU FUER FEHLERMELDUNG
	RET
;
;
;
SETHEAD:
	;SETZE HEAD BYTE AUF 00H ODER 01H
	;SETZE HEAD BIT IN UNIT BYTE
	;
	;FOLGENDE KOMBINATIONEN SIND MOEGLICH:
	;X BEDEUTET UNBESTIMMT, - BEDEUTET KEINE AENDERUNG ZU VORHER
	;
	; HEAD VORHER=>	UNIT NACHHER,	HEAD NACHHER
	; XXXXXX00	000000--	00000000
	; XXXXXX01	000001--	00000001
	; XXXXXX10	000001--	00000000
	; XXXXXX11	000000--	00000001
	;
	LDA	HEAD	;LADE HEAD BIT
	MOV	C,A	;RETTE IN C
	ANI	1	;
	STA	HEAD	;
	MOV	A,C	;
	RLC		;EIN BIT NACH LINKS
	MOV	C,A	;
	RLC		;ZWEI BIT NACH LINKS
	XRA	C	;ERZEUGE UNIT BIT
	ANI	04H	;BLENDE ANDERE BITS AUS
	MOV	C,A	;SAVE
	LDA	UNIT	;LADE DRIVE NR.
	ANI	03H	;BLENDE OBERE BITS AUS
	ORA	C	;HEAD DAZU
	STA	UNIT	;ZURUECK
	RET
;
;
;
TEST:
	;DIESE ROUTINE ERMITTELT DIE DATEN DER PLATTE, DIE SICH IM VON
	;UNIT SPEZIFIZIERTEN LAUFWERK BEFINDET
	;GETESTET WIRD DIE SPUR, DIE IN TEST$TRACK STEHT
	;ALS ERGEBNIS WERDEN TEST$TYPE UND TEST$MSEK GESETZT
	;KANN DER PLATTEN-TYP NICHT ERMITTELT WERDEN IST DER AKKU AUF FFH
	;WENN PLATTEN-TYP ERKANNT WURDE IST AKKU=00H
	;
	CALL	RECAL		;RECALIBRIERE
        LDA     UNIT    	;SEITE 0 WAEHLEN
        ANI     03H		;
        STA     UNIT		;
	LDA	TEST$TRACK	;POSITIONIERE AUF DIE SPUR
	STA	TRACK		;DEREN FORMAT ERKANNT WERDEN SOLL
	CALL	SEEK		;
				;
	MVI	A,00		;TESTE OB SD,MAXI
	STA	TEST$TYPE	;
	CALL	MAXI$SET	;
	CALL	READID		;VERSUCHE ID-FELD ZU LESEN
	JZ	TEST1		;SPRUNG WENN SD,MAXI
				;
	MVI	A,40H		;TESTE OB DD,MAXI
	STA	TEST$TYPE	;
	CALL	READID		;
	JZ	TEST1		;SPRUNG WENN DD,MAXI
				;
	MVI	A,20H		;TESTE OB SD,MINI
	STA	TEST$TYPE	;
	CALL	MINI$SET	;
	CALL	READID		;
	JZ	TEST1		;SPRUNG WENN SD,MINI
				;
	MVI	A,60H		;TESTE OB DD,MINI
	STA	TEST$TYPE	;
	CALL	READID		;
	JZ	TEST1		;SPRUNG WENN DD,MINI
				;
TEST2:	MVI	A,0FFH		;BLEIBT NICHTS MEHR  UEBRIG
	RET			;RUECKSPRUNG MIT FEHLER
				;
TEST1:				;OK, MINI ODER MAXI, FM ODER MFM
				;ERKANNT
				;ZAEHLE JETZT DIE ANZAHL DER SEKTOREN
				;AUF DER SPUR
	CALL	READ$ID		;LESE ERSTES ID-FELD
	JRNZ	TEST2		;SPRUNG WENN NICHT MOEGLICH
	LDA	REST+5		;LADE SEKTORNUMMER
	MOV	D,A		;NACH D UM EINE UMDREHUNG ABZUWARTEN
	MOV	C,A		;NACH C UM GROESSTEN SEKTOR ZU ERMITTELN
	MVI	B,52		;MAXIMAL 52 LESEVERSUCHE, DANN FEHLER
TEST3:	PUSH	B		;RETTE REGISTER
	PUSH	D		;
	CALL	READ$ID		;LESE NAECHSTES ID-FELD
	POP	D		;RESTORE REGISTER
	POP	B		;
	JRNZ	TEST2		;SPRUNG WENN FEHLER
	LDA	REST+5		;LADE SEKTORNUMMER
	CMP	D		;EINE UMDREHUNG ?
	JRZ	TEST4		;DANN ENDE (MAX-SEKTOR IN C)
	CMP	C		;NEUE SEKTORNUMMER GROESSER ALS ALLE ANDEREN?
	JRC	TEST5		;SPRUNG WENN NEIN
	MOV	C,A		;SONST NEUER SEKTOR DER GROESSTE
TEST5:	DJNZ	TEST3		;LESE NEUEN SEKTOR EIN
	JR	TEST2		;WENN ZAEHLER ABLAEUFT, DANN FEHLER
				;
TEST4:	MOV	A,C		;LEGE GROSSTE SEKTORNUMMER AB
	STA	TEST$MSEK	;
				;
	LDA	REST+6		;PACKE SEKTORGROESSE ZU TEST$TYPE
	ANI	0FH		;
	MOV	C,A		;
	LDA	TEST$TYPE	;
	ORA	C		;
	STA	TEST$TYPE	;
				;
	LDA	UNIT		;SOLL TWO-SIDED-BIT IMMER AUF HIGH SEIN?
	CMA			;(NAEMLICH DANN, WENN ENTSPRECHENDES
	ANI	00000011B	;BIT IM OBEREN NIPPLE VON SEEKNR AUF HIGH)
	MOV	B,A		;
	ORA	A		;
	LDA	SEEKNR		;
	JRZ	TEST6		;KEIN SCHIEBEN NOTWENDIG
TEST7:	RLC			;
	DJNZ	TEST7		;
TEST6:	ANI	80H		;WENN OBERSTES BIT 1, DANN TS-BIT AUCH EINS
	JRNZ	TEST8		;SONST TS-BIT WIE TS-LEITUNG
	CALL	SENSD		;LESE TWO-SIDED SIGNAL EIN
	RLC			;VERSCHIEBE IN OBEERSTES BIT
	RLC			;
	RLC			;
	RLC			;
	ANI	80H		;BLENDE REST AUS
TEST8:	MOV	C,A		;PACKE ZU TEST$TYPE
	LDA	TEST$TYPE	;
	ORA	C		;
	STA	TEST$TYPE	;
				;OK, ALLES GEPRUEFT
	MVI	A,0		;FEHLERFREIE RUECKKEHR
	RET			;
;
;
;
READID:
	;LESE NAECHSTES ID FELD
	;IN TEST$TYPE BIT 6 SEHT OB FM ODER MFM
	;KONNTE KEIN ID-FELD GELESEN WERDEN, DANN IST AKKU<>0
	;UND ZERO-FLAG NICHT GESETZT
	;
	LXI	B,020AH		;READ ID KOMMANDO
	LDA	TEST$TYPE	;PACKE MFM BIT DAZU
	ANI	040H		;
	ORA	C		;
	MOV	C,A		;
	CALL	MOTO		;LESE ID-FELD
	CALL	RESULT		;WAR LESEVERSUCH ERFOLGREICH?
	ORA	A		;
	RET
;
;
;
MAXI$SET:
	;SETZT FLOPPY KONTROLER AUF MAXI-LAUFWERKE
	PUSH	PSW
	MVI	A,PAD$MINI
	OUT	P$LS259
	POP	PSW
	RET
;
;
;
MINI$SET:
	;SETZT FLOPPY-KONTROLER AUF MINI-LAUFWERKE
	PUSH	PSW
	MVI	A,PAD$MINI OR 1
	OUT	P$LS259
	POP	PSW
	RET
;
;
;
SENSD	LXI	B,0204H
	CALL	CMFD
	CALL	NEXT
	RET
;
;
;
DISKERR:
	;GIBT DISK FEHLERMELDUNG AUS
	;BENUTZT DAZU DIE RESULT TABELLE
	;UND DIE ERMSG EINTRAGUNG
	;
	LDA	DERMSG		;SOLL FEHLERMELDUNG
	INR	A		;UNTERDRUECKT WERDEN ?
	RZ			;WENN JA, RUECKSPRUNG
	LHLD	ERMSG		;LADE READ BZW WRITE TEXT
	CALL	SOUT		;UND GEBE IHN AUS
	LDA	REST		;LADE LAUFWERK NUMMER
	ANI	03H		;ISOLIERE LE NR
	ADI	41H		;WANDLE IN ASCCI
	MOV	C,A		;GEBE LAUFWERK BUCHSTABE AUS
	CALL	ECHO		;
				;
	LXI	H,TXT1		;GEBE TRACK AUS
	CALL	SOUT		;
	LDA	REST+3		;
	CALL	DEZOUT		;
				;
	LXI	H,TXT2		;GEBE HEAD AUS
	CALL	SOUT		;
	LDA	REST+4		;
	ADI	30H		;WANDLE IN ASCII
	MOV	C,A		;
	CALL	ECHO		;
				;
	LXI	H,TXT3		;GEBE SECTOR AUS
	CALL	SOUT		;
	LDA	REST+5		;
	CALL	DEZOUT		;
				;
				;GEBE FEHLER IM KLARTEXT AUS
				;
	LXI	D,ERROR$TABLE	;
	LDA	REST+1		;LESE STATUS1
	MOV	H,A		;
	LDA	REST+2		;LESE STATUS2
	MOV	L,A		;
ERRLOP:
	DAD	H		;TESTE OB FEHLERBIT GESETZT
	PUSH	H		;
	LDAX	D		;
	MOV	L,A		;
	INX	D		;
	LDAX	D		;
	MOV	H,A		;
	CC	SOUT		;WENN JA GEBE TEXT AUS
	POP	H		;
	INX	D		;ZEIGE AUF NAECHSTE MELDUNG
	MOV	A,H		;KEIN FEHLER MEHR DA?
	ORA	L		;
	JRNZ	ERRLOP		;
				;
	CALL	CROUT		;
				;
	RET			;OK, ENDE
;
;
;**********************************************************
;***							***
;***  ROUTINEN ZUM EIN UND AUSLESEN DER UHRZEIT		***
;***   FUER DEN UPD 1990				***
;***							***
;**********************************************************
;
;
;
SEND$TIME$COM:
		; SENDE DIE UNTEREN 3BITS DES AKKU ALS KOMMANDO
		; ZUM UPD 1990
		;
		CALL	SEND$PRECOM
		CALL	SEND$STB
		RET
;
;
;
SEND$PRECOM:
		;SENDE GEBE DIE UNTEREN 3 BITS DES AKKU
		;AUF DEN LEITUNGEN C0-C2 AUS
		;DIENT FUER UHREN KOMMANDO,
		;DISK PRECOMPENSATION UND JUMPER EINLESEN
		;
	PUSH	B		;RETTE BC
	MVI	C,PAD$C0	;ADRESSE DES BITS
	MVI	B,3		;ZAEHLER
SEND$TIME$COM$1:
	RRC			;ZYKLISCH VERSCHIEBEN
	PUSH	PSW		;RETTE AKKU
	ANI	80H		;MASKIERE BIT
	ORA	C		;
	OUT	P$TIME$OUT	;
	MVI	A,16		;EINE ADRESSE HOEHER
	ADD	C		;
	MOV	C,A		;
	POP	PSW		;
	DJNZ	SEND$TIME$COM$1	;GEBE ALLE DREI BITS AUS
	POP	B		;
	RET			;
;
;
;
SEND$STB:
		;SENDE STROBE ZUM UPD1990
		;
	MVI	A,PAD$STB OR 1	;
	OUT	P$TIME$OUT	;
	MVI	A,10		;
SSTB:	DCR	A		;
	JRNZ	SSTB		;
	MVI	A,PAD$STB	;
	OUT	P$TIME$OUT	;
	RET
;
;
;
SEND$CLK:
		;SENDE SHIFT TAKT ZUM UPD1990
	MVI	A,PAD$CLK OR 80H;
	OUT	P$TIME$OUT	;
	MVI	A,10		;
SCKL:	DCR	A		;
	JRNZ	SCKL		;
	MVI	A,PAD$CLK	;
	OUT	P$TIME$OUT	;
	RET
;
;
;
TIME$ENABLE:
	RET
;
;
;
TIME$DISABLE:
		;SETZE CS DES UPD 1990 AUF OFF
	RET
;
;
;
READ$SHIFT:
		; DIE 40 BITS DES SHIFTREGISTERS DES UPD 1990
		; WERDEN IN DIE NACHFOLGENDEN 5 BYTES VON (HL)
		; ABGELEGT. NACH DIESER AKTION IST DAS SCHIFFTREGISTER
		; GELOESCHT

	MVI	A,1		;READ SCHIF REGISTER
	CALL	SEND$TIME$COM
	MVI	B,5		;LESE 5 BYTES AUS
READ$SHIFT$1:
	MVI	C,8		;JEDES BYTE ENTHAELT 8 BIT
READ$SHIFT$2:
	IN	P$TIME$IN	;LESE EIN BIT AUS
	CMA			;74LS258 NEGIERT
	RAL
	MOV	A,D		;SETZE UNTERSTES BIT IN D
	RAR			;ENTSPRECHEND CARRY
	MOV	D,A
	CALL	SEND$CLK	;SHIFTE NAECHSTES BIT
	DCR	C		;LESE PRO BYTE 8 BIT AUS
	JRNZ	READ$SHIFT$2	;IST BYTE FERTIG?
	MOV	M,D		;LEGE BYTE NACH (HL)
	INX	H		;ZEIGER AUF NAECHSTES BYTE
	DJNZ	READ$SHIFT$1	;LESE FUENF BYTES AUS
	MVI	A,0		;GEHE IN HOLD MODE
	CALL	SEND$TIME$COM
	RET

WRITE$SHIFT:
		; SCHREIBT SHIFTREGISTER MIT DEN 5 BYTES, AUF DIE
		; (HL) ZEIGT

	MOV	D,M		;LESE ERSTES BYTE EIN
	MVI	A,1		;GEHE IN SHIFT MODE
	CALL	SEND$TIME$COM
	MVI	B,5		;SCHREIBE FUENF BYTES EIN
WRITE$SHIFT$1:
	MVI	C,8		;JEDES BYTE ENTHAELT ACHT BIT
WRITE$SHIFT$2:
	MOV	A,D		;AUSGABE BYTE IN AKKU
	RRC
	ANI	80H
	ORI	PAD$C0
	OUT	P$TIME$OUT
	MOV	A,D		;SCHIEBE UM EINE POS. NACH RECHTS
	RAR
	MOV	D,A		;ZURUECK IN D
	CALL	SEND$CLK	;TAKTE BIT EIN
	DCR	C		;SCHON 8 BIT AUSGEGEBEN?
	JRNZ	WRITE$SHIFT$2
	INX	H		;LESE NAECHSTES BYTE
	MOV	D,M		;NACH D
	DJNZ	WRITE$SHIFT$1	;SCHREIBE INSGESAMT FUENF BYTES
	MVI	A,0		;SETZE UPD 1990 AUF HOLD
	CALL	SEND$TIME$COM
	RET

SET$PHYS$TIME:
		;SETZE ZEIT IM UPD 1990 MIT DEN FUENF BYTES DIE
		;IN PHYS$TIME STEHEN

	CALL	TIME$ENABLE	;AKTIVIERE UPD 1990
	LXI	H,SHIFT$CONT	;RETTE SHIFTREGISTER INHALT
	CALL	READ$SHIFT
	LXI	H,PHYS$TIME	;SCHREIBE ZEIT IN SHIFTREGISTER
	CALL	WRITE$SHIFT
	MVI	A,2		;SETZE ZAEHLER
	CALL	SEND$TIME$COM
	LXI	H,SHIFT$CONT	;LADE ALTEN SHIFTREGISTER INHALT
	CALL	WRITE$SHIFT
	CALL	TIME$DISABLE	;DEAKTIVIERE UPD 1990
	RET

READ$PHYS$TIME:
		;LESE ZEIT AUS UPD 1990 IN DIE FUENF BYTES
		;VON PHYS$TIME

	CALL	TIME$ENABLE	;AKTIVIERE UPD 1990
	LXI	H,SHIFT$CONT	;RETTE SHIFTREGISTER INHALT
	CALL	READ$SHIFT
	MVI	A,3		;SETZE SHIFTREGISTER MIT ZEIT
	CALL	SEND$TIME$COM
	MVI	B,0FFH		;WARTE ETWAS
READ$PHYS$TIME$1:
	DJNZ	READ$PHYS$TIME$1
	LXI	H,PHYS$TIME	;LESE ZEIT AUS
	CALL	READ$SHIFT
	LXI	H,SHIFT$CONT	;LADE SHIFTREGISTER INHALT ZURUECK
	CALL	WRITE$SHIFT
	CALL	TIME$DISABLE	;DEAKTIVIERE UPD 1990
	RET

SET$SHIFT:
		;SETZE SHIFTREGISTER MIT FUENF BYTES
		;SHIFT$CONT
	
	CALL	TIME$ENABLE	;AKTIVIERE UPD 1990
	LXI	H,SHIFT$CONT	;LADE SHIFT REG.
	CALL	WRITE$SHIFT
	CALL	TIME$DISABLE
	RET
;
;
;
GET$SPEED:
	;TESTE OB UHR IN ORDNUNG
	;WENN OK, A=FF, WENN NICHT IN ORDNUNG, A=00
	;WENN UHR OK, DANN IN HL TAKTFREQUENZ
	CALL	TIME$ENABLE	;SELECT UPD 1990
	MVI	A,0		;IN HOLD MODE
	CALL	SEND$TIME$COM
				;WARTE AUF AENDERUNG AM DATENAUSGANG
	LXI	H,0		;
	LXI	D,0FFFFH	;TIME OUT
	IN	P$TIME$IN	;LESE AUSGANG
	ANI	TIME$DATA$MASK
	MOV	B,A		;NACH B
GET$SPEED1:
	IN	P$TIME$IN	;LESE AUSGANG BIS AENDERUNG ODER TIME OUT
	ANI	TIME$DATA$MASK	;MASKIERE
	CMP	B
	JRNZ	GET$SPEED2	;VERAENDERUNG, WEITER
	MOV	C,A		;RETTE AKKU
	DCX	D		;TIME OUT ZAEHLER EINS RUNTER
	MOV	A,D
	ORA	E		;TIME OUT
	JRNZ	GET$SPEED1	;UHR NICHT OK?
	CALL	TIME$DISABLE	;
	XRA	A		;FEHLER MELDUNG
	RET
GET$SPEED2:			;TESTE TAKT FREQUENZ
	MOV	B,A		;WIEDER IN B FUER VERAENDERUNG
	MVI	C,TIME$DATA$MASK	;MASKE
GET$SPEED3:			;ERMITTLE TAKT, LOOP MUSS 50 ZYKLEN DAUERN
	IN	P$TIME$IN	; 11 ZYKLEN
	ANA	C		;MASKIERE, 4 ZYKLEN
	CMP	B		;GLEICH ?, 4 ZYKLEN
	JRNZ	GET$SPEED4	;ENDE,	7 ZYKLEN
	INX	H		; 6 ZYKLEN
	NOP			;DIENT NUR ZUR VERZOEGERUNG, 4 ZYKLEN
	NOP			; 4 ZYKLEN
	JMP	GET$SPEED3	; 10 ZYKLEN
GET$SPEED4:
	CALL	TIME$DISABLE
	MVI	A,0FFH
	RET
;
;
;
;*************************************************************;
;                                                             ;
;ENDE DES MASCHINEN CODES, ES FOLGEN NUN TABELLEN             ;
;                                                             ;
;*************************************************************;
;
;
;
TXT1	DB	', track #'
	DB	24H
TXT2	DB	', head #'
	DB	24H
TXT3	DB	', sector #'
	DB	24H
;
ERROR$TABLE:	DW	B15MSG	;FEHLERMELDUNGEN FUER ST1
		DW	NOBMSG
		DW	B13MSG
		DW	B12MSG
		DW	NOBMSG
		DW	B10MSG
		DW	B9MSG
		DW	B8MSG
;
		DW	NOBMSG	;FEHLERMELDUNGEN FUER ST2
		DW	B6MSG
		DW	B5MSG
		DW	B4MSG
		DW	NOBMSG
		DW	NOBMSG
		DW	B1MSG
		DW	B0MSG
;
NOBMSG	DB	24H
B15MSG	DB	10,13,' end of cylinder',24H
B13MSG	DB	10,13,' data error',24H
B12MSG	DB	10,13,' over run',24H
B10MSG	DB	10,13,' no data',24H
B9MSG	DB	10,13,' not writable',24H
B8MSG	DB	10,13,' missing address mark',24H
B6MSG	DB	10,13,' control mark',24H
B5MSG	DB	10,13,' data error in data field',24H
B4MSG	DB	10,13,' wrong cylinder',24H
B1MSG	DB	10,13,' bad cylinder',24H
B0MSG	DB	10,13,' missing address mark in data field',24H
;
TXTRD:
	DB	BELL,0DH,0AH,' Read error on $'
TXTWR:
	DB	BELL,0DH,0AH,' Write error on $'
;
;
SOFT$BAUD$TAB:
	;BAUDRATEN FAKTOR FUER DIE SOFTSCHNITTSTELLE
	;BERRECHNUNG ERFOLGT SO:
	;EINTRAG:=((1000000/BAUDRATE)-12,5)*65536/240000
	;
	;
	IF	ACHTMHZ
	;
	DW	50	; 9600   BAUD
	DW	106	; 4800   BAUD
	DW	221	; 2400   BAUD
	DW	448	; 1200   BAUD
	DW	1814	;  300   BAUD
	DW	4054	;  134.5 BAUD
	DW	7275	;   75   BAUD
	DW	50	; 9600   BAUD
	DW	22	;19200   BAUD
	DW	69	; 7200   BAUD
	DW	145	; 3600   BAUD
	DW	297	; 1800   BAUD
	DW	903	;  600   BAUD
	DW	3634	;  150   BAUD
	DW	4958	;  110   BAUD
	DW	10916	;   50   BAUD
;
	ELSE
;
	DW	25	; 9600   BAUD
	DW	53	; 4800   BAUD
	DW	110	; 2400   BAUD
	DW	224	; 1200   BAUD
	DW	907	;  300   BAUD
	DW	2027	;  134.5 BAUD
	DW	3637	;   75   BAUD
	DW	25	; 9600   BAUD
	DW	11	;19200   BAUD
	DW	35	; 7200   BAUD
	DW	72	; 3600   BAUD
	DW	148	; 1800   BAUD
	DW	452	;  600   BAUD
	DW	1817	;  150   BAUD
	DW	2479	;  110   BAUD
	DW	5458	;   50   BAUD
;
	ENDIF
;
;
SGNON: 
	DB	0DH,0AH
	DB	'Monitor'
	DB	0DH,0AH
	DB	'$'
;
;
;
KENNUNGSTEXT:
	DB	'PROF-80'	;WIRD VON INIT INS RAM KOPIERT
;
;
;
CMDMSG:		;NACH EINGABE EINES ZEICHENS WIRD TEXT AUSGEGEBEN
		;
	DB	'Address for read (write) from (to) drive $'
	DB	'Boot CP/M$'
	DB	'Check drive $'
	DB	'Display memory $'
	DB	'EPROM test$'
	DB	'Fill memory $'
	DB	'Go to $'
	DB	'Help$'
	DB	'Keyboard mode$'
	DB	'In port $'
	DB	'List time$'
	DB	'Move memory $'
	DB	'New date and time set$'
	DB	'Out port $'
	DB	'Read from drive $'
	DB	'Substitute memory $'
	DB	'Test memory $'
	DB	'User defined disk timing$'
	DB	'Verify memory $'
	DB	'Write to drive $'
	DB	'X Register $'
	DB	0		;ENDE DER COMMAND TEXTE
;
CADR: 
	DW	0
	DW	UCMD
	DW	KCMD
	DW	LCMD
	DW	HCMD
	DW	GCMD
	DW	WCMD
	DW	ACMD
	DW	RCMD
	DW	OCMD
	DW	CCMD
	DW	TCMD
	DW	VCMD
	DW	FCMD
        DW      BCMD
	DW	XCMD
	DW	SCMD
	DW	MCMD
	DW	ICMD
	DW	ECMD
	DW	DCMD
	DW	NCMD
;
;
;
CTAB: 
	DB	'N'
	DB	'D'
        DB      'E'
        DB      'I'
        DB      'M'
        DB      'S'
        DB      'X'
        DB      'B'
	DB	'F'
	DB	'V'
	DB	'T'
	DB	'C'
	DB	'O'
	DB	'R'
	DB	'A'
	DB	'W'
	DB	'G'
	DB	'H'
	DB	'L'
	DB	'K'
	DB	'U'
NCMDS	EQU	$-CTAB
;
;
;
RTAB: 
	DB	'A'
	DB	ASAVE AND 0FFH
        DB      0
        DB      'B'
        DB      BSAVE AND 0FFH
        DB      0
        DB      'C'
        DB      CSAVE AND 0FFH
        DB      0
        DB      'D'
        DB      DSAVE AND 0FFH
        DB      0
        DB      'E'
        DB      ESAVE AND 0FFH
        DB      0
        DB      'F'
        DB      FSAVE AND 0FFH
        DB      0
        DB      'H'
        DB      HSAVE AND 0FFH
        DB      0
        DB      'L'
        DB      LSAVE AND 0FFH
        DB      0
        DB      'M'
        DB      HSAVE AND 0FFH
        DB      1
        DB      'P'
        DB      PSAVE+1 AND 0FFH
        DB      1
        DB      'S'
        DB      SSAVE+1 AND 0FFH
        DB      1
	DB	'a'
	DB	AASAVE AND 0FFH
	DB	0
	DB	'b'
	DB	BBSAVE AND 0FFH
	DB	0
	DB	'c'
	DB	CCSAVE AND 0FFH
	DB	0
	DB	'd'
	DB	DDSAVE AND 0FFH
	DB	0
	DB	'e'
	DB	EESAVE AND 0FFH
	DB	0
	DB	'f'
	DB	FFSAVE AND 0FFH
	DB	0
	DB	'h'
	DB	HHSAVE AND 0FFH
	DB	0
	DB	'l'
	DB	LLSAVE AND 0FFH
	DB	0
	DB	'm'
	DB	HHSAVE AND 0FFH
	DB	1
	DB	'X'
	DB	XSAVE+1 AND 0FFH
	DB	1
	DB	'Y'
	DB	YSAVE+1 AND 0FFH
	DB	1
	DB	'I'
	DB	ISAVE AND 0FFH
	DB	0
	DB	'R'
	DB	RSAVE AND 0FFH
	DB	0
	DB	0,0	;ENDE KENNUNG DER TABELLE
;
;
;
DISKPAGE:	; DIE DISKPAGE WIRD DER SYSTEMPAGE UEBERLAGERT
		;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	RET
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	RET
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	RET
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	EXX
	OUTI
	EXX
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	RET
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	RET
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	RET
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
	EXX
	INI
	EXX
	INP	L
	PCHL
	DB	-1,-1,-1,-1,-1,-1,-1,-1,-1
	;
LASTADD	EQU	$-1	;LETZTE BENUTZTE ADRESSE IM EPROM
;
;
;
;************************************* BEGINN DES RAM-BEREICHES ******
;
;
;
		ORG	SYSTEMPAGE-1024-256
		;
BOOTADR		EQU	$	;HIERHER WIRD ERSTER SEKTOR GELADEN
		;
		DS	1024	;PLATZ FUER ERSTEN SEKTOR
		;
		DS	256-26	;PLATZ FUER STACK
		;
REGS:		EQU	$
MSTAK:		EQU	$
		;
		; REGISTER INHALTE
		;
RSAVE:		DS	1
ISAVE:		DS	1
LLSAVE		DS	1
HHSAVE		DS	1
EESAVE		DS	1
DDSAVE		DS	1
CCSAVE		DS	1
BBSAVE		DS	1
FFSAVE		DS	1
AASAVE		DS	1
YSAVE:		DS	2
XSAVE:		DS	2
ESAVE:		DS	1
DSAVE:  	DS	1
CSAVE:  	DS	1
BSAVE:  	DS	1
FSAVE:  	DS	1
ASAVE:  	DS	1
LSAVE:  	DS	1
HSAVE:  	DS	1
PSAVE:  	DS      2
SSAVE:  	DS      2
				;
				; DIE NACHFOLGENDEN SPEICHERZELLEN MUESSEN
				; MIT DER DISKPAGE GEMISCHT WERDEN KOENNEN
				;
SYSTEMPAGE:			; 
RWPOLL:				; NACHDEM DIE SYSTEMPAGE VON DER DISKPAGE
				; UEBERLAGERT WURDE, ERLEDIGT EIN CALL VON
				; RWPOLL DIE DISK-UEBERTRAGUNG.
				;
				;*** ERSTE 16 BYTE ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
TEMP:	  	DS	1	;ALLGEMEINER ZWISCHENSPEICHER
BAUD$JUMPERBYTE	DS	1	;STELLUNG DES JUMPERS J5: 0=KEIN JUMPER
				;1=1-3,2=2-4,3=3-5,4=4-6
CLKFLG		DS	1	;"0": UHR NICHT OK, "FF": UHR OK
DISKFLG		DS	1	;"0": UPD 765 NICHT OK, "FF": UPD 765 OK
SYSTEMTAKT	DS	2	;SYSTEMFREQUENZ * 100 HZ
DISPADR		DS	2	;LETZTER ZAEHLERSTAND DES D-BEFEHLS
EOTSAVE		DS	1	;WIRKLICHES ENDE EINER SPUR
EOTFLG		DS	1	;FEHLERFLAG FUER DISK R/W UEBER SPUR ENDE
RWCMD		DS	1	;COMMANDO FUER RWCOM
ERMSG		DS	2	;MEASSAGE FUR RWCOM
				;
				;
				;*** ZWEITE 16 BYTE ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
IO$JUMPERBYTE	DS	1	;STELLUNG DES JUMPERS J4: 0=KEIN JUMPER
				;1=1-3,2=2-4,3=3-5,4=4-6. DIRIGIERT KONSOLE
PHYS$TIME	DS	5	;ZWISCHENSPEICHER FUER UPD 1990 ZAEHLER INHALT
SHIFT$CONT	DS	5	;ZWISCHENSPEICHER FUER UPD 1990 SHIFTREGISTER 
SOFTVERZ	DS	2	;VERZOGERUNGSZEIT FUER DUPLEX-SCHNITTSTELLE
				;
				;
				;*** DRITTE 16 BYTE ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
TEST$TYPE	DS	1	;WIRD BEI TEST GESETZT (FORMATERKENNUNG FLOPPY)
				;BIT 7: 0=SS, 1=DS
				;BIT 6: 0=SD, 1=DD
				;BIT 5: 0=MAXI, 1=MINI
				;BIT 4: IMMER 0
				;BIT 0-3: SEKTORGROESSE
				;
TEST$MSEK	DS	1	;ANZAHL DER SEKTOREN/SPUR, DIE TEST ERMITTELTE
TEST$TRACK	DS	1	;AUF DIESER SPUR WIRD DAS FLOPPY-
				;FORMAT GETESTET (DEFAULT=1)
UMLEIT$NMI	DS	3	;EIN NMI GEHT UEBER DIESEN SPRUNG
				;
BANK$ERR$BYTE	DS	1	;BELEGUNG DER ZWEI RAM BANKS
				;0: BANK 0 UND BANK 1 OK
				;1: BANK 0 FEHLER
				;2: BANK 1 FEHLER
				;
DMAADR		DS	2	;DMA ADRESSE FUER FLOPPY READ UND WRITE
SECTCNT		DS	1	;ANZAHL DER SEKTOREN FUER FLOPPY READ UND WRITE
UMLEIT$GETCM	DS	3	;ROUTINEN, DIE VON CP/M BENUTZT WERDEN, MUESSEN
				;UEBER DIESEN SPRUNG AUF BEFEHLS-EINGABE-EBENE
				;ZURUECKKEHREN. CP/M BIOS SETZT DIESEN SPRUNG 
				;DANN AUF WBOOT
				;
				;
				;*** VIERTE 16 BYTE
		DS	3	;FREI FUER FLOPPY BEDIENUNG
				;KOMMANDO-TABELLE FUER FLOPY-CONTROLER
CMDTAB		DS	1	;
UNIT		DS	1	;WIRD VON C-BEFEHL GESETZT
TRACK   	DS      1	;WIRD VON A-BEFEHL GESETZT
HEAD    	DS      1	;WIRD VON A-BEFEHL GESETZT
SECTOR  	DS      1	;WIRD VON A-BEFEHL GESETZT
SECSZ   	DS      1	;WIRD VON C-BEFEHL GESETZT
EOT     	DS      1	;WIRD VON C-BEFEHL GESETZT
GAPLL		DS      1	;WIRD VON C-BEFEHL GESETZT
DTLL    	DS      1	;WIRD VON C-BEFEHL GESETZT
UMLEIT$CONST	DS	3	;KONSOLEN STATUS GEHT UEBER DIESEN SPRUNG
SEEKNR		DS	1	;EINIGE LAUFWERKE BENOETIGEN ZWEI STEPIMPULSE
				;DIE UNTEREN 4 BIT GEBEN FUER JEDES LW
				;AN, OB ES EIN ('0') ODER ZWEI ('1') IMPULSE
				;PRO SPURWECHSEL BRAUCHT, LAUFWERK 0 IST LSB.
				;DIE OBEREN 4 BIT DIESES BYTES GEBEN AN, OB
				;TEST DAS TWO-SIDED-BIT IMMER AUF 1 ODER
				;ENTSPRECHEND DER TWO-SIDED-LEITUNG SETZTEN
				;SOLL. DURCH DIESE ERWEITERUNG SPART MAN SICH
				;DEN HARDWARE-ZUSATZ (SIEHE CP/M ANPASSUNS-
				;BESCHREIBUNG) FUER GEMISCHTEN BETRIEB MIT
				;80 TRACK LAUFWERKEN.
				;DEFAULTMAESSIG WIRD SEEKNR MIT XSEEKNR
				;INITIALISIERT. SEEKNR KANN ABER AUCH MIT DEM
				;U-BEFEHL GESETZT WERDEN.
				;
				;*** FUENFTE 16 BYTES ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
REST    	DS      7	;ERGEBNISSTABELLE DES FLOPY-CONTROLERS
UMLEIT$CONIN	DS	3	;KONSOLEN EINGABE GEHT UEBER DIESEN SPRUNG
UMLEIT$CONOUT	DS	3	;KONSOLEN AUSGABE GEHT UEBER DIESEN SPRUNG
				;
				;
				;*** SECHSTE 16 BYTES ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
IN$BUFF$END	DS	11	;FIFO ZEICHEN BUFFER FUER DUPLEX EINGABE
				;IM INTERRUPTBETRIEB (J-51-A GESETZT)
IN$BUFF$ZEIG	DS	2	;ZEIGER FUER ZEICHEN BUFFER
				;
				;
				;*** SIEBTE 16 BYTES ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
DERMSG		DS	1	;"0":AUSGABE VON FLOPPY-FEHLER
				;"FF": AUSGABE VON FLOPPY-FEHLER UNTERDRUECKEN
RWRETRY		DS	1	;ANZAHL DER LESE/SCHREIB-VERSUCHE MIT FLOPPY
WRITE$PRECOM	DS	1	;WRITE PRECOMPENSATION FUER RWCOM ROUTINE
KENNUNG		DS	7	;DER MONITOR SCHREIBT HIER PROF-80 KENNUNG EIN
MON$VERS	DS	1	;MONITOR VERSIONSNUMMER
COMMON$PAGE	DS	1	;PAGEGRENZE FUER COMMON BEREICH (SETZT BIOS)
CURRENT$BANK	DS	1	;GEWAEHLTE BANK UNTER COMMON (SETZT BIOS)
				;
				;
				;*** ACHTE 16 BYTES ***
		DS	3	;FREI FUER FLOPPY BEDIENUNG
SOFTPRNTVERZ	DS	2	;VERZOEGERUNGSZEIT FUER SIMPLEX SCHNITTSTELLE
READY$BYTE	DS	1	;DIE UNTEREN 4 BITS GEBEN AN, OB EIN LW
				;EIN READY SIGNAL LIEFERN KANN ('0') ODER OB
				;ES KEIN READY LIEFERT ('1').
				;DIE OBEREN 4 BITS GEBEN AN, OB BEI DEM
				;BETREFFENDEN LW UEBERHAUPT SCHON GETESTET
				;WURDE OB ES READY LIEFERT
				;'0'= SCHON GETESTET, '1'= NOCH NICHT GETESTET
				;LAUFWERK 0 IST LSB
EPROMZ		DS	1	;WIEVIEL MAL WURDE EPROM EINGESCHALTET?
				;(WIRD VOM BIOS GESETZT)
TYPELIST	DS	2	;ZEIGER AUF DISK$TYPE$LIST (WIRD VOM BIOS
				;GESETZT)
SPECD$WORD	DS	2	;DER INHALT DIESER ZWEI BYTE BESTIMMT DIE
				;STEP-RATE, DIE HEAD-LOAD-TIME UND DIE HEAD-
				;UNLOAD-TIME. SPECD$WORD WIRD NACH EINEM RESET
				;VOREINGESTELLT. NACH JEDEM CHECK DRIVE WERDEN
				;DIE DRIVE-ZEITEN NEU GESETZT.
				;DIE 16 BIT VON SPECD$WORD SIND FOLGENDERMASSEN
				;AUFGEBAUT:
				;            SSSSUUUU LLLLLLLX
				;
				; SSSS:	STEPRATE 0000=16MS
				;		 0001=15MS
				;		 .........
				; 		 1111=1MS
				;
				; UUUU: HEADUNLOADTIME IN 16 MS SCHRITTEN
				;	0000=0MS, 0001=16MS, .. ,1111=240MS
				;
				; LLLLLLL: HEADLOADTIME IN 2 MS SCHRITTEN
				;
				; X: IMMER 1       
				;
				;DEFAULTMAESSIG WIRD SPECD$WORD MIT
				;XSPECD$WORD INITIALISIERT, ES KANN ABER
				;AUCH MIT DEM U-BEFEHL GESETZT WERDEN.
				;
TE$TIME		DS	1	;WARTEZEIT NACH DISK-WRITE IN 100US (BEI 6MHZ)
SIOABAUD	DS	1	;JUMPERSTELLUNG UNIO J2-A
SIOBBAUD	DS	1	;JUMPERSTELLUNG UNIO J2-B
STEP$WAIT	DS	1	;WARTEZEIT VOR SEEK WENN MOTOR VORHER AUS WAR
				;IST BEI EPSON 3,5 ZOLL LAUFWERKEN NOTWENDIG.
				;ZEIT: MAL 10 MS (BEI 6 MHZ)
		DS	1	;NOCH FREI
				;
				;
				;***  NEUNTE 16 BYTE ***
		DS	1	;FREI FUER FLOPPY BEDIENUNG
ALT$UNIT	DS	1	;LAUFWERK UND TRACK BEI LETZTEM
ALT$TRACK	DS	1	;SEEK AUFRUF
		DS	13	;NOCH FREI
				;
				;
		DS	7*16	;FREIHALTEN FUER ERWEITERUNGEN UND
				;FLOPPY BEDIENUNG
				;
	END

2-B
STEP$WAIT	DS	1	;WARTEZEIT VOR SEEK WENN MOTOR VORHER AUS WAR
				;IST BEI EPSON 3,5 ZOLL LAUFWERKEN NOTWENDIG.
				;ZEIT: