;*********************************************************
;***                                                   ***
;***  CSYSGEN: DIESES PROGRAMM KOPIERT DIE SYSTEM-     ***
;***  SPUREN VON/AUF MINI UND MAXI 		       ***
;***  LETZTE AENDERUNG AM: 13.08.1984 (JOACHIM)        ***
;***                                                   ***
;*********************************************************
;
	MACLIB	Z80
	MACLIB	CDEF
;
	TITLE	'PROF-80 SYSGEN'
;
BDOS		EQU	00005H
WBOOT		EQU	00000H
TPA		EQU	100H
EPROMCODE	EQU	2000H	;HIERHER WERDEN DIE EPROM ROUTINEN GELADEN
SYSTEMSAVE	EQU	EPROMCODE+900H
STACK		EQU	EPROMCODE+400H
;
;
;
		ORG	EPROM
		;
		DS	7*3
MONSETCMDT	DS	3
		DS	5*3
MONREAD		DS	3
MONWRITE	DS	3
		DS	3*3
		DS	5
		DS	2*3
MONTEST		DS	3
;
;
;
	ORG	TPA
	;
	LXI	H,KENNUNG	;PRUEFE OB PROF-80 COMPUTER
	LXI	D,PROF80	;
	MVI	B,7		;
CHECKLOOP:			;
	LDAX	D		;
	CMP	M		;
	JRNZ	COMPUTER$FALSCH	;
	DJNZ	CHECKLOOP	;
	LDA	CURRENT$BANK	;PRUEFE OB BANK 0 ODER BANK 1
	ANI	0FEH		;
	JRZ	CHECKOK		;SPRUNG WENN COMPUTER = PROF-80 UND BANK0/1
COMPUTER$FALSCH:
	LXI	H,FALSCHTXT	;GEBE FEHLERMELDUNG AUS
	CALL	SOUT		;
	JMP	WBOOT		;
;
FALSCHTXT:
	DB	0DH,0AH,'Error CSYSGEN runs only in bank 0 or bank 1'
	DB	0DH,0AH,'of a PROF-80 computer',0DH,0AH,'$'
PROF80	DB	'PROF-80'
;
CHECKOK:
;
	LXI	SP,STACK	;SETZE STACK NEU
	LXI	H,SWITCHCODE	;COPIERE EPROM
	LXI	D,EPROMCODE	;ROUTINEN
	LXI	B,EPROMCODEL	;
	LDIR			;
	LXI	H,ANFTXT	;GEBE VERSION AUS
	CALL	SOUT		;
START:	
	LXI	H,STEXT		;LESE SOURCE DRIVE EIN
	CALL	SOUT		;
	CALL	CONIN		;LESE LAUFWERKBUCHSTABEN EIN
	CALL	ECHO		;
	JC	MAINLP2		;
	CALL	VALID		;LAUFWERKS ANGABE KORREKT?
	JRNC	MAINLP1		;SPRUNG WENN OK
	LXI	H,ETEXT		;
	CALL	SOUT		;
	JR	START		;NEUE EINGABE
MAINLP1	STA	DRIVECR		;SPEICHERE BUCHSTABEN AB
	LXI	H,SETEXT	;GEBE LW. NOCHMAL AUS
	CALL	SOUT		;
	LDA	DRIVECR		;
	MOV	C,A		;
	CALL	CONOUT		;
	LXI	H,EETEXT	;
	CALL	SOUT		;
	CALL	CONIN		;
	CALL	ECHO		;
	JNC	START		;
	CALL	GETSYS		;LESE SYSTEM EIN
	LXI	H,QTEXT		;
	CALL	SOUT		;
MAINLP2:
	LXI	H,DTEXT		;
	CALL	SOUT		;
	CALL	CONIN		;LESE ZEICHEN
	CALL	ECHO		;ZURUECK ZUR KONSOLE
	JC	WBOOT		;WAR RETURN, ZURUECK ZUM CP/M
	CALL	VALID		;PRUEFE OB ZEICHEN OK
	JRNC	MAINLP3		;
	LXI	H,ETEXT		;
	CALL	SOUT		;
	JR	MAINLP2		;NEUE EINGABE
MAINLP3	STA	DRIVECR		;LEGE LAUFWERKBUCHSTABE AB
	LXI	H,DETEXT	;
	CALL	SOUT		;
	LDA	DRIVECR		;
	CALL	ECHO		;
	LXI	H,EETEXT	;
	CALL	SOUT		;
	CALL	CONIN		;
	CALL	ECHO		;
	JRNC	MAINLP2		;
	CALL	PUTSYS		;
	LXI	H,QTEXT		;
	CALL	SOUT		;
	JMP	MAINLP2		;
;
;
;
GETSYS:
	MVI	A,0		;
	STA	WRITEFLAG	;
	JMP	GETPUTSYS	;
;
;
;
PUTSYS:
	MVI	A,0FFH		;
	STA	WRITEFLAG	;
	JMP	GETPUTSYS	;
;
;
;
GETPUTERR:
		;FEHLERMELDUNG FUER SCHLECHTE SYSTEMSPUREN
	LXI	H,BTRKTXT
	CALL	SOUT
	LXI	H,SOTXT
	LDA	WRITEFLAG
	ORA	A
	JRZ	BADTRK1
	LXI	H,DETXT
BADTRK1	CALL	SOUT
	JMP	START
BTRKTXT	DB	0DH,0AH,'BAD SYSTEM TRACK ON $'
SOTXT	DB	'SOURCE$'
DETXT	DB	'DESTINATION$'
;
;
;
ANFTXT	DB	0AH,0DH
	DB	'CSYSGEN Version 1.0',0AH,0DH,24H
;
;
;
STEXT	DB	0AH,0DH
	DB	'SOURCE DRIVE NAME (OR RETURN TO SKIP) '
	DB	24H
;
QTEXT:
	DB	'FUNCTION COMPLETE'
	DB	24H
;
ETEXT	DB	0AH,0DH
	DB	'INVALID DRIVE NAME (USE A,B,C OR D)'
	DB	24H
;
DTEXT	DB	0AH,0DH
	DB	'DESTINATION DRIVE NAME (OR RETURN TO REBOOT) '
	DB	24H
;
DETEXT	DB	0AH,0DH
	DB	'DESTINATION ON '
	DB	24H
;
SETEXT	DB	0AH,0DH
	DB	'SOURCE ON '
	DB	24H
;
EETEXT	DB	', THEN TYPE RETURN'
	DB	24H
;
;
;
VALID:
	;SETZT CARRY FLAG, WENN ZEICHEN IN A
	;KEIN GUELTIGER LAUFWERKSBUCHSTABE IST
	CPI	'A'
	RC
	CPI	'E'
	JRC	NRET
SRET	STC
	RET
NRET	STC
	CMC
	RET
;
;
;
ECHO:
	;SCHREIBT ZEICHEN IN A AUF KONSOLE
	;BEI CR WIRD CR LF AUSGEGEBEN UND CARRY GESETZT
	;
	MOV	C,A		;
	CALL	CONOUT		;
	CPI	0DH		;
	JNZ	NRET		;OHNE CARRY ZURUECK
	MVI	C,0AH		;
	CALL	CONOUT		;
	JMP	SRET		;MIT CARRY ZURUECK
;
;
;
CONOUT	PUSH	PSW		;
	PUSH	B		;
	PUSH	D		;
	PUSH	H		;
	MOV	E,C		;
	MVI	C,6		;
	CALL	BDOS		;
	POP	H		;
	POP	D		;
	POP	B		;
	POP	PSW		;
	RET			;
;
;
;
CONIN	PUSH	B		;
	PUSH	D		;
	PUSH	H		;
CONIN1	MVI	E,0FFH		;INPUT
	MVI	C,6		;
	CALL	BDOS		;
	CPI	00H		;
	JRZ	CONIN1		;
	CPI	'a'		;WANDLE IN GROSSBUCHSTABEN
	JRC	CONIN2		;
	SUI	'a'-'A'		;
CONIN2	POP	H		;
	POP	D		;
	POP	B		;
	RET			;
;
;
;
SOUT:
        ;GIBT ASCIISTRING AUS (ANFANG IN HL,ENDE DURCH $)
	;
        MOV	A,M		;
	CPI	24H		;ENDE DES STRINGS ?
        RZ			;
        MOV     C,A		;
        CALL    CONOUT		;
        INX     H		;
        JMP     SOUT		;
;
;
;
;------------------------------------------------------------
;
;
GETPUTSYS:
	;WENN WRITEFLAG=0 DANN LESE DIE SYSTEMSPUREN
	;WENN WRITEFLAG <> 0 DANN SCHREIBE DIE SYSTEMSPUREN
	;
	XRA	A		;SETZE CMDTAB FUER SPUR EINS
	STA	TEST$TRACK	;
	LDA	DRIVECR		;SETZE UNIT
	DCR	A		;
	ANI	00000011B	;
	STA	UNIT		;
	CALL	TEST		;TESTE DRIVE
	CALL	SETCMDT		;SETZE CMDTABELLE
	XRA	A		;
	STA	TRACK		;
	STA	HEAD		;
				;
	MVI	A,1		;LADE/SCHREIBE BOOTSEKTOR
	STA	SECTOR		;
	STA	SECTCNT		;
	LXI	H,SYSTEMSAVE	;
	SHLD	DMAADR		;
	LDA	WRITEFLAG	;
	ORA	A		;
	JRZ	BOOTSEK1	;
	CALL	WRITE		;
	JR	BOOTSEK2	;
BOOTSEK1:			;
	CALL	READ		;
BOOTSEK2:			;
	JNZ	GETPUTERR	;
				;
				;LADE/SCHREIBE CCP,BDOS UND BIOS
	LXI	H,SYSTEMSAVE+80H;
	SHLD	NEXTDMA		;DMA-ADRESSE FUER NAECHSTE SPUR
	MVI	A,2		;ANFANGS SECTOR DER SPUR
GETPUT0	STA	SECTOR		;
	LDA	SECSZ		;BERECHNE BYTES/SEKTOR
	LXI	H,64		;
	INR	A		;
GETPUT1	DAD	H		;
	DCR	A		;
	JRNZ	GETPUT1		;
	XCHG			;BYTES/SEKTOR IN DE
	LHLD	NEXTDMA		;NEUE DMA-ADRESSE
	SHLD	DMAADR		;FUER READ SETZEN
				;
	LDA	EOT		;
	MOV	C,A		;
	LDA	SECTOR		;
	MVI	B,1		;SEKTOR ZAEHLER
GETPUT3	LHLD	NEXTDMA		;BERRECHNE ANZAHL DER SEKTOREN
	DAD	D		;DIE VON DIESER SPUR GELESEN WERDEN
	SHLD	NEXTDMA		;SOLLEN.
	CMP	C		;LETZTER SEKTOR
	JRZ	GETPUT5		;
	INR	A		;
	INR	B		;
	JR	GETPUT3		;
				;
GETPUT5	MOV	A,B		;LEGE BERRECHNETE SEKTORZAHL AB
	STA	SECTCNT		;
	LDA	WRITEFLAG	;LESEN ODER SCHREIBEN?
	ORA	A		;WENN NULL LESEN
	JRZ	GETPUT8		;SONST SCHREIBEN
	CALL	WRITE		;
	JR	GETPUT9		;
GETPUT8	CALL	READ		;
GETPUT9	JNZ	GETPUTERR	;BEI FEHLER MELDUNG
				;
	LDA	TEST$TYPE	;LADE MAXIMAL 2 SPUREN BEI MAXI
	ANI	20H		;BZW. 3 SPUREN BEI MINI
	MVI	C,2		;
	JRZ	GETPUT6		;
	MVI	C,3		;
GETPUT6	LDA	TRACK		;ERHOEHE SPUR UM EINS
	INR	A		;
	CMP	C		;GENUG SPUREN UEBERTRAGEN?
	RZ			;DANN ENDE
	STA	TRACK		;
	STA	TEST$TRACK	;TESTE NAECHSTE SPUR
	CALL	TEST		;
	CALL	SETCMDT		;SETZE CMDTAB FUER SPUR > 0
	MVI	A,1		;LESE ALLE ANDEREN SPUREN AB SEKTOR EINS
	JR	GETPUT0		;
				;
;-------------------------------------------------------------------
;
;
;
SWITCHCODE:	;DIESER BEREICH WIRD NACH EPROMCODE
		;KOPIERT, DAMIT MONITOR UP'S BENUTZT WERDEN
		;KOENNEN
;
;
;
READOFF		EQU	$-SWITCHCODE
		CALL	EPROMON
		CALL	MONREAD
		CALL	EPROMOFF
		RET
;
WRITEOFF	EQU	$-SWITCHCODE
		CALL	EPROMON
		CALL	MONWRITE
		CALL	EPROMOFF
		RET
;
TESTOFF		EQU	$-SWITCHCODE
		CALL	EPROMON
		CALL	MONTEST
		CALL	EPROMOFF
		RET
;
SETCMDTOFF	EQU	$-SWITCHCODE
		CALL	EPROMON
		CALL	MONSETCMDT
		CALL	EPROMOFF
		RET
;
EPROMONOFF	EQU	$-SWITCHCODE
		PUSH	PSW		;
		LDA	EPROMZ		;
		ORA	A		;
		JRNZ	EPROMON1	;
		INR	A		;
		STA	EPROMZ		;
		PUSH	B		;
		MVI	B,0		;KACHEL 0
		MVI	C,P$RAM$TABLE	;PORT DER RAM TABELLE
		MVI	A,0		;EPROM BANK
		OUTP	A		;
		MVI	B,10H		;KACHEL 1
		OUTP	A		;
		POP	B		;
		POP	PSW		;
		RET			;
EPROMON1	INR	A		;
		STA	EPROMZ		;
		POP	PSW		;
		RET
;
EPROMOFFOFF	EQU	$-SWITCHCODE
		PUSH	PSW		;
		LDA	EPROMZ		;
		DCR	A		;
		JRNZ	EPROMOFF1	;
		STA	EPROMZ		;
		PUSH	B		;
		MVI	B,0		;KACHEL 0
		MVI	C,P$RAM$TABLE	;PORT
		LDA	CURRENT$BANK	;ALTE TPA BANK
		ADI	2		;PHYS ADR.
		OUTP	A		;
		MVI	B,10H		;
		OUTP	A		;
		POP	B		;
		POP	PSW		;
		RET			;
EPROMOFF1	STA	EPROMZ		;
		POP	PSW		;
		RET
;
;
READ		EQU	READOFF+EPROMCODE
WRITE		EQU	WRITEOFF+EPROMCODE
TEST		EQU	TESTOFF+EPROMCODE
SETCMDT		EQU	SETCMDTOFF+EPROMCODE
EPROMON		EQU	EPROMONOFF+EPROMCODE
EPROMOFF	EQU	EPROMOFFOFF+EPROMCODE
;
EPROMCODEL	EQU	$-SWITCHCODE
;
;
;
;-------------------------------------------------------------------
;
;
NEXTDMA		DS	2	;
DRIVECR		DS	1	;ZWISCHENSPEICHER FUER LAUFWERK CHR
WRITEFLAG	DS	1	;
;
;
;
;-------------------------------------------------------------------
				;
				; DIE NACHFOLGENDEN SPEICHERZELLEN MUESSEN
				; MIT DER DISKPAGE GEMISCHT WERDEN KOENNEN
				;
		ORG	SYSTEMPAGE
				;
				;
				;*** 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 BITS GEBEN FUER JEDES LW
				;AN, OB ES EIN ('0') ODER ZWEI ('1') IMPULSE
				;PRO SPURWECHSEL BRAUCHT
				;LAUFWERK 0 IST LSB
				;
				;*** 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
		DS	9	;NOCH FREI
				;
				;
		DS	8*16	;FREIHALTEN FUER ERWEITERUNGEN UND
				;FLOPPY BEDIENUNG
				;
	END
