;*********************************************
;
; EPROM-Treiber fuer VDIP1/VDIP2 an M001/M052
;	Version 2.0 (KC85/3/4/5)
;	KC85/2 nicht unterstuetzt
;
;	+-----------------------------------+
;	:	Schaltplan Version 1.1!     :
;	+-----------------------------------+
;	: PIO-A bidirektional		    :
;	: PIO-B Bitberieb / Statusabfrage   :
;	: Terminal-Interrupt von BSTB !     :
;	+-----------------------------------+
;
; Funktionen in CAOS:
;	VINCULUM, BASIC, REBASIC, BSAVE, ULOAD, USAVE, DEVEX
;
; Funktionen im Vinculum-Menue:
;	MENU, CLS, USB, LOAD, SAVE, DIR
;
; Uebersetzen:
;	SLRZ80 VDIP2/A
;	REN VDIP2.COM VDIP2.KCC
;
; (c) Mario Leubner 20.12.2007-07.01.2009
;
; VDIP2.Z80 (Includes: UBASEX.INC, UDEVEX.INC)
;*********************************************

;Allgemeine Vereinbarungen:

CAOS44	EQU	1	; 0 = bis CAOS 4.2

PROLOG	EQU	3E3EH	; Prologbyte fuer Vinculum-Menu

; Arbeitszellen im RAM-0:

NAME	EQU	0	; Dateiname 8 Zeichen, Typ 3 Zeichen
SLOT	EQU	NAME+11	; Steckplatz Modul M001
MSTW	EQU	SLOT+1	; urspruenglicher Schaltzustand
DATUM	EQU	SLOT+2	; Datum im DOS-Format
TIME	EQU	SLOT+4	; Uhrzeit im DOS-Format
ISR	EQU	SLOT+6	; ISR im RAM0

; ab 200H nur in Benutzung fuer DIR/Sort:

data	EQU	200h	; Datenpuffer fuer DIR und DIRT (30 Zeichen)
pointer	EQU	21eh	; Zeiger in Verzeichnispuffer
count	EQU	220h	; Anzahl Dateien
table	EQU	222h	; Zeiger auf Beginn der Zeigertabelle (Sort)
GAP	EQU	224h	; Variable fuer SORT
J	EQU	226h	;	"	"
TPAEND	EQU	228H	; Speicherende (4000h oder 8000h)
page	EQU	22ah	; Zeilenzaehler fuer Page-Modus
MEMRY	EQU	230h	; ab hier wird das Verzeichnis abgelegt

; CAOS-Vorblock:
	DB	'USB'	; Dateiname ...
	DB	'M001'

IF CAOS44
	DB	'4'
ELSE
	DB	' '
ENDIF
	DB	'KCC'
	DS	5,0
DB	2
DW	BEGIN		; Anfangsadresse
DW	ENDE		; Endadresse
	DS	107,0	; Rest von Vorblock

	.phase	0C000H	; Basisadresse
BEGIN:

MKENN	EQU	0EFH	; Kennung M001
			; Portadressen:
PIOA	EQU	4	; Daten A
PIOB	EQU	5	; Daten B
PIOAS	EQU	6	; Steuer A
PIOBS	EQU	7	; Steuer B

IVEK	EQU	0D0H	; Interrupt-Vektor PIO

; IRM-Arbeitszellen:

CASS	EQU	0B700H	; Kassettenpuffer
ARGN	EQU	0B781H	; Anzahl Argumente
ARG1	EQU	0B782H	; ARG1 (Anfangsadresse)
ARG2	EQU	0B784H	; ARG2 (Endadresse)
ARG3	EQU	0B786H	; ARG3 (Startadresse)
NUMVX	EQU	0B797H	; Zahlenwert
WINNR	EQU	0B79BH	; Fensternummer
WINON	EQU	0B79CH	; Fensteranfang
CURSO	EQU	0B7A0H	; Cursorposition
STBT	EQU	0B7A2H	; Bildschrimsteuerbyte
COLOR	EQU	0B7A3H	; Farbattribut
CCTL0	EQU	0B7A6H	; Zeichenbildtabelle 1
CCTL1	EQU	0B7A8H	; Zeichenbildtabelle 2
SUTAB	EQU	0B7B0H	; CAOS-Unterprogrammtabelle
IOERR	EQU	0B7C9H	; Sprungadresse IO-ERROR (BASIC)
DTPTR	EQU	0B7DAH	; Pointer in CASS-Puffer (BASIC)
PROMPT	EQU	0B7ECH	; CAOS-Prompt

; CAOS-Systemprogramme:
 
PV1	EQU	0F003H	; Sprungverteiler 1
CRT	EQU 00H
KBD	EQU 04H
INLIN	EQU 17H
RHEX	EQU 18H
ERRM	EQU 19H
HLHX	EQU 1AH
HLDE	EQU 1BH
AHEX	EQU 1CH
OSTR	EQU 23H
LF	EQU	0AH
CLS	EQU	0CH
CR	EQU	0DH
OCHR	EQU 24H
MODU	EQU 26H
CRLF	EQU 2CH
WININ	EQU 3CH
WINAK	EQU 3DH
INIEA	EQU 43H
INIME	EQU 44H
MENU	EQU 46H
IRMON	EQU	0F018H	; IRM einschalten
IRMOF	EQU	0F01BH	; IRM ausschalten

; Vinculum-Kommandos:
 
DIR	EQU	01H	; Directroy
DLF	EQU	07H	; Delete File
WRF	EQU	08H	; Write to File
OPW	EQU	09H	; Open/write
CLF	EQU	0AH	; Close
RDF	EQU	0BH	; Read from File
OPR	EQU	0EH	; Open/read
SCS	EQU	10H	; Short CMD
ECS	EQU	11H	; Extend. CMD
IPH	EQU	91H	; Binaer-Modus einstellen

;--------------------------------------

; Datenbereich im EPROM:

DAT08:	DW	38H,21H	; 01.01.2008	0011 1000 0010 0001
			;		yyyy yyym mmmd dddd
	DW	0	; 00:00 Uhr

INIT:	DB	3	; 3 Ports

	DB	PIOBS
	 DB	5	; Anzahl
	  DB	0CFH	; Bitbetrieb
	  DB	33H	; I/O festlegen (00110011)
	  DB	IVEK	; Int.-Vektor
	  DB	17H	; DI, Maske folgt
	  DB	0FFH	; kein Bit aktiv

	DB	PIOB	; Daten
	 DB	2
	  DB	4	; RESET
	  DB	44H	; RD&WR inaktiv

	DB	PIOAS
	 DB	2
	  DB	8FH	; bidirektional
	  DB	07H	; kein INT

;--------------------------------------

; Suche+Einschalten Modul, Initialisieren PIO:
; PA:	CY=1	Fehler (Modul nicht gefunden)
;
MINIT:	LD	L,7		; ab Steckplatz 7
NEXT:	LD	A,1
	CALL	PV1
	DB	MODU		; Modultyp+Zustand "auslesen"
	LD	A,H
	CP	MKENN		; richtiges Modul?
	JR	Z,FOUND
	INC	L		; naechster Steckplatz
	JR	NZ,NEXT
	CALL	PV1
	DB	OSTR
	DB	'Modul M001 nicht gefunden!'
	DB	7,CR,LF,0
	SCF			; Fehlercode
	RET
	;
FOUND:	LD	H,D		; Schaltzustand und
	LD	(SLOT),HL	; Steckplatz merken
	SET	0,D		; Modul ein bei M001
	LD	A,2		; Modul "schalten"
	CALL	PV1
	DB	MODU
	LD	HL,INIT		; PIO-Daten
	LD	D,(HL)		; Anzahl Ports
	INC	HL
	CALL	PV1		; PIO initialisieren
	DB	INIME
	LD	HL,DAT08	; aus EPROM
	LD	DE,DATUM	; Standard-Datum
	LD	BC,4
	LDIR			; als Vorbelegung kopieren
	AND	A		; OK
	RET

;--------------------------------------

	DW	7F7FH
	DB	'VINCULUM',1

START:	RES	0,(IX+7)	; Vinculum-Modus (VERIFY)
	call	minit		; Modul initialisieren
	ret	c		; nicht gefunden

; Datum holen und konvertieren:

	CALL	DCONV		; Datum von D004 holen
	JR	NC,UHROK	; kein Fehler
uhr1:	CALL	PV1
	DB	OSTR
	DB	'Datum: 01.01.09',0
	CALL	PV1
	DB	INLIN		; Eingabe Datum
	LD	HL,7
	ADD	HL,DE
	EX	DE,HL
	CALL	PV1
	DB	RHEX		; Tag erfassen
	ld	a,(de)
	cp	'.'
	jr	nz,uhr1		; kein Trennzeichen
	ld	a,(numvx)
	ld	c,a		; Tag BCD
	inc	de
	CALL	PV1
	DB	RHEX		; Monat erfassen
	ld	a,(de)
	cp	'.'
	jr	nz,uhr1		; kein Trennzeichen
	ld	a,(numvx)
	ld	b,a		; Monat BCD
	inc	de
	CALL	PV1
	DB	RHEX		; Jahr erfassen
	LD	A,(numvx)	; Jahr
	call	conv		; Datum konvertieren
	INC	HL
	XOR	A
	LD	(HL),A		; 00:00 als Uhrzeit eintragen
	inc	HL
	LD	(HL),A
UHROK:

; Interrupt vorbereiten:

	LD	DE,ISR
	LD	HL,ISRC
	LD	BC,ENDISR-ISRC
	LDIR			; ISR -> RAM0
	LD	A,I
	LD	H,A
	LD	L,IVEK		; INT-Vektor
	LD	DE,ISR
	LD	(HL),E
	INC	HL		; ISR eintragen
	LD	(HL),D
 
; Fenster 0 (CAOS):
 
	LD	A,0		; Fenster 0
	LD	HL,0
	LD	DE,2028H
	CALL	PV1
	DB	WININ
	LD	A,39H		; weiss/blau
	LD	(COLOR),A
	ld	a,cls
	call	pv1		; Bildschirm loeschen
	db	crt
	LD	A,31H		; gelb/blau
	LD	(COLOR),A
	CALL	PV1
	DB	OSTR
	DB	12H		; scrollen
	DB	' Vinculum Terminal V2.0    ` by ML-Soft',0
	LD	HL,1F01H
	LD	(CURSO),HL	; Position links/unten
	call	pv1
	db	ostr
	DB	'M001 auf ',0
	LD	A,(SLOT)
	CALL	PV1
	DB	AHEX		; Steckplatz anzeigen
	LD	HL,1F1DH
	LD	(CURSO),HL	; Position rechts/unten
	ld	a,(datum+1)
	and	1fh		; Tag
	ld	l,a
	ld	h,0
	call	hldez		; anzeigen
	ld	a,'.'
	call	pv1
	db	crt
	ld	hl,(Datum)
	ld	a,h
	srl	l
	rra
	rra
	rra
	rra
	rra
	and	0fh		; Monat
	ld	l,a
	ld	h,0
	call	hldez		; anzeigen
	ld	a,'.'
	call	pv1
	db	crt
	ld	a,(datum)
	srl	a
	ld	l,a
	ld	h,0
	ld	de,1980		; Jahr
	add	hl,de
	call	hldez		; anzeigen
	LD	A,39H		; weiss/blau
	LD	(COLOR),A
 
; Fenster 1 (Terminal):
 
	LD	A,1		; Fenster 1
	LD	HL,0101H
	LD	DE,1326H
	CALL	PV1
	DB	WININ
	LD	A,3CH		; wei~/gr}n
	LD	(COLOR),A
	CALL	PV1
	DB	OSTR
	DB	CLS
	DB	12H		; scrollen
	DB	0
	LD	A,(STBT)
	OR	22H		; IBM / Farbe aus
	LD	(STBT),A

; vorhandene Daten leeren:
 
	CALL	sync		; mit Vinculum synchronisieren
	IN	A,(PIOA)	; Dummy-Eingabe
 
; Fenster 2 (Menu):
 
	LD	A,2		; Fenster 2
	LD	HL,1501H
	LD	DE,0A26H
	CALL	PV1
	DB	WININ
	LD	HL,STBT
	RES	1,(HL)		; Farbe ein
	INC	HL
	LD	(HL),38H	; wei~/schwarz
	LD	A,'>'
	LD	(PROMPT),A
	LD	A,low(PROLOG)
	LD	(IX+9),A	; neues Prologbyte
	CALL	SAV8		; EI, ECS ...
	JR	MEN0
 
; Terminal-Schleife:
 
	DW	PROLOG
	DB	'MENU'
	DB	1
	POP	HL		; Stack clear
MEN0:	ld	a,2
	call	pv1
	db	winak		; Fenster 2 aktivieren
	CALL	PV1
	DB	OSTR
	DB	CLS
;	DB	CR,LF
	DB	'* Vinculum-USB *',0
	CALL	PV1
	DB	MENU		; Menue anzeigen
	RET

; Terminalfenster l|schen:
 
	DW	PROLOG
	DB	'CLS'
	DB	1
	LD	A,1
	CALL	PV1		; Fenster 1
	DB	WINAK
	LD	A,0CH		; BS l|schen
	CALL	PV1
	DB	CRT
	LD	A,2		; Fenster 2
	CALL	PV1
	DB	WINAK
	RET
 
; Kommando zu VDIP1 senden:
 
	DW	PROLOG
	DB	'USB'
IF CAOS44
	DB	1FH	; neu: Textargument aus Kommandozeile
ELSE
	DB	1	; alt: Kommando per Eingabe abfragen
	CALL	PV1
	DB	OSTR
	DB	'Kommando:',0
	CALL	PV1
	DB	INLIN
	LD	HL,9
	ADD	HL,DE
	EX	DE,HL
ENDIF
USB1:	LD	A,(DE)
	OR	A
	JR	Z,USB2		; Ende-0
	INC	DE
	CALL	PUT		; >> USB
	JR	USB1
	;
USB2:	LD	A,CR		; abschliessendes CR
	CALL	PUT
	RET
 
; EXIT zu CAOS:
 
	DW	PROLOG
	DB	'QUIT'
	DB	1
EXIT1:	LD	A,0		; Fenster 0
	CALL	PV1
	DB	WINAK		; anw{hlen
	LD	HL,1400h
	ld	(CURSO),HL	; Position zwischen Fenster 1+2
	LD	A,'%'
	LD	(PROMPT),A
	LD	A,7FH		; CAOS-
	LD	(IX+9),A	; Prologbyte
	LD	A,3		; Interrupt AUS
	OUT	(PIOBS),A
EXIT2:	LD	HL,(SLOT)
	LD	D,H		; urspruenglicher Zustand
	LD	A,2		; Modul "schalten"
	CALL	PV1
	DB	MODU
	RET
 
; Datei laden:
 
	DW	7f7fh
	DB	'ULOAD',1
	SET	0,(IX+7)	; CAOS-Modus (LOAD)
	call	minit		; Modul initialisieren
	ret	c		; nicht gefunden
	call	sync		; mit Vinculum synchronisieren
	jr	c,exit2		; TimeOut
	CALL	LOAD		; Datei laden
	push	af
	CALL	PV1
	DB	CRLF		; neue Zeile
	pop	af
	JR	C,EXIT2		; Fehler
	LD	A,(CASS+10H)
	CP	3
	JR	C,EXIT2		; kein Autostart
	LD	A,(ARGN)
	CP	2
	JR	NC,EXIT2	; Start unterdruecken!
	LD	HL,(ARG3)
	PUSH	HL		; Startadrasse aufrufen
	jr	exit2		; vorher Modul aus!
	;
	DW	PROLOG
	DB	'LOAD',1
	CALL	LOAD		; Datei laden
	JR	C,LOA8		; Fehler
	LD	A,(CASS+10H)
	CP	3
	JR	C,LOA8		; kein Autostart
	LD	A,(ARGN)
	CP	2
	JR	NC,LOA8		; Start unterdruecken!
	CALL	SAV8
	LD	HL,(ARG3)
	PUSH	HL		; Startadrasse aufrufen
	jp	exit1		; vorher Modul aus!

LOA8:	JP	SAV8		; EI usw...
;
; Datei laden
;
; PA:	CY=1	Fehler
;
LOAD:	CALL	GETKCC		; Dateiname eingeben
IF CAOS44
	RET	C		; BRK (ab CAOS 4.3)
ENDIF
	LD	A,3
	OUT	(PIOBS),A	; Interrupt aus
	LD	A,SCS		; Short CMD
	CALL	PUT
	CALL	EXEC
	RET	C		; Error
	LD	A,IPH		; HEX- bzw. BIN-Modus
	CALL	PUT
	CALL	EXEC
	RET	C		; Error
	LD	A,OPR		; Open/read
	CALL	OPEN
	CALL	EXEC
	RET	C		; Error

; Vorblock lesen...

	LD	HL,CASS		; Ziel=Kassettenpuffer
	LD	B,128
	CALL	READ		; Vorblock lesen
	RET	C		; Error
	LD	A,(CASS+10H)
	SUB	2
	CP	9
	JR	C,LOA1
	CALL	PV1
	DB	OSTR
	DB	' Keine MC-Datei!',0
	SCF			; Fehlerflag setzen
	RET
	;
LOA1:	LD	HL,(CASS+11H)	; AADR
	LD	DE,(CASS+13H)	; EADR
	LD	BC,(CASS+15H)	; SADR
	PUSH	BC
	LD	A,(ARGN)
	AND	A		; Ladeoffset?
	JR	Z,LOA2		; nein
	LD	BC,(ARG1)	; Offset
	ADD	HL,BC
	EX	DE,HL		; AADR, EADR
	ADD	HL,BC		; umrechnen
	EX	DE,HL
	EX	(SP),HL
	ADD	HL,BC		; SADR umrechn.
	EX	(SP),HL
LOA2:	ld	a,19h		; Zeilenanfang
	call	pv1
	db	OCHR
	CALL	PV1
	DB	HLDE		; AADR EADR anzeigen
	LD	A,(CASS+10H)
	CP	3		; Autostart?
	JR	C,LOA3		; nein
	EX	(SP),HL
	CALL	PV1
	DB	HLHX		; SADR anzeigen
	EX	(SP),HL
LOA3:	POP	BC
	LD	(ARG1),HL	; AADR merken
	LD	(ARG2),DE	; EADR ...
	LD	(ARG3),BC	; SADR ...
	call	pv1
	db	crlf		; neue Zeile fuer Blocknummern

; Daten laden...

LOA5:	LD	DE,(ARG1)	; akt. Adresse
	LD	HL,(ARG2)	; Endadresse
	AND	A
	SBC	HL,DE
	JP	Z,CLOSE		; fertig!
	LD	BC,128
	SBC	HL,BC
	JR	NC,LOA6		; mehr als 128 Byte
	ADD	HL,BC		; Rest
	LD	C,L
LOA6:	LD	B,C		; Anzahl
	EX	DE,HL		; Ladeadresse
	CALL	READ
	RET	C		; Error
	CALL	BLNR		; Blocknummer anzeigen
	LD	(ARG1),HL
	JR	LOA5

; Datei speichern:
 
	DW	7f7fh
	DB	'USAVE'
IF CAOS44
	DB	5
ELSE
	DB	1
ENDIF
	SET	0,(IX+7)	; CAOS-Modus (LOAD)
	call	minit		; Modul initialisieren
	ret	c		; nicht gefunden
	call	sync		; mit Vinculum synchronisieren
	ret	c		; TimeOut
	JR	SAVE
	;
	DW	PROLOG
	DB	'SAVE'
IF CAOS44
	DB	5
ELSE
	DB	1
ENDIF
SAVE:	CALL	GETKCC		; Dateiname eingeben
IF CAOS44
	RET	C		; BRK (ab CAOS 4.3)
ENDIF
BSAVE:	LD	A,3
	OUT	(PIOBS),A	; Interrupt aus
	LD	A,SCS		; Short CMD
	CALL	PUT
	CALL	EXEC
	JR	C,SAV8		; Error
	LD	A,IPH		; HEX- bzw. BIN-Modus
	CALL	PUT
	CALL	EXEC
	JR	C,SAV8		; Error

; Vorblock erzeugen...
 
	LD	DE,CASS+128
	XOR	A
SAV1:	DEC	E		; Kassettenpuffer
	LD	(DE),A		; loeschen
	JR	NZ,SAV1
	LD	HL,NAME		; Dateiname
	LD	BC,8+3		; Name + Typ
	LDIR			; in Vorblock kopieren
	LD	HL,ARGN		; Adresse in Vorblock kopieren
	LD	A,(HL)		; Anzahl der Argumente
	ADD	A		; *2
	INC	A		; +1
	LD	C,A
	LD	E,10H
	LDIR			; Argumente

	CALL	UTEST		; Test ob Datei bereits vorhanden ist
	JR	C,SAV8		; Abbruch oder Fehler
	LD	A,OPW		; Open/write
	CALL	OPEN		; Datei zum Schreiben oeffnen
	CALL	EXEC
	JR	C,SAV8		; Error
	LD	HL,CASS
	CALL	WRITE		; Vorblock schreiben
	JR	C,SAV8		; Error
	CALL	BLNR		; Blocknummer anzeigen
 
; Daten schreiben...
 
	LD	HL,(ARG1)	; Anfangsadresse
SAV6:	CALL	WRITE		; Datenblock schreiben
	JR	C,SAV8		; Error
	CALL	BLNR		; Blocknummer anzeigen
	PUSH	HL
	LD	DE,(ARG2)	; Endadresse
	AND	A
	SBC	HL,DE		; fertig?
	POP	HL
	JR	C,SAV6		; weiter
 
	CALL	CLOSE
SAV8:	LD	A,ECS		; Extend. CMD
	CALL	PUT
	LD	A,CR
	CALL	PUT
	BIT	0,(IX+7)	; Vinculum-Modus?
	jr	nz,sav9		; nein
	LD	A,83H		; Interrupt EIN
	OUT	(PIOBS),A
sav9:	CALL	PV1
	DB	CRLF
	RET

; Verzeichnis einlesen, sortieren und anzeigen

	DW	PROLOG
	DB	'DIR'		; Verzeichnisanzeige
IF CAOS44
	DB	1FH	; neu: Textargument aus Kommandozeile
	EX	DE,HL		; Maske in HL
ELSE
	DB	1	; alt: Maske per Eingabe abfragen
	CALL	PV1
	DB	OSTR
	DB	'Maske:',0
	CALL	PV1
	DB	INLIN
	LD	HL,6
	ADD	HL,DE
ENDIF
	CALL	getmsk		; Maske aufbereiten und nach NAME kopieren

	ld	hl,4000h	; Test, ob RAM4 vorhanden ist
	ld	(hl),a
	inc	(hl)
	inc	a
	cp	(hl)
	jr	nz,ram4
	add	hl,hl		; HL=8000h
RAM4:	ld	(TPAEND),hl

	LD	A,3
	OUT	(PIOBS),A	; Interrupt aus
	LD	A,SCS		; Short CMD
	CALL	PUT
	CALL	EXEC
	RET	C		; Error
	LD	A,IPH		; HEX- bzw. BIN-Modus
	CALL	PUT
	CALL	EXEC
	RET	C		; Error

; DIR-Kommando ausfuehren:

	ld	a,dir		; DIR
	call	put
	ld	a,cr		; ohne Parameter
	call	put

	ld	hl,memry	; Directory hier ablegen
	ld	(pointer),hl	; Zeiger setzen
	ld	hl,0
	ld	(count),hl	; Zaehler zuruecksetzen
rd0:	ld	hl,data		; Datenpuffer fuer eine Zeile
	ld	b,30		; max. Puffergroesse
rd1:	call	getw		; Zeichen holen
	jp	c,SAV8		; Fehler
	ld	(hl),a		; ablegen
	inc	hl
	cp	cr
	jr	z,rd2		; CR erkannt
	djnz	rd1		; weiter bis Puffer voll ist
rd2:	ld	hl,data
	ld	a,(hl)
	cp	'>'
	jp	z,disp		; Prompt erkannt -> Anzeige Verzeichnis
	cp	cr
	jr	z,rd0		; Leerzeile -> ignorieren

; Eintrag in Puffer kopieren:

	ld	hl,(pointer)	; Verzeichnispuffer
	ld	de,data		; gelesene Zeile
	ld	a,(de)
	ld	b,12		; max. Laenge 8.3
mov1:	ld	a,(de)
	ld	c,a		; Zeichen merken
	cp	cr		; fertig?
	jr	nz,mov5
	ld	a,b
	cp	4		; Position von Trennzeichen?
	ld	a,' '
	jr	nz,mov4		; nein, Rest sind ein Leerzeichen
	ld	a,'.'
	jr	mov4		; Dateien ohne Typ mit Punkt ergaenzen!
mov5:	inc	de
	ld	a,c
	cp	' '		; Trennzeichen Verzeichnisname/DIR ?
	jr	z,mov2
	cp	'.'		; Trennzeichen Dateiname/Typ?
	jr	nz,mov4
	ld	a,(data)
	cp	'.'		; Unterverzeichnis?
	jr	z,mov3
mov2:	ld	a,b		; noch Zeichen
	cp	5		; kleiner als 5?
	jr	c,mov3		; ja, wir sind richtig
	ld	a,' '
	ld	(hl),a		; Leerzeichen einfuegen
	inc	hl		; ansonsten ein Zeichen weiter gehen
	dec	b		; und mitzaehlen
	jr	mov2
mov3:	ld	a,c
mov4:	ld	(hl),a		; Zeichen ablegen
	inc	hl
	djnz	mov1		; wiederholen fuer alle 12 Zeichen

; Test, ob Eintrag der Maske entspricht:

	ld	hl,(pointer)
	ld	a,(hl)		; erstes Zeichen
	cp	'.'		; Unterverzeichnis?
	jr	z,copy		; ja, nicht rausfiltern!
	ld	de,NAME
	ld	a,(de)
	cp	' '		; Maske angegeben?
	jr	z,copy		; nein, alles anzeigen!
	ld	b,8		; Dateiname pruefen
cop1:	ld	a,(de)
	cp	'?'		; Wildcard?
	jr	z,cop2
	cp	(hl)
	jr	nz,rd0		; entspricht nicht der Maske!
cop2:	inc	hl
	inc	de
	djnz	cop1
	inc	hl		; Trennzeichen uebergehen
	ld	b,3		; Dateityp pruefen
cop3:	ld	a,(de)
	cp	'?'		; Wildcard?
	jr	z,cop4
	cp	(hl)
	jp	nz,rd0		; entspricht nicht der Maske!
cop4:	inc	hl
	inc	de
	djnz	cop3

; Eintrag uebernehmen:

copy:	ld	hl,(pointer)
	ld	bc,12
	add	hl,bc		; Zeiger weitersetzen
	ld	(pointer),hl	; neuer Zeiger jetzt gueltig
	ex	de,hl
	ld	hl,(tpaend)
	sbc	hl,de
	jp	c,MEMERR	; Speicherueberlauf!
	ld	hl,(count)
	inc	hl		; Eintraege zaehlen
	ld	(count),hl
	jp	rd0		; naechsten einlesen

; Anzeige sortiertes Directory (in 3 Spalten):

disp:	ld	a,' '
	call	pv1
	db	crt
	ld	hl,(count)
	call	HLDEZ		; Anzahl dezimal anzeigen
	call	pv1
	DB	ostr
	db	' Dateien/Verzeichnisse.',0
	LD	A,1
	CALL	PV1		; Terminal-Fenster 1 anwaehlen
	DB	WINAK
	LD	A,0CH		; BS loeschen
	CALL	PV1
	DB	CRT
	ld	hl,(pointer)
	ld	(table),hl	; Beginn Zeigertabelle nach Eintraegen
	ld	hl,(count)
	ld	a,h
	or	l
	jp	z,disp9		; keine Eintraege vorhanden!
	call	sort		; Verzeichnis sortieren
	jr	c,memerr	; Speicher reicht nicht (fuer Zeigertabelle)
	ld	hl,(table)	; Zeigertabelle
	ld	de,(count)	; Anzahl Eintraege
disp2:	ld	a,16		; 16 Zeilen pro Seite
disp3:	ld	(page),a
disp4:	ld	c,3		; 3 Spalten pro Zeile
disp5:	ld	a,d
	or	e
	jr	z,disp9		; alle Dateien sind angezeigt!
	push	hl
	ld	a,(hl)
	inc	hl
	ld	h,(hl)
	ld	l,a		; Zeiger lesen
	ld	b,12
disp6:	ld	a,(hl)
	inc	hl
	call	crtx		; Dateiname anzeigen
	djnz	disp6
	pop	hl
	inc	hl
	inc	hl		; naechster Zeiger
	dec	de		; Anzahl -1
	dec	c
	jr	z,disp7		; neue Zeile
	ld	a,' '
	call	crtx		; Leerzeichen zwischen den Spalten
	jr	disp5		; weiter in dieser Zeile
	;
disp7:	ld	a,(page)
	dec	a		; letzte Zeile erreicht?
	jr	nz,disp3	; nein, weiter anzeigen
	;
disp8:	call	pv1
	db	kbd		; Tastatureingabe abwarten
	cp	3
	jr	z,dispx		; BRK -> Abbruch
	cp	' '
	jr	z,disp4		; SPC -> eine weitere Zeile
	cp	cr
	jr	nz,disp8
	jr	disp2		; CR = neue Seite

disp9:	call	pv1
	db	crlf
dispx:	LD	A,2		; Fenster 2
	CALL	PV1
	DB	WINAK
	jp	sav8		; ECS, EI ...

MEMERR:	CALL	PV1
	DB	OSTR
	DB	'Speicherende erreicht!',cr,lf,0
	jp	sav8

; eingelesenes Verzeichnis alphabetisch sortieren,
; Verzeichnisse dabei zuerst anordnen
; PA:	CY=1	Speicherueberlauf

; 1. Zeigertabelle erzeugen:

sort:	ld	hl,(table)	; Beginn der Zeigertabelle
	ld	de,(count)
	add	hl,de
	add	hl,de		; + 2 Byte je Eintrag
	ex	de,hl
	ld	hl,(tpaend)	; TPA-Ende
	sbc	hl,de
	ret	c		; das reicht nicht!

	ld	hl,(count)	; Anzahl Elemente
	push	hl
	ld	de,memry	; Tabelle der Namen
	ld	hl,(table)	; Zeigertabelle
	ld	bc,12		; Laenge eines Eintrages
BLORD:	ld	(hl),e
	inc	hl
	ld	(hl),d
	inc	hl
	ex	de,hl
	add	hl,bc		; naechstes Element
	ex	de,hl
	ex	(sp),hl
	dec	hl		; noch ein Element?
	ld	a,h
	or	l
	ex	(sp),hl
	jr	nz,BLORD
	pop	hl
;
; 2. Sortieren ueber Zeiger-Methode
; (Shell-SORT von "Software Tools", Kernigan/Plaugher, (c) 1976)
;
	ld	hl,(count)	; Anzahl Elemente
	ld	(GAP),hl	; GAP fuer ersten Vergleich initialisieren
SORT0:	ld	hl,(GAP)
	srl	h
	rr	l		; GAP:=GAP/2
	ld	a,l
	or	h
	ret	z		; fertig, wenn GAP/2=0
	bit	0,l		; GAP ungeradzahlig?
	jr	nz,SORT1
	dec	hl		; GAP ungerade machen
SORT1:	ld	(GAP),hl
SORT2:	ld	(J),hl		; J:=GAP
;
; For (J=GAP+1; J<=N; J=J+1)
;
RIGHT:	ld	hl,(J)
	inc	hl		; J:=J+1
	ld	(J),hl
	ex	de,hl		; DE=(J)
	ld	hl,(count)
	or	a
	sbc	hl,de		; Anzahl-J
	jr	c,SORT0		; neu starten, wenn I > N
;
; For (I=J-GAP; J>0; I=J-GAP)
;
LEFT:	ld	hl,(GAP)
	ex	de,hl
	sbc	hl,de		; I:=J-GAP
	jr	c,RIGHT		; wenn J < 0
	jr	z,RIGHT		; wenn J = 0
;
; Set JG=I+GAP
;
	ex	de,hl
	add	hl,de		; JG:=I+GAP
;
; If (I) <= (JG) then Break else Exchange
;
	push	hl
	push	de
	call	COMPAR		; Vergleich
	pop	de
	pop	hl
	jr	z,RIGHT		; Dateiname gleich (sollte nicht vorkommen!)
	jr	nc,RIGHT	; richtig sortiert
	push	de
	call	SWAP		; Austausch
	pop	de
	jr	LEFT		; zurueck furr weitere Tests
;
; Zeiger zweier Elemente austauschen
; PE:	HL,DE	Nummer der Elemente
; VR:	AF,BC,DE,HL
;
SWAP:	ld	bc,(table)	; Adresstabelle
	dec	bc
	dec	bc
	add	hl,hl		; *2
	add	hl,bc		; 1. Element
	ex	de,hl
	add	hl,hl		; *2
	add	hl,bc		; 2. Element
	call	SWAP1		; erst aufrufen, dann reinlaufen
SWAP1:	ld	c,(hl)
	ld	a,(de)
	ex	de,hl
	ld	(hl),c
	ld	(de),a
	inc	hl
	inc	de
	RET
;
; Zwei Eintraege ueber deren Zeiger vergleichen
; PE:	HL,DE	Nummer der Elemente
; PA:	CY=1	(HL) > (DE)
;	Z=1	Namen gleich, dann
;		CY'=1	(HL) > (DE) bei Vergleich der EXT-Nummer
; VR:	AF,BC,DE,HL
;
COMPAR:	ld	bc,(table)	; Adresstabelle
	dec	bc
	dec	bc
	add	hl,hl		; *2
	add	hl,bc		; 1. Element
	ex	de,hl
	add	hl,hl		; *2
	add	hl,bc		; 2. Element
	ex	de,hl
	ld	c,(hl)
	inc	hl
	ld	b,(hl)		; BC ist Adresse des ersten Elements
	ex	de,hl
	ld	e,c
	ld	d,b		; DE ist Adresse des ersten Elements
	ld	c,(hl)
	inc	hl
	ld	h,(hl)
	ld	l,c		; HL ist Adresse des zweiten Elements
	push	hl
	push	de
	ld	bc,8		; Trennzeichen nach Dateiname
	add	hl,bc
	ex	de,hl
	add	hl,bc
	ex	de,hl
	ld	a,(de)
	cp	(hl)		; DIR oder Datei?
	pop	de
	pop	hl
	ret	nz		; unterschiedlich
	ld	b,8		; Vergleich Dateiname
	call	CMPLE
	ret	nz		; unterschiedlich
	inc	de
	inc	hl		; Trennzeichen uebergehen
	ld	b,3
CMPLE:	ld	a,(de)
	cp	(hl)		; Vergleich
	inc	de
	inc	hl
	ret	nz		; Ende, sobald ungleich
	djnz	CMPLE
	ret

; ==============================

; Datenblock lesen (128 Byte)
;
;PE:	HL	Zieladresse
;	B	Anzahl Datenbytes
;
;PA:	HL=HL+B	Daten im Puffer
;	CY=1	Fehler
 
READ:	LD	A,RDF		; Read from File
	CALL	PUT
	LD	A,' '
	CALL	PUT
	XOR	A
	CALL	PUT
	XOR	A
	CALL	PUT
	XOR	A
	CALL	PUT
	LD	A,B		; Anzahl
	CALL	PUT
	LD	A,CR
	CALL	PUT
REA1:	PUSH	BC
	CALL	GETW		; Zeichen holen
	POP	BC
	RET	C		; Timeout
	LD	(HL),A
	INC	HL
	DJNZ	REA1
	JR	REA2
;
; Datenblock schreiben (128 Byte)
;
; PE:	HL	Adresse
;
; PA:	HL	HL+80H
;	CY=1	Fehler
;
; VR:	HL,AF,B

WRITE:	LD	A,WRF		; Write to File
	CALL	PUT
	LD	A,' '
	CALL	PUT
	XOR	A
	CALL	PUT
	XOR	A
	CALL	PUT
	XOR	A
	CALL	PUT
	LD	B,128
	LD	A,B
	CALL	PUT
	LD	A,CR
	CALL	PUT
WRI1:	LD	A,(HL)
	INC	HL
	CALL	PUT
	DJNZ	WRI1
REA2:	inc	(ix+2)		; naechster Block
	JP	EX1		; OK testen
;
; Datei oeffnen
;
; PE:	A	Kommando (OPR/OPW)
;	(NAME)	Dateiname
;	(IX+2)	Blocknummer = 0
;
; VR:	AF,HL,BC,DE
;
OPEN:	LD	(IX+2),0	; Vorblock = Blocknummer 0
	LD	C,A		; Kommando
	CALL	PUT
	LD	A,' '
	CALL	PUT
	call	outnam		; Dateiname
	LD	A,C
	CP	OPW		; Write?
	RET	NZ
	LD	A,' '		; Leerzeichen
	CALL	PUT
	CALL	DCONV		; Datum holen
	LD	HL,DATUM
	LD	B,4		; 32 Bit
OPE3:	LD	A,(HL)
	INC	HL
	CALL	PUT
	DJNZ	OPE3
	RET
;
; Blocknummer anzeigen und zurueck zu Zeilenanfang
;
BLNR:	ld	a,(ix+2)
	call	pv1
	db	ahex		; Blocknummer anzeigen
	call	pv1
	DB	ostr
	db	'> ',19h,0	; Cursor an Zeilenanfang
	ret
;
; Dateiname eingeben und speichern,
; falls nicht angegeben den Standard-Dateityp ergaenzen
;
; PE:	HL	Zeiger auf Standard-Dateityp
; PA:	CY=1	BRK (ab CAOS 4.3)
;	NAME	Dateiname 8.3
;
KCC:	DB	'KCC'		; Standard-Typ, wenn nichts angegeben
GETKCC:	LD	HL,KCC
GETNAM:	CALL	PV1
	DB	OSTR
	DB	'Name :',0
	CALL	PV1
	DB	INLIN
IF CAOS44
	RET	C		; BRK (ab CAOS 4.3)
ENDIF
	PUSH	HL		; Standard-Dateityp merken
	LD	HL,6
	ADD	HL,DE		; Beginn der Eingabekette
	ld	de,name+11
	ld	a,' '
getn1:	dec	e
	ld	(de),a		; mit Leerzeichen vorbelegen
	jr	nz,getn1
	LD	B,12		; 8.3
getn2:	ld	a,(hl)
	inc	hl
	cp	21h		; Ende?
	jr	c,getn5		; ja
	cp	'.'		; Trennzeichen?
	jr	nz,getn3	; nein
	ld	e,8		; weiter mit Dateityp
	jr	getn4
getn3:	ld	(de),a		; Zeichen uebernehmen
	inc	de
getn4:	djnz	getn2		; weitere Zeichen
getn5:	pop	hl		; Standard-Dateityp
	ld	a,e
	cp	9		; Dateityp
	ret	nc		; ist schon bearbeitet
	ld	e,8
	ldi			; Standard-Dateityp kopieren
	ldi
	ldi
	and	a		; CY=0 - OK
	ret
;
; Dateiname senden 8.3
;
outnam:	ld	hl,name
	ld	b,8		; Dateiname
	call	outn2
	ld	a,'.'		; Trennzeichen
	call	put
	ld	b,3		; Dateityp
outn2:	ld	a,(hl)
	inc	hl
	cp	21h
	call	nc,put
	djnz	outn2
	ret
;
; Datum von DEP 3.0 holen/konvertieren
;
; PA:	(DATUM)	Bin{rwerte DOS-Format
;	CY=1	kein Datum von D004 geholt
;
; VR:	BC,HL,AF,DE
;
DCONV:	LD	BC,0FC80H
	IN	A,(C)
	CP	0A7H
	SCF
	RET	NZ		; kein D004
	LD	BC,0B3F3H
	IN	A,(C)
	CP	5
	SCF
	RET	NZ		; keine CAOS-BA
	LD	BC,83F1H
	IN	A,(C)
	CP	30H
	RET	C		; < DEP 3.0
	INC	B
	IN	A,(C)		; Jahr
	INC	B
	IN	D,(C)		; Tag
	INC	B
	IN	E,(C)		; Tag
	PUSH	DE
	POP	BC
	CALL	CONV		; Datum konvertieren
	INC	HL
	LD	BC,87F1H
	IN	A,(C)		; Stunde
	CALL	BCD
	LD	(HL),A
	INC	B
	IN	A,(C)		; Minute
	CALL	BCD
	RLA
	RLA
	RLA
	RL	(HL)
	RLA
	RL	(HL)
	RLA
	RL	(HL)
	INC	HL
	LD	(HL),A
	INC	B
	IN	A,(C)		; Sekunde
	CALL	BCD
	RRA
	OR	(HL)		; CY=0 -> OK
	LD	(HL),A
	RET
 ;
; PE:	A	Jahr
;	B	Monat
;	C	Tag
; PA:	DATUM	konvertiert in DOS-Format
;
CONV:	CALL	BCD
	SUB	80		; 1980=0
	JR	NC,DC1		; 1980-1999
	ADD	A,100		; 2000-2079
DC1:	LD	HL,DATUM
	LD	(HL),A
	LD	A,B		; Monat
	CALL	BCD
	RLA
	RLA
	RLA
	RLA
	RLA
	RL	(HL)
	INC	HL
	LD	(HL),A
	LD	A,C		; Tag
	CALL	BCD
	OR	(HL)
	LD	(HL),A
	RET

; BCD -> bin{r konvertieren
;
;PE:	A	BCD-Zahl
;PA:	A	Bin{rzahl
;	CY=0
;VR:	AF,E
 
BCD:	PUSH	AF
	RRA
	RRA
	RRA
	RRA
	AND	0FH	; Zehner
	LD	E,A
	INC	E
	LD	A,-10
BCD1:	ADD	A,10
	DEC	E
	JR	NZ,BCD1
	LD	E,A
	POP	AF
	AND	0FH	; Einer
	ADD	E
	RET
 
; Spezial-CRT-Routine (CR -> CR+LF)
 
CRTX:	CALL	PV1
	DB	CRT	;Zeichen anzeig.
	CP	CR	;falls CR,
	RET	NZ
	LD	A,LF	;LF anh{ngen
	CALL	PV1
	DB	CRT
	RET
 
;------ Eingabe ------
;
;PA:	A	Datenbyte
;	CY=1	keine Daten verf}gbar
;VR:	AF,AF'
 
GET:	IN	A,(PIOB)
	RRCA
	RET	C		; keine Daten vorhanden
	LD	A,40H		; RD# aktiv
	OUT	(PIOB),A
	IN	A,(PIOA)	; Daten holen
	EX	AF,AF'
	LD	A,44H		; RD# inaktiv
	OUT	(PIOB),A
	EX	AF,AF'
	RET

;------ Eingabe mit Wait und TimeOut ------
;
;PA:	A	Datenbyte
;	CY=0	OK
;	CY=1	TimeOut
;VR:	AF,AF',BC

GETW:	ld	bc,0		; Zeitkonstante fuer TimeOut
getw1:	call	get		; Daten holen
	ret	nc		; OK
	dec	bc
	ld	a,b
	or	c
	jr	nz,getw1	; Zeit abwarten...
Timout:	call	pv1
	db	ostr
	db	'TimeOut-Error',cr,lf,0
	scf
	ret

;------ Ausgabe ------
;
;PE:	A	Datenbyte
;VR:	AF

PUT:	OUT	(PIOA),A	; Daten
WAIT:	IN	A,(PIOB)
	RRCA
	RRCA
	JR	C,WAIT		; nicht bereit, warten!
	LD	A,4CH
	OUT	(PIOB),A	; WR aktiv
	LD	A,44H
	OUT	(PIOB),A	; WR inaktiv
	RET 

; ----- Synchronisieren mit Vinculum ----
;
; PA:	CY=0 OK		CY=1 Fehler
;
; VR:	AF, AF', BC
;
sync:	ld	bc,0		; fuer Zeitschleifen
sync1:	CALL	GET		; Daten holen
	jr	c,sync2		; keine Daten vorhanden
	bit	0,(ix+7)
	call	z,crtx		; im Vinculum-Modus anzeigen
	jr	sync1		; bis alles abgeholt ist
sync2:	djnz	sync1		; 256mal kontrollieren...
sync3:	in	a,(PIOB)	; Status abfragen
	rrca
	rrca
	jr	sync4		; bereit, Daten zu schreiben
	dec	c
	jr	nz,sync1	; noch 256mal versuchen
	jp	Timout
sync4:	djnz	sync3		; 256mal kontrollieren...
	in	a,(PIOB)
	and	3		; nur Bit 0 und 1 auswerten
	cp	1		; alle Daten abgeholt und bereit zum schreiben?
	jp	nz,sync1	; nein !
; 1. cr
	ld	a,cr
	call	put		; <cr> muss irgendwie <cr> zurueckgeben
sync5:	call	getw
	ret	c		; TimeOut
	cp	cr
	jr	nz,sync5	; wiederholen bis <cr> kommt
; 2. E,cr
	ld	a,'E'		; E <cr> muss E <cr> zurueckgeben
	call	put
	ld	a,cr
	call	put
sync6:	call	getw		; Daten holen
	ret	c		; TimeOut
sync7:	cp	'E'
	jr	nz,sync6	; wiederholen bis "E" kommt
	call	getw
	ret	c		; TimeOut
	cp	cr
	jr	nz,sync7	; wiederholen bis "E",cr kommt
; 3. e,cr
	ld	a,'e'		; e <cr> muss e <cr> zurueckgeben
	call	put
	ld	a,cr
	call	put
sync8:	call	getw		; Daten abholen
	ret	c		; TimeOut
sync9:	cp	'e'
	jr	nz,sync8	; wiederholen bis "e" kommt
	call	getw
	ret	c		; TimeOut
	cp	cr
	jr	nz,sync9	; wiederholen bis "e",cr kommt
	ret
;
; Test ob vorhandene Datei ueberschrieben werden soll:
;
; PA:	CY=1	Datei vorhanden - Abbruch, oder unerwartete Antwort!
;	CY=0	Datei nicht vorhanden oder erfolgreich geloescht
;
UTEST:	LD	A,OPR		; Open/read
	CALL	OPEN		; Versuch, Datei zum Lesen zu oeffnen
	LD	A,CR		; Kommandoabschluss
	CALL	PUT
	CALL	GETW		; Ergebnis holen
	RET	C
	CP	'>'		; Prompt?
	JR	NZ,UT1		; nein, dann muss es ein Fehlercode sein
	CALL	GETW		; naechstes Zeichen
	RET	C
	CP	CR
	jr	z,UT3		; kein Fehler beim Oeffnen = Datei vorhanden
	SCF
	RET			; unerwartete Antwort
	;
UT1:	ld	d,a		; erstes Zeichen merken
	CALL	GETW		; zweites Zeichen holen
	RET	C		; Timeout
	ld	e,a		; zweites Zeichen merken
	CALL	GETW		; drittes Zeichen holen
	RET	C		; Timeout
	cp	cr
	SCF
	RET	nz		; unerwartete Antwort
	ld	hl,'FI'
	AND	A
	sbc	hl,de		; Datei nicht vorhanden (Firmware 3.64)
	ret	z		; FI-Error erkannt -> OK
	ld	hl,'CF'
	and	a
	sbc	hl,de		; Datei nicht vorhanden (Firmware 3.66)
	ret	z		; CF-Error erkannt -> OK
	ld	a,d
	CALL	CRTX
	ld	a,e
	call	CRTX		; Errorcode anzeigen
	JP	ERRX		; (kann eigentlich nur FO = "File open" sein)
	;
UT3:	CALL	CLOSE		; geoeffnete Datei schliessen
	ret	c		; Fehler
	CALL	PV1
	DB	OSTR
	db	'Datei ueberschreiben (j/n)? ',0
ask:	call	pv1
	db	KBD
	and	5fh		; upcase
	cp	'N'
	jr	z,TOK		; nein
	cp	'J'
	jr	nz,ask
tok:	call	PV1
	DB	CRT		; Zeichen J oder N anzeigen
	push	af
	CALL	PV1
	DB	CRLF		; neue Zeile
	pop	af
	cp	'J'
	SCF			; "N"icht ueberschreiben = Abbruch
	ret	NZ
;	JR	DELET		; Datei loeschen
;
; Datei loeschen:
;
;PA	CY=1	Error
;
DELET:	LD	A,DLF		; Delete File
	DB	21H		; LD HL,nn
;
; Datei schlie~en:
;
;PA	CY=1	Error
;
CLOSE:	LD	A,CLF		; Close File
	CALL	PUT
	LD	A,' '
	CALL	PUT
	call	outnam		; Dateiname
;	JR	EXEC
;
; Kommando ausfuehren:
;
; PA:	CY=1	Fehler oder Timeout
;
; VR:	AF, AF', BC
;
EXEC:	LD	A,CR	; Kommando
	CALL	PUT	; Abschluss
EX1:	CALL	GETW
	JR	C,ERR3	; Timeout
	CP	'>'
	JR	NZ,ERR
	CALL	GETW
	JR	C,ERR3	; Timeout
	CP	CR
	RET	Z	; OK
ERR:	CALL	CRTX	; Errorcode
	CALL	GETW
	JR	C,ERR3	; Timeout
	CP	CR	; Ende?
	JR	NZ,ERR
ERRX:	LD	A,'-'
	CALL	CRTX
ERR3:	CALL	PV1
	DB	ERRM
	SCF		; Fehler!
	RET
;
; HL dezimal anzeigen ohne fuehrende Nullen
; PE:	HL=Zahl
; VR:	-
;
HLDEZ:	PUSH	HL
	PUSH	DE
	LD	DE,0
HLDZ1:	PUSH	BC
	PUSH	AF
	LD	BC,10000	; Zehntausender
	CALL	DEZ
	LD	BC,1000		; Tausender
	CALL	DEZ
	LD	BC,100
	CALL	DEZ		; Hunderter
	LD	BC,10
	CALL	DEZ		; Zehner
	LD	A,L
	ADD	A,'0'
	CALL	CRTX		; Einer
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	RET
	;
DEZ:	LD	A,'0'
DEZ1:	AND	A
	SBC	HL,BC
	JR	C,DEZ2		; keine weiteren Teile
	INC	A
	JR	DEZ1
	;
DEZ2:	ADD	HL,BC
	CP	'0'
	JR	NZ,DEZ3		; Ziffer ungleich '0'
	INC	D
	DEC	D
	RET	Z		; f}hrende Nullen weglassen
DEZ3:	CALL	CRTX
	INC	D		; Anzeige laeuft
	RET

;
; Maske aus Eingabe erzeugen (entnommen aus ML/NC):
; PE:	HL	Eingabestring
; PA:	HL	Zeiger auf Trennzeichen nach Maske
; VR:	AF,B,DE,HL
;
GETMSK:	LD	A,(HL)		; erstes Zeichen testen
	CP	21h		; Eingabe vorhanden?
	LD	DE,NAME+11
	LD	B,11		; L{nge der Maske
	LD	A,'?'		; *.* vorgeben
	JR	C,NM0
	LD	A,' '		; sonst leere Maske
NM0:	DEC	DE
	LD	(DE),A
	DJNZ	NM0
	RET	C		; keine Eingabe
	LD	B,8		; max. 8 Zeichen testen
NM1:	LD	A,(HL)
	cp	21h
	RET	c		; Ende wenn < 21h
	INC	HL
	CP	'.'
	JR	Z,NM4		; weiter mit Typ
	CP	'*'
	JR	Z,NM2		; Joker f}r Rest
	LD	(DE),A
	INC	DE
	DJNZ	NM1
	JR	NM3		; fertig mit Name
	;
NM2:	LD	A,'?'		; Joker in Dateiname
	LD	(DE),A
	INC	DE
	DJNZ	NM2
NM3:	LD	A,(HL)
	CP	'.'		; Punkt nach Name?
	JR	NZ,NM4
	INC	HL
NM4:	LD	DE,NAME+8	; Dateityp
	LD	B,3		; max. 3 Zeichen testen
NM5:	LD	A,(HL)
	cp	21h
	RET	c		; Ende wenn < 21h
	INC	HL
	CP	'*'
	JR	Z,NM6		; Joker f}r Rest
	LD	(DE),A
	INC	DE
	DJNZ	NM5
	RET
	;
NM6:	LD	A,'?'		; Joker in Dateityp
	LD	(DE),A
	INC	DE
	DJNZ	NM6
	RET

; ----- ISR f}r Terminal (PIO-B) ----
; wird in RAM-0 kopiert und dort abgearbeitet!
; 
ISRC:	PUSH	AF
	EX	AF,AF'
	PUSH	AF
	LD	A,(IX+4)
	PUSH	AF
	AND	7FH		; CAOS-C off
	LD	(IX+4),A
	OUT	(86H),A
ISR0:	CALL	GET
	JR	C,ISR3		; keine Daten
	EX	AF,AF'
	PUSH	HL
	PUSH	DE
	PUSH	BC
	LD	A,(IX+1)
	PUSH	AF
	AND	0FDH		; Pixelebene
	LD	(IX+1),A
	OUT	(84H),A
	LD	A,1		; Terminal-
	CALL	PV1		; Fenster
	DB	WINAK
	EX	AF,AF'		; Datenbyte
	CALL	CRTX		; anzeigen
	LD	A,2
	CALL	PV1		; Men}-Fenster
	DB	WINAK
	POP	AF
	LD	(IX+1),A
	OUT	(84H),A
	POP	BC
	POP	DE
	POP	HL
ISR3:	POP	AF
	LD	(IX+4),A
	OUT	(86H),A
	POP	AF
	EX	AF,AF'
	POP	AF
IRET:	EI
	RETI
ENDISR:

	include	ubasex.inc	; BASIC-Erweiterung
	include udevex.inc	; EDAS-Erweiterung

ENDE:	; Endadresse der  KCC-Datei

	.dephase
	END
