;******************************************************************
;***								***
;***  GRIP-5 source-code XR-Version    				*** 
;***  fuer Microsoft MACRO80-Assembler		  B.Emese	***	
;***  09.01.1988			(C) 1987  conitec	***
;***						  MicroLabor    ***
;******************************************************************
;Jan 1987 V 4.21 Struktur-Ueberarbeitung,Fehlerbeseitigung  BE/JCL
;Feb 1987 V 4.22 Area fill  JCL
;Feb 1987 V 4.22 REPLACE-MODE  JCL
;Feb 1987 V 4.23 PATTERN,SPRAY  JCL
;Feb 1987 V 4.31 256-KB-Ram-PAGE  JCL
;Mar 1987 V 5.11 HD6345 implementiert  JCL
;Mar 1987 V 5.32 Smooth Scroll  JCL
;Mar 1987 V 5.35 Zeilenloeschen smooth  JCL
;Apr 1987 V 5.40 TX Alpha Zeichenposition vertikal pixelweise  JCL
;Apr 1987 V 5.41 ESC ESC 8 ohne Cursor Home  JCL
;May 1987 V 5.42 <EEQ>,<EEJ>,VEKTOR  Fehlerbeseitigung  BE/JCL
;May 1987 V 5.43 Spooler,Zielkanal,Area fill  Fehlerbeseitigung  BE/JCL
;May 1987 V 5.44 Hardcopy Fehlerbeseitigung  JCL
;Jun 1987 V 5.45 Horiz.Line, Trigon-Fill,Stack 128 Worte,TXNULL,EEZ EEz BE
;Aug 1987 V 5.52 Schneller vertikaler Vektor, Blockfill init, kein Flimmern TVI-Farbmodus
;Aug 1987 V 5.53 IBM Originaltastaturcode Konvertierungsprogramm, Serial KB verbessert BE
;Jan 1988 V 5.60 XR-ColorKarte, NEC P6 Hardcopy BE
;Feb 1988 V 5.62 ECB Input Fehler, XRMASK Fehler

	ASEG		;absolute code
	.Z80
	TRUE	EQU	-1
	FALSE	EQU	0
;--------------------------
;conditional Compiling switches

HD6345	EQU	TRUE
RAM256	EQU	TRUE
XR	EQU	TRUE
DEBUG	EQU	FALSE

PITCH	EQU	768	;Pixels/Zeile
BLOCKS	EQU	PITCH/8	;Blocks/Zeile
	IF	HD6345
SCANS	 EQU	288	;Pixels/Spalte
	ELSE
SCANS	 EQU	280	;Pixels/Spalte
	ENDIF
VBLKS	EQU	SCANS/8	;Blocks/Spalte
VBLMAX	EQU	41	;Bei IBM-Monitor oder 7 Pixel/Zeile
;--------------------------
	IF HD6345
VERS1	 EQU	'.5'+0
	ELSE
VERS1	 EQU	'.4'+0
	ENDIF
	IF	XR
VERS2	EQU	'27'+0
	ELSE
VERS2	EQU	'26'+0
	ENDIF

EPAGE	DEFL	0
	INCLUDE	GRIPG1.MAC
	IF	EPAGE EQ 0	;Erste EPROM-PAGE
	 EXT	CHRGNB,ZSZDFB,LDZROM,STGOFB,STGONB,SETZPT,INIRAM,IBLVKT,I15,TKSET
	 EXT	INISTI,INIECB,INIIBM,SETHST,V24EI,V24SI,V24DFA,TBAUDA,RDJMP
	 EXT	IBMKV,HRDLIN,TBWSET,ZSCHKS,JPCHKS,INIVDA,INIRES
	 EXT	SETCOL,SETCDF,BLNKCL
	IF	DEBUG
	 EXT	AOUT,AOUTS,HLOUT
	ENDIF
	 PUBLIC	EXHBF,KCHM,STDTAB,STDESC,STESCH,LSTECH,CXOUT,CXOPL,SINIP1,SINIPL,HBFVA
	 PUBLIC	ZLCX,STDRT,QUOFF,P0P,VKTGEN,POR,CHROR,LOE,LOE1,SCROFA,SCRONB
	 PUBLIC	THPT,BLINK,MELO,SRERR,ZADRN,INIT,WARM,ESEND,INISPR
	 PUBLIC	V24OUT,V24OPL,KBFIN,KBFIPL,KBFOUT,KBFOPL,ECBIP1,ECBIPL,ECBOUT,ECBOPL
	 PUBLIC	TBWTVI,TXWRT,TBWTVC,TXCWRT,TBITVI,TBITVC,FBECLR,FBECLI
	 PUBLIC	INIITL,SL2CLR
	IF	XR
	 EXT	INIXR,XRCOMP,XRKOVB,KOVOL,DKOVOL,XRSELA,RDJXR
	 EXT	XRSPKT,XRBONB,XRGRAU,BLNKOF,SETCDA,ADDA,ADDB,ADDC
	 PUBLIC	XRMAIN
	ENDIF
	ELSE			;Zweite EPROM-PAGE
	 PUBLIC	CHRGNB,ZSZDFB,LDZROM,STGOFB,STGONB,SETZPT,INIRAM,IBLVKT,I15,TKSET
	 PUBLIC	INISTI,INIECB,INIIBM,SETHST,V24EI,V24SI,V24DFA,TBAUDA,RDJMP
	 PUBLIC IBMKV,HRDLIN,TBWSET,ZSCHKS,JPCHKS,INIVDA,INIRES
	 PUBLIC	SETCOL,SETCDF,BLNKCL
	IF	DEBUG
	 PUBLIC	AOUT,AOUTS,HLOUT
	ENDIF
	 EXT	EXHBF,KCHM,STDTAB,STDESC,STESCH,LSTECH,CXOUT,CXOPL,SINIP1,SINIPL,HBFVA
	 EXT	ZLCX,STDRT,QUOFF,P0P,VKTGEN,POR,CHROR,LOE,LOE1,SCROFA,SCRONB
	 EXT	THPT,BLINK,MELO,SRERR,ZADRN,INIT,WARM,ESEND,INISPR
	 EXT	V24OUT,V24OPL,KBFIN,KBFIPL,KBFOUT,KBFOPL,ECBIP1,ECBIPL,ECBOUT,ECBOPL
	 EXT	TBWTVI,TXWRT,TBWTVC,TXCWRT,TBITVI,TBITVC,FBECLR,FBECLI
	 EXT	INIITL,SL2CLR
	IF	XR
	 PUBLIC	INIXR,XRCOMP,XRKOVB,KOVOL,DKOVOL,XRSELA,RDJXR
	 PUBLIC	XRSPKT,XRBONB,XRGRAU,BLNKOF,SETCDA,ADDA,ADDB,ADDC
	 EXT	XRMAIN
	ENDIF
	ENDIF
;--------------------------
ROM	EQU	0000H	;EPROM 27256
RAM	EQU	4000H	;System-Ram I/O PUFFER, Stack
PARAM	EQU	4600H	;System-Ram Parameterfeld

	ORG	RAM
	DS	256
STKH	EQU	$	;Prozessor Stack 128 Worte ca. 25 Ebenen benutzt

ECBIBF:	DS	256	;ECB-INPUT Buffer
ECIEND	EQU	$
KYBBF:	DS	64	;Keyboardbuffer parallel
KYBEND	EQU	$
KBSBF:	DS	64	;Keyboardbuffer seriell
KBSEND	EQU	$
KBIBF:	DS	64	;IBM-Tastatur Puffer
KBIEND	EQU	$
PIXBUF:	DS	64
BRTBUF	EQU	PIXBUF		;Breitzeichenbuffer
CHRBUF	EQU	PIXBUF+32	;Characterbuffer fuer Attributbildung
USRBUF:	DS	256	;Buffer fuer Userprogramm
USREND	EQU	$
SINBF:	DS	256	;Seriell INP Buffer
SIBEND	EQU	$
	IF	XR
BLKMAX	EQU	12	;Anzahl der gleichzeitig m|glichen Blinkfarben
BLKCTB:	DS	7*BLKMAX+1	;Blinkfarben und Originalfarben je 7 Byte pro Eintrag
	DS	11	;frei muss zusammen 96 Byte bleiben
	ELSE
COLTB1:	DS	48	;Colortabelle 1
COLTB2:	DS	48	;Colortabelle 2 Blinkfarben
	ENDIF
CURBF:	DS	32	;Cursor zeichen
CURCHR:	DS	32	;Zeichen unter Cursor
STL2BF:	DS	96	;Statuszeile 2 Textbuffer

	ORG	PARAM

HAUPT:	DS	30	;EXHBF	Ram-Ablauffeld
HPRTA	EQU	HAUPT+3	;KCHM
HPRTB	EQU	HAUPT+6	;BLINK
HPRTC	EQU	HAUPT+9	;CXVA
HPRTD	EQU	HAUPT+12;THPT
HPRTE	EQU	HAUPT+15;SRERR
HPRTF	EQU	HAUPT+18;TONZL
HPRTG	EQU	HAUPT+21;MELO
HPRTH	EQU	HAUPT+24;SPOL

ZHLPTR:	DS	2	;Zielladepointer
ECBILP:	DS	2	;ECBIBF Ladepointer
ECBIVP:	DS	2	;ECBIBF Verarbeitungspointer

KYBF:	DS	8*3	;Keyboard Pointerfeld Anordnung beibehalten
KYBLP	EQU	KYBF	;Keyboard parallel LP
KYBVP	EQU	KYBF+2	;Keyboard parallel VP
KYBILP	EQU	KYBF+8	;Keyboard IBM LP
KYBIVP	EQU	KYBF+10	;Keyboard IBM VP
KYBSLP	EQU	KYBF+16	;Keyboard seriell LP
KYBSVP	EQU	KYBF+18	;Keyboard seriell VP

SINLP:	DS	2	;V24 IN LP
SINVP:	DS	2	;V24 IN VP
SPOLLP:	DS	2	;Spooler LP
SPOLVP:	DS	2	;Spooler VP
UEZHL:	DS	2	;Uebertragungszahl bytes von/zu Quelle/Ziel
WRKCHR:	DS	1	;Arbeitszeichen von Host
OUTCHR:	DS	1	;Arbeitszeichen zum Host
BLNKR:	DS	1	;Blinkrate
	IF	XR
EBNVP:	DS	1	;Ebenen Auslesepointer fuer Quelle Farbvideo
EBNLP:	DS	1	;Bitzaehler fuer XR Farbbilduebertragung
VRAMSP:	DS	1	;VideoRamSpalte fuer ColorBild Uebertragung
	ELSE
EBNVP:	DS	1	;Ebenen Auslesepointer fuer Quelle Farbvideo
EBNLP:	DS	2	;Ebenenzaehler fuer Farbbilduebertragung
	ENDIF
SPANZ:	DS	1	;Spaltenanzahl
ZLANZ:	DS	1	;Zeilenanzahl
LINTYP:	DS	1	;Linientyp TTX Vektormode 
ZLSIZE:	DS	2	;aktuelle Zeilengroesse in bytes $300 oder $0600
UEGRZ:	DS	2	;Ueberlaufgrenze fuer Zielpuffer
HRDDRK:	DS	1	;Hardcopydrucker '0-3'
ST2LPT:	DS	2	;Statuszeile 2 Textpointer
SPLINH:	DS	2	;Spoolerinhalt
VRAMZL:	DS	1	;VideoRamZeile fuer ColorBild Uebertragung
IXHMT:	DS	1	;0,1,2 Grad der Indexhochstellung 0=tief
MODUS:	DS	2	;Konstellationsmodus
CHSET:	DS	2	;Zeichensatzadresse

CURPT:	DS	2	;Cursor Position Schreibpage
VDCST:	DS	2	;VDC-Startadresse
VDCST2:	DS	2	;VDC-Startadresse fuer zweite Page non-interlaced

CSP:	DS	1	;Cursorspalte
CZL:	DS	1	;Cursorzeile
DSPST:	DS	2	;Bildschirmstartadresse
DSPANF:	DS	2	;Home Position in Video-Ram
CHGPLN	EQU	$-CSP	;Daten, die bei Pagewechsel getauscht werden
GCPOS:	DS	2	;Grafikcursor-Pos.TTX
GCMSK:	DS	1	;Graphikcursor Bitposition
WPAGE	EQU	$	;Zwischenspeicher Page in interlaced

CSP2:	DS	1
SPCNT	EQU	$	;Spaltenzaehler in MONTST interlaced
CZL2:	DS	1
DSPST2:	DS	2
DSPAN2:	DS	2
ENDPOS:	DS	2	;Vektor-Endpunkt Bildadresse
ENDMSK:	DS	1	;Vektor-Endpunkt Maske

BLKSPD:	DS	1	;Blinkgeschwindigkeit
KOMTAB:	DS	2	;aktuelle Kommandotabelle
ESCTAB:	DS	2	;Einfach-ESC 
ESCCHR:	DS	2	;Einfach-ESC Folgezeichen
LESCCH:	DS	2	;Laenge der Zeichentabelle
SKVLP:	DS	2	;Stringkonvertierungstabelle,Ladepointer

STAT1:	DS	1	;Systemstatusbits
STAT2:	DS	1	; "
STAT3:	DS	1	; "
STAT4:	DS	1	; "
STAT5:	DS	1	; "
BRTFLG:	DS	1	;Breitschrift  16,8
ABLMRK:	DS	2	;Ablauf-Flags

BYTCNT:	DS	2	;Anzahl der Sendebytes binaer
TSTBYT:	DS	1	;Tastaturbyte
VRAMAD:	DS	2	;Video-Ram Zugriffsadresse
SL2FLD:	DS	2	;Position 2. Statuszeile
USRLP:	DS	2	;Usrbuf-Ladepointer
PTCHLP:	DS	2	;Systempatchpointer
HRDCLP:	DS	2	;Hardcopy patch area Ladepointer
SCRCNT:	DS	1	;Zeilencounter fuer Softscroll
QULVP:	DS	2	;Quellen Verarbeitungspointer

ZLBLD:	DS	3	;Zielpuffer-Ladeprogramm 1 Byte
ZLPLZ:	DS	3	;Zielpufferplatz-Programm
QUVA:	DS	3	;Quellpufferverarbeitung 1 Byte
QUINH:	DS	3	;Quellpufferinhalt-Programm
HBINPR:	DS	3	;Host-INPUT-Verarbeitungsprogramm

MELLP:	DS	2	;MELPUF LP
MELVP:	DS	2	;MELPUF VP
MELDAU:	DS	1	;Melodiedauerzaehler
IBMCNT:	DS	1	;IBM Time out Counter
ATTRIB:	DS	1	;Zeichensatzattribute
ATRFLG:	DS	1	;Attribute ohne Breitschrift
EXZSLP:	DS	2	;Pointer fuer EXT. Zeichensatz
ZLVAP:	DS	2	;Ziel-Sende-Programm
ABPROG:	DS	3	;Abbruchprogramm
ZLRET:	DS	3	;Returnprogramm
QUVAP:	DS	2	;Quellverarbeitungsprogramm
ZPTR:	DS	2	;Zustandspointer fuer Koordinatenaufnahme
VKTPRG:	DS	2	;Vektorverarbeitung
MASTER:	DS	2	;Hauptverarbeitungsprogramm

KYIR:	DS	1	;Keyboard Input seriell Byte
KYIBM:	DS	1	;IBM Keyboard Input ein Zeichen
IBMBIT:	DS	1	;IBM Bitcounter
IBMPT:	DS	2	;Pointer auf IBMBUF
TABC:	DS	1	;Timer A Controlwort-Zwischenspeicher
SKDRH:	DS	1	;Timer-Datenregister fuer ser. Keyboard Baudrate/2
SKDR:	DS	1	;Timer-Datenregister fuer ser. Keyboard Baudrate
VDPT:	DS	2
XOFLG:	DS	1

SKBC:	DS	1	;Ser. Keyb. BIT-Counter
SKBW:	DS	1	;Ser. Keyb. Wortlaenge
NMIJP:	DS	3	;Absprung bei NMI not used
JUMPER:	DS	1	;Jumperstellung

PIXLOG:	DS	3	;Vektorlogik Pixelverknuepfung
PFKT:	DS	1	;Vektorlogiknummer
CHRPRG:	DS	2	;Adresse des Char-generierungsprogramms
CHRFKT:	DS	3	;Characterfunktion TTX Alpha
CHRFKS:	DS	2	;Characterfunktion SAVE

HBYT:	DS	1	;High byte Zwischenspeicher
	IF	XR
XRWR:	DS	1	;aktueller Write-Wert
XRRD:	DS	1
XRRDC:	DS	1
XRVID:	DS	1	;Status VID0, VID1
	ELSE
COLRG1:	DS	1	;Color Steuerregister 1
COLRG2:	DS	1	;Color Steuerregister 2
HGFRG1:	DS	1	;Hintergrundfarbe Colorkarte 1
HGFRG2:	DS	1	;Hintergrundfarbe Colorkarte 2
	ENDIF
X2:	DS	2
Y2:	DS	2	;Koordinaten des Endpunkts
X1:	DS	2
Y1:	DS	2	;Koordinaten des Startpunkts
EBENE:	DS	1	;Hardcopy VideoRam Leseebene
DRKSPL:	DS	1	;Druckerspalte bei Zeilenweise ausgeben
SCRTIM:	DS	1	;Scroll Statuszeilengenerierung
CHGPRG:	DS	2	;Charactergen Programmziel
DSPST4:	DS	2	;Display Startadresse High-Page
TXNULL:	DS	2	;TX-Ursprungadresse
IBMMOD:	DS	1	;IBM Tastaturmodus 
	IF	XR
HRDKTR:	DS	1	;Kontrast fuer Schwarz-weiss Hardcopy
XRCOLT:	DS	7	;zuletzt mit <EEW><EEw> eingestellter Farbindex RGB und BlinkRGB
XRBRGB	EQU	XRCOLT+4
XRCOL:	DS	1	;XR Schreibfarbe im Maskenmodus
XRHGF:	DS	1	;XR Hintergrundfarbe
XRSTAT:	DS	1
SETRGB:	DS	3	;JP Farbcomprimierroutine Rot,Gruen Blau
KVMTRX:	DS	12	;Kovolutionmatrix Parameter
KVFAKT	EQU	KVMTRX		;Teilerfaktor
H11	EQU	KVMTRX+1
H12	EQU	KVMTRX+2
H13	EQU	KVMTRX+3
H21	EQU	KVMTRX+4
H22	EQU	KVMTRX+5
H23	EQU	KVMTRX+6
H31	EQU	KVMTRX+7
H32	EQU	KVMTRX+8
H33	EQU	KVMTRX+9
KVCLIP	EQU	KVMTRX+10	;Kovolution Clipping-Konstante 16 bit
KVLBPT:	DS	2	;Kovolutionspaltenbufferpointer
ALIASG:	DS	1	;AntiAliasing fuer RGB-Komprimierung
	ELSE
	DS	29	;frei
	ENDIF

;------ TABVDC 6345 CRT-Controller Register

VDCRE:	DS	16	;Tabelle VDC Register
VDCR	EQU	$-1	;VDC-Register 0
VDCR31:	DS	1
VDCR30:	DS	1	;VDC-Register 30

;------ ab hier resistente Daten keine Initialisierung wenn JPCHKS OK

RESDAT	EQU	$

HBFLD:	DS	3	;Host-OUTPUT-Puffer-Ladeprogramm
HBPLZ:	DS	3	;Host-OUTPUT-Pufferplatz-Programm
HBFRD:	DS	3	;Host-INPUT-Pufferverarbeitung
HBINH:	DS	3	;Host-INPUT-Pufferinhalt
TASTBD:	DS	1	;Tastatur Baudrate
TASTAT:	DS	1	;Tastatur par ser IBM Tastaturdaten
HOST:	DS	1	;Hostkanal
V24EB:	DS	1	;Empfaengerbaudrate
V24SB:	DS	1	;Sendebaudrate
V24PAR:	DS	1	;V24-Parameter 
;Ab hier Initialisierung aus Tabelle, wenn Checksum Error
ITLFLG:	DS	1	;Interlace=01  non-intl=00
MSCHST:	DS	1	;aktueller Zeichensatz
MONITR:	DS	1	;gewaehlte Monitoranpassung
ZWZL:	DS	1	;Zwischenzeilen Bits 0-3, Smooth Scroll Bit 5,
			;Double Size Bit 4
TXOFFS:	DS	1	;Nullpunkt-Offset TX-Modus
CHKBYT:	DS	1	;Checkbyte um Nullfehler zu vermeiden Inhalt 41
RESDTE	EQU	$	;muss kleiner 256 Byte sein wegen JPCHKS

CHKSJP:	DS	2	;residente Checksumme fuer Jumperdaten 
CHKSUM:	DS	2	;residente Checksumme fuer Zeichensatz
CHKRES:	DS	1	;FLAG von ININEU an INIRES

;------ ab hier fast keine Ram Initialisierung

IBMBUF:	DS	10	;IBM Tastaturzeichenpuffer
TRBDX:	DS	2	;Betrag DeltaX von P0 nach P2 Trigon Fill
TRBDY:	DS	2	;Bresenham Zaehler fuer P0 nach P2 Trigon Fill
SETFIL:	DS	3	;Pixelroutine fuer Horlin und FFIL
GETFIL:	DS	3	;Pixelroutine fuer FFIL
ABLCON:	DS	10	;Ablauf-Kontrollfeld TTX
KOV	EQU	ABLCON
SPRAY:	DS	2	;SPRAY-Grauwerte
KYBPT:	DS	2	;Pointer to Keyboardpointers for Read and Display
KYBPTI:	DS	2	;Pointer to Keyboardpointers for Input
VLX:	DS	1	;5 bit X Low
VHX:	DS	1	;5 bit X High
VLY:	DS	1	;5 bit Y Low
VHY:	DS	1	;5 bit Y High

ERRG:	DS	1	;Fehlerregister V-24
ARBF:	DS	21	;Arbeitsfeld fuer lokale Parameter
PIXLG1:	DS	3	;PIXLOG-Weiterfuehrung

DPQU:	DS	2	;Quelladresse fuer Textdisplay
DPLEN:	DS	2	;Textlaenge
DPZA:	DS	2	;Displayzieladresse
TXTBF:	DS	24	;24 Byte Textpuffer Statuszeile
	DS	1
FRBPUF:	DS	4	;Farbbyte Puffer fuer Farbbilduebertragung
TRMZCH:	DS	1
LDADR:	DS	2	;Startadresse Zwischenspeicher bei BLKUP,DWN
ZLADR:	DS	2	;Zieladresse
STRLP:	DS	2	;Stringpointer bei Zeichenumconvertierung
STRLEN:	DS	1	;Stringlaenge
KCHR:	DS	1	;Keyboardcharacter in STKV
	IF	XR
GRAUBF:	DS	4	;Grauwertberechnung fuer NEC P6 Hardcopy
	DS	2	;frei
	ELSE
REDRG1:	DS	1
REDRG2:	DS	1
GRNRG1:	DS	1
GRNRG2:	DS	1
BLURG1:	DS	1
BLURG2:	DS	1
	ENDIF
	IF	$ GT 47CCH
	.PRINTX '*** ERROR: RESDAT zu gro~! ***'
	ENDIF
	ORG	47CCH

SEC50:	DS	1	;Uhrzeit Puffer
STD:	DS	1
MIN:	DS	1
SEC:	DS	1

	ORG	47D0H

HRDCBF:	DS	16	;patch area fuer Hardcopy
HRDCLN	EQU	$

INTVKT:	DS	32	;32 Byte INT-Vektor STI Adress must be 47E0H

	ORG	4800H

MELPUF:	DS	1024		;1k Melodiepuffer, 256 byte wenn Kovolution benutzt wird
MLBEND	EQU	$
KVLBF	EQU	MELPUF+256	;Zwischenspeicher fuer Kovolutionberechnung
KVLSPB	EQU	KVLBF+30	;Zwischenspeicher einer Spalte fuer Kovolutionberechnung
RGBBUF	EQU	MELPUF+256	;Zwischenspeicher fuer RGB Komprimierung Spaltenuebertrag
RGBVAL	EQU	RGBBUF+8	;Zwischenspeicher fuer RGB Komprimierung 3 Farbwerte
RGBA	EQU	RGBVAL+3
RGBB	EQU	RGBA+3
RGBC	EQU	RGBA+6
SKVTAB:	DS	1024		;1k Stringtabelle
SKVEND	EQU	$
VZSATZ:	DS	4096		;4k variabler Zeichensatz

RAMEND	EQU	$		;Ende des System Rams 6000H

;------ Systemadressen -----
GRAFIT	EQU	1E00H		;Grafikzeichensatz Statuszeile Interlaced 
ZSATZI	EQU	2000H		;Zeichensatz Interlaced
IZSZI	EQU	2800H		;Index Zeichensatz Interlaced
ZSATZ	EQU	3000H		;Standardzeichensatz
ZSZGRK	EQU	3400H		;Griechisch/Math.Zeichensatz
GRAFIK	EQU	ZSZGRK		;Graphikzeichensatz fuer Statuszeile non Interl.
IZSATZ	EQU	3800H		;Indexzeichensatz
IGZSTZ	EQU	3C00H		;Griechisch Index

SPOLBF	EQU	8000H		;Spoolerbuffer 32k
SPLLEN	EQU	0000H-SPOLBF	;Spoolerbufferlaenge
SPOLND	EQU	0000H		;Spoolerbuffer Ende zyklisch

;I/O Portadressen

CXSTB	EQU	00H	;Centronix Strobe
EPROM	EQU	10H	;EPROM page select
VOL0	EQU	11H	;Volume sound
RTS	EQU	12H	;Request to send
PAGE	EQU	13H	;Ram-Page select 0=VIDEO 1=Spooler
STR	EQU	14H	;Centronix long strobe
INTL	EQU	15H	;Interlaced Videoram paging if low
DPAGE	EQU	16H	;displayed Video-page select
VOL1	EQU	17H	;Volume sound
IDR	EQU	20H
GPIP	EQU	IDR+1
IPRB	EQU	IDR+2
IPRA	EQU	IDR+3
ISRB	EQU	IDR+4
ISRA	EQU	IDR+5
IMRB	EQU	IDR+6
IMRA	EQU	IDR+7
PVR	EQU	IDR+8
TABCR	EQU	IDR+9
TBDR	EQU	IDR+0AH
TADR	EQU	IDR+0BH
UCR	EQU	IDR+0CH
RSR	EQU	IDR+0DH
TSR	EQU	IDR+0EH
UDR	EQU	IDR+0FH
LRS	EQU	30H	;Light pen scharf
STATR	EQU	40H
VDCAR	EQU	50H	;VDC Adresse
VDCWR	EQU	52H	;VDC write
VDCRD	EQU	53H	;VDC read
CNTRX	EQU	60H	;Centronix Daten
ECBDA	EQU	70H	;ECB Bus Daten
PBDA	EQU	71H	;Parallel Tastatur
PARST	EQU	72H
PARCTL	EQU	73H
	IF	XR
XRFLGS	EQU	080H	;XR Flagregister
XRCLRG	EQU	0C0H	;XR Colorregister
XRCLU0	EQU	0E0H	;XR Color Look-up Table Register Farbnummer
XRCLU1	EQU	0E1H	;XR Color Look-up Table Farbwerte RGB
XRCLU2	EQU	0E2H	;XR Color Look-up Table Mask Register
	ELSE
CLRG1	EQU	0F0H	;Color NR. Steuerregister
CLRG2	EQU	0B0H
REDOUT	EQU	0E0H	;Rotanteilsteuerregister
RD2OUT	EQU	0A0H
GRNOUT	EQU	0D0H	;Gruenanteil
GR2OUT	EQU	090H
BLUOUT	EQU	0C0H	;Blauanteil
BL2OUT	EQU	080H
	ENDIF

BLACK	EQU	0
WHITE	EQU	0FFH
CR	EQU	0DH
LF	EQU	0AH
XON	EQU	11H
XOF	EQU	13H
ESC	EQU	1BH

IBMSTB	EQU	10	;Nr of Strobes for IBM Keyboard
CSTEPS	EQU	48 
IMRBV	EQU	11000010B	;initial values for Int Mask registers INISTI, INIT
IMRAV	EQU	10111000B


ZLSPR	EQU	PITCH-7	;Zeilenblocksprung
ZLSIZN	EQU	PITCH	;non interlaced PITCH=ZLSIZN
ZLSIZI	EQU	PITCH*2 ;interlaced

;*******************************************
;* MACROS
;*******************************************
SUBHL	MACRO	REG
	OR	A		;Subtraction HL=HL-REG
	SBC	HL,REG
	ENDM
JPBITZ	MACRO	P1,P2,P3	;Sprung wenn BIT nicht gesetzt
	BIT	P1,P2
	JR	Z,P3
	ENDM
JPBIT	MACRO	P1,P2,P3	;Sprung wenn Bit gesetzt
	BIT	P1,P2
	JR	NZ,P3
	ENDM
JRNZW	MACRO	P1,P2,P3
	CP	P1
	JR	C,P3
	CP	P2+1
	JR	NC,P3
	ENDM
JRZW	MACRO	P1,P2,P3
	LOCAL	JRZW1
	CP	P1
	JR	C,JRZW1
	CP	P2+1
	JR	C,P3
JRZW1:
	ENDM
FLAG	MACRO	BIT1,P1
	BIT	BIT1,(IX+P1-RESDAT)
	ENDM
JPI	MACRO	P1		;springe wenn interlaced
	BIT	0,(IX+ITLFLG-RESDAT)
	JP	NZ,P1
	ENDM
JPNI	MACRO	P1		;springe wenn non-interlaced
	BIT	0,(IX+ITLFLG-RESDAT)
	JP	Z,P1
	ENDM
SETNI	MACRO	N,R
	LOCAL	SETNI1
	BIT	0,(IX+ITLFLG-RESDAT)
	JR	NZ,SETNI1
	SET	N,R
SETNI1:
	ENDM
CALLB	MACRO	ADR
	RST	18H
	DW	ADR
	ENDM
CALLA	MACRO	ADR
	RST	18H
	DW	ADR
	ENDM
LDRI	MACRO	R1,R2,RR	;Register per (rr) laden
	LD	R2,(RR)
	INC	RR
	LD	R1,(RR)
	INC	RR
	ENDM
LDW	MACRO	MEM,VAL
	LD	HL,VAL
	LD	MEM,HL
	ENDM
LDB	MACRO	MEM,VAL
	LD	A,VAL
	LD	MEM,A
	ENDM
PRINTS  MACRO	PAGE,SPACE
	IF2
	.PRINTX	*PAGE SPACE Bytes*
	ENDIF
	ENDM
SETR	MACRO	REG,VAL		;VDC-Register direkt setzen
	LD	BC,VAL*256+REG
	CALL	VDCWRB
	ENDM
SETRA	MACRO	REG		;VDC-Register aus A setzen
	LD	C,REG
	CALL	VDCWRA
	ENDM
SETRHL	MACRO	REG		;VDC-Registerpaar aus HL setzen
	LD	C,REG
	CALL	VDCWHL
	ENDM
XRBIT	MACRO
	OUT	(XRCLU0),A
	ENDM
XRBRES	MACRO
	LD	A,70H
	OUT	(XRFLGS),A
	LD	A,77H
	OUT	(XRFLGS),A
	ENDM
;****************************************************************************
;MODUL START Power on Restart und Warmstart
;****************************************************************************
	ASEG
	IF	EPAGE EQ 0
	 ORG	0100H
	ELSE
	 ORG	4100H
	ENDIF
	.PHASE	ROM
;-----------------------
RESET:	DI			;Power up RESET
	LD	B,5		;short delay after power up
RSDL:	DEC	BC
	LD	A,0FFH		;Umschalten auf 2.EPROM Bank fuer Systemtest
	OUT	(EPROM),A	;Programmteil wird in ROMPGB weitergefuehrt
	LD	A,B
	OR	C
	JR	NZ,RSDL
	IF	EPAGE EQ 0
	JP	RESET
PAGENR:	DB	0
	ELSE
	JP	SYSTST
PAGENR:	DB	0FFH
	ENDIF
;-----------------------
	REPT	0018H-$
	NOP
	ENDM
RST18:	EX	(SP),IY		;RESTART 18 ruft eine Routine der anderen EPROM Haelfte auf
	EX	(SP),HL
	LDRI	H,L,IY		;die Zieladresse folgt dem RST Aufruf
	PUSH	AF
	IF	EPAGE EQ 0
	 LD	A,0FFH		;Umschalten auf 2.EPROM Bank
	ELSE
	 LD	A,0
	ENDIF
	OUT	(EPROM),A
	POP	AF
	EX	(SP),HL
	EX	(SP),IY
	CALL	JPIY
	PUSH	AF
	IF	EPAGE EQ 1
	LD	A,0
	ELSE
	LD	A,0FFH
	ENDIF
	OUT	(EPROM),A
	POP	AF
	RET
JPIY:	JP	(IY)

INIJMP:	XOR	A		;Ruecksprung von Systemtest
	OUT	(EPROM),A
	JP	INIT
WRMJMP:	XOR	A
	OUT	(EPROM),A
	JP	WARM

	REPT	0066H-$
	NOP
	ENDM

IBMINT:	PUSH	AF		;schnellstmoegliche NMI Routine Mitte eines Bits
	IN	A,(GPIP)	;IN muss spaetestens 18 usec nach /Clock ausgefuehrt sein
	RLA			;Bit 6 into CY
	RLA
	IN	A,(PARST)	;Spiketest
	BIT	1,A		;BIT veraendert CY nicht
	JR	NZ,IBMIN2
	RR	(IX+KYIBM-RESDAT)	;Shift Bit into KYIBM
	LD	A,(IBMCNT)
	OR	A
	JR	NZ,IBMIN3	;erster Clock Impuls setzt Bitcounter auf Beginn
	LD	A,IBMSTB		;Byte fertig eingelesen, warte auf naechstes Byte
	LD	(IBMBIT),A
IBMIN3:	DEC	(IX+IBMBIT-RESDAT)	;Bitcounter decrement
	JR	NZ,IBMIN1
	LD	A,IBMSTB		;Byte fertig eingelesen, warte auf naechstes Byte
	LD	(IBMBIT),A
	PUSH	HL
	LD	HL,(IBMPT)	;IBMPT zeigt auf 10 byte Zeichenpuffer
	LD	A,(KYIBM)	;gelesenes Zeichen in Zeichenpuffer lesen
	LD	(HL),A
	INC	HL		;IBMPT erhoehen
	LD	(IBMPT),HL	;
	POP	HL
IBMIN1:	LD	A,2		;fuer IBM serial data Bit
	LD	(IBMCNT),A	;Timeout 2/50 s noetig fuer Korrektur von Stoerimpulsen
IBMIN2:	POP	AF		;und um IBMPT auf 0 zu setzen
	RETN			;xxx Cycles = Hz
;****************************************************************************
;MODUL INT
;****************************************************************************
; Diese Interrupt Routinen muessen in beiden EPROM-Seiten am gleichen Platz
; stehen !

RETI:	EI
	RETI
;-----------------------	
	IF	DEBUG
	DB	'ECBINT'
	ENDIF

ECBINT:	PUSH	AF		;Interrupt von ECB-Bus
	PUSH	BC
	PUSH	DE
	PUSH	HL
	LD	HL,(ECBILP)	;1 byte von ECB-Bus in ECB-Inputbuffer
	LD	DE,(ECBIVP)	;laden
	LD	C,LOW ECBIBF
	LD	B,LOW ECIEND	;ECBIN-Puffer-Ende NWB
	IN	A,(ECBDA)
	CALL	BFLD
	LD	(ECBILP),HL
	JP	NZ,IRT

ECIIOF:	IN	A,(IMRA)	;Puffer ist voll
	RES	7,A		;sperre ECB-Interrupt
	OUT	(IMRA),A
	JP	IRT
;-----------------------
	IF	XR

INCVRA:	LD	HL,(VRAMAD)	;Increment Video Adresse pixelzeilenweise
	LD	A,(VRAMSP)	;Spaltenzaehler am Ende der Zeile ?
	INC	A
	CP	BLOCKS
	JR	C,INCVR2
	XOR	A		;ja
	LD	(VRAMSP),A
	LD	A,(VRAMZL)	;Zeilenzaehler auf 8 ?
	INC	A
	CP	8
	JR	C,INCVR3
	XOR	A
	LD	(VRAMZL),A
	LD	A,H
	INC	HL
	JR	INCVR4

INCVR3:	LD	(VRAMZL),A
	LD	A,H
	LD	DE,95*8-1
	SUBHL	DE
	JR	INCVR4

INCVR2:	LD	(VRAMSP),A
	LD	A,H
	LD	DE,8
	ADD	HL,DE
INCVR4:	JPI	INCVR1		;im non-Interlaced oberstes Bit beibehalten
	RL	H
	RLA
	RR	H
INCVR1:	LD	(VRAMAD),HL
	RET
;-----------------------
CLBILD:	PUSH	AF
	PUSH	BC
	PUSH	DE
	PUSH	HL
	IN	A,(ECBDA)
	LD	HL,(VRAMAD)	;Farbbild von Host einlesen
	LD	B,A
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	LD	(HL),B		;Byte einlesen nach XR im Bitmodus
	XRBIT
	LD	HL,EBNLP	;zaehlt von 8-0
	DEC	(HL)
	JR	NZ,SWBIL1	;insgesamt 8 Byte an gleiche Stelle schreiben
	LD	(HL),8
	CALL	INCVRA		;increment VideoRamAdress
	JR	SWBIL1

	ELSE
CLBILD:	PUSH	AF
	PUSH	BC
	PUSH	DE
	PUSH	HL
	IN	A,(ECBDA)
	LD	HL,(EBNLP)	;Pointer zeigt auf Farbbytepuffer
	LD	(HL),A
	INC	HL
	LD	A,LOW (FRBPUF+4);wenn 4 Byte empfangen sind, Farben berechnen
	CP	L
	JR	NZ,CLBIL1
	LD	HL,FRBPUF
CLBIL1:	LD	(EBNLP),HL
	JR	NZ,SWBIL1	;warte auf insgesamt 4 byte fuer 4 Farbebenen

	LD	C,(HL)
	INC	HL
	LD	D,(HL)
	INC	HL
	LD	E,(HL)
	LD	HL,(VRAMAD)
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	PUSH	AF
	CALL	CLBLDA
	POP	AF
	JR	SWBIL4
	ENDIF

SWBILD:	PUSH	AF
	PUSH	BC
	PUSH	DE
	PUSH	HL
	IN	A,(ECBDA)
	LD	HL,(VRAMAD)	;Schwarz-Weiss Bild einlesen
	LD	B,A
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	LD	(HL),B
SWBIL4:	JPI	SWBIL3
SWBIL2:	INC	HL
	RL	H		;oberstes bit erhalten
	RLA
	RR	H
	LD	(VRAMAD),HL
	JR	SWBIL1
SWBIL3:	LD	H,A
	INC	HL
	LD	(VRAMAD),HL

SWBIL1:	LD	DE,(BYTCNT)
	DEC	DE
	LD	(BYTCNT),DE
	LD	A,D
	OR	E
	JP	NZ,IRT
	LD	HL,ABLMRK+1	;Ende der Uebertragung im Direktmodus
	RES	7,(HL)
	LDW	(INTVKT+30),ECBINT
	JP	IRT
;-----------------------
	IF	NOT XR
CLBLDA:	LD	B,10000000B	;Maske
CLBIL2:	LD	A,(COLRG1)	;Farben fuer COLOR-Byte berechnen
	SET	3,A		;Schreiben nur in Farbebene
	RR	A		;und in Video-Ram plazieren
	RR	A
	RR	A
	RL	C
	RLA
	RL	D
	RLA
	RL	E
	RLA
	XOR	00000111B
	OUT	(CLRG1),A
	LD	A,B
	LD	(HL),A
	RR	B
	JR	NC,CLBIL2
	LD	A,10110110B	;4.Byte in Grundebene setzen
	OUT	(CLRG1),A
	LD	A,(FRBPUF+3)
	RET

	ENDIF
;-----------------------
PBINT:	PUSH	AF		;PORT B Interrupt Paralleltastatur
	PUSH	BC
	PUSH	DE
	PUSH	HL
	IN	A,(PBDA)
	LD	HL,KYBLP
	CALL	KCHS		;A in KYBBF eintragen
IRT:	POP	HL
	POP	DE
	POP	BC
	POP	AF
	EI
	RETI
;-----------------------
	IF	DEBUG
	DB	'KCHS'
	ENDIF

KCHS:	L	(TSTBYT),	;A enthaelt Tastaturcode HL Pointer auf Buffer
	LD	A,(TASTAT)
	JPBITZ	7,A,KCHS3
	PUSH	HL
	LD	A,(PAGENR)
	LD	B,A
	PUSH	BC
	LD	A,0FFH
	OUT	(EPROM),A
	CALL	IBMKV		;Umcodierung IBM Tastatur und Tabelle in 2.EPROM Page
	POP	BC		;IBMKV setzt TSTBYT
	LD	A,B
	OUT	(EPROM),A	;zurueckschalten auf alte Page vor CALL IBMKV
	POP	HL
	RET	NZ		;Zeichen war Steuerzeichen kein Eintrag in KYB-Buffer

KCHS3	LD	A,(TSTBYT)
	LD	(KYBPTI),HL
	LDRI	D,E,HL		;HL zeigt auf Keyboardpointerfeld
	PUSH	DE
	LDRI	D,E,HL
	LDRI	B,C,HL
	LD	B,(HL)
	POP	HL

	CALL	PLATZ
	OR	A
	RET	Z		;kein Platz im KYBBF

	PUSH	BC
	LD	A,(TSTBYT)
	LD	B,A
	LD	A,(MODUS)
	BIT	5,A		;invertiert ?
	LD	A,B
	JR	Z,KCHS1		;CPL bei Inv. Daten
	CPL
KCHS1:	LD	B,A
	LD	A,(SKBW)
	BIT	3,A
	LD	A,B
	JR	NZ,KCHS2	;wenn 7 bit loesche Bit 8
	AND	7FH

KCHS2:	POP	BC
	CALL	BFL		;Byte in KYBBF Puffergrenzen in BC
	EX	DE,HL		;neuer Ladepointer KYBLP ablegen
	LD	HL,(KYBPTI)
	LD	(HL),E
	INC	HL
	LD	(HL),D
	CALL	KLICK
	LD	HL,ABLMRK+1
	SET	6,(HL)		;Keyboard Flag setzen
	RET
;-----------------------
SININT:	PUSH	AF		;V-24 serial Input INT
	PUSH	BC
	PUSH	DE
	PUSH	HL
SINERR:	LD	A,(MODUS)	;XON/XOF aktiv ?
	JPBITZ	6,A,SININ3

	IN	A,(UDR)		;Flag setzen wenn XOF empfangen
	CP	XOF		;nicht in Puffer aufnehmen
	JR	NZ,SININ4
	LD	HL,XOFLG
	SET	6,(HL)
	JR	SININ2
SININ4:	CP	XON		;Flag ruecksetzen bei XON
	JR	NZ,SININ5
	LD	HL,XOFLG
	RES	6,(HL)
	JR	SININ2

SININ3:	IN	A,(UDR)		;lade V-24 Receiver buffer
SININ5:	LD	HL,(SINLP)	;1 Byte in serial INPUT Buffer laden
	LD	DE,(SINVP)
	LD	B,LOW SIBEND
	LD	C,LOW SINBF
	CALL	BFLD		;lade received Byte in Input buffer
	LD	(SINLP),HL

	CALL	PLATZ
	CP	16
	JP	NC,IRT		;wenn mehr als 16 bytes frei, RETI

	LD	A,(MODUS)	;Puffer ist voll
	JPBITZ	6,A,SININ1

	LD	HL,XOFLG	;XON/XOFF Protokoll aktiv
	BIT	7,(HL)		;XOFF bereits gesendet ?
	JP	NZ,IRT

	IN	A,(TSR)		;noch nicht senden wenn Transmit Buffer not
	JPBITZ	7,A,SININ2	;empty
	SET	7,(HL)
	LD	A,XOF		;send XOF
	OUT	(UDR),A
SININ2:	JP	IRT

SININ1:	LD	A,80H		;RTS/CTS Protokoll aktiv
	OUT	(RTS),A		;RTS setzen
	JP	IRT
;-----------------------
SSND:	IN	A,(TSR)
	JPBITZ	7,A,SSND1	;direkt senden bei Transmit Puffer leer
	LD	A,B
	OUT	(UDR),A
SSND1:	RET
;-----------------------
	IF	DEBUG
	DB	'KSERIN'
	ENDIF

KSERIN:	PUSH	AF		;Startbit INT serielle Tastatur
	PUSH	HL		;moeglichst schnell Timer A starten
	LD	A,(SKDRH)
	OUT	(TADR),A	;Timer Datenregister laden
	LD	A,(TABC)	;Prescale laden
	LD	H,A
	IN	A,(TABCR)	;Timer Control
	AND	0FH		;Timer B unberuehrt
	OR	H		;Timer A aktiv
	OUT	(TABCR),A	;Timer A Start
	LD	A,(SKDR)	;Timer auf 1 bit Time ab naechsten Mal
	OUT	(TADR),A
	IN	A,(IMRB)
	RES	7,A		;Disable Startbit INT
	OUT	(IMRB),A
	LD	A,8+1		;Wortlaenge in Bitcounter
	LD	(SKBC),A
	IN	A,(IMRA)	;enable Timer A Interrupt
	SET	6,A
	OUT	(IMRA),A
	POP	HL
	POP	AF
	EI
	RETI
;-----------------------
ITA:	PUSH	AF		;INT Mitte eines Bits
	LD	A,(SKBC)
	OR	A
	JR	Z,STPBIT
	DEC	A
	LD	(SKBC),A
	IN	A,(GPIP)	;Flag-Port
	BIT	5,A		;ser.Keyb. Bit
	SCF
	JR	NZ,CCR
	CCF
CCR:	LD	A,(KYIR)
	RRA
	LD	(KYIR),A
	POP	AF
	EI
	RETI

STPBIT:	PUSH	BC		;PUSH AF bereits erfolgt
	PUSH	DE
	PUSH	HL
	IN	A,(IMRA)	;disable Timer A INT
	RES	6,A
	OUT	(IMRA),A
	IN	A,(TABCR)
	AND	0FH
	OUT	(TABCR),A	;Timer A STOP
	IN	A,(IPRB)	;serielles Keyboard aktivieren
	RES	7,A		;reset SKBD pending bit
	OUT	(IPRB),A
	IN	A,(IMRB)	;enable KSERIN INT
	SET	7,A
	OUT	(IMRB),A
	LD	A,(KYIR)	;byte in KYBBF eintragen
	LD	HL,KYBSLP
	CALL	KCHS
	JP	IRT
;-----------------------
ITIMER:	PUSH	AF		;timing und Uhr Interrupt
	PUSH	BC
	PUSH	DE
	PUSH	HL

	LD	HL,SCRTIM	;Scrolltimer
	LD	A,(HL)
	OR	A
	JR	Z,ITIM6		;Kein Scroll aktiv
	DEC	(HL)
	JR	NZ,ITIM4
	LD	HL,STAT2	;Flag zum Zeichnen der Statuszeile
	SET	7,(HL)
	JR	ITIM6
	
ITIM4:	IF	HD6345		;Softscroll
	 LD	HL,SCRCNT
	 LD	A,(HL)
	 OR	A		;Softscroll aktiv?
	 JR	Z,ITIM6		;nein

	 LD	A,5
	 LD	(SCRTIM),A	;Timer retriggern
 	 LD	A,(ZWZL)
	 AND	00001111B
	 LD	B,A
	 LD	A,29
	 CALL	VDCIN		;Scroll-Register lesen
	 LD	C,(HL)
	 ADD	A,C		;Scrollgeschw. anpassen
	 SRL	C
	 ADD	A,C		;A:=1.5*C
	 OUT	(VDCWR),A	;!
	 SUB	B		;Max. Raster erreicht?
	 JR	C,ITIM6		;Nein

	 LD	DE,0
ITIM8:	 LD	HL,SCRCNT
	 DEC	(HL)
	 LD	HL,BLOCKS
	 ADD	HL,DE		;Neue Zeile
	 EX	DE,HL
	 SUB	B
	 JR	NC,ITIM8

	 ADD	A,B
	 OUT	(VDCWR),A	;Scroll Register !
	 LD	A,22
	 CALL	VDCINW		;Scr 3 Start
	 ADD	HL,DE		;Adresse erhoehen
	 RES	4,H
	 LD	C,22
	 CALL	VDCOTW
	 LD	A,(STAT3)
	 BIT	5,A		;Scr 1+3 gekoppelt?
	 JR	Z,ITIM6
	 LD	A,12
	 CALL	VDCINW		;Scr 1 mitscrollen
	 ADD	HL,DE
	 RES	4,H
	 LD	C,12
	 CALL	VDCOTW
	ENDIF

ITIM6:	LD	HL,SEC50	;Uhr
	DEC	(HL)
	JR	NZ,ITIM1

	LD	A,50
	LD	(SEC50),A
	CALL	TINC		;Uhr weiterzaehlen
	LD	A,0CDH
	LD	HL,THPT		;UHR-Routine aktivieren jede Sekunde
	LD	(HPRTD),A
	LD	(HPRTD+1),HL

ITIM1:	LD	HL,STAT4
	JPBIT	2,(HL),ITIM2

	LD	HL,BLNKR
	DEC	(HL)
	JR	NZ,ITIM2
	LD	A,(BLKSPD)
	LD	(HL),A
	LD	A,0CDH
	LD	HL,BLINK
	LD	(HPRTB),A
	LD	(HPRTB+1),HL
	
ITIM2:	LD	A,(IBMCNT)
	OR	A
	JR	Z,MELTIM
	DEC	A
	LD	(IBMCNT),A	;Timeout Zaehler 0 bei Ende Bytefolge von IBM-Keyb.
	JR	NZ,MELTIM

	LD	HL,IBMBUF
	JR	ITIBM2
ITIBM1:	LD	A,(HL)	;IBM-bytes in KYBBF eintragen
	PUSH	HL
	LD	HL,KYBILP
	CALL	KCHS
	POP	HL
	INC	HL
ITIBM2:	LD	A,(IBMPT)	;vergleiche Low-byte
	CP	L
	JR	NZ,ITIBM1
	LD	HL,IBMBUF	;IBMBUF logisch loeschen
	LD	(IBMPT),HL
	
MELTIM:	LD	A,(MELDAU)
	OR	A
	JP	Z,IRT		;keine Aktion bei Melodiedauer 0
	DEC	A
	LD	(MELDAU),A
	JP	NZ,IRT		;laufender Ton noch nicht zu Ende
	LD	A,0CDH
	LD	HL,MELO		;einen Ton weiterschalten
	LD	(HPRTG),A
	LD	(HPRTG+1),HL
	JP	IRT
;-----------------------
RERRI:	PUSH	AF		;serial Receive error
	PUSH	BC
	PUSH	DE
	PUSH	HL
	IN	A,(RSR)
	LD	(ERRG),A
	AND	8FH
	OUT	(RSR),A
	LD	A,0CDH
	LD	DE,SRERR
	LD	(HPRTE),A
	LD	(HPRTE+1),DE
	JP	SINERR		;Byte noch lesen
;****************************************************************************
;VDC-UTILITIES
;****************************************************************************
IN2VAD:	PUSH	BC
	LD	BC,BLOCKS*2
	JR	INCVA2

INCVAD:	PUSH	BC		;VDC-Adresse um eine Zeile erhoehen
	LD	BC,BLOCKS
INCVA2:	ADD	HL,BC
	JPNI	INCVA1
	ADD	HL,BC
	LD	A,H
	AND	1FH
	LD	H,A
	POP	BC
	RET
INCVA1:	LD	A,H
	AND	0FH
	LD	H,A
	POP	BC
	RET

DECVAD:	PUSH	BC
	LD	BC,-BLOCKS
	JR	INCVA2
DC2VAD:	PUSH	BC
	LD	BC,-BLOCKS*2
	JR	INCVA2
;-------------------------
INCVST:	LD	HL,(VDCST)
	CALL	INCVAD
	LD	(VDCST),HL
	RET
;-------------------------
SETVDC:	LD	HL,(VDCST)
	IF	HD6345		;VDC setzen, wenn fertig gescrollt
	 LD	A,(SCRCNT)
	 OR	A
	 RET	NZ		;Smooth Scroll: nichts setzen
	 SETR	29,0
	 LD	A,(SCRTIM)
	 AND	11111110B	;Hard Scroll fertig?
	 JP	Z,NRMVDC	;Ja: VDC-Adressen komplett neu
	 LD	A,(STAT3)
	 BIT	5,A		;Gekoppelt?
	 JR	Z,VDCAD3	;Nein: Nur Scr 3 setzen
	ENDIF
VDCAD:	LD	(VDCR-13),HL
	LD	C,12		;Screen 1+3 Startadr setzen
	IF	HD6345
	 CALL	VDCWHL
VDCAD3:	 CALL	IN2VAD		;Um 2 Zeilen erhoehen
	 LD	C,22		;Screen 3 Start Adr
	ENDIF

VDCWHL: DI
	CALL	VDCOTW
	EI
	RET

VDCOTW:	LD	A,C		;VDC-Register C aus HL setzen
	OUT	(VDCAR),A
	LD	A,H
	OUT	(VDCWR),A
	LD	A,C
	INC	A
	OUT	(VDCAR),A
	LD	A,L
	OUT	(VDCWR),A
	RET
;-----------------------
VDCRDA:	DI
	CALL	VDCIN
	EI
	RET

VDCIN:	OUT	(VDCAR),A	;VDC-Register abfragen
	IN	A,(VDCRD)
	RET

VDCRHL:	DI
	CALL	VDCINW
	EI
	RET

VDCINW:	LD	L,A		;Registerpaar abfragen
	CALL	VDCIN
	LD	H,A
	LD	A,L
	INC	A
	CALL	VDCIN
	LD	L,A
	RET
;------------------------
VDCW30: LD	(VDCR30),A
	LD	C,30
	JR	VDCWRA
VDCW31:	LD	(VDCR31),A
	LD	C,31
VDCWRA:	LD	B,A		;Setze VDC-Register C mit Wert in A
VDCWRB:	LD	A,C
	DI
	CALL	VDCOUT
	EI
	RET

VDCOUT:	OUT	(VDCAR),A	;Adresse setzen
	LD	A,B
	OUT	(VDCWR),A	;Wert setzen
	RET
;------------------------
SSCR1:	PUSH	HL		;Scr 1 + 3 koppeln
	LD	HL,STAT3
	SET	5,(HL)		;Koppel-Flag
	LD	A,(VDCR31)
	SET	4,A
	CALL	VDCW31		;Scr 1+3 Smooth Scroll enable
	LD	A,22
	CALL	VDCRHL		;Scr 3 Start lesen
	CALL	DC2VAD		;2 Zeilen zurueck
	LD	C,12
	CALL	VDCWHL		;Scr 1 Start setzen
	POP	HL
	RET
;-----------------------
NRMVDC: LDB	(SCRCNT),0	;VDC Normalzustand (No Scroll)
	LD	HL,(VDCST)
	CALL	VDCAD
	IF	HD6345
	 SETR	29,0		;smooth scroll enable
	 SETR	18,-1		;screen 2 disable
	 SETR	24,-1		;screen 4 disable
	 LD	A,3		;screen 3 Startpos=4 (interlaced)
	 JPI	NRMVD1
	 LD	A,1		;screen 3 Startpos=2 (non-interlaced)
NRMVD1:	 LD	C,21
	 CALL	VDCWRA
	 LD	A,(STAT2)
	 BIT	1,A		;Statuszeile 1 an ?
	 JP	Z,SSCR1		;nein Screen 1+3 koppeln
	 LD	HL,STAT3
	 RES	5,(HL)		;Koppelflag
	 LD	A,(VDCR31)
	 AND	00001111B
	 SET	6,A
	 CALL	VDCW31		;Scr 3 Smooth Scroll enable
	ENDIF
	RET
;****************************************************************************
;MODUL INIT
;****************************************************************************
	IF	EPAGE EQ 0
ININEU:	DI			;<EER>
	LD	HL,CHKRES	;Flag fuer INIRES setzen, damit keine Datenverlustanzeige
	SET	0,(HL)
	LD	HL,0FFFFH
	LD	(CHKSUM),HL	;Checksummen zerstoeren
	LD	(CHKSJP),HL
	JR	WARM

INIT:	DI
	XOR	A		;Einsprung von Power-On
	LD	(STD),A		;Uhr reset
	LD	(MIN),A
	LD	(SEC),A
	LD	A,50
	LD	(SEC50),A
	LD	HL,CHKRES
	RES	0,(HL)


WARM:	LD	SP,STKH		;Warmstart
	LD	A,HIGH INTVKT
	LD	I,A
	IM	2
	LD	IX,RESDAT	;fuer schnelle BIT-abfrage auf Mode
	LD	A,0FFH
	OUT	(RTS),A		;V-24 Empfang sperren
	CALLB	INISTI		;Initialisiere MK3801
	XOR	A
	OUT	(IMRB),A	;disable any interrupts during Initialization
	OUT	(IMRA),A
	CALLB	INIECB
	CALLB	INIRAM		;Initialisiere System-Ram
	IF	XR
	 CALLB	INIXR		;XR-Karten initialisieren
	ENDIF
	CALL	INIVID		;Initialisiere Video-Ram
	CALLB	INIRES		;residente Parameter + VDC setzen
	IF	XR
	 CALLB	RDJXR		;Read Jumper for XR-Switch Mode
	ENDIF
	CALLB	INIIBM		;ACIA 8255 initialisieren IBM-Tastatur reset


	XOR	A
	OUT	(IPRB),A	;reset any interrupt pending bits
	LD	A,IMRBV
	OUT	(IMRB),A
	LD	A,IMRAV
	OUT	(IMRA),A
	EI			;ab hier Interrupt erlaubt
	LD	A,0FFH
	OUT	(STR),A		;Centronix Strobe 2 High
	XOR	A
	OUT	(RTS),A		;V-24 Empfang ein
	OUT	(PAGE),A
	OUT	(VOL0),A
	OUT	(VOL1),A

	CALL	SETDFB		;Drucker patch area setzen
	IF	XR
	 LD	A,17H		;alle XR-Karten selektieren
	 OUT	(XRFLGS),A
	 CALLB	SETCDA
	ELSE
	 CALLB	SETCDF		;Defaultfarben einstellen fuer alle Karten
	ENDIF
	CALL	STLGEN		;Statuszeilen darstellen
	JP	HAUPT		;Sprung zur variablen Hauptschleife im Ram
;----------------------------------------------------------
INIVDC:	LD	HL,VDCRE	;16 register laden
	LD	BC,0F00H+VDCWR
	DI
INIV:	LD	A,B
	OUT	(VDCAR),A
	OUTI
	OR	A
	JR	NZ,INIV
	EI
	CALL	SETMON		;Noch Monitor-Korrektur
	IF	HD6345
	 SETR	24,-1		;Scr 4 abschalten
	 SETR	27,0		;No Adjust
	 SETR	33,0		;No Offset
	 LD	A,(VDCR30)
	 CALL	VDCW30
	ENDIF
	JP	NRMVDC
;-----------------------
	ENDIF
	IF	EPAGE EQ 1
INIRAM:	LD	HL,STKH		;alle Puffer loeschen nach Stack
	LD	DE,STKH+1
	LD	BC,STL2BF-STKH-1
	LD	(HL),0
	LDIR
	LDB	(USRBUF),0C9H
	LDB	(CHKBYT),41	;Damit <> 0
	LD	HL,IBLK0	;Variablen Defaultwerte
	LD	DE,PARAM	;in Arbeits-Ram
	LD	BC,LT0
	LDIR
	LD	HL,IBLVKT	;Interrupt Vektortabelle generieren
	LD	DE,INTVKT
	LD	BC,LTVKT
	LDIR
	LD	HL,TABVDC
	LD	DE,VDCRE
	LD	BC,LTABVD	;Register 0-15,30,31
	LDIR
	LD	HL,KYBBF
	LD	DE,KYBBF+1
	LD	BC,KBIEND-KYBBF-1
	LD	(HL),' '
	LDIR			;alle Keyboardpuffer loeschen
	RET
;-----------------------
	ENDIF
	IF	EPAGE EQ 0

INIITL:	BIT	0,A		;erwartet ITLFLG in A
	JR	NZ,SETITL	;NON-INT - INTERLACED Umschaltung

	LD	HL,ZLSIZN*2
	LD	A,(STAT2)
	JPBIT	1,A,ININI1
	LD	HL,0
ININI1:	LD	(DSPANF),HL
	LDW	(VDCST),0000H
	LD	(VDCR-13),HL	;Display Startadresse
	LDW	(DSPST),8000H
	LDW	(EXZSLP),VZSATZ+' '*8
	LDW	(SL2FLD),26*ZLSIZN
	LDW	(ZLSIZE),ZLSIZN
	LDW	(CHGPRG),ZADRN
	LDW	(CSP2),0000H	;auch Page 2 HOME
	LDB	(VDCR-8),0	;Display Mode
	LD	A,0FFH
	OUT	(INTL),A
	XOR	A
	OUT	(PAGE),A
	OUT	(DPAGE),A
	JR	SETIT2
	
SETITL:	LD	HL,ZLSIZI*2
	LD	A,(STAT2)
	JPBIT	1,A,SETIT1
	LD	HL,0
SETIT1:	LD	(DSPANF),HL
	LDW	(VDCST),1000H
	LD	(VDCR-13),HL	;Display Startadresse
	LDW	(DSPST),0000H
	LDW	(EXZSLP),VZSATZ+' '*16
	LDW	(SL2FLD),26*ZLSIZI
	LDW	(ZLSIZE),ZLSIZI
	LDW	(CHGPRG),ZADRI
	LDB	(VDCR-8),3	;Display Mode
	XOR	A
	OUT	(INTL),A
	OUT	(DPAGE),A
SETIT2:	CALL	SETZWZ
	CALL	INIVDC
	CALLB	TBWSET
	CALL	INITXN
	LD	A,(PFKT)
	CALL	SETFKT
	CALL	CHOME
	CALLB	LDZROM
	CALL	PTRES		;Spooler abschalten
	CALL	SPLOFF
	RET
	ENDIF
;-----------------------
	IF	EPAGE EQ 1

INISTI:	LD	HL,TABSTI
	LD	BC,0E00H+IDR	;14 direkte STI-Register
DIRLD:	INC	C
	OUTI
	JR	NZ,DIRLD
	LD	BC,800H+IDR	;8 indirekte register
	LD	E,0
IDIRLD:	IN	A,(PVR)		;via PVR Pointer Vektor Register
	AND	11111000B	;adressierbar
	OR	E
	OUT	(PVR),A
	INC	E
	OUTI
	JR	NZ,IDIRLD
	RET
;---------------------
	IF	DEBUG
	DB	'INIXR'
	ENDIF
	IF	XR
INIXR:	LD	A,30H
	OUT	(XRFLGS),A
	LD	A,40H
	OUT	(XRFLGS),A
	LD	A,50H
	OUT	(XRFLGS),A
	LD	A,60H
	OUT	(XRFLGS),A
	LD	A,17H		;read enable alle XR-Karten als enable fuer Register
	OUT	(XRFLGS),A
	LD	A,0FFH
	OUT	(XRCLU2),A	;Color-Lookup Mask Register auf FF=keine Maske
	XRBRES			;Bitcounter reset

	LD	A,01H		;teste ob XR-Karte 1 selektiert
	OUT	(XRFLGS),A	;schreibe im Bitmodus auf XR-Karte 2 byte
	LD	A,20H		;Bitmodus aktivieren
	OUT	(XRFLGS),A
	LD	HL,8000H
	LD	B,55H
	LD	(HL),B
	XRBIT			;increment Bitcounter
	SLA	B
	LD	(HL),B
	XRBRES			;Bitcounter reset
	LD	A,11H		;lese von XR-Karte 1
	OUT	(XRFLGS),A
	LD	A,55H
	CP	(HL)		;wenn Bitmodus lesen nicht moeglich ist
	LD	B,00001000B	;nur Grundkarte aktivieren
	JR	NZ,INIXR1
	LD	B,00000001B	;XR Karte 1 selektieren

INIXR1:	CALL	XRSELA

	LD	A,27H		;Maskenmodus auf Defaultwert alle XR-Maskenmodus
	OUT	(XRFLGS),A
	CALL	XRVID?		;Teste ob Kamera angeschlossen
	RET
;-----------------------
	IF	DEBUG
	DB	'XRVID?'
	ENDIF

XRVID?:	LD	A,(VDCR30)
	OR	11000000B	;TV sync mode display disabled
	CALL	VDCW30
	LD	A,40H
	OUT	(XRFLGS),A
	LD	A,51H
	OUT	(XRFLGS),A	;XR auf SLAVE-Mode schalten um VSYNC zu bekommen
	IN	A,(GPIP)
	AND	00000010B
	LD	D,A
	LD	BC,0FFFFH
XRVID2:	IN	A,(GPIP)	;Teste ob VSYNC sich aendert
	AND	00000010B
	CP	D
	JR	NZ,XRVID1
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,XRVID2	;Time-out erreicht

	LD	HL,XRSTAT
	RES	2,(HL)		;kein VSYNC keine Kamera angeschlossen
	JR	XRVID3
	
XRVID1:	LD	HL,XRSTAT	;Kamera ist angeschlossen
	SET	2,(HL)
XRVID3:	LD	A,40H
	OUT	(XRFLGS),A	;XR auf MASTER-Mode zurueckschalten
	LD	A,50H
	OUT	(XRFLGS),A
	LD	A,(VDCR30)
	AND	00111011B
	CALL	VDCW30		;VDC auf MASTER-Mode zur}ckschalten
	RET

	ENDIF	;XR

	ENDIF	;EPAGE 1
;----------------------
	IF	EPAGE EQ 0

INIVID:	LD	A,(STAT1)	;Video-Ram komplett loeschen
	PUSH	AF
	SET	5,A		;Grundebene auch loeschen
	RES	3,A		;mit 0 Bits
	LD	(STAT1),A
	CALLB	INIVDA
	POP	AF
	LD	(STAT1),A
	RET

CLRCOL:	LD	A,(STAT1)	;<EEz> nur Farbkarte loeschen
	PUSH	AF
	RES	5,A		;Grundebene nicht loeschen
	LD	(STAT1),A
	CALLB	INIVDA
	POP	AF
	LD	(STAT1),A
	JP	STLGEN

CLRVID:	CALL	INIVID		;<EEZ> Video-Ram komplett loeschen mit STLGEN
	JP	STLGEN
	ENDIF
;------------------------
	IF	EPAGE EQ 1

INIVDA:	CALLA	SCROFA		;Bildschirm dunkelschalten wegen Farbkarte
	LD	HL,MODUS	;Farbmodus, damit auch Farbpage geloescht wird
	LD	A,(HL)		;Modus bleibt unveraendert
	PUSH	AF
	SET	7,(HL)		;im Farbmodus loeschen
	IF	XR
	 LD	A,(XRWR)
	 PUSH	AF
	 LD	A,07H
	 LD	(XRWR),A
	 OUT	(XRFLGS),A	;alle XR-Karten loeschen
	 LD	A,(XRRD)
	 PUSH	AF
	 LD	A,17H		;rea select alle XR
	 LD	(XRRD),A	;wegen Hintergrundfarbe in LOE
	 OUT	(XRFLGS),A
	ENDIF
	IF	RAM256
	 CALL	INIVI0		;High-Page loeschen
	 IN	A,(GPIP)
	 XOR	00000100B	;Page wechseln
	 OUT	(GPIP),A
	ENDIF
	CALL	INIVI0
	IF	XR
	 POP	AF
	 LD	(XRRD),A	;XR-Readmodus wieder normal
	 OUT	(XRFLGS),A
	 POP	AF
	 LD	(XRWR),A	;XR-Schreibmodus wieder normal
	 OUT	(XRFLGS),A
	ENDIF
	POP	AF
	LD	(MODUS),A	;Farbmodus wieder normal
	CALLA	SCRONB		;Bild hell
	RET
;----------------------
INIVI0:	JPNI	INIVI1
	LD	HL,0
	LD	BC,8000H
	CALLA	LOE1
	LD	HL,8000H
	LD	BC,8000H
	CALLA	LOE1
	RET

INIVI1:	XOR	A
	OUT	(PAGE),A
	LD	BC,8000H	;Video-Ram Page 1 loeschen
	CALLA	LOE
	SET	7,A
	OUT	(PAGE),A
	LD	BC,8000H	;Video-Ram Page 2 loeschen
	CALLA	LOE
	LD	A,(STAT3)	;normale Anzeigepage wieder anzeigen
	OUT	(PAGE),A
	RET
;-----------------------
INIRES:	CALL	JPCHKS		;Jumperparameter pruefen
	JR	NZ,INIRE1
	LD	A,(TASTAT)	;Checksumme stimmt stelle Tastatur ein
	CALL	TKSET
	LD	A,(TASTBD)
	CALL	TBAUDA
	LD	A,(HOST)	;Hostkanal setzen
	LD	B,A
	CALL	SETHST
	LD	A,(V24EB)
	CALL	V24EI
	LD	A,(V24SB)
	CALL	V24SI
	LD	A,(V24PAR)
	CALL	V24DFA
	JR	INIRE2

INIRE1:	LDB	(ITLFLG),0	;Defaultwerte setzen
	LDB	(MONITR),00100101B
	LDB	(ZWZL),'8'
	LDB	(MSCHST),'0'	;ASCII-Zeichensatz
	LDB	(TXOFFS),35	;TX 560 Pixel vertikal
	CALL	RDJMP		;neue Werte und Checksumme abspeichern
	CALL	JPCHKS
	LD	(CHKSJP),BC
	LD	HL,STAT5
	SET	0,(HL)

INIRE2:	LD	A,(ITLFLG)
	CALLA	INIITL
	CALL	ZSCHKS		;pruefe Checksumme der Zeichensaetze
	JR	Z,INIRE3
	CALL	LDZROM		;ROM-Zeichensatz in Ram kopieren
	CALLA	SL2CLR		;Text der unteren Statuszeile loeschen
	CALL	ZSCHKS		;neue Checksumme bilden
	LD	(CHKSUM),BC	;neue Checksumme abspeichern
	LD	HL,STAT5	;Data lost Flag 2 setzen
	SET	1,(HL)
INIRE3:	LD	HL,CHKRES
	BIT	0,(HL)
	RES	0,(HL)
	RET	Z
	LD	HL,STAT5	;keine Datenverlustanzeige wenn ESC ESC R
	RES	0,(HL)
	RES	1,(HL)
	RET
;-----------------------
JPCHKS:	LD	HL,0		;Checksumme bilden der Jumperdaten
	LD	DE,RESDAT	;Host, Tastatur, V24-parameter
	LD	B,0
JPCHK1:	LD	A,(DE)
	LD	C,A
	ADD	HL,BC
	INC	DE
	LD	A,E
	CP	LOW RESDTE	;Tabelle der resistenten Daten muss < 256 Byte sein
	JR	NZ,JPCHK1
	LD	B,H
	LD	C,L
	LD	HL,(CHKSJP)	;mit alter Checksumme vergleichen
	SUBHL	BC
	RET
;-----------------------
ZSCHKS:	LD	HL,STAT5
	RES	3,(HL)
	LD	HL,0000H	;Checksumme bilden wenn Zeichensatz umdefiniert
	LD	DE,VZSATZ	;wurde
	LD	B,0
ZSCHK1:	LD	A,(DE)
	LD	C,A
	ADD	HL,BC
	INC	DE
	LD	A,D
	CP	HIGH RAMEND
	JR	NZ,ZSCHK1

	LD	DE,STL2BF
ZSCHK2:	LD	A,(DE)		;Text 2.Statuszeile pruefen
	LD	C,A
	ADD	HL,BC
	INC	DE
	LD	A,E
	CP	LOW (STL2BF+BLOCKS)
	JR	NZ,ZSCHK2

	LD	B,H
	LD	C,L
	LD	HL,(CHKSUM)	;mit alter Checksumme vergleichen
	SUBHL	BC
	RET	
;-----------------------
INIIBM:	LD	A,(TASTAT)	;teste ob IBM-Tastatur aktiv
	BIT	3,A
	RET	Z
	
	LD	A,09AH		;Mode 0 PortA,B,C A in B in PC4-7 in PC0-PC2 Ausgang
	OUT	(PARCTL),A
	LD	A,02H		;PC1 Low
	OUT	(PARCTL),A
	LD	BC,8000H	;wait 20 ms or more
IBMRE1:	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,IBMRE1
	LD	HL,IBMRTB	;initialize 8255 Mode 2
	LD	BC,0400H+PARCTL
	OTIR
	RET

IBMRTB:	DB	0C3H,0CH,09H,05H

INIECB:	LD	HL,TB8255	;initialize 8255 Mode 2
	LD	BC,0400H+PARCTL
	OTIR
	RET
TB8255:	DB	0C6H,0CH,09H,05H	;INT ECB out disable, INT Parallel enable
;-----------------------	
IBMCTRL	EQU	1DH	;Control Taste
IBMSH1	EQU	2AH	;Shift Taste links
IBMSH2	EQU	36H	;Shift Taste rechts
IBMALT	EQU	38H	;Alt Taste
IBMNUM	EQU	45H	;NumLock Taste
IBMSCR	EQU	46H	;ScrollLock Taste
IBMCAP	EQU	3AH	;CapsLock Taste
IBMBS	EQU	0EH	;BackSpace Taste fuer RESET Erkennung

IBMKV:	LD	A,(TSTBYT)
	LD	HL,IBMMOD
	JPBITZ	7,A,IBMKV0
	SET	7,(HL)		;Bit 7 gesetzt = release Code
	JR	IBMKV6
IBMKV0:	RES	7,(HL)		;speichere Make oder Break Statusbit
IBMKV6:	RES	7,A		;fuer weitere Untersuchung Bit 7 loeschen
	LD	B,01000000B	;Maske fuer CTRL key
	CP	IBMCTRL
	JR	Z,IBMSPK	;IBM special key erkannt
	LD	B,00100000B	;Maske fuer Shift
	CP	IBMSH1
	JR	Z,IBMSPK
	CP	IBMSH2
	JR	Z,IBMSPK
	LD	B,00010000B	;Maske fuer ALT Key
	CP	IBMALT
	JR	NZ,IBMKEY	;ganz normales Zeichen

IBMSPK:	LD	A,B
	JPBIT	7,(HL),IBMSP1		;HL enthaelt IBMMOD,A enthalt BitMaske
	OR	(HL)			;entsprechendes Bit setzen wenn Taste gedrueckt
	JR	IBMSP2
IBMSP1:	XOR	0FFH			;entsprechendes Bit loeschen wenn losgelassen
	AND	(HL)
IBMSP2:	LD	(HL),A
IBMSP3:	XOR	A		;Z-Bit reset
	DEC	A
	RET

IBMKEY:	BIT	7,(HL)		;Taste wurde losgelassen deshalb keine Aktion
	RET	NZ

	CP	IBMNUM
	JR	NZ,IBMKE7
	LD	A,(HL)
	XOR	00001000B
	JR	IBMSP2
IBMKE7:	CP	IBMSCR
	JR	NZ,IBMKE8
	RES	3,(HL)
	JR	IBMSP3
IBMKE8:	CP	IBMCAP
	JR	NZ,IBMKE9
	LD	A,(HL)
	XOR	00000100B
	JR	IBMSP2

IBMKE9:	LD	D,(HL)		;IBMMOD
	JRNZW	47H,53H,IBMKE1
	LD	HL,IBMNTB	;IBM Umcodetabelle fuer Numerikblock
	SUB	47H
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	A,(HL)
	BIT	3,D
	JR	Z,IBMK99
	SET	7,A		;bei nicht NUMLOCK setze 8.bit
	JR	IBMK99
	
IBMKE1:	LD	HL,IBMTAB	;IBM Umcodetabelle Basis
	BIT	6,D		;Ctrl
	JR	Z,IBMKE3
	LD	HL,IBMTAB+2*48H
	JR	IBMKE5
IBMKE3:	BIT	5,D		;Shift
	JR	Z,IBMKE4
	LD	HL,IBMTAB+48H
	JR	IBMKE5
IBMKE4:	BIT	2,D
	JR	Z,IBMKE5
	JRZW	2CH,32H,IBMKE6
	JRZW	1EH,28H,IBMKE6
	JRNZW	10H,1AH,IBMKE5
IBMKE6:	LD	HL,IBMTAB+48H	;CapsLock aktiv
IBMKE5:	BIT	4,D
	JR	Z,IBMKE2
	LD	BC,3*48H
	ADD	HL,BC
	BIT	6,D
	JR	Z,IBMKE2
	CP	IBMBS
	JP	Z,WRMJMP
IBMKE2:	LD	B,0
	LD	C,A
	ADD	HL,BC
	LD	A,(HL)

IBMK99:	LD	(TSTBYT),A
	CP	A		;Z-Bit set, Tastencode in TSTBYT
	RET
IBMNTB:	DB	37H,38H,39H,2DH,34H,35H,36H,2BH,31H,32H,33H,30H,2EH

IBMTAB:	DB	000H,01BH,031H,032H,033H,034H,035H,036H	;00H Norm
	DB	037H,038H,039H,030H,07EH,027H,008H,009H
	DB	071H,077H,065H,072H,074H,07AH,075H,069H	;10H
	DB	06FH,070H,07DH,02BH,00DH,000H,061H,073H
	DB	064H,066H,067H,068H,06AH,06BH,06CH,07CH	;20H
	DB	07BH,023H,000H,03CH,079H,078H,063H,076H
	DB	062H,06EH,06DH,02CH,02EH,02DH,000H,0AAH	;30H
	DB	000H,020H,000H,0C0H,0C1H,0C2H,0C3H,0C4H
	DB	0C5H,0C6H,0C7H,0C8H,0C9H,000H,000H,000H	;40H

	DB	000H,01BH,021H,022H,040H,024H,025H,026H	;00H Shift
	DB	02FH,028H,029H,03DH,03FH,060H,008H,009H
	DB	051H,057H,045H,052H,054H,05AH,055H,049H	;10H
	DB	04FH,050H,05DH,02AH,00DH,000H,041H,053H
	DB	044H,046H,047H,048H,04AH,04BH,04CH,05CH	;20H
	DB	05BH,05EH,000H,03EH,059H,058H,043H,056H
	DB	042H,04EH,04DH,03BH,03AH,05FH,000H,090H	;30H
	DB	000H,020H,000H,0E0H,0E1H,0E2H,0E3H,0E4H
	DB	0E5H,0E6H,0E7H,0E8H,0E9H,000H,000H,000H	;40H

	DB	000H,01BH,031H,040H,000H,034H,035H,036H	;00H Ctrl
	DB	037H,038H,039H,030H,07EH,027H,07FH,009H
	DB	011H,017H,005H,012H,014H,01AH,015H,009H	;10H
	DB	00FH,010H,01DH,05DH,00DH,000H,001H,013H
	DB	004H,006H,007H,008H,00AH,00BH,00CH,01CH	;20H
	DB	01BH,01EH,000H,05CH,019H,018H,003H,016H
	DB	002H,00EH,00DH,02CH,02EH,01FH,000H,090H	;30H
	DB	000H,020H,000H,0C0H,0C1H,0C2H,0C3H,0C4H
	DB	0C5H,0C6H,0C7H,0C8H,0C9H,000H,000H,000H	;40H

;	Mit ALT

	DB	000H,09BH,0B1H,0B2H,0B3H,0B4H,0B5H,0B6H	;00H Norm
	DB	0B7H,0B8H,0B9H,0B0H,0FEH,0A7H,088H,089H
	DB	0F1H,0F7H,0E5H,0F2H,0F4H,0FAH,0F5H,0E9H	;10H
	DB	0EFH,0F0H,0FDH,0ABH,08DH,000H,0E1H,0F3H
	DB	0E4H,0E6H,0E7H,0E8H,0EAH,0EBH,0ECH,0FCH	;20H
	DB	0FBH,0A3H,000H,0BCH,0F9H,0F8H,0E3H,0F6H
	DB	0E2H,0EEH,0EDH,0ACH,0AEH,0ADH,000H,09AH	;30H
	DB	000H,0A0H,000H,0D0H,0D1H,0D2H,0D3H,0D4H
	DB	0D5H,0D6H,0D7H,0D8H,0D9H,000H,000H,000H	;40H

	DB	000H,09BH,0A1H,0A2H,0C0H,0A4H,0A5H,0A6H	;00H Shift
	DB	0AFH,0A8H,0A9H,0BDH,0BFH,0E0H,088H,089H
	DB	0D1H,0D7H,0C5H,0D2H,0D4H,0DAH,0D5H,0C9H	;10H
	DB	0CFH,0D0H,0DDH,0AAH,08DH,000H,0C1H,0D3H
	DB	0C4H,0C6H,0C7H,0C8H,0CAH,0CBH,0CCH,0DCH	;20H
	DB	0DBH,0DEH,000H,0BEH,0D9H,0D8H,0C3H,0D6H
	DB	0C2H,0CEH,0CDH,0BBH,0BAH,0DFH,000H,0A0H	;30H
	DB	000H,0A0H,000H,0F0H,0F1H,0F2H,0F3H,0F4H
	DB	0F5H,0F6H,0F7H,0F8H,0F9H,000H,000H,000H	;40H

	DB	000H,09BH,0B1H,0C0H,080H,0B4H,0B5H,0B6H	;00H Ctrl
	DB	0B7H,0B8H,0B9H,0B0H,0FEH,0A7H,0FFH,089H
	DB	091H,097H,085H,092H,094H,09AH,095H,089H	;10H
	DB	08FH,090H,09DH,0DDH,08DH,000H,081H,093H
	DB	084H,086H,087H,088H,08AH,08BH,08CH,09CH	;20H
	DB	09BH,09EH,000H,0DCH,099H,098H,083H,096H
	DB	082H,08EH,08DH,0ACH,0AEH,09FH,000H,0A0H	;30H
	DB	000H,0A0H,000H,0D0H,0D1H,0D2H,0D3H,0D4H
	DB	0D5H,0D6H,0D7H,0D8H,0D9H,000H,000H,000H	;40H

;-----------------------

	IF	DEBUG
	DB	'IBLK0'
	ENDIF

;===== Ram Initialisierungsblock ab 4600H =====

IBLK0	EQU	$

	CALL	EXHBF	;HAUPT Host Input Verarbeitung
	CALL	KCHM	;Keyboard Input Verarbeitung
	JR	$+3	;BLINK
	NOP
	JR	$+3	;CXVA
	NOP
	JR	$+3	;THPT
	NOP
	JR	$+3	;SRERR
	NOP
	JR	$+3	;TONZL
	NOP
	JR	$+3	;MELO
	NOP
	JR	$+3
	NOP
	JP	HAUPT	;Ruecksprung zum Ablauffeldanfang

	DW	0000H	;ZHLPTR
	DW	ECBIBF	;ECBILP
	DW	ECBIBF	;ECBIVP
	DW	KYBBF	;KYBLP
	DW	KYBBF	;KYBVP
	DW	KYBBF
	DW	KYBEND
	DW	KBIBF	;KYBILP
	DW	KBIBF	;KYBIVP
	DW	KBIBF
	DW	KBIEND
	DW	KBSBF	;KYBSLP
	DW	KBSBF	;KYBSVP
	DW	KBSBF
	DW	KBSEND
	DW	SINBF	;SINLP
	DW	SINBF	;SINVP
	DW	SPOLBF	;SPOLLP
	DW	SPOLBF	;SPOLVP
	DW	0	;UEZHL
	DB	0	;WRKCHR
	DB	0	;OUTCHR
	DB	10H	;BLNKR
	IF	XR
	 DB	8	;EBNVP
	 DB	8	;EBNLP
	 DB	0	;VRAMSP
	ELSE
	 DB	4	;EBNVP
	 DW	FRBPUF	;EBNLP
	ENDIF
	DB	80	;SPANZ
	DB	24	;ZLANZ
	DB	0FFH	;LINTYP
	DW	ZLSIZN	;ZLSIZE
	DW	0000H	;UEGRZ
	DB	0	;HRDDRK Default EPSON
	DW	STL2BF	;ST2LPT
	DW	0000H	;SPLINH
	DB	0	;VRAMZL
	DB	0	;IXHMT
	DB	00001001B,00H	;MODUS

	DW	VZSATZ	;CHSET
	DW	8600H	;CURPT
	DW	0	;VDCST
	DW	0	;VDCST2

	DB	0	;CSP	Anordnung beibehalten ! SPLDEF
	DB	0	;CZL
	DW	8000H	;DSPST
	DW	ZLSIZN*2	;DSPANF
	DW	8000H	;GCPOS
	DB	1	;GCMSK Zusatzrand
	DB	0	;CSP2  WPAGE in Interlaced
	DB	0	;CZL2  SPCNT in Interlaced
	DW	8000H	;DSPST2
	DW	ZLSIZN*2	;DSPAN2
	DW	8000H	;ENDPOS
	DB	1	;ENDMSK

	DB	10H	;BLKSPD default Cursor Blinkgeschwindigkeit
	DW	STDTAB	;KOMTAB statische Kommandotabelle
	DW	STDESC	;ESCTAB
	DW	STESCH	;ESCCHR
	DW	LSTECH	;LESCCH,Laenge der Zeichentabelle
	DW	SKVTAB	;SKVLP	
	IF	XR
	DB	00H	;STAT1	;Schreibfarbe ist transparent bei XR, also ohne Grundebene
	ELSE
	DB	60H	;STAT1	;Schreibfarbe ist nicht transparent fuer Grip-Color
	ENDIF
	DB	02H	;STAT2
	DB	00H	;STAT3
	DB	54H	;STAT4
	DB	04H	;STAT5
	DB	8	;BRTFLG
	DB	0,0	;ABLMRK

	DW	0000H	;BYTCNT
	DB	0	;TSTBYT
	DW	0000H	;VRAMAD
	DW	26*ZLSIZN	;SL2FLD
	DW	USRBUF	;USRLP
	DW	USRBUF	;PTCHLP
	DW	HRDCBF	;HRDCLP
	DB	0	;SCRCNT
	DW	0000H	;QULVP
	JP	CXOUT	;ZLBLD
	JP	CXOPL	;ZLPLZ
	JP	SINIP1	;QUVA
	JP	SINIPL	;QUINH
	JP	HBFVA	;HBINPR
	DW	MELPUF	;MELLP Melodie Ladepointer
	DW	MELPUF	;MELVP Melodie Verarbeitungspointer
	DB	0	;MELDAU
	DB	0	;IBMCNT
	DB	30H	;ATTRIB
	DB	00H	;ATRFLG
	DW	VZSATZ+' '*8	;EXZSLP
	DW	ZLCX	;ZLVAP Centronix-Ausgabe
	JP	STDRT	;ABPROG
	JP	STDRT	;ZLRET
	DW	QUOFF	;QUVAP 
	DW	P0P	;ZPTR Zustandspointer Koordinatenaufnahme
	DW	VKTGEN	;VKTPRG Vektorverarbeitung
	DW	EXHBF	;MASTER Host Input Verarbeitung
	DB	0	;KYIR
	DB	0	;KYIBM
	DB	IBMSTB	;IBMBIT
	DW	IBMBUF	;IBMPT
	DB	50H	;TABC
	DB	24	;SKDRH
	DB	48	;SKDR
	DW	0000H	;VDPT
	DB	0	;XOFLG
	DB	8	;SKBC seriell Keyb. Bitcounter
	DB	8	;SKBW seriell Keyb. Wortlaenge
	JP	0000	;not used, early NMIJP but sorry no longer available
	DB	0	;Jumperstellung
	JP	POR	;PIXLOG Pixellogik TTX Vektormodus
	DB	0	;PFKT

	DW	TBWTVI	;CHRPRG Charactererzeugung TVI default
	JP	CHROR	;CHRFKT Charakterlogik TTX Alpha
	DW	CHROR	;CHRFKS

	DB	0	;HBYT
	IF	XR
	DB	00H	;XRWR
	DB	10H	;XRRD
	DB	10H	;XRRDC
	DB	00H	;XRVID
	ELSE
	DB	10110110B;COLRG1 R/W Grunde. Farbe 1
	DB	10110110B;COLRG2 R/W Grunde. Farbe 1
	DB	10101111B;Hintergrundfarbe fuer TVI-Farbmodus
	DB	10101111B; "
	ENDIF
	DW	0,0,0,0	;X2,Y2,X1,Y1
	DB	0	;EBENE Farbausleseebene=Grundebene
	DB	1	;DRKSPL
	DB	0	;SCRTIM
	DW	ZADRN	;CHGPRG
	DW	8000H	;DSPST4
	DW	8000H-34*ZLSIZN+7	;TXNULL
	DB	00001000B		;IBMMOD NumLock aktiv

	IF	XR
	DB	00H	;HRDKTR Hardcopykontrast bis Farbnr 0 incl. weiss
	DB	1,3FH,0,0,3FH,0,0	;XRCOLT zuletzt mit <EEW><EEw> eingestellte Farbe
	DB	47	;XRCOL XR aktuelle Schreibfarbe
	DB	0	;XRHGF XR Hintergrundfarbe
	DB	0	;XRSTAT
	JP	0	;SETRGB Farbkomprimierroutine wird bei Aufruf eingesetzt
	DB	4,1,1,1,1,2,1,1,1,1	;KVMTRX als 2^(n-1) mit Vorzeichen
	DW	0	;KVCLIP Kovolution Clipping-Konstante signed decimal
	DW	KVLSPB	;KVLBPT Pointer auf Spaltenzwischenspeicher
	DB	1	;ALIASG AntiAliasing aktiv
	ELSE
	DB	0,0,0,0,0,0,0,0,0,0
	DB	0,0,0,0,0,0,0,0,0,0
	DB	0,0,0,0,0,0,0,0,0	;frei
	ENDIF

LT0	EQU	$-IBLK0


;===== Tabelle der Interrupt-Vektoren =====


IBLVKT	EQU	$
I0:	DW	RETI
I1:	DW	ITIMER	;50 Hz Sync
I2:	DW	RETI
I3:	DW	RETI
I4:	DW	RETI	;TDINT 		disabled
I5:	DW	RETI	;TCINT 		disabled
I6:	DW	PBINT	;INT PORT B 	paralleles Keyboard
I7:	DW	KSERIN	;INT 		serielles Keyb.
I8:	DW	RETI	;TBINT 		disabled
I9:	DW	RETI	;Transmit error Int.
I10:	DW	RETI
I11:	DW	RERRI	;receive error Int.
I12:	DW	SININT	;serielle Eingabe Int.
I13:	DW	ITA	;Timer A Int.
I14:	DW	RETI	;externer Int.
I15:	DW	ECBINT	;ECB-Bus Int.hoechste Prioritaet
LTVKT	EQU	$-IBLVKT

	IF	DEBUG
	DB	'TABVDC'
	ENDIF

;===== VD-Controller 15 MHz Initialisierung =====

HSYNC	EQU	BLOCKS+3
VSYNC	EQU	VBLKS

TABVDC:	DW	0000H		;VDC-Cursorposition
	DW	0000H		;Display Start
	DB	7		;Cursor End-Zeile
	DB	7		;Cursor Start-Zeile
	DB	7		;Scan-lines pro Zeile
	DB	00000000B	;Interlace/Skew/Blink
	DB	VSYNC		;Vert. Sync Zeichenzeilen
	DB	26		;displayed Zeilen 24+2
	DB	0		;vertical adjust
	DB	38		;vertical total
	DB	33H		;Sync Laenge
	DB	HSYNC		;Hor. Sync Pos.
	DB	BLOCKS		;Zeichen pro Zeile
	DB	BLOCKS+23	;Hor. total Zeilen
	DB	01000000B	;Control 2, Reg 31
	DB	00000011B	;Control 1, Reg 30
LTABVD	EQU	$-TABVDC

TABSTI:	DB	0		;GPIP
	DB	0		;IPRB
	DB	0		;IPRA
	DB	0		;ISRB Interrupt in Service Register
	DB	0		;ISRA
	DB	IMRBV		;IMRB Interrupt Mask Register
	DB	IMRAV		;IMRA V24 enable

 VRA	EQU	LOW INTVKT OR 08H

	DB	VRA		;PVR Pointer/Vector Register
	DB	0		;TABCR Timer A/B-Control,stopped
	DB	0		;TBDR  Timer Datenregister Sound
	DB	52		;TADR  Timer Datenregister serial Keyboard
	DB	88H		;UCR,/1,7-BIT-W,1 ST/1 STP,NO P.
	DB	1		;RSR Receive enable
	DB	83H		;TSR Transmit enable, Ruhepegel LOW
;INDIREKTE REGISTER
	DB	0		;SCR
	DB	3		;TDDR Timer Datenregister V24 receive 9600
	DB	3		;TCDR Timer Datenregister V24 transmit 9600
	DB	10010010B	;AER
	DB	IMRBV		;IERB enable 8 Interrupts
	DB	IMRAV		;IERA
	IF	RAM256
	 DB	00000100B	;DDR Datenrichtung INPUT ausser XA8
	ELSE
	 DB	0
	ENDIF
	DB	11H		;TCDCR TIMER C/D-Control Prescale 4

;-----------------------
TABJ3A:	DW	HKYB	;Host Keyboard Local Modus 5-6
	DW	HB24	;Host V24	9600 Baud  1-2
	DW	HB6	;		1200 Baud  4-5
	DW	HB12	;		4800 Baud  2-3
	DW	HECB	;Host ECB-Bus              offen
TABJ3B:	DW	T7S60	;Tastatur seriell  600 Baud 7 Bit 11-12
	DW	T8S12	;	  seriell 1200 Baud 8 Bit  7-8
	DW	TIBM	;	  custom modified IBM extern getaktet 8 bit 10-11
	DW	TIBMKV	;	  original IBM extern getaktet Umcodierung aktiv 8 bit 8-9
	DW	TPAR	;Tastatur parallel 8 bit
	IF	XR
TABJ3C:	DW	JMPRET
	DW	JMPRET
	DW	JMPRET
	DW	XRSWTC	;XR Switch Betrieb
	DW	JMPRET
	ENDIF
;-----------------------
	IF	DEBUG
	DB	'RDJMP'
	ENDIF
RDJMP:	LD	B,00100000B	;Jumper J3/5 auswerten, Tastaturdef.
	LD	HL,TABJ3B
	CALL	JSTAT
	LD	B,00010000B	;Jumper J3/4 auswerten, Hostdef.
	LD	HL,TABJ3A
	CALL	JSTAT
	LD	A,00001010B	;V24parameter voreinstellen
	CALL	V24DFA
	RET
	IF	XR
RDJXR:	LD	B,00010000B
	LD	HL,TABJ3C
	CALL	JSTAT
	RET
	ENDIF
;-----------------------
JSTAT:	LD	A,0FFH
	OUT	(VOL0),A	;Jumperfeld 3 in 2 Abschnitten einlesen
	OUT	(VOL1),A	;B enthaelt Maske fuer Bit 4 oder 5
	OUT	(PAGE),A
	LD	C,0

	IN	A,(STATR)	;je 5 Stellungen sind moeglich
	AND	B
	JR	NZ,JSTAT1	;Stellung GND !

	INC	C
	XOR	A
	OUT	(VOL0),A
	IN	A,(STATR)
	AND	B
	JR	NZ,JSTAT1	;Stellung VOL0 !

	INC	C
	XOR	A
	OUT	(VOL1),A
	IN	A,(STATR)
	AND	B
	JR	NZ,JSTAT1	;Stellung VOL1 !

	INC	C
	XOR	A
	OUT	(PAGE),A
	IN	A,(STATR)
	AND	B
	JR	NZ,JSTAT1	;Stellung PAGE !
	INC	C		;Jumper offen !

JSTAT1:	LD	B,0
	RL	C		;BC= 0,2,4,6,8
	LD	A,C
	EX	DE,HL
	LD	HL,JUMPER
	RRD			;2*4 Bit Jumperstellung abspeichern
	EX	DE,HL

	ADD	HL,BC		;Programm aus Tabelle in HL berechnen
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	EX	DE,HL
	JP	(HL)		;Absprung zum berechneten Programmteil

HB6:	LD	A,'7'		;Position 1200 Baud
	JR	HSER
HB12:	LD	A,'9'		;Position 4800 Baud
	JR	HSER
HB24:	LD	A,':'		;Position 9600 Baud

HSER:	PUSH	AF		;Host ist seriell
	CALL	V24SI
	POP	AF
	CALL	V24EI		;Sende- und Empfangsbaudrate einstellen
	LD	B,2		;Modus fuer seriell V24
	LD	HL,SINIP1	;Initialisierung der Hostprogramme im Ram
	LD	DE,SINIPL
	EXX
	LD	HL,V24OUT
	LD	DE,V24OPL
	JR	COM4J3

HKYB:	LD	B,0
	LD	HL,KBFIN	;Local Modus
	LD	DE,KBFIPL
	EXX
	LD	HL,KBFOUT	;Dummy Ausgabe im Local Modus 
	LD	DE,KBFOPL
	JR	COM4J3

HECB:	LD	B,1		;alle anderen Parameter voreingestellt
	LD	HL,ECBIP1
	LD	DE,ECBIPL
	EXX
	LD	HL,ECBOUT
	LD	DE,ECBOPL

COM4J3:	LD	A,0C3H		;JP
	LD	(HBFLD),A
	LD	(HBPLZ),A
	LD	(HBFRD),A
	LD	(HBINH),A
	LD	(HBFLD+1),HL
	LD	(HBPLZ+1),DE
	EXX
	LD	(HBFRD+1),HL
	LD	(HBINH+1),DE

SETHST:	LD	A,(MODUS)	;Hostkanalkennung in MODUS eintragen
	AND	11111100B
	OR	B
	LD	(MODUS),A
	LD	A,B
	LD	(HOST),A
	RET
;-----------------------
TPAR:	LD	C,00000000B	;parallel Tastatur enable
	JR	TAST
;	----------------
TIBM:	LD	C,00001000B	;Tastatu IBM  bit Umcodierung inaktiv
	JR	TAST
TIBMKV:	L	C,10001000	;Tastatu IBM  bit Umcodierung aktiv
	JR	TAST
;	----------------
T7S12:	LD	A,6
	CALL	TBAUDA
	LD	C,01010000B	;Tastatur 1200 Baud 7 bit
	JR	TSER

T8S12:	LD	A,6
	CALL	TBAUDA
	LD	C,00010000B	;Tastatur 1200 Baud 8 bit
	JR	TSER

T7S60:	LD	A,5
	CALL	TBAUDA
	LD	C,01010000B	;Tastatur 600 Baud 7 bit

TSER:	IN	A,(GPIP)	;Tastaturpolaritaet testen
	AND	00100000B
	JR	NZ,TAST
	SET	5,C

TAST:	LD	A,C
	CALL	TKSET		;Tastaturparameter setzen
JMPRET:	RET

	IF	XR
XRSWTC:	LD	A,0C2H		;8255 PortB Input
	OUT	(PARCTL),A
	IN	A,(PBDA)
	BIT	7,A
	RET	Z
	LD	HL,STAT2
	RES	1,(HL)		;keine Statuszeile
	LD	HL,STAT4
	RES	4,(HL)		;Cursor aus
	LD	HL,XRMAIN
	LD	(MASTER),HL
	LD	(HAUPT+1),HL	;Replace EXHBF by XRMAIN Routine
	RET
	ENDIF
;----------------------------
	ENDIF	;EPAGE 1
	IF	EPAGE EQ 0
;****************************************************************************
;MODUL PUF	Pufferverwaltung
;****************************************************************************
	IF	DEBUG
	DB	'PUF'
	ENDIF

SIBLEN	EQU	SIBEND-SINBF
KYBLEN	EQU	64		;fester Wert wegen KBFDSP
ECILEN	EQU	ECIEND-ECBIBF
;-----------------------
INHALT:	LD	A,L		;LP 	Inhaltermittlung
	SUB	E		;VP
	RET	NC		;Anzahl in A
	ADD	A,B		;Pufferlaenge addieren
	RET			;Anzahl in A
;-----------------------
	ENDIF

PLATZ:	LD	A,L		;Platzermittlung
	SUB	E		;LP-VP
	CPL			;(VP-1)-LP
	RET	C		;Platz in A
NCPL:	ADD	A,B		;-Inhalt + Laenge-1
	RET			;Platz in A
;-----------------------
BFL:	LD	(HL),A		;Pufferladen A -> (HL) mit Grenzen in BC
	INC	L
	LD	A,B
	CP	L
	RET	NZ
	LD	L,C
	RET			;Einsprung fuer Dummy-Interruptverwaltung
;-----------------------
;Pufferladeroutine BFLD: Ladepointer in HL,Verarbeitungspointer in DE
;Ladebyte in A, Startadr. in C, Endadr. in B
BFLD:	CALL	BFL
	LD	A,E
	CP	C
	JR	NZ,BFLD1	;VP nicht am Pufferanf.
	LD	A,B		;Pufferende (+1)
BFLD1:	DEC	A
	CP	L		;wenn LP=VP-1, dann ist Puffer voll
	RET			;wenn voll Z-Flag gesetzt
;-----------------------
	IF	EPAGE EQ 0

BFVA:	LD	A,E		;Pufferentladen Pointer wie oben
	CP	L
	RET	Z		;Puffer leer VP=LP
BFV:	LD	A,E		;(DE)->A mit Grenzen in BC
	INC	A
	CP	B		;VP am Pufferende ?
	LD	A,(DE)
	JR	NZ,BFVA1	;nein
	LD	E,C
	DEC	E
BFVA1:	INC	E
	DEC	C		;NZ
	RET
;-----------------------
CXOUT:	OUT	(CNTRX),A
	OUT	(CXSTB),A
	XOR	A
	OUT	(STR),A
	LD	A,0FFH
	OUT	(STR),A
	RET
;-----------------------
CXOPL:	IN	A,(GPIP)	;Centronix Ausgabe
	AND	00001000B	;Busy ?
	RET			;bei NZ, warten
;-----------------------
KBFINA:	LD	DE,(KYBPT)	;lesen aus beliebigem Keyboardbuffer
	PUSH	DE		;HL zeigt auf Ladepointer KYBLP,SLP,ILP
	LD	(KYBPT),HL
	CALL	KBFIN
	POP	DE
	LD	(KYBPT),DE
	RET
;-----------------------
KBFIN:	LD	HL,(KYBPT)	;1 Byte ausaktuellem Keyboardbuffer holen
	LDRI	D,E,HL
	PUSH	DE
	LDRI	D,E,HL
	LDRI	B,C,HL
	LD	B,(HL)
	POP	HL
	CALL	BFVA
	LD	HL,(KYBPT)	;Keyboard VP erhoehen
	INC	HL
	INC	HL
	LD	(HL),E
	INC	HL
	LD	(HL),D
	RET
;-----------------------
KBFIPL:	LD	HL,(KYBPT)
KBFIPA:	LDRI	D,E,HL		;Einsprung von Quellkanal Keyboard
	PUSH	DE
	LDRI	D,E,HL
	POP	HL
	LD	B,KYBLEN
	CALL	INHALT
	RET
;-----------------------
KBFOPL:	XOR	A		;Z Flag Dummy Ausgabe an Keyboard in Local Mode
	RET
KBFOUT:	DI			;DI weil KCHS INT-Routine
	LD	HL,(KYBPT)
	CALL	KCHS		;Wenn Puffer voll werden alle folgenden Zeichen
	EI			;ignoriert
	RET
;-----------------------
ECBOUT:	OUT	(ECBDA),A	
	RET
;-----------------------
ECBOPL:	IN	A,(PARST)
	AND	10000000B
	JR	NZ,ECBOP1
	DEC	A		;NZ wenn Ausgabe gesperrt
	RET
ECBOP1:	CP	A
	RET
;-----------------------
;ECB-INPUT-Verarbeitungsroutinen
ECBIP1:	DI
	LD	HL,(ECBILP)	;1 Byte aus ECB-Input Puffer laden
	LD	DE,(ECBIVP)
	LD	B,LOW ECIEND
	LD	C,LOW ECBIBF
	CALL	BFVA		;Z bei Puffer leer, sonst Byte in A
	LD	(ECBIVP),DE
	PUSH	AF
	IN	A,(IMRA)	;enable Receive Int wenn Puffer leer
	BIT	7,A
	JR	NZ,ECBIP3
	SET	7,A
	OUT	(IMRA),A
ECBIP3:	EI
	POP	AF
	RET
;-----------------------
ECBIPL:	LD	HL,(ECBILP)
	LD	DE,(ECBIVP)
	LD	B,LOW ECILEN	;=0 bei 256 Byte Puffergroesse
	CALL	INHALT
	LD	B,LOW ECIEND
	LD	C,LOW ECBIBF
	LD	HL,ECBIVP
	RET
;-----------------------
;V24-INPUT-Verarbeitungsroutinen
SINIP1:	DI
	LD	HL,(SINLP)
	LD	DE,(SINVP)
	LD	B,LOW SIBEND
	LD	C,LOW SINBF
	CALL	BFVA		;Z bei Puffer leer, sonst Byte in A
	LD	(SINVP),DE
	EI
	PUSH	AF
	CALL	INHALT		;wenn weniger als 8 byte im Puffer
	CP	8		;Empfang einschalten
	JR	NC,SIP1NP

	LD	A,(MODUS)
	JPBITZ	6,A,SIP1N1

	LD	A,(XOFLG)	;wenn XOFF gesendet 1 * XON senden
	JPBITZ	7,A,SIP1NP
	LD	B,A
	IN	A,(TSR)
	JR	Z,SIP1NP
	LD	A,B
	RES	7,A
	LD	(XOFLG),A
	LD	A,XON
	OUT	(UDR),A
	JR	SIP1NP

SIP1N1:	XOR	A
	OUT	(RTS),A
SIP1NP:	POP	AF
	EI
	RET
;-----------------------
SINIPL:	LD	HL,(SINLP)
	LD	DE,(SINVP)
	LD	B,LOW SIBLEN
	CALL	INHALT
	LD	B,LOW SIBEND
	LD	C,LOW SINBF
	LD	HL,SINVP
	RET
;-----------------------
;V24-OUTPUT-Laderoutinen
V24OUT:	OUT	(UDR),A
	RET
;-----------------------
V24OPL:	IN	A,(TSR)		;Transmitter Buffer empty ?
	AND	10000000B
	JR	NZ,V24OP1
	DEC	A
	RET
	
V24OP1:	LD	A,(MODUS)	;XON/XOF Protokoll aktiv
	JPBITZ	6,A,V24OP3
	LD	A,(XOFLG)
	BIT	6,A
	RET

V24OP3:	IN	A,(GPIP)	;CTS aktiv ?
	AND	00000001B
	RET
;-----------------------
ADLD:	CALL	HBINH
	CP	4
	JR	C,ADLDZ		;nicht genuegend Daten,Z-Ausgang
	CALL	HBFRD		;Adresse aus Hostpuffer nach HL
	LD	(ARBF+1),A	;HWHB von HWB
	CALL	HBFRD
	LD	(ARBF),A	;NWHB von HWB
	CALL	HBFRD
	LD	(ARBF+3),A	;HWHB von NWB
	CALL	HBFRD
	LD	(ARBF+2),A	;NWHB von NWB
	LD	HL,(ARBF)
	CALL	GET		;HWB in A
	LD	E,A
	LD	HL,(ARBF+2)
	CALL	GET		;NWB in A
	LD	H,E
	LD	L,A
	OR	0FFH
	RET			;NZ-Ausgang
ADLDZ:	CP	A
	RET
;----------------------------
PUT:	PUSH	BC		;Binaerzahl in A als HEX-Wert in HL
	LD	B,4		;umformen
PUTH:	SLA	A
	RL	H
	DJNZ	PUTH
	LD	B,4
PUTL:	SLA	A
	RL	L
	DJNZ	PUTL
	LD	A,H
	CALL	ED
	LD	H,A
	LD	A,L
	CALL	ED
	LD	L,A
	POP	BC
	RET

ED:	AND	0FH		;0 -> 30H
	OR	30H
	CP	3AH		;A -> 41H
	JP	C,ED1
	ADD	A,7
ED1:	RET
;-----------------------
GET:	PUSH	BC		;HEX-Wert in HL zu Binaerzahl (A)
	LD	A,L		;umformen
	CALL	DED
	LD	L,A
	LD	A,H
	CALL	DED
	LD	B,4
GETL:	SLA	A
	DJNZ	GETL
	OR	L
	POP	BC
	RET

DED:	CP	40H
	JP	M,DEDL
	AND	0FH
	ADD	A,9
	RET
DEDL:	AND	0FH
	RET
;-----------------------
HBFVA:	CALL	HBFRD		;HBINPR bei ECB-Host
	LD	(WRKCHR),A
	RET
;****************************************************************
;* MODUL LOOP Hauptprogrammschleife
;****************************************************************
VPSUB:	POP	HL		;neue Masterroutine einsetzen
	LD	(HAUPT+1),HL
	JP	(HL)
VPSUB2:	POP	HL
	LD	(HAUPT+4),HL
	JP	(HL)
;-----------------------
	IF	XR
	IF	DEBUG
	DB	'XRMAIN'
	ENDIF
XRMAIN:	LD	A,0C2H		;PortB normal Input Mode
	OUT	(PARCTL),A
	CALLB	XRSPKT
	LDB	(ZLANZ),35
	CALL	SETDSP		;Full screen
	LD	A,4		;NEC P6 Grauausdruck
	LD	(HRDDRK),A
	LD	HL,STAT3	;invertiert
	SET	6,(HL)
	CALL	VPSUB

	IN	A,(PBDA)	;test for Interlaced
	AND	00000001B
	XOR	00000001B
	CALL	ITLCHA

XRMAI1:	IN	A,(PBDA)
	BIT	2,A
	JR	NZ,XRMAI3
	CALL	XRGENL
	JR	XRMAI2
XRMAI3:	CALL	XRGEOF

XRMAI2:	IN	A,(PBDA)
	BIT	3,A
	JR	NZ,XRMAI4
	CALL	XRSCON
	JR	XRMAI5
XRMAI4:	CALL	XRSCOF

XRMAI5:	IN	A,(PBDA)
	BIT	6,A
	JR	NZ,XRMAI6
	CALL	HRDCOP
XRMAI6:	RET
	ENDIF	;XR
;----------------------	

	IF	DEBUG
	DB	'EXHBF'
	ENDIF

EXHBF:	CALL	HBINPR		;Hauptroutine zur Zeichenverarbeitung
	JR	NZ,EXHBF1	;im TVI oder TX Alpha Mode
	JP	CURORG		;Cursor an wenn Empfang zu Ende

EXHBF1:	CALL	CUROFF		;Cursor aus wenn Zeichen empfangen werden
	LD	A,(WRKCHR)
	LD	HL,ABLMRK
	JPBIT	1,(HL),ESCEX	;ESC-Sequenz
	CP	20H
	JP	C,KOMEX		;Programm f}r Controlcodeinterpretation
	JPBITZ	7,A,DSPCHR

EXHBI:	LD	HL,ABLMRK+1
	SET	5,(HL)
	RES	7,A
	LD	HL,STDRT
	LD	(ZLRET+1),HL
	JP	ZLDIR		;Direkt-byte zum Zielkanal

DSPCHR:	CALL	CHRGEN		;Textzeichen anzeigen
	CALL	CURGT
	CALL	KBFIPL
	OR	A
	JR	Z,EXHBF		;weitere Zeichen verarbeiten
	RET
;----------------------------
STDRT:	LD	HL,(MASTER)	;Standardreturn von VPSUB Aufruf
	LD	(HAUPT+1),HL	;wenn (MASTER) ausgetauscht war EXHBF,TTXVA
	RET
STDRT2:	LD	HL,KCHM		;Return wenn KCHM ausgetauscht war
	LD	(HAUPT+4),HL
	RET
;-----------------------
KOMEX:	LD	C,A		;Controlkommando ausfuehren
	LD	HL,(KOMTAB)
	JR	ADSP		;Adresssprung
;-----------------------
ESCEX:	CP	ESC		;weiteres ESC ?
	JR	NZ,ESCN
	SET	4,(HL)		;Doppelescape-Flag setzen
	RET
;----------------------
ESCN:	RES	1,(HL)		;ESC Kommando wird fertig
	BIT	4,(HL)
	RES	4,(HL)
	JR	NZ,DESC		;Doppel ESC Sequenz ?
	LD	HL,(ESCCHR)	;ESC-Tabelle ist wirksam
	LD	DE,(ESCTAB)
	LD	BC,(LESCCH)
	JR	TABEX

DESC:	LD	HL,DESCCH	;Doppel ESC Sequenz ausfuehren
	LD	DE,DESCTB	;Modultabelle
	LD	BC,LDESCH	;Laenge der Zeichentabelle

TABEX:	CPIR			;Eintrag suchen
	RET	NZ		;keine Aktion bei ungueltigen Kommandos
TABEXA:	EX	DE,HL
ADSP:	SLA	C
	LD	B,0
	ADD	HL,BC		;Adresse des Arbeitsprogramms holen
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	EX	DE,HL
	JP	(HL)		;Absprung zum Arbeitsprogramm
;-----------------------
	IF	DEBUG
	DB	'KCHM'
	ENDIF

KCHM:	LD	HL,ABLMRK+1
	JPBITZ	6,(HL),KCHM1
	RES	6,(HL)
	CALL	KLZDSP
	CALL	KBFDSP		;wenn neues Zeichen von KB, anzeigen

KCHM1:	LD	HL,MODUS
	LD	A,(HL)
	AND	00000011B
	JR	Z,KCHM3		;LOCAL mode keine weitere Verarbeitung
	LD	A,(HL)
	AND	00011000B	;Tastatur abgewaehlt keine Pufferverarbeitung
	CP	00011000B
	RET	Z

	JPBIT	2,(HL),STKV	;Zeichenkonvertierungs-FLAG

KCHM2:	CALL	KBFIPL		;ist byte in aktuellem Keyboardbuffer ?
	OR	A
	RET	Z		;Return wenn Buffer leer
	CALL	HBPLZ		;ist Platz im Host ausgabebuffer ?
	RET	NZ		;kein Platz vorhanden
	CALL	KBFIN		;1 Byte aus Keyboardbuffer holen
	LD	B,A
	LD	A,(STAT5)	;Host-Ausgabewortlaenge 7 bit ?
	JPBITZ	2,A,KCHM4
	RES	7,B
KCHM4:	LD	A,B
	CALL	HBFLD		;Ausgabe an Hostpuffer
KCHM3:	JP	KLZDSP		;Pufferladezahl anzeigen
;-----------------------
STKV:	CALL	KBFIPL		;KYBBF-Inhalt testen
	OR	A
	RET	Z		;keine Aktion wenn Puffer leer

	CALL	KBFIN		;Keyboardzeichen aus Puffer lesen 
	LD	E,A
	LD	HL,SKVTAB
	LD	B,0
STK1:	LD	A,(HL) 		;Zeichen in Tabelle suchen
	LD	C,A
	INC	HL
	OR	(HL)
	JR	Z,CHDKT		;wenn 0 und Laenge 0 Zeichen nicht gefunden
	LD	A,C
	CP	E		;Zeichen in SKVTAB ?
	JR	Z,ZKVP		;ja
	LD	A,(HL)		;Laenge des Strings
	LD	C,A
	INC	C		;+1 fuer Laengenfeld
	ADD	HL,BC		;HL zeigt auf naechsten String
	JR	STK1
;-----------------------
CHDKT:	LD	A,E
	LD	(KCHR),A	;Zeichen ausgeben
	CALL	VPSUB2
	CALL	HBPLZ		;Zeichen ohne Stringkonv. in Hostpuffer
	RET	NZ		;warte auf Platz im Hostpuffer
	LD	A,(KCHR)
	LD	B,A
	LD	A,(STAT5)	;Host-Ausgabewortlaenge 7 bit ?
	JPBITZ	2,A,CHDKT1
	RES	7,B
CHDKT1:	LD	A,B
	CALL	HBFLD		;Ausgabe an Hostpuffer
	JP	ZKVP1
;-----------------------
ZKVP:	LD	A,(HL)		;Bei Laenge 0 kein Zeichen ausgeben
	OR	A
	JP	Z,KCHM3

	LD	(STRLEN),A
	INC	HL		;Pointer auf Stringanfang
	LD	(STRLP),HL
	CALL	VPSUB2
	CALL	HBPLZ
	RET	NZ
	LD	HL,(STRLP)
	LD	A,(HL)
	CALL	HBFLD
	INC	HL
	LD	(STRLP),HL
	LD	A,(STRLEN)
	DEC	A
	LD	(STRLEN),A
	RET	NZ
ZKVP1:	CALL	KLZDSP
	JP	STDRT2
;**************************************************
;* MODUL CHARGEN Character Generierung
;**************************************************
SETZAD:	LD	DE,(VDPT)	;Pointer auf VideoRam
	LD	A,(STAT1)
	BIT	7,A		;TX Mode?
	RET	Z
	EX	DE,HL
	PUSH	BC
	LD	HL,(GCPOS)
	LD	BC,(ZLSIZE)
	SUBHL	BC		;Cursor liegt unter Zeichen
	SETNI	7,H
	POP	BC
	EX	DE,HL
	RET

CHRGEN:	CALL	ZADR		;Pointer auf Character in CHSET
	CALL	SETZAD
	LD	A,(BRTFLG)
	LD	C,A
	LD	B,0
TBWRT:	JPBITZ	4,C,TBWRT1
	PUSH	BC
	PUSH	DE
	PUSH	HL
	LD	DE,BRTBUF
	LD	B,8
	JPNI	TBWRT2		;Interlaced 16 Zeichen Breitschrift
	LD	B,16
TBWRT2:	LD	A,(HL)
	CALL	SETBRT
	DJNZ	TBWRT2
	POP	HL
	LD	B,8
	JPNI	TBWRT3
	LD	B,16
TBWRT3:	LD	A,(HL)
	RLCA
	RLCA
	RLCA
	RLCA
	CALL	SETBRT
	DJNZ	TBWRT3
	POP	DE
	POP	BC
	LD	HL,BRTBUF

TBWRT1:	PUSH	HL
	LD	HL,(CHRPRG)	;Charactererzeugungsprogramm auswaehlen
	JP	(HL)
;-------------------------- Char-generierungsprogramm fuer TVI-Grundmodus
	IF	DEBUG
	DB	'TBWTVI'
	ENDIF

TBWTVI:	POP	HL		;HL Pointer auf Zeichen
	RES	7,B		;Cursorflag loeschen in TVI Routine
CHRWRT:	REPT	8		;schneller als LDIR !
	LDI
	ENDM
	JP	PE,CHRWRT	;bei Breitschrift weitere 8 Byte
TBWTV3:	RET
;-------------------------- Char-gen fuer TVI-Grundmodus interlaced
TBITVI:	POP	HL		;HL Pointer auf Zeichen
	RES	7,B		;Cursorflag loeschen in TVI Routine
CHRWTI:	LD	A,D
	OUT	(PAGE),A
	PUSH	BC		;8 =Norm 16= Breitschrift
	PUSH	DE
	SET	7,D
	REPT	8		;schneller als LDIR !
	 LDI
	ENDM
	POP	DE
	POP	BC
	LD	A,D
	ADD	A,HIGH PITCH
	LD	D,A
	OUT	(PAGE),A
	PUSH	DE
	SET	7,D
	REPT	8		;schneller als LDIR !
	 LDI
	ENDM
	POP	DE
	
	RET	PO	;bei Breitschrift weitere 16 Byte
	EX	DE,HL	;DE auf naechste Spalte vorruecken
	LD	BC,PITCH-8
	SUBHL	BC
	EX	DE,HL
	LD	BC,8
	JP	CHRWTI
;--------------------------- Char-gen fuer TVI-Farbmodus
TBWTVC:	POP	HL
	BIT	7,B		;Zeichen fuer Cursor
	RES	7,B
	JR	NZ,TVC2		;XR springt hier nie
TVC1:	CALL	FBECLR		;vor jedem Zeichen Feld in Farbebene loeschen
	PUSH	HL
	PUSH	DE
	PUSH	BC
	CALL	CHRWRT
	POP	BC
	POP	DE
	POP	HL
	LD	A,(STAT1)
	BIT	6,A
	RET	Z

	PUSH	HL
	LD	HL,CHROR
	JPBIT	4,A,TVC3
	LD	HL,CHRDEL
TVC3:	LD	(CHRFKT+1),HL
	IF	XR
	 LD	A,00H		;Schreiben in Grundebene freigeben
	 OUT	(XRFLGS),A
	 LD	A,10H
	 OUT	(XRFLGS),A
	ELSE
	 LD	A,10110000B
	 OUT	(CLRG1),A
	ENDIF
	POP	HL
	CALL	TXWR1
	IF	XR
	 LD	A,(XRWR)
	 OUT	(XRFLGS),A
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ENDIF
	JR	FRBRES

TVC2:	IF	NOT XR		;Cursor in Grundebene schreiben
	 LD	A,10110000B
	 OUT	(CLRG1),A
	 OUT	(CLRG2),A
	ENDIF
	CALL	CHRWRT

	IF	XR
FRBRES:	LD	A,(XRCOL)	;Schreibfarbe wiederherstellen
	OUT	(XRCLRG),A
	RET

	ELSE
FRBRES:	LD	A,(COLRG2)
	OUT	(CLRG2),A
	LD	A,(COLRG1)
	OUT	(CLRG1),A
	RET
	ENDIF
;-------------------------- Char-gen fuer TVI-Farbmodus Interlaced
TBITVC:	POP	HL
	BIT	7,B		;Zeichen fuer Statuszeile ? oder Cursor
	RES	7,B
	JR	NZ,TVCI2	;XR springt hier nie

TVCI1:	CALL	FBECLI		;vor jedem Zeichen Feld in Farbebene loeschen
	PUSH	HL
	PUSH	DE
	PUSH	BC
	CALL	CHRWTI		;Farbebenen beschreiben
	POP	BC
	POP	DE
	POP	HL
	LD	A,(STAT1)	;keine weitere Aktion wenn transparent
	BIT	6,A
	RET	Z

	PUSH	HL		;sonst
	LD	HL,CHROR	;Grundebenenbit 1 setzen durch OR
	JPBIT	4,A,TVCI3
	LD	HL,CHRDEL	;Grundebenenbit 0 setzen durch DEL
TVCI3:	LD	(CHRFKT+1),HL
	IF	XR
	 LD	A,00H		;Schreiben in Grundebene freigeben
	 OUT	(XRFLGS),A
	 LD	A,10H
	 OUT	(XRFLGS),A
	ELSE
	 LD	A,10110000B	;Schreiben in Grundebene
	 OUT	(CLRG1),A
	ENDIF
	POP	HL
	CALL	TXWR1
	IF	XR
	 LD	A,(XRWR)
	 OUT	(XRFLGS),A
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ENDIF
	JR	FRBRES

TVCI2:	IF	NOT XR		;XR erreicht diesen Label nie
	 LD	A,10110000B	;Zeichen ist Cursorzeichen
	 OUT	(CLRG1),A
	 OUT	(CLRG2),A
	ENDIF
	CALL	CHRWTI
	JP	FRBRES
;----------------------- Char-generierungsprogramm fuer TTX-Alpha
TXWRT:	POP	HL
	BIT	7,B
	RES	7,B
	JP	NZ,CHWRI	;Statuszeile / Cursor 

TXWR1:	PUSH	BC
	PUSH	DE
	LD	C,D
	LD	B,8
	JPNI	TXWR2

	LD	A,D
	OUT	(PAGE),A
	SET	7,D
	LD	B,16
TXWR2:	CALL	CHRFKT		;AND OR XOR REP Funktion durchfuehren
	INC	HL		;obere Haelfte des Buchstabens
	INC	E

	LD	A,E
	AND	07		;Zeilengrenze erreicht?
	JR	NZ,TXWR3
	
	LD	A,E
	SUB	8
	LD	E,A
	LD	A,C
	ADD	A,HIGH PITCH
	LD	D,A
	LD	C,A
	JPNI	TXWR4
	OUT	(PAGE),A
TXWR4:	SET	7,D
TXWR3:	DJNZ	TXWR2

	POP	DE
	POP	BC
	BIT	4,C		;bei Breitschrift weitere 16 Byte
	RET	Z		;bei Normal RETURN

	EX	DE,HL		;DE auf naechste Spalte vorruecken
	LD	BC,8
	ADD	HL,BC
	EX	DE,HL
	LD	C,0		;Stop im Naechsten Umlauf
	JP	TXWR1
;---------------------------- Char-gen fuer TTX-A Farbmodus
TXCWRT:	POP	HL
	BIT	7,B
	RES	7,B
	JP	NZ,TVC2		;Cursor in Grundebene schreiben

	LD	A,(PFKT)
	CP	2		;Teste ob DeleteFunktion aktiv
	JR	NZ,TXCWR1

	IF	XR
	 LD	A,(XRHGF)	;Hintergrundfarbe aktivieren
	 OUT	(XRCLRG),A
	ELSE
	 LD	A,(HGFRG1)
	 OUT	(CLRG1),A
	 LD	A,(HGFRG2)
	 OUT	(CLRG2),A
	ENDIF

TXCWR1:	PUSH	HL
	LDW	(CHRFKT+1),CHRREP
	POP	HL
	LD	A,(PFKT)
	CP	6
	CALL	Z,FBXCLR	;loescht Feld unter Buchstaben	
	PUSH	HL
	PUSH	DE
	PUSH	BC
	CALL	TXWR1
	LDW	(CHRFKT+1),(CHRFKS)
	POP	BC
	POP	DE
	POP	HL

	LD	A,(PFKT)
	CP	2		;Test ob Deletefunktion aktiv
	JR	NZ,TXCWR3
	LD	A,(STAT1)
	JPBITZ	5,A,TXCWR2

	BIT	3,A
	JR	TXCWR5

TXCWR3:	LD	A,(STAT1)
	JPBITZ	6,A,TXCWR2

	LD	A,(PFKT)
	CP	4		;Test auf XOR-Funktion
	JR	NZ,TXCWR4
	PUSH	HL
	LD	HL,CHRXOR
	JR	TXCWR6

TXCWR4:	LD	A,(STAT1)
	BIT	4,A
TXCWR5:	PUSH	HL
	LD	HL,CHROR
	JR	NZ,TXCWR6
	LD	HL,CHRDEL
TXCWR6:	LD	(CHRFKT+1),HL
	POP	HL
	IF	XR		;Grundebene einschalten
	 LD	A,00H
	 OUT	(XRFLGS),A
	 LD	A,10H
	 OUT	(XRFLGS),A
	ELSE
	 LD	A,(COLRG1)	;Umschalten auf Schreiben in Grundebene
	 XOR	00011000B	;fuer Alphazeichen Logik
	 OUT	(CLRG1),A
	ENDIF
	CALL	TXWR1
TXCWR2:	LD	HL,(CHRFKS)
	LD	(CHRFKT+1),HL
	IF	XR
	 LD	A,(XRWR)
	 OUT	(XRFLGS),A
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ENDIF
	JP	FRBRES
;----------------------
CHRREP:	LD	A,(HL)	;Zeichen durch REPLACE schreiben
	LD	(DE),A
	RET
CHRDEL:	LD	A,(DE)	;Zeichen in der Hintergrundfarbe schreiben
	OR	(HL)
	XOR	(HL)
	LD	(DE),A
	RET
CHROR:	LD	A,(DE)	;Zeichen in der Vordergrundfarbe schreiben
	OR	(HL)
	LD	(DE),A
	RET
CHRXOR:	LD	A,(DE)	;Zeichen durch invertieren schreiben
	XOR	(HL)
	LD	(DE),A
	RET
;-----------------------
	IF	XR
FBXCLR:	PUSH	HL		;loeschen TTX-A Replace keine Blockgrenzen
	LD	A,(XRHGF)	;jedes Zeichen vorher mit Hintergrundfarbe
	OUT	(XRCLRG),A	;loeschen
	PUSH	DE
	PUSH	BC
	LD	HL,CLRFLD	;Pointer auf volles Feld FF
	CALL	TXWR1
	POP	BC
	POP	DE
	POP	HL
	JP	FRBRES		;Zeichen in gewaehlter Farbe einschreiben

	ELSE
FBXCLR:	PUSH	HL		;loeschen TTX-A Replace keine Blockgrenzen
	LD	HL,STAT1
	LD	A,(HGFRG1)	;jedes Zeichen vorher mit Hintergrundfarbe
	JPBITZ	5,(HL),FBXCL1
	JPBITZ	3,(HL),FBXCL1	;Grundebenenbit
	SET	4,A		;Grundebene mitbeschreiben wenn Hintergrund GE 1
FBXCL1: OUT	(CLRG1),A	;loeschen in der Farbebene
	LD	A,(HGFRG2)
	OUT	(CLRG2),A
	PUSH	DE
	PUSH	BC
	LD	HL,CLRFLD	;Pointer auf volles Feld FF
	CALL	TXWR1		;Fuehrt LDI's aus
	POP	BC
	POP	DE
	POP	HL
	LD	A,(STAT1)
	JPBITZ	5,A,FBXCL2
	JPBIT	3,A,FBXCL2
	PUSH	HL
	PUSH	DE
	PUSH	BC
	LD	HL,NULFLD
	CALL	TXWR1		;Fuehrt LDI's aus
	POP	BC
	POP	DE
	POP	HL
FBXCL2:	JP	FRBRES		;Zeichen in gewaehlter Farbe einschreiben
	ENDIF
;---------------------
	IF	XR
FBECLR:	PUSH	HL
	LD	A,(XRHGF)	;jedes Zeichen vorher mit Hintergrundfarbe
	OUT	(XRCLRG),A	;loeschen
	PUSH	DE
	PUSH	BC
	LD	HL,CLRFLD	;Pointer auf volles Feld FF
	CALL	CHRWRT
	POP	BC
	POP	DE
	POP	HL
	JP	FRBRES

	ELSE
FBECLR:	PUSH	HL
	LD	HL,STAT1
	LD	A,(HGFRG1)	;jedes Zeichen vorher mit Hintergrundfarbe
	JPBITZ	5,(HL),FBECL1
	JPBITZ	3,(HL),FBECL1	;Grundebenenbit
	SET	4,A		;Grundebene mitbeschreiben wenn Hintergrund GE 1
FBECL1:	OUT	(CLRG1),A	;loeschen in der Farbebene
	LD	A,(HGFRG2)
	OUT	(CLRG2),A
	PUSH	DE
	PUSH	BC
	LD	HL,CLRFLD	;Pointer auf volles Feld FF
	CALL	CHRWRT
	POP	BC
	POP	DE
	POP	HL
	LD	A,(STAT1)
	JPBITZ	5,A,FBECL2
	JPBIT	3,A,FBECL2
	PUSH	HL	;wenn Grundebene 0 dann im zweiten Durcjgang loeschen
	PUSH	DE
	PUSH	BC
	LD	HL,NULFLD
	CALL	CHRWRT
	POP	BC
	POP	DE
	POP	HL
FBECL2:	JP	FRBRES		;Zeichen in gewaehlter Farbe einschreiben
	ENDIF

CLRFLD:	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
NULFLD:	DB	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DB	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;-----------------------
	IF	XR
FBECLI:	PUSH	HL		;im TVI Farbmodus mit Hintergrundfarbe
	LD	A,(XRHGF)	;jedes Zeichen vorher mit Hintergrundfarbe
	OUT	(XRCLRG),A	;loeschen
	PUSH	DE
	PUSH	BC
	LD	HL,CLRFLD	;Pointer auf volles Feld FF
	CALL	CHRWTI
	POP	BC
	POP	DE
	POP	HL
	JP	FRBRES		;Zeichen in gewaehlter Farbe einschreiben

	ELSE
FBECLI:	PUSH	HL		;im TVI Farbmodus mit Hintergrundfarbe
	LD	HL,STAT1	;Zeichenuntergrund loeschen
	LD	A,(HGFRG1)	;jedes Zeichen vorher mit Hintergrundfarbe
	JPBITZ	5,(HL),FBECI1	;wenn nicht transparent
	JPBITZ	3,(HL),FBECI1
	SET	4,A		;auch in Grundebene loeschen
FBECI1: OUT	(CLRG1),A	;loeschen in der Farbebene
	LD	A,(HGFRG2)
	OUT	(CLRG2),A
	PUSH	DE
	PUSH	BC
	LD	HL,CLRFLD	;Pointer auf volles Feld FF
	CALL	CHRWTI
	POP	BC
	POP	DE
	POP	HL
	LD	A,(STAT1)
	JPBITZ	5,A,FBECI2
	JPBIT	3,A,FBECI2	;wenn nicht transparent
	PUSH	HL		;Grundebene loeschen
	PUSH	DE
	PUSH	BC
	LD	HL,NULFLD
	CALL	CHRWTI
	POP	BC
	POP	DE
	POP	HL	
FBECI2:	JP	FRBRES		;Zeichen in gewaehlter Farbe einschreiben
	ENDIF
;-----------------------
ZADR:	LD	HL,(CHGPRG)	;Interlaced Zeichengenerierung Sprungverteiler
	JP	(HL)

ZADRN:	LD	HL,(CHSET)
	LD	C,A	;Pointer HL auf Zeichen im Zeichensatz setzen
	XOR	A	;HL=Zeichensatzanfang
	SLA	C	;A =Zeichen 0-7F
	RLA
	SLA	C
	RLA
	SLA	C
	RLA		;Hexwert*8=relative Zeichensatzadr.
	LD	B,A
	ADD	HL,BC
	LD	A,(ATRFLG)	;Atribute setzen wenn vorhanden
	OR	A
	RET	Z
				;Attribute setzen ----------
	LD	DE,CHRBUF	;Normzeichen oder Indexzeichen aus Zeichensatz
	LD	A,(ATTRIB)
	JPBITZ	2,A,SETAT3
	LD	B,8
SETAT8:	LD	A,(HL)		;invertierte Schrift holen
	CPL
	LD	(DE),A
	INC	DE
	INC	HL
	DJNZ	SETAT8
	LD	C,0FFH
	JR	SETAT7
	
SETAT3:	LD	BC,8		;normale Schrift holen
	LDIR			;HL zeigt auf Character in VZSATZ, C=0
SETAT7:	LD	A,(ATTRIB)
	AND	00110000B
	JR	Z,SETAT5	;Index tief bleibt unveraendert
	CP	00110000B	;Normschrift
	JR	Z,SETAT5
	CP	00010000B
	JR	NZ,SETAT2

	LD	HL,CHRBUF+1	;verschieben der Indexschrift um 1 Pixelzeile
	LD	DE,CHRBUF
	PUSH	BC		;C enthaelt Einfuegepixels
	LD	BC,7
	LDIR
	POP	BC
	JR	SETAT4

SETAT2:	PUSH	BC		;verschieben der Indexschrift um 2 Pixelzeilen
	LD	HL,CHRBUF+2
	LD	DE,CHRBUF
	LD	BC,6
	LDIR
	POP	BC
	LD	A,C
	LD	(CHRBUF+6),A
SETAT4:	LD	A,C
	LD	(CHRBUF+7),A	;HL zeigt auf CHRBUF

SETAT5:	LD	A,(ATTRIB)	;unsichtbare Schrift
	JPBITZ	0,A,SETATR
	LD	HL,NULFLD
	RET

SETATR:	LD	B,A
	JPBITZ	1,B,SETAT1	;durchgestrichen
	LD	A,C
	CPL
	LD	(CHRBUF+4),A
SETAT1:	JPBITZ	3,B,SETAT6	;unterstrichen
	LD	A,C
	CPL
	LD	(CHRBUF+7),A
SETAT6:	LD	HL,CHRBUF
	RET
;-----------------------
ZADRI:	JPBITZ	7,A,ZADRI1	;Sonderzeichen fuer Statuszeile
	RES	7,A		;aus GRAFIK Zeichensatz holen
	LD	HL,GRAFIT
	JR	ZADRI2
ZADRI1:	LD	HL,(CHSET)	;sonst aus aktuellem Zeichensatz
ZADRI2:	LD	C,A	;Pointer HL auf Zeichen im Zeichensatz setzen
	XOR	A	;HL=Zeichensatzanfang
	SLA	C	;A =Zeichen 0-7F
	RLA
	SLA	C
	RLA
	SLA	C
	RLA		;Hexwert*8=relative Zeichensatzadr.
	SLA	C
	RLA
	LD	B,A
	ADD	HL,BC
	LD	A,(ATRFLG)	;Atribute setzen wenn vorhanden
	OR	A
	RET	Z
				;Attribute setzen ----------
	LD	DE,CHRBUF	;Normzeichen oder Indexzeichen aus Zeichensatz
	LD	A,(ATTRIB)
	JPBITZ	2,A,SETAI3
	LD	B,16
SETAI8:	LD	A,(HL)		;invertierte Schrift
	CPL
	LD	(DE),A
	INC	DE
	INC	HL
	DJNZ	SETAI8
	LD	BC,0FFFFH
	JR	SETAI7

SETAI3:	LD	BC,16		;holen
	LDIR			;HL zeigt auf Character in VZSATZ, BC=0000

SETAI7:	LD	A,(ATTRIB)
	AND	00110000B
	JR	Z,SETAI5	;Index tief bleibt unveraendert
	CP	00110000B	;Normschrift
	JR	Z,SETAI5
	CP	00010000B
	JR	NZ,SETAI2

	LD	HL,CHRBUF+2
	LD	DE,CHRBUF
	PUSH	BC
	LD	BC,14
	LDIR
	POP	BC
	JR	SETAI4

SETAI2:	LD	HL,CHRBUF+4
	LD	DE,CHRBUF
	PUSH	BC
	LD	BC,12
	LDIR
	POP	BC
	LD	(CHRBUF+12),BC
SETAI4:	LD	(CHRBUF+14),BC	;HL zeigt auf CHRBUF

SETAI5:	LD	A,(ATTRIB)	;unsichtbare Schrift
	JPBITZ	0,A,SETAIR
	LD	HL,NULFLD
	RET
SETAIR:	PUSH	AF
	LD	A,B
	CPL
	LD	B,A
	LD	A,C
	CPL
	LD	C,A
	POP	AF
	JPBITZ	1,A,SETAI1	;durchgestrichen
	LD	(CHRBUF+6),BC
SETAI1:	JPBITZ	3,A,SETAI6	;unterstrichen
	LD	(CHRBUF+14),BC
SETAI6:	LD	HL,CHRBUF
	RET
;-----------------------
SETBRT:	PUSH	HL
	LD	C,4
	LD	H,A
SETBR1:	RR	A
	RR	L
	RR	H
	RR	L
	DEC	C
	JR	NZ,SETBR1
	LD	A,L
	LD	(DE),A
	POP	HL
	INC	HL
	INC	DE
	RET
;-----------------------
CURADR:	LD	HL,(DSPST)	;Cursorpointer aus Spalte und Zeile berechnen
	LD	BC,(DSPANF)	;Bildfeldanfang beruecksichtigen
	ADD	HL,BC
	LD	A,(CZL)
	OR	A
	JR	Z,CURPO1	;Zeile 0 ?
	LD	B,A
	LD	DE,(ZLSIZE)
CURPO2:	ADD	HL,DE
	DJNZ	CURPO2

CURPO1:	LD	A,(CSP)		;Cursorspalte
	OR	A
	JR	Z,CURPOR	;Cursor in Spalte 0 ?
	LD	B,A
	LD	DE,8
CURPO4:	ADD	HL,DE
	DJNZ	CURPO4

CURPOR:	SETNI	7,H
	LD	(CURPT),HL
	LD	(VDPT),HL	;VIDEO-Ram Pointer
	RET
;-----------------------
	IF	DEBUG
	DB	'CURRES'
	ENDIF

	IF	XR
CURCLR	EQU	$
CURRES:	LD	HL,STAT4	;Cursor ist abgeschaltet
	BIT	4,(HL)
	RET	Z

	RES	1,(HL)		;Cursor status aus
	LD	HL,MODUS	;Farbmodus
	JPBITZ	7,(HL),CURRE1
	CALL	XRCURC		;XR Cursor Change
	RET

CURRE1:	LD	HL,CURBF	;Zeichen unter Cursor schreiben 
	LD	DE,(VDPT)
	LD	A,(BRTFLG)
	LD	C,A
	LD	B,80H
	JP	TBWRT1
;----------------------------
XRCURC:	LD	A,20H
	OUT	(XRFLGS),A	;Bitmodus einschalten
	LD	HL,(VDPT)	;VDPT steht immer auf einer durch 8/16 teilbaren Adresse
	JPNI	XRCUR1
	LD	D,2		;zwei Durchlaufe bei Interlaced
XRCUR5:	PUSH	DE
	PUSH	HL		;rette VDPT
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
XRCUR1:	LD	A,(BRTFLG)	;bei Breitschrift 16 sonst 8
	LD	C,A		;XR hat nur Blockcursor
XRCUR3:	LD	B,8
XRCUR2:	LD	A,(HL)		;1 Zeile Cursor lesen = 8 byte
	XOR	0FFH
	LD	(HL),A
	XRBIT			;Bitcnt increment
	DJNZ	XRCUR2

	INC	HL
	DEC	C
	JR	NZ,XRCUR3

	JPNI	XRCUR4
	POP	HL		;hole VDPT aus Stack
	LD	A,H
	ADD	A,HIGH PITCH
	LD	H,A
	POP	DE
	DEC	D
	JR	NZ,XRCUR5
	
XRCUR4:	LD	A,27H
	OUT	(XRFLGS),A	;Bitmodus abschalten
	RET

	ELSE
CURRES:	LD	HL,STAT4	;Cursor smily ?
	JPBIT	0,(HL),CRSMIL
CURCLR:	LD	HL,STAT4	;Cursor ist abgeschaltet
	BIT	4,(HL)
	RET	Z

	LD	HL,CURBF	;Zeichen unter Cursor schreiben
	LD	DE,(VDPT)
	LD	A,(BRTFLG)
	LD	C,A
	LD	B,80H
	JP	TBWRT1
	ENDIF
;-----------------------
	IF	XR
CURSET:	LD	HL,STAT4	;Cursor ist abgeschaltet
	BIT	4,(HL)
	RET	Z
	SET	1,(HL)		;Cursor Status
	LD	HL,MODUS	;Farbmodus
	JPBITZ	7,(HL),CURSE1
	CALL	XRCURC		;XR Cursor Change
	RET

CURSE1:	LD	HL,CURCHR	;sonst Zeichen aus CURCHR ohne Breitschrift
	LD	DE,(VDPT)	;Zieladresse setzen
	LD	A,(BRTFLG)
	LD	C,A
	LD	B,80H
	JP	TBWRT1		;Einsprung ohne Breitschriftumsetzung

	ELSE
CRSMIL:	LD	HL,VZSATZ+16
	JPI	CURSE2
	LD	HL,VZSATZ+8	;smily Cursor
	JP	CURSE2
CURSET:	LD	HL,STAT4	;Setze Cursorzeichen
	BIT	4,(HL)
	RET	Z		;Cursor unsichtbar

	LD	A,(STAT4)	;springe wenn weder selbstdefiniert
	AND	10000001B	;noch smily
	JR	Z,CURSE1

	LD	HL,VZSATZ	;bei Selbstdefiniertem Cursor
CURSE2:	CALL	CURSIN		;Zeichen 00H aus Zeichensatz setzen
	JP	TBWRT

CURSE1:	LD	HL,CURCHR	;sonst Zeichen aus CURCHR ohne Breitschrift
	CALL	CURSIN
	JP	TBWRT1		;Einsprung ohne Breitschriftumsetzung

CURSIN:	LD	DE,(VDPT)	;Zieladresse setzen
	LD	A,(BRTFLG)
	LD	C,A
	LD	B,80H
	RET
	ENDIF
;-----------------------
CURRD:	IF	XR
	 LD	HL,MODUS
	 BIT	7,(HL)
	 RET	NZ	;im XR Farbmodus braucht Cursor nicht gelesen werden
	ENDIF

	LD	HL,(CURPT)
	LD	DE,CURBF
	LD	A,(BRTFLG)
	JPI	CURRDI
	LD	C,A
	LD	B,0
	LDIR

	LD	HL,STAT4
	JPBIT	5,(HL),CURRD3

	LD	HL,CURBF
	LD	DE,CURCHR
	LD	A,(BRTFLG)
	LD	B,A
CURRD2:	LD	A,(HL)		;Block Cursor
	CPL
	LD	(DE),A
	INC	HL
	INC	DE
	DJNZ	CURRD2
	RET

CURRD3:	LD 	HL,CURBF	;underlined Cursor bilden
	LD	DE,CURCHR
	LD	BC,16
	LDIR
	LD	A,0FFH
	LD	(CURCHR+7),A
	LD	(CURCHR+15),A
	RET
;-----------------------
CURRDI:	PUSH	AF
	PUSH	HL
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	LD	BC,8
	LDIR

	POP	HL
	LD	A,H
	ADD	A,HIGH PITCH
	LD	H,A
	OUT	(PAGE),A
	PUSH	HL
	SET	7,H
	LD	BC,8
	LDIR
	POP	HL
	POP	AF
	JPBITZ	4,A,CURDI4	;bei Breitschrift weitere 16 Byte

	LD	BC,PITCH-8
	SUBHL	BC
	XOR	A		;Stop im Naechsten Umlauf
	JP	CURRDI

CURDI4:	LD	HL,STAT4	;Cursor underlined ?
	JPBIT	5,(HL),CURDI3

	LD	HL,CURBF
	LD	DE,CURCHR
	LD	A,(BRTFLG)
	SLA	A
	LD	B,A
CURDI2:	LD	A,(HL)		;Block Cursor invers
	CPL
	LD	(DE),A
	INC	HL
	INC	DE
	DJNZ	CURDI2
	RET

CURDI3:	LD 	HL,CURBF	;underlined Cursor bilden
	LD	DE,CURCHR
	LD	A,(BRTFLG)
	SLA	A
	LD	C,A
	LD	B,0
	LDIR
	LD	HL,0FFFFH
	LD	(CURCHR+14),HL
	LD	(CURCHR+30),HL
	RET
;-----------------------
CUROFF:	LD	HL,STAT4	;Cursor wegnehmen Untergrund schreiben
	BIT	4,(HL)		;Cursor ist abgeschaltet
	RET	Z
	BIT	2,(HL)		;Cursor ist bereits aus
	RET	NZ
	SET	2,(HL)
	IF	XR
	 LD	A,(MODUS)
	 JPBITZ	7,A,CUROF2
	 BIT	3,(HL)
	 RES	3,(HL)
	 JR	NZ,CUROF3
	 CALL	XRCURC
	 JR	CUROF3
	ENDIF
CUROF2:	RES	3,(HL)		;Cursorphase aus
	CALL	CURCLR	;loesche Cursor, schreibe Zeichen unter Cursor
	IF	NOT XR
	 LD	HL,SEC50	;nur fuer GRIP-COLOR
	 LD	A,(HL)
CUROF1:	 CP	(HL)		;OUT-Befehle synchronisieren wegen Stoerung
	 JR	Z,CUROF1
	ENDIF
CUROF3:	CALLB	SETCOL		;Farb Blinkphase 1 waehrend Empfang
	LD	HL,0118H
	LD	(HPRTB),HL	;BLINK entfernen falls bereits gesetzt
	RET
;-----------------------
CURORG:	LD	HL,STAT2	;hat SCROLL stattgefunden ?
	JPBITZ	7,(HL),CUROR2	;nach Zeitverzoegerung
	RES	7,(HL)
	BIT	3,(HL)		;War STZ voruebergehend aus?
	CALL	NZ,STLGEN	;Statuszeile 1,2 anschalten nach SCROLL
CUROR2:	LD	HL,STAT5
	JPBITZ	3,(HL),CUROR1	;wurden zwischenzeitlich residente Daten veraendert ?
	CALLB	ZSCHKS		;Checksumme des residenten Daten bilden
	LD	(CHKSUM),BC	;neue Checksumme abspeichern

CUROR1:	LD	HL,STAT4
	BIT	4,(HL)		;Cursor ist abgeschaltet
	RET	Z
	BIT	2,(HL)		;enable Cursor after each Message
	RET	Z
	RES	2,(HL)
	LD	A,(BLKSPD)
	LD	(BLNKR),A
	CALL	CURRD		;lese Zeichen unter Cursor vorher
	JP	CURSET		;setze Cursor
;---------------------
BLINK:	CALL	SPLZCH		;Spoolerzeichen setzen
	LD	A,(STAT4)	;Cursorphase wechselt
	XOR	00001000B
	LD	(STAT4),A
	CALLB	BLNKCL		;Farben blinken lassen
	LD	HL,STAT4
	JPBITZ	4,(HL),BLINK1	;Cursor unsichtbar ?
	JPBITZ	6,(HL),BLINK1	;Cursor steady ?
	JPBIT	3,(HL),BLKOFF	;Cursor Status
	CALL	CURSET
	JR	BLINK1

BLKOFF:	CALL	CURRES
BLINK1:	LD	HL,0118H	;BLINK aus Ablauffeld entfernen
	LD	(HPRTB),HL
	RET
;-----------------------
	IF	DEBUG
	DB	'SCROLL'
	ENDIF

SCROLL:	JPI	SCROLI
	CALL	SCRLIN
	CALL	SCRLBU		;Bildschirm nach oben
	JP	SETVDC
;-----------------------
SCRLBU:	JPI	SCRBUI
	LD	HL,STAT5	;ist Anzeigepage=Arbeitspage ?
	LD	A,(STAT3)
	XOR	(HL)
	JPBITZ	7,A,SCROL1
	LD	HL,(VDCST2)
	CALL	INCVAD
	LD	(VDCST2),HL
	JR	SCROL2

SCROL1:	CALL	INCVST

SCROL2:	LD	HL,(DSPST)	;neue Display Startadresse setzen
	LD	BC,(ZLSIZE)
	ADD	HL,BC
	SET	7,H
	LD	(DSPST),HL

	LD	HL,STAT2	;wenn Statuszeile 2 an
	BIT	2,(HL)
	CALL	NZ,UZLOE	;letzte Textzeile loeschen

	LD	A,(ZLANZ)
	CALL	ZLPOS
	CALL	ZPADR		;Adresse nach der letzten Zeile
	CALL	LOE1		;letzte sichtbare Zeile loeschen
	JP	CURADR		;Cursor absolute Adresse neu setzen
;-----------------------
SCRDWN:	JPI	SCRDWI
	CALL	SCROLL
	JP	CURAUF
;-----------------------
SCRLUP:	JPI	SCRLUI
	CALL	SCRLTM

	LD	HL,STAT5	;ist Anzeigepage=Arbeitspage ?
	LD	A,(STAT3)
	XOR	(HL)
	AND	10000000B
	JR	Z,SCRLU1
	LD	HL,(VDCST2)
	LD	DE,BLOCKS
	SUBHL	DE
	LD	A,H
	AND	0FH
	LD	H,A
	LD	(VDCST2),HL
	JR	SCRLU2

SCRLU1:	LD	HL,(VDCST)	;neue VDC-Startadresse
	LD	DE,BLOCKS	;um eine Zeile verschieben
	SUBHL	DE
	LD	A,H
	AND	0FH		;VDC-Startadresse mod 4096
	LD	H,A
	LD	(VDCST),HL

SCRLU2:	LD	HL,(DSPST)	;neue Display Startadresse setzen
	LD	DE,(ZLSIZE)
	SUBHL	DE
	SET	7,H
	LD	(DSPST),HL

	LD	A,(ZLANZ)
	CALL	ZLOE

	LD	HL,STAT2	;wenn Statuszeile 2 an
	JPBITZ	2,(HL),SCRLU3
	LD	A,(ZLANZ)	;letzte Textzeile loeschen
	DEC	A
	CALL	ZLOE

SCRLU3:	LD	BC,(ZLSIZE)
	CALL	LOE
	LD	HL,(DSPST)	;0. und 1. Zeile loeschen
	LD	BC,(DSPANF)
	ADD	HL,BC
	SET	7,H
	LD	BC,(ZLSIZE)
	CALL	LOE1
	LD	A,(ZLANZ)
	LD	B,A
	DEC	B
	LD	A,(CZL)
	CP	B
	JR	NC,SCRLU4
	INC	A
SCRLU4:	LD	(CZL),A
	CALL	CURADR		;Cursor absolute Adresse neu setzen
	JP	SETVDC
;-----------------------
SCRLFT:	JPI	SCRLFI
	CALL	SCRLTM

	LD	HL,STAT5	;ist Anzeigepage=Arbeitspage ?
	LD	A,(STAT3)
	XOR	(HL)
	AND	10000000B
	JR	Z,SCRLF1
	LD	HL,(VDCST2)
	LD	A,(BRTFLG)
	PUSH	AF
	JPBITZ	4,A,SCRLF3
	INC	HL
SCRLF3:	INC	HL
	LD	A,H
	AND	0FH
	LD	H,A
	LD	(VDCST2),HL
	JR	SCRLF2

SCRLF1:	LD	HL,(VDCST)	;neue VDC-Startadresse
	LD	A,(BRTFLG)
	PUSH	AF
	JPBITZ	4,A,SCRLF8
	INC	HL
SCRLF8:	INC	HL
	LD	A,H
	AND	0FH		;VDC-Startadresse mod 4096
	LD	H,A
	LD	(VDCST),HL
SCRLF2:	LD	HL,(DSPST)
	POP	AF
	LD	C,A
	LD	B,0
	ADD	HL,BC
	SET	7,H
	LD	(DSPST),HL
	JPBITZ	4,C,SCRLF4
	LD	A,BLOCKS-2
	JR	SCRLF7
SCRLF4:	LD	A,BLOCKS-1
SCRLF7:	CALL	SPLOE
	LD	HL,BRTFLG
	LD	A,(CSP)
	OR	A
	JR	Z,SCRLF5
	JPBITZ	4,(HL),SCRLF6
	DEC	A
SCRLF6:	DEC	A
	LD	(CSP),A
SCRLF5:	CALL	CURADR
	JP	SETVDC
;-----------------------
SCRIGT:	JPI	SCRIGI
	CALL	SCRLTM

	LD	HL,STAT5	;ist Anzeigepage=Arbeitspage ?
	LD	A,(STAT3)
	XOR	(HL)
	AND	10000000B
	JR	Z,SCRIG1
	LD	HL,(VDCST2)
	LD	A,(BRTFLG)
	PUSH	AF
	JPBITZ	4,A,SCRIG3
	DEC	HL
SCRIG3:	DEC	HL
	LD	A,H
	AND	0FH
	LD	H,A
	LD	(VDCST2),HL
	JR	SCRIG2

SCRIG1:	LD	HL,(VDCST)	;neue VDC-Startadresse
	LD	A,(BRTFLG)
	PUSH	AF
	JPBITZ	4,A,SCRIG8
	DEC	HL
SCRIG8:	DEC	HL
	LD	A,H
	AND	0FH		;VDC-Startadresse mod 4096
	LD	H,A
	LD	(VDCST),HL
SCRIG2:	LD	HL,(DSPST)
	POP	AF
	LD	C,A
	LD	B,0
	SUBHL	BC
	SET	7,H
	LD	(DSPST),HL
	XOR	A
	CALL	SPLOE
	LD	HL,BRTFLG
	LD	A,(SPANZ)
	JPBITZ	4,(HL),SCRIG5
	DEC	A
SCRIG5:	DEC	A
	LD	B,A
	LD	A,(CSP)
	CP	B
	JR	NC,SCRIG6
	JPBITZ	4,(HL),SCRIG7
	INC	A
SCRIG7:	INC	A
	LD	(CSP),A
SCRIG6:	CALL	CURADR
	JP	SETVDC
;-----------------------
SCROLI:	CALL	SCRLIN		;Verzoegerung fuer Statuszeilenschreiben
	CALL	SCRBUI
	JP	SETVDC
;-----------------------
SCRBUI:	CALL	INCVST		;Scroll nach oben

	LD	HL,(DSPST)	;neue Display Startadresse setzen
	LD	BC,ZLSIZI
	ADD	HL,BC
	LD	(DSPST),HL

	LD	HL,STAT2	;wenn Statuszeile 2 an
	JPBITZ	2,(HL),SCROI3
	LD	A,(ZLANZ)	;letzte Textzeile loeschen
	DEC	A
	CALL	ZLOE

SCROI3:	LD	HL,(DSPST)	;letzte sichtbare Zeile loeschen
	LD	BC,ZLSIZI*(VBLKS-1)
	ADD	HL,BC
	LD	BC,ZLSIZI
	CALL	LOE1
	JP	CURADR
;-----------------------
SCRDWI:	CALL	SCROLI		;Scroll mit Cursorbewegung
	JP	CURAUF
;-----------------------
SCRLUI:	CALL	SCRLTM		;Scroll nach unten

SCRLI1:	LD	HL,(VDCST)	;neue VDC-Startadresse
	LD	DE,2*BLOCKS	;um eine Zeile verschieben
	SUBHL	DE
	LD	A,H
	AND	1FH		;VDC-Startadresse mod 4096
	LD	H,A
	LD	(VDCST),HL

SCRLI2:	LD	HL,(DSPST)	;neue Display Startadresse setzen
	LD	DE,ZLSIZI
	SUBHL	DE
	LD	(DSPST),HL

	LD	A,(ZLANZ)	;letzte Textzeile loeschen
	CALL	ZLOE

	LD	HL,STAT2	;wenn Statuszeile 2 an
	JPBITZ	2,(HL),SCRLI3
	LD	A,(ZLANZ)	;Zeile darunter loeschen
	INC	A
	CALL	ZLOE

SCRLI3:	LD	BC,ZLSIZI	; 1. Zeile loeschen
	CALL	LOE
	LD	HL,(DSPST)	; 1. Text-Zeile loeschen
	LD	BC,(DSPANF)
	ADD	HL,BC
	LD	BC,ZLSIZI
	CALL	LOE1
	LD	A,(ZLANZ)	;Cursor an neue Position setzen
	LD	B,A
	DEC	B
	LD	A,(CZL)
	CP	B
	JR	NC,SCRLI4
	INC	A
SCRLI4:	LD	(CZL),A
	CALL	CURADR
	JP	SETVDC
;-----------------------
SCRLFI:	CALL	SCRLTM		;Verzoegerung fuer Statuszeilenschreiben

SCRFI1:	LD	HL,(VDCST)	;neue VDC-Startadresse
	LD	A,(BRTFLG)
	PUSH	AF
	JPBITZ	4,A,SCRFI3
	INC	HL
SCRFI3:	INC	HL
	LD	A,H
	AND	1FH		;VDC-Startadresse mod 8192
	LD	H,A
	LD	(VDCST),HL
SCRFI2:	LD	HL,(DSPST)
	POP	AF
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	(DSPST),HL
	JPBITZ	4,C,SCRFI4
	LD	A,BLOCKS-1-1
	JR	SCRFI7
SCRFI4:	LD	A,BLOCKS-1
SCRFI7:	CALL	SPLOE
	LD	HL,BRTFLG
	LD	A,(CSP)
	OR	A
	JR	Z,SCRFI5
	JPBITZ	4,(HL),SCRFI6
	DEC	A
SCRFI6:	DEC	A
	LD	(CSP),A
SCRFI5:	CALL	CURADR
	JP	SETVDC
;-----------------------
SCRIGI:	CALL	SCRLTM		;Verzoegerung fuer Statuszeilenschreiben

SCRGI1:	LD	HL,(VDCST)	;neue VDC-Startadresse
	LD	A,(BRTFLG)
	PUSH	AF
	JPBITZ	4,A,SCRGI3
	DEC	HL
SCRGI3:	DEC	HL
	LD	A,H
	AND	1FH		;VDC-Startadresse mod 4096
	LD	H,A
	LD	(VDCST),HL
SCRGI2:	LD	HL,(DSPST)
	POP	AF
	LD	C,A
	LD	B,0
	SUBHL	BC
	LD	(DSPST),HL
	XOR	A
	CALL	SPLOE
	LD	HL,BRTFLG
	LD	A,(SPANZ)
	JPBITZ	4,(HL),SCRGI5
	DEC	A
SCRGI5:	DEC	A
	LD	B,A
	LD	A,(CSP)
	CP	B
	JR	NC,SCRGI6
	JPBITZ	4,(HL),SCRGI7
	INC	A
SCRGI7:	INC	A
	LD	(CSP),A
SCRGI6:	CALL	CURADR
	JP	SETVDC
;-----------------------
SCRLIN:	IF	HD6345
	 LD	A,12
	 CALL	VDCRDA		;Scr 1 Start High Addr
	 AND	00001111B
	 LD	B,A
	 LD	A,(VDCST+1)
	 AND	00001111B
	 SUB	B		;Wieviele Zeilen bisher gescrollt?
	 AND	00001111B
	 JPI	SCRLN2
	 CP	3		; = 8 Zeilen
	 CALL	NC,SSCR1	;Zu viele: Scr 1+3 koppeln
SCRLN1:	 FLAG	5,ZWZL		;Smooth Scroll aktiv?
	 JR	Z,SCRLTM	;Nein
	 LD	HL,SCRCNT	;Smooth Scroll Counter
	 INC	(HL)
	 JR	SCRLTM
SCRLN2:	 CP	6
	 CALL	NC,SSCR1
	ENDIF

SCRLTM:	LDB	(SCRTIM),10	;Verzoegerung fuer Statuszeilenschreiben
	LD	HL,STAT2
	SET	3,(HL)		;Statuszeile aus
	RES	7,(HL)		;Jetzt nicht neu zeichnen!

	IF	HD6345
WTSCRL:	 FLAG	6,ZWZL		;Slow Smooth Scroll?
	 RET	Z		;nein
SLWSCL:	 LD	A,(SCRCNT)	;Warten bis fertiggescrollt
	 OR	A
	 JR	NZ,SLWSCL
	ENDIF
	RET
;**************************************************
;* MODUL STATUS  Statuszeilenbearbeitung
;*****************************************************
STLGEN:	LD	A,(STAT1)	;Hintergrund deckend loeschen
	PUSH	AF
	SET	5,A
	RES	3,A		;Grundebene loeschen
	LD	(STAT1),A
	IF	XR
	 LD	A,(XRHGF)	;Hintergrund immer schwarz
	 PUSH	AF
	 XOR	A
	 LD	(XRHGF),A
	ELSE
	 LD	HL,(HGFRG1)	;beide Register austauschen !
	 PUSH	HL		;Statuszeile 1 immer mit schwarzem Hintergrund
	 LD	HL,1010111110101111B
	 LD	(HGFRG1),HL
	ENDIF
	LD	HL,STAT2
	RES	3,(HL)
	JPBITZ	1,(HL),STLGE1

	LD	HL,(ZLSIZE)
	LD	A,(MODUS)
	BIT	7,A		;Color-Modus?
	JR	Z,STLGE3
	ADD	HL,HL		;Dann auch 2. Zeile loeschen
STLGE3:	LD	B,H
	LD	C,L
	CALL	LOE
	CALL	NRMVDC
	CALL	STLEIN

STLGE1:	LD	HL,STAT2
	BIT	2,(HL)
	CALL	NZ,ST2EIN
	IF	XR
	 POP	AF
	 LD	(XRHGF),A
	ELSE
	 POP	HL
	 LD	(HGFRG1),HL
	ENDIF
	POP	AF
	LD	(STAT1),A
	RET
;-----------------------
STLEIN:	CALL	LINDSP	;Strich
	CALL	VERDSP	;GRIP-Version
	CALL	KBFDSP	;Keyboardbuffer display
	CALL	KLZDSP	;Keyboard Ladezahl
	CALL	MODDSP	;MODUS-Display
	CALL	CSFAIL	;Checksum Fail
	CALL	THPT	;Uhr einblenden
	RET
;-----------------------
;Statuszeilen-Displaypositionen

VERFLD	EQU	1*8	;Versionsnummer, Emblem
KBAFLD	EQU	16*8	;Keyboard Art feld
KBFFLD	EQU	19*8	;Keyboardbuffer-Display
KLZFLD	EQU	34*8	;Keyboardbufferfuellung
HSTFLD	EQU	38*8	;Hostzeichen
SPLFLD	EQU	41*8	;Spoolerzeichen
TTXFLD	EQU	44*8	;Tectronix-Mode-Zeichen
MELFLD	EQU	47*8	;Melodiezeichen
XRFLD	EQU	50*8	;XR-Symbol
TONFLD	EQU	53*8	;Bell/Klick-Zeichen
MODFLD	EQU	56*8	;MODUS (4 Hex-Zahlen)
ERRFLD	EQU	61*8	;Fehlersignal
PLZFLD	EQU	64*8	;Checksum error Datensatz
PL2FLD	EQU	66*8	;Checksum error Zeichensatz
UHRFLD	EQU	69*8	;Uhrzeichen
TIMFLD	EQU	71*8	;Zeitfeld

STM:	DB	8DH,8EH,8FH,' GRIP-'	;CONITEC Emblem
	DW	VERS1,VERS2
LSTM	EQU	$-STM
LINFLD:	DB	9EH		;Strich
TRFLD:	DB	80H		;Trennstrich
;-----------------------
LINDSP:	LD	DE,(ZLSIZE)	;Strich auf 2. Zeile
	LD	C,BLOCKS
	CALL	MSGAD
LINDS1:	LD	HL,LINFLD
	CALL	MSGDI
	JR	NZ,LINDS1
	RET
;-----------------------
TRDSP:	LD	HL,TRFLD	;Trennstrich ausgeben
	CALL	MSGAD
MSGDI:	LD	B,1
	CALL	MSGDD
	DEC	C
	RET
;-----------------------
ST2EIN:	LD	HL,STL2BF	;Statusline 2 generieren
	LD	DE,(SL2FLD)
	LD	B,BLOCKS
	JP	MSGD
;-----------------------
MSGAD:	PUSH	BC		;Bildschirmzielfeld berechnen
	EX	DE,HL
	LD	BC,(DSPST)
	ADD	HL,BC
	SETNI	7,H
	EX	DE,HL
	POP	BC
	RET

MSGD:	CALL	MSGAD
MSGDD:	LD	(VDPT),DE	;Videoramzieladresse
	LD	A,(HL)
	PUSH	BC
	PUSH	HL
	PUSH	DE
	CALLB	CHRGNB
	POP	HL
	POP	DE
	LD	BC,0008H	;Cursor increment
	ADD	HL,BC
	SETNI	7,H
	EX	DE,HL
	POP	BC
	INC	HL		;naechstes Zeichen
	DJNZ	MSGDD

	LD	HL,(CURPT)
	LD	(VDPT),HL
	RET
;-----------------------
VERDSP:	LD	HL,STM		;Startmeldung
	LD	B,LSTM		;Laenge der Meldung
	LD	DE,VERFLD	;Bildschirmzielfeld
	JP	MSGD		;Message aus ROM-zeichensatz setzen
;-----------------------
KBFDSP:	LD	A,(STAT2)	;Keyboard-Puffer Display
	AND	00001010B	;nur wenn Statuszeile an
	CP	00000010B
	RET	NZ

	LD	HL,TXNKBD
	LD	A,(MODUS)
	AND	00011000B
	CP	00011000B
	JR	Z,KBFDS2

	LD	HL,(KYBPT)
	LDRI	D,E,HL		;DE enthaelt KB Ladepointer
	EX	DE,HL
	LD	DE,TXTBF+14
	LD	B,14		;14 Zeichen anzeigen
	LD	A,L
	AND	11000000B	;Laenge der Puffer muss je 64 Byte sein
	LD	C,A		;bei Ueberlauf obere Bits erhalten

KBFDS1:	DEC	DE
	DEC	L
	LD	A,L
	AND	00111111B
	OR	C
	LD	L,A	
	LD	A,(HL)
	LD	(DE),A
	DJNZ	KBFDS1

	LD	HL,TXTBF
KBFDS2:	LD	DE,KBFFLD
	LD	B,14
	CALL	MSGD
	RET
TXNKBD:	DB	' Keyboards OFF'
;-----------------------
KLZDSP:	LD	A,(STAT2)	;display Keyboardladezahl
	AND	00001010B	;nur wenn Statuszeile an
	CP	00000010B
	RET	NZ

	LD	A,(MODUS)	;wenn Keyboards OFF keine Ladezahl anzeigen
	AND	00011000B
	CP	00011000B
	RET	Z

	LD	HL,(KYBPT)
	LD	A,(HL)
	INC	HL
	INC	HL
	LD	C,(HL)
	SUB	C
	JR	NC,KZDSP	;LP<=VP
	ADD	A,KYBLEN	;Pufferlaenge
KZDSP:	CALL	PUT
	LD	A,H
	LD	H,L
	LD	L,A
	LD	(TXTBF),HL
	LD	B,2
	LD	DE,KLZFLD
	LD	HL,TXTBF
	CALL	MSGD
	RET
;-----------------------
MODDSP:	LD	A,(STAT2)
	BIT	1,A		;Statuszeile an ?
	RET	Z

	LD	A,(MODUS)	;Keyboard Art Display
	LD	HL,9796H	;ohne Umcodierung
	JPBITZ	2,A,MODDS3
	LD	HL,9594H	;mit Umcodierung
MODDS3:	LD	DE,KBAFLD
	CALL	SMSG

	LD	HL,TXTBF
	LD	A,(MODUS)
	AND	00000011B	;LOCAL Modus ?
	LD	DE,2020H	;'  '
	JR	Z,NHSTC
	LD	DE,8B8CH	;Hostzeichen
NHSTC:	CALL	TXBLD		;Zeichen + '!' eintragen
	LD	DE,9899H
	JPI	MODDS1
	LD	DE,2020H	;Spooler Zeichen zunaechst noch nicht zeichnen
MODDS1:	CALL	TXBLD
	LD	DE,2020H
	LD	A,(STAT1)	;Tectronix ?
	JPBITZ	7,A,NTXC
	LD	DE,9293H	;Tectronixzeichen
NTXC:	CALL	TXBLD
	LD	DE,2020H
	IF	XR
	 LD	A,(MODUS)
	 JPBITZ	7,A,MODDS2
	 LD	DE,9A9BH	;XR-Farb Symbol
	ENDIF
MODDS2:	CALL	TXBLD
	PUSH	HL
	LD	HL,(MELVP)	;Melodie laeuft ?
	LD	DE,MELPUF
	SUBHL	DE
	POP	HL
	LD	DE,2020H
	JR	Z,NMELC
	LD	DE,898AH	;Melodiezeichen
NMELC:	CALL	TXBLD

	LD	HL,TXTBF
	LD	DE,HSTFLD
	LD	B,15		;5 Zeichen
	CALL	MSGD
	CALL	SPLZCH		;Spoolerzeichen schreiben
	LD	A,(MODUS)
	CALL	PUT
	LD	A,H
	LD	H,L
	LD	L,A
	LD	(TXTBF),HL
	LD	A,(MODUS+1)
	CALL	PUT
	LD	A,H
	LD	H,L
	LD	L,A
	LD	(TXTBF+2),HL
	LD	HL,TXTBF
	LD	DE,MODFLD
	LD	B,4
	JP	MSGD		;Systemkennzahl MODUS ausgeben
;-----------------------
TXBLD:	LD	(HL),D
	INC	HL
	LD	(HL),E
	INC	HL
	LD	(HL),80H	;senkrechter Strich
	INC	HL
	RET
;-----------------------
CSFAIL:	LD	HL,STAT5	;bei Checksumerror Pilz zeichnen
	BIT	0,(HL)
	JR	Z,CSFAI1
	LD	HL,9190H
	LD	DE,PLZFLD
	CALL	SMSG
CSFAI1:	LD	HL,STAT5	;unterschiedlichen Pilz fuer Zeichensatzverlust
	BIT	1,(HL)
	RET	Z
	LD	HL,9D9CH
	LD	DE,PL2FLD
	JP	SMSG
;-----------------------
SRERR:	LD	HL,9F9EH	;Zeichen f}r serial receive error
	LD	DE,ERRFLD
	CALL	SMSG
	LD	HL,0118H
	LD	(HPRTE),HL
	RET
;---------------------------
THPT:	LD	HL,0118H
	LD	(HPRTD),HL	;desaktivieren im Ablauffeld
	LD	A,(STAT2)
	AND	00001010B	;Statuszeile an ?
	CP	00000010B	;kein SCROLL ?
	RET	NZ

	LD	HL,8281H	;Uhrzeichen erzeugen
	LD	DE,UHRFLD
	CALL	SMSG

	LD	HL,TXTBF
	LD	A,' '
	LD	(HL),A
	INC	HL
	EX	DE,HL
	LD	A,(STD)
	CALL	PUT
	EX	DE,HL
	LD	(HL),D
	INC	HL
	LD	(HL),E
	INC	HL
	LD	A,':'
	LD	(HL),A
	INC	HL
	EX	DE,HL
	LD	A,(MIN)
	CALL	PUT
	EX	DE,HL
	LD	(HL),D
	INC	HL
	LD	(HL),E
	INC	HL
	LD	A,':'
	LD	(HL),A
	INC	HL
	EX	DE,HL
	LD	A,(SEC)
	CALL	PUT
	EX	DE,HL
	LD	(HL),D
	INC	HL
	LD	(HL),E

	LD	HL,TXTBF
	LD	B,9
	LD	DE,TIMFLD
	CALL	MSGD
	RET
;-----------------------
	ENDIF			;EPAGE EQ 0
TINC:	OR	A		;reset carry-Flag for DAA
	LD	A,(SEC)		;Timeincrement
	INC	A
	DAA
	CP	60H
	JR	Z,TINC2
	LD	(SEC),A
	RET

TINC2:	XOR	A
	LD	(SEC),A
	LD	A,(MIN)
	INC	A
	DAA
	CP	60H
	JR	Z,TINC3
	LD	(MIN),A
	RET

TINC3:	XOR	A
	LD	(MIN),A
	LD	A,(STD)
	INC	A
	DAA
	CP	24H
	JR	Z,TINC4
	LD	(STD),A
	RET

TINC4:	XOR	A
	LD	(STD),A
	RET
;-----------------------
	IF	EPAGE EQ 0
SMSG:	LD	A,(STAT2)	;wenn Statuszeile an
	BIT	1,A
	RET	Z
	BIT	3,A
	RET	NZ
	LD	(TXTBF),HL	;Symboldisplay
	LD	HL,TXTBF
	LD	B,2
	CALL	MSGD
SMSG1:	RET
;-----------------------
SL2CLR:	LD	HL,STL2BF	;Text der unteren Statuszeile loeschen
	LD	(ST2LPT),HL
	LD	DE,STL2BF+1
	LD	BC,BLOCKS-1
	LD	(HL),' '
	LDIR
	RET
;-----------------------
	IF	DEBUG
	DB	'LOE'
	ENDIF
LOE:	LD	HL,(DSPST)	;Video-Ram ab Anfang loeschen
LOE1:	JPI	LOEI1		;Startadresse HL, Laenge BC
	PUSH	HL
	DEC	BC
	ADD	HL,BC
	INC	BC
	POP	HL
	JR	NC,LOESCH

	LD	D,H
	LD	E,L
	LD	HL,0		;Seitenueberschreitung 1.Block loeschen
	SUBHL	DE			;Anzahl1=0000-Anfangsadresse
	PUSH	BC
	LD	B,H
	LD	C,L
	LD	H,D
	LD	L,E
	PUSH	BC
	CALL	LOESCH
	POP	BC		;2.Seite loeschen Anzahl2=Gesamt-Anzahl1
	POP	HL
	SUBHL	BC
	LD	B,H
	LD	C,L
	LD	HL,8000H

LOESCH:	LD	A,(MODUS)	;im Grundmodus Ram loeschen
	JPBITZ	7,A,LOE2

	IF	XR
	 LD	A,(XRHGF)
	 OUT	(XRCLRG),A
	ELSE
	 LD	A,(HGFRG1)	;Schreiben in Farbebene mit Hintergrundfarbe
	 OUT	(CLRG1),A
	 LD	A,(HGFRG2)
	 OUT	(CLRG2),A
	ENDIF
	PUSH	HL
	PUSH	BC
LOESC1:	LD	(HL),WHITE
	CPI
	JP	PE,LOESC1
	POP	BC
	POP	HL

	IF	XR
	 LD	A,00H
	 OUT	(XRFLGS),A	;Write in Grundebene
	 LD	A,10H
	 OUT	(XRFLGS),A	;lesen von Grundebene
	ELSE
	 LD	A,10110111B	;Schreiben in Grundebene
	 OUT	(CLRG1),A
	ENDIF
	LD	A,(STAT1)
	JPBITZ	5,A,LOESC3	;fertig wenn transparent

	JPBITZ	3,A,LOE2	;entweder 1 der 0 in GE schreiben
	LD	A,0FFH
	JR	LOE3
LOE2:	XOR	A
LOE3:	LD	E,L
	LD	D,H
	INC	DE
	DEC	BC
	LD	(HL),A
	LDIR
LOESC3:	IF	XR
	 LD	A,(XRWR)
	 OUT	(XRFLGS),A
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ENDIF
	JP	FRBRES
; ---------------------		;Loeschen Interlaced
LOEI1:	LD	A,H		;Video-Ram ab HL loeschen
	LD	(WPAGE),A	;mit Pagegrenzenberechnung
	SET	7,H		;HL,BC  muss durch 8 teilbar sein
LOEI3:	LD	A,(WPAGE)
	OUT	(PAGE),A
	XOR	80H		;jetzt andere Page
	LD	(WPAGE),A
	PUSH	HL		;ueber Pagegrenze hinaus
	DEC	BC
	ADD	HL,BC
	INC	BC
	POP	HL
	JR	NC,LOESCH

	LD	D,H
	LD	E,L
	LD	A,H
	LD	HL,0		;Seitenueberschreitung 1.Block loeschen
	PUSH	BC
	SET	7,D
	SUBHL	DE			;Anzahl1=0000-Anfangsadresse
	LD	B,H
	LD	C,L
	LD	H,A
	LD	L,E
	PUSH	BC
	CALL	LOESCH
	POP	BC		;2.Seite loeschen Anzahl2=Gesamt-Anzahl1
	POP	HL
	SUBHL	BC
	LD	B,H
	LD	C,L
	LD	HL,8000H
	JR	LOEI3

;****************************************************************************
;MODUL KOM	Kommandoausf}hrung
;****************************************************************************
;Controlcode-Tabelle TVI-Modus 00H-1FH

STDTAB:	DW	RETM,RETM,RETM,RETM,RETM,RETM,RETM
	DW	BELL	;Tonzeichen
	DW	CURLFT	;Cursor links
	DW	CURGT	;Cursor rechts
	DW	PLF	;Line Feed
	DW	CURAUF	;Cursor auf
	DW	ERASE	;Bild loeschen Cursor Home
	DW	PCR	;Carriage Return
	DW	RETM,RETM,RETM,RETM,RETM,RETM,RETM,RETM
	DW	PLF
	DW	RETM,RETM,RETM
	DW	BCLEAR	;Bild loeschen
	DW	ESCAPE
	DW	RETM,RETM
	DW	CHOME	;Cursor Home
	DW	LFCR	;LF + CR

;-----------------------
ESCAPE:	LD	HL,ABLMRK
	SET	1,(HL)		;Kommandoflag ESC-Sequenz laeuft
RETM:	RET
;-----------------------
PLF:	LD	A,(ZLANZ)	;Line Feed ausf}hren
	LD	B,A		;Teste ob Cursor in der letzten Zeile
	DEC	B
	LD	A,(CZL)
	CP	B
	JP	NC,SCROLL
	INC	A
PLF2:	LD	(CZL),A
	JP	CURADR
;-----------------------
LFCR:	CALL	PLF
PCR:	LDB	(CSP),0
	JP	CURADR
;-----------------------
CHOME:	XOR	A
	LD	(CZL),A
	LD	(CSP),A
	JP	CURADR
;-----------------------
GETVBL:	LD	A,(TXOFFS)	;Sichtbare Zeilen berechnen
	LD	HL,STAT1
	BIT	7,(HL)		;TX Mode?
	RET	NZ
	LD	A,(ZLANZ)
	LD	HL,STAT2
	BIT	1,(HL)		;STZ1?
	JR	Z,GETVB1
	ADD	A,2
GETVB1:	BIT	2,(HL)		;STZ2?
	RET	Z
	INC	A
	RET
;-----------------------
BCLEAR:	CALL	GETVBL		;Zeilenanzahl
	LD	BC,(ZLSIZE)
	LD	HL,0
BCLEA1:	ADD	HL,BC
	DEC	A
	JR	NZ,BCLEA1
	LD	B,H		;Laenge
	LD	C,L
	LD	HL,(DSPST)	;ZLANZ Zeilen loeschen ab HOME
	SETNI	7,H
	CALL	LOE1
	JP	STLGEN		;Vorsichtshalber STZ regenerieren
;-----------------------
ERASE:	CALL	BCLEAR		;<^L> Bild loeschen + Cursor Home
	JP	CHOME
;----------------------
CURGT:	LD	A,(STAT1)
	BIT	7,A		;TX Mode?
	JR	NZ,CURGTX
	LD	A,(SPANZ)	;Cursor right
	LD	HL,BRTFLG
	JPBITZ	4,(HL),CURGT2
	DEC	A
CURGT2:	DEC	A
	LD	B,A
	LD	A,(CSP)
	CP	B
	JR	NC,CURGT1	;Cursor am Ende der Zeile ?
CURGT4:	JPBITZ	4,(HL),CURGT3
	INC	A		;bei Breitschrift 2 Incr.
CURGT3:	INC	A
	LD	(CSP),A
	LD	HL,(CURPT)	;schnelle Cursorneuposition
	LD	A,(BRTFLG)	;nach normalem Cursor advance
	LD	B,0
	LD	C,A
	ADD	HL,BC
	JP	C,CURPOR	;bei Uebertrag Interlaced abtesten und evtl. Bit 7 setzen
	LD	(CURPT),HL
	LD	(VDPT),HL	;VIDEO-Ram Pointer
	RET

CURGT1:	LD	HL,BRTFLG
	XOR	A		;Naechste Zeile
	LD	(CSP),A		
	LD	A,(ZLANZ)
	LD	B,A
	DEC	B
	LD	A,(CZL)
	CP	B
	JP	NC,SCROLL
	INC	A
	LD	(CZL),A
CURRG2:	JP	CURADR
;-----------------------
CURATX:	LD	HL,(GCPOS)	;TX Cursor auf
	LD	BC,(ZLSIZE)
CURTX2:	SUBHL	BC
	JR	CURTX1

PLFTX:	LD	HL,(GCPOS)	;TX Line Feed
	LD	BC,(ZLSIZE)
	JR	CURTX

CURLTX:	LD	HL,(GCPOS)
	LD	A,(BRTFLG)
	LD	B,0
	LD	C,A
	JR	CURTX2

CURGTX:	LD	HL,(GCPOS)	;TX Cursor right
	LD	A,(BRTFLG)
	LD	B,0
	LD	C,A

CURTX:	ADD	HL,BC
CURTX1:	SETNI	7,H
	LD	(GCPOS),HL
	RET
;-----------------------
CURLFT:	LD	HL,BRTFLG
	LD	A,(CSP)
	OR	A
	JR	NZ,CURLF1
	LD	A,(CZL)		;keine Reaktion wenn
	OR	A		;Cursor oben links
	RET	Z
	DEC	A
	LD	(CZL),A
	LD	A,(SPANZ)
CURLF1:	JPBITZ	4,(HL),CURLF2
	DEC	A
CURLF2:	DEC	A
	LD	(CSP),A
	JP	CURADR
;-----------------------
CURAUF:	LD	A,(CZL)
	OR	A
	RET	Z	;oberste Zeile keine Wirkung
	DEC	A
	LD	(CZL),A
	JP	CURADR
;***************************************************
;* MODUL COLOR bzw. MODUL XR Farbbefehle 
;***************************************************
	ENDIF	;EPAGE 0
	IF	EPAGE EQ 1
	IF	XR

SETCDF:	LD	A,(XRRDC)
	OUT	(XRFLGS),A
SETCDA:	XOR	A		;Defaultfarben einstellen
	OUT	(XRCLU0),A	;beginne bei Farbnummer 0, wird automatisch incrementiert
	LD	C,XRCLU1

	LD	HL,STEPTB
	LD	D,0
	LD	B,CSTEPS
SETCD1:	LD	A,(HL)
	OUT	(C),A
	OUT	(C),D
	OUT	(C),D
	INC	HL
	DJNZ	SETCD1

	LD	HL,STEPTB
	LD	B,CSTEPS
SETCD3:	LD	A,(HL)
	OUT	(C),D
	OUT	(C),A
	OUT	(C),D
	INC	HL
	DJNZ	SETCD3

	LD	HL,STEPTB
	LD	B,CSTEPS
SETCD4:	LD	A,(HL)
	OUT	(C),D
	OUT	(C),D
	OUT	(C),A
	INC	HL
	DJNZ	SETCD4

	LD	HL,STEPTB
	LD	B,CSTEPS
SETCD5:	LD	A,(HL)
	OUT	(C),A
	OUT	(C),A
	OUT	(C),D
	INC	HL
	DJNZ	SETCD5

	XOR	A
	LD	B,64
SETCD6:	OUT	(C),A
	OUT	(C),A
	OUT	(C),A
	INC	A
	DJNZ	SETCD6
	JP	SETCD2

XRSPKT:	LD	A,(XRRDC)
	OUT	(XRFLGS),A
	XOR	A
	OUT	(XRCLU0),A
	LD	HL,SPKTAB	;Rot = C  Gruen = D  Blau = E
	LD	C,00111111B	;Beginn mit Rot=63 Blau=0
	LD	E,0

	LD	B,42
XRSPK1:	LD	D,(HL)		;Gruen aufsteigend von Tabelle
	CALL	SETSPK
	INC	HL
	DJNZ	XRSPK1

	LD	D,(HL)
	LD	B,42
XRSPK2:	LD	C,(HL)		;Rot abfallend
	CALL	SETSPK
	DEC	HL
	DJNZ	XRSPK2

	LD	C,(HL)
	LD	B,42
XRSPK3:	LD	E,(HL)		;Blau aufsteigend
	CALL	SETSPK
	INC	HL
	DJNZ	XRSPK3

	LD	E,(HL)
	LD	B,42
XRSPK4:	LD	D,(HL)		;Gruen abfallend
	CALL	SETSPK
	DEC	HL
	DJNZ	XRSPK4

	LD	D,(HL)
	LD	B,42
XRSPK5:	LD	C,(HL)		;Rot aufsteigend
	CALL	SETSPK
	INC	HL
	DJNZ	XRSPK5

	LD	C,(HL)
	LD	B,42
XRSPK6:	LD	E,(HL)		;Blau abfallend
	CALL	SETSPK
	DEC	HL
	DJNZ	XRSPK6

	LD	E,(HL)		;Farbindex 252-255 ist Rot
	LD	B,4
XRSPK7:	CALL	SETSPK
	DJNZ	XRSPK7
	JP	SETCD2


SETSPK:	LD	A,C
	OUT	(XRCLU1),A
	LD	A,D
	OUT	(XRCLU1),A
	LD	A,E
	OUT	(XRCLU1),A
	RET


SPKTAB:	DB	0,2,3,5,6,8,9,11,12,14,15,17,18,20,21,23,24,26,27,29,30,32,34,35
	DB	37,38,40,41,43,44,46,47,49,50,52,53,55,56,58,59,61,62,63

STEPTB:	DB	00,01,03,04,05,07,08,09,11,12,13,15,16,17,19,20,21,23,24,25,27,28,29,31
	DB	32,33,35,36,37,39,40,41,43,44,45,47,48,49,51,52,53,55,56,57,59,60,61,63

XRBONB:	LD	A,(XRRDC)
	OUT	(XRFLGS),A
	XOR	A		;XR-Karte auf Bonbonfarben stellen
	OUT	(XRCLU0),A	;beginne bei Farbnummer 0, wird automatisch incrementiert
	LD	B,A
XRBON1:	XOR	A		;setze Knallbonbonfarben
	BIT	3,B
	JR	Z,XRBON2
	LD	A,3FH	
XRBON2:	OUT	(XRCLU1),A	;Rotwert
	XOR	A
	BIT	4,B
	JR	Z,XRBON3
	LD	A,3FH
XRBON3:	OUT	(XRCLU1),A	;Gruenwert
	XOR	A
	BIT	5,B
	JR	Z,XRBON4
	LD	A,3FH
XRBON4:	OUT	(XRCLU1),A	;Blauwert
	INC	B
	JR	NZ,XRBON1
	JP	SETCD2

XRGRAU:	LD	A,(XRRDC)
	OUT	(XRFLGS),A
	XOR	A		;XR-Karte auf Grauwertscala stellen
	OUT	(XRCLU0),A	;beginne bei Farbnummer 0, wird automatisch incrementiert
	LD	B,A
XRGRA1:	LD	A,B
	SRL	A
	SRL	A
	OUT	(XRCLU1),A	;Rotwert
	OUT	(XRCLU1),A	;Gruenwert
	OUT	(XRCLU1),A	;Blauwert sind gleich
	INC	B
	JR	NZ,XRGRA1

SETCD2:	LD	A,0FFH		;Farbmaskenregister desaktivieren
	OUT	(XRCLU2),A
	LD	A,(XRRD)	;standard Read enable
	OUT	(XRFLGS),A
	JR	BLKOF1

BLNKOF:	CALL	SETCOL		;Blinken abschalten <EE!z> Originalfarben setzen
BLKOF1:	LD	HL,BLKCTB
	LD	DE,BLKCTB+1
	LD	BC,7*BLKMAX-1
	LD	(HL),0FFH
	LDIR			;Blinken abschalten
	RET

	ELSE
SETCDF:	LD	HL,CLRTAB	;Farb Defaultwerte einstellen fuer GRIP-COLOR
	LD	DE,COLTB1
	LD	BC,3*16
	PUSH	HL
	PUSH	BC
	LDIR
	POP	BC
	POP	HL
	LD	DE,COLTB2
	LDIR
	CALL	SETCOL
	RET

CLRTAB:	DB	08H,08H,08H	;Defaultfarben
	DB	10H,10H,10H	;weiss Reinfarben 7
	DB	20H,28H,28H
	DB	3FH,30H,30H	;cyan Farbe 6
	DB	48H,40H,48H
	DB	50H,5FH,50H	;purpur Farbe 5
	DB	60H,60H,68H
	DB	7FH,7FH,70H	;blau Farbe 4
	DB	88H,88H,80H
	DB	90H,90H,9FH	;gelb Farbe 3
	DB	0A0H,0A8H,0A0H
	DB	0BFH,0B0H,0BFH	;gruen Farbe 2
	DB	0C8H,0C0H,0C0H
	DB	0D0H,0DFH,0DFH	;rot Farbe 1
	DB	0E0H,0E0H,0E0H	;WEISS Grundfarbe
	DB	0FFH,0FFH,0FFH	;Hintergrundfarbe schwarz

	ENDIF
;----------------------------------
	IF	XR

;Aufbau Blinktabelle BLKCTB: 12 Eintraege zu je 7 byte
;1=Farbindex 2,3,4=rgb Farbe 5,6,7=rgb Blinkfarbe
;Farbindex FF bedeutet kein Eintrag

BLNKCL:	LD	HL,STAT4	;Farben Blinkroutine wird von BLINK aufgerufen
	JPBITZ	3,(HL),RESCOL

SETCOL:	LD	DE,1		;Farbtabelle an Lookup-Table ausgeben
	JR	SETCO2
RESCOL:	LD	DE,4		;Blinkfarbentabelle an Lookup-Table ausgeben
SETCO2:	LD	B,BLKMAX	;maximal 12 Blinkfarben gleichzeitig
	LD	HL,BLKCTB	;Pointer auf Blinktabelle in HL

SETCO3:	LD	A,(HL)		;BLKCNR enthaelt eine Liste aus Farbnummern
	CP	0FFH		;FF ist unbelegter Platz
	JR	Z,SETCO4
	LD	A,(HL)
	OUT	(XRCLU0),A

	PUSH	HL
	ADD	HL,DE		;Offset 1 oder 4 addieren fuer Blinkphase
	LD	C,3
SETCO1:	LD	A,(HL)
	INC	HL
	OUT	(XRCLU1),A	;RGB Werte ausgeben
	DEC	C
	JR	NZ,SETCO1
	POP	HL

SETCO4:	PUSH	BC
	LD	BC,7
	ADD	HL,BC
	POP	BC
	DJNZ	SETCO3
	RET

	ELSE
BLNKCL:	LD	HL,STAT4
	JPBITZ	3,(HL),RESCOL
SETCOL:	LD	HL,COLTB1	;Farbtabelle komplett an Colorkarte 1 ausgeben
	JR	SETCO2
RESCOL:	LD	HL,COLTB2	;Blinkfarbentabelle komplett an Colorkarte 1 ausgeben
SETCO2:	LD	B,16
SETCO1:	LD	A,(HL)
	OUT	(REDOUT),A
	INC	HL
	LD	A,(HL)
	OUT	(GRNOUT),A
	INC	HL
	LD	A,(HL)
	OUT	(BLUOUT),A
	INC	HL
	DJNZ	SETCO1
	RET
	ENDIF
	ENDIF	;EPAGE 1
;-----------------------
	IF	EPAGE EQ 0
	IF	XR
COLMIX	EQU	$
COLPUR:	CALL	VPSUB		;<EEW><EEw> Farbton einstellen
	CALL	HBINH		;Farbzuordnung einer Farbnummer einlesen
	CP	4		;warte auf 4 Byte Eingabe xrgb
	RET	C
	CALL	HBFRD		;Farbnummer einlesen

	LD	HL,XRCOLT
	LD	(HL),A		;xrgb einlesen, Farbindex abspeichern
	INC	HL
	LD	B,3		;3*4 bit Farbanteil einlesen
COLPU1:	PUSH	HL
	PUSH	BC
	CALL	HBFRD		;naechstes Byte lesen
	POP	BC
	POP	HL
	SUB	30H
	AND	00111111B	;Farbanteil ROT GRUEN BLAU je 6 bit
	LD	(HL),A
	INC	HL
	DJNZ	COLPU1
	LD	A,(XRCOLT)
	CALL	REMBLK		;Farbe falls vorhanden aus Blinktabelle entfernen
	CALL	RGBOUT		;Farbton an Lookup Table ausgeben
	JP	STDRT		;neuer Farbton ist eingestellt

	ELSE
COLMIX:	LD	HL,STAT3	;<EEw> Farbton einstellen fuer Farben mit GE=1
	RES	4,(HL)		;Flag fuer Bit 7 Farbanteil
	JR	COLMI2
COLPUR:	LD	HL,STAT3	;<EEW> Farbton einstellen fuer Farben mit GE=0
	SET	4,(HL)
COLMI2:	CALL	VPSUB		;warte auf 4 Byte Eingabe xrgb
	CALL	HBINH		;Farbzuordnung einer Farbnummer einlesen
	CP	4
	RET	C
	CALL	HBFRD		;Farbnummer einlesen
	SUB	20H		;Bit 4 ist in STAT3
	JR	NZ,COLMI3
	LD	HL,STAT3	;bei ESC ESC W 0 Defaultfarben einstellen
	JPBITZ	4,(HL),COLMI3
	CALL	COLRD
	CALLB	SETCDF
	JR	COLMI4

COLMI3:	CALL	COLRD
	CALL	CTB1LD		;in Colortabelle 1 und 2 eintragen
	CALL	CTB2LD		;
	CALL	RGBOUT
COLMI4:	JP	STDRT		;neuer Farbton ist eingestellt
	ENDIF
;-----------------------
	IF	XR
COLRVM	EQU	$
COLRVP:	CALL	VPSUB
	CALL	HBINH
	CP	4
	RET	C
	CALL	HBFRD		;Farbnummer hier ist ein Dummy !!
	LD	A,(XRCOLT)	;Als Blinkfarbe gilt die zuletzt umdefinierte Farbe
	CALL	REMBLK		;Farbe falls vorhanden aus Blinktabelle entfernen
	LD	HL,XRBRGB
	LD	B,3		;3*4 bit Farbanteil einlesen
COLRV1:	PUSH	HL
	PUSH	BC
	CALL	HBFRD		;naechstes Byte lesen
	POP	BC
	POP	HL
	SUB	30H
	AND	00111111B	;Farbanteil ROT GRUEN BLAU je 6 bit
	LD	(HL),A
	INC	HL
	DJNZ	COLRV1
	CALL	APPBLK		;Blinkfarbe neu in Tabelle aufnehmen
	JP	STDRT		;neuer Farbton ist eingestellt

	ELSE
COLRVM:	LD	HL,STAT3	;<EEY> Blinkfarbe einstellen fuer GE=0
	RES	4,(HL)
	JR	COLRV2
COLRVP:	LD	HL,STAT3	;<EEy> Blinkfarbe einstellen fuer GE=1
	SET	4,(HL)
COLRV2:	CALL	VPSUB		;warte auf 4 Byte Eingabe
	CALL	HBINH		;Farbzuordnung einer Farbnummer einlesen
	CP	4
	RET	C
	CALL	HBFRD		;Farbnummer einlesen
	SUB	20H		;Bit 4 ist in STAT3
	JR	NZ,COLRV3
	LD	HL,STAT3
	JPBITZ	4,(HL),COLRV3
	CALL	COLRD		;bei ESC ESC Y 0 Blinken abschalten
	LD	HL,COLTB1
	LD	DE,COLTB2
	LD	BC,3*16
	LDIR
	JR	COLRV4

COLRV3:	CALL	COLRD		;Blinkfarbe ist in Tabelle aufgenommen
	CALL	CTB2LD
COLRV4:	JP	STDRT
	ENDIF
;---------------------------------
	IF	XR
REMBLK:	LD	HL,BLKCTB	;Remove Blinkcolor A from table
	LD	DE,7		;teste ob XRCOLT in Blinkfarben-Tabelle vorkommt
	LD	B,BLKMAX	;maximal 12 Eintraege abtesten
REMBL1:	CP	(HL)
	JR	Z,REMBL2
	ADD	HL,DE		;vorruecken auf naechsten Eintrag
	DJNZ	REMBL1		;Ende nach 12 Eintraegen
	RET
REMBL2:	LD	A,0FFH		;Eintrag ist geloescht
	LD	(HL),A
	RET

APPBLK:	LD	HL,BLKCTB	;Append Blinkcolor to Table new Color in XRBCOL
	LD	DE,7		;teste ob freier Platz in Blinkfarben-Tabelle
	LD	B,BLKMAX	;maximal 12 Eintraege abtesten
	LD	A,0FFH
APPBL1:	CP	(HL)
	JR	Z,APPBL2
	ADD	HL,DE		;vorruecken auf naechsten Eintrag
	DJNZ	APPBL1		;Ende nach 12 Eintraegen kein freier Platz
	RET
APPBL2:	EX	DE,HL
	LD	HL,XRCOLT	;neue Blinkfarbe eintragen
	LD	BC,7		;7 Byte
	LDIR
	RET
	ENDIF
;---------------------------------
	IF	NOT XR
COLRD:	PUSH	AF
	RRC	A
	RRC	A
	RRC	A
	AND	11100000B
	XOR	11100000B
	LD	B,A
	LD	A,(STAT3)
	AND	00010000B
	OR	B
	LD	(REDRG1),A	;Register der Farbanteile anwaehlen
	LD	(GRNRG1),A
	LD	(BLURG1),A
	POP	AF
	SLA	A
	SLA	A
	AND	11100000B
	XOR	11100000B
	LD	B,A
	LD	A,(STAT3)
	AND	00010000B
	OR	B
	LD	(REDRG2),A	;fuer GRIP-COLOR 2
	LD	(GRNRG2),A
	LD	(BLURG2),A
	LD	HL,REDRG1
	LD	B,3		;3*4 bit Farbanteil einlesen
COLRD1:	PUSH	HL
	PUSH	BC
	CALL	HBFRD
	POP	BC
	POP	HL
	AND	00001111B	;Farbanteil ROT GRUEN BLAU
	XOR	00001111B	;Register S 189 invertieren
	LD	C,A
	OR	(HL)
	LD	(HL),A
	INC	HL
	LD	A,C
	OR	(HL)
	LD	(HL),A
	INC	HL
	DJNZ	COLRD1
	RET
	ENDIF
;-----------------------
	IF	XR
RGBOUT:	LD	HL,XRCOLT
	LD	A,(HL)		;HL zeigt auf 4 byte xrgb
	OUT	(XRCLU0),A	;A=Farbindex HL=Pointer auf RGB
	INC	HL
	LD	B,3
RGBOU1:	LD	A,(HL)
	OUT	(XRCLU1),A
	INC	HL
	DJNZ	RGBOU1
	RET

	ELSE
RGBOUT:	LD	HL,REDRG1	;neue Farbeinstellung ausgeben
	LD	DE,OUTTAB
	LD	B,6
RGBOU1:	LD	A,(DE)
	LD	C,A
	LD	A,(HL)
	OUT	(C),A
	INC	HL
	INC	DE
	DJNZ	RGBOU1
	RET

OUTTAB:	DB	REDOUT,RD2OUT,GRNOUT,GR2OUT,BLUOUT,BL2OUT
	ENDIF
;-----------------------
	IF	NOT XR
CTB1LD:	LD	DE,COLTB1	;Color Table 1 Load Oroginalfarben 
	JR	CTBLD
CTB2LD:	LD	DE,COLTB2	;Color Table 2 Load Blinkfarben 
CTBLD:	LD	HL,REDRG1
	LD	A,(HL)	;HL Pointer auf neue Farbwerte REDRG1 od. REDRG2
	AND	11110000B
	RRCA		;DE COLTB1 oder COLTB2
	RRCA
	RRCA
	LD	B,A
	RRCA
	ADD	A,B	;Farbindex * 3 als Index fuer Tabelle
	LD	B,0
	LD	C,A
	EX	DE,HL
	ADD	HL,BC	;HL zeigt auf Colortabelle fuer neue Werte
	EX	DE,HL
	LDI
	INC	HL
	LDI
	INC	HL
	LDI
	RET
	ENDIF
;-----------------------
EBNDEF:	CALL	VPSUB		;Ebene definieren
	CALL	HBINPR
	RET	Z
	LD	B,A
	AND	00001111B
	LD	(EBENE),A
	LD	HL,STAT3	;Flag fuer invertierte Ausgabe setzen
	RES	6,(HL)
	BIT	6,B
	JP	Z,STDRT
	SET	6,(HL)
	JP	STDRT
;-----------------------
	IF	XR
COLDEF	EQU	$
COLDFT:	CALL	VPSUB		;<EV> Farbe definieren transparent
	CALL	HBINPR
	RET	Z
	LD	(XRCOL),A	;XR Color Maske ist Schreibfarbe im Maskenmodus
	OUT	(XRCLRG),A
	CALL	SETFKT
	JP	STDRT
	
	ELSE
COLDFT:	CALL	VPSUB		;<EV> Farbe definieren transparent
	CALL	HBINPR
	RET	Z
	SUB	20H
	LD	HL,STAT1
	RES	6,(HL)
	JR	COLDE1

COLDEF:	CALL	VPSUB		;<EW> Farbe definieren opak
	CALL	HBINPR
	RET	Z
	LD	HL,STAT1
	SET	6,(HL)
	RES	4,(HL)
	JPBITZ	6,A,COLDE1
	SET	4,(HL)

COLDE1:	PUSH	AF
	AND	00000111B
	XOR	00000111B
	LD	B,A
	LD	A,(COLRG1)
	AND	11111000B
	OR	B
	LD	(COLRG1),A
	OUT	(CLRG1),A
	POP	AF
	SRL	A
	SRL	A
	SRL	A
	AND	00000111B
	XOR	00000111B
	LD	B,A
	LD	A,(COLRG2)
	AND	11111000B
	OR	B
	LD	(COLRG2),A
	OUT	(CLRG2),A
	CALL	SETFKT		;Character und Vektorfunktion waehlen
	JP	STDRT
	ENDIF
;-----------------------
	IF	XR
HGFDEF	EQU	$
HGFDFT:	CALL	VPSUB		;<Ev><Ew> XR Hintergrundfarbe definieren
	CALL	HBINPR
	RET	Z
	LD	(XRHGF),A	;XR Color Maske ist Schreibfarbe im Maskenmodus
	CALL	SETFKT
	JP	STDRT
	
	ELSE
HGFDFT:	CALL	VPSUB
	CALL	HBINPR
	RET	Z
	SUB	20H
	LD	HL,STAT1
	RES	5,(HL)
	JR	HGFDE1

HGFDEF:	CALL	VPSUB
	CALL	HBINPR
	RET	Z

	LD	HL,STAT1
	SET	5,(HL)
	RES	3,(HL)
	JPBITZ	6,A,HGFDE1
	SET	3,(HL)
HGFDE1:	PUSH	AF
	AND	00000111B
	XOR	00000111B
	OR	10101000B
	LD	(HGFRG1),A
	POP	AF
	SRL	A
	SRL	A
	SRL	A
	AND	00000111B
	XOR	00000111B
	OR	10101000B
	LD	(HGFRG2),A
	CALL	SETFKT
	JP	STDRT
	ENDIF
;****************************************************************************
;MODUL ESC
;****************************************************************************
;ESC-Sequenzen TVI-Modus

STESCH:	DB	'+;.=?ERTtYyVvWwGno)($%1234'
LSTECH	EQU	$-STESCH
STDESC:	DW	SCRLFT	;Scroll left
	DW	SCRLUP	;Scroll down
	DW	SCRIGT	;Scroll right
	DW	SCRDWN	;Scroll up
	DW	STGROF	;Strichgraphik aus
	DW	STGRON	;Strichgraphik ein
	DW	INVOF	;Invertieren aus
	DW	INVON	;Invertieren ein
	DW	SCROFF	;Bildschirm aus
	DW	SCRON	;Bildschirm an
	DW	ATRIBU	;Zweichenattribute setzen
	DW	HGFDEF	;Hintergrundfarbe einstellen
	DW	COLDEF	;aktuelle Farbe einstellen
	DW	HGFDFT
	DW	COLDFT	;Farbe einstellen transparent
	DW	ERPGR	;loesche Rest des Bildschirms
	DW	ERPGR
	DW	ERZR	;loesche Rest der Zeile
	DW	ERZR
	DW	ERLIN	;Cursorzeile loeschen
	DW	INSLIN	;Zeile einfuegen
	DW	CUR?	;Cursor abfragen
	DW	CURPOS	;Cursor positionieren
	DW	CURATR	;Cursorattribute setzen
	DW	ERASE	;Bildschirm loeschen
	DW	ERASE
;-----------------------
WTSYNC:	PUSH	HL	;warte auf SYNC Impuls
	LD	HL,SEC50
	LD	A,(HL)
WTSYN1:	CP	(HL)
	JR	Z,WTSYN1
	POP	HL
	RET
;-----------------------
SCRON:	LD	HL,STAT1
	RES	0,(HL)
SCRONA:	CALL	WTSYNC
SCRONB:	SETR	1,BLOCKS	;displayed Columns set to default
	RET
;-----------------------
SCROFF:	LD	HL,STAT1
	SET	0,(HL)
SCROFA:	SETR	1,0		;displayed Columns set to zero
	RET
;-----------------------
INVON:	LD	HL,ATTRIB
	SET	2,(HL)
	LD	HL,ATRFLG
	SET	2,(HL)
	RET
INVOF:	LD	HL,ATTRIB
	RES	2,(HL)
	LD	HL,ATRFLG
	RES	2,(HL)
	RET
;----------------------
STGROF:	CALLB	STGOFB
	RET
STGRON:	CALLB	STGONB
	RET
;----------------------
ATRIBU:	CALL	VPSUB		;Attribute bestimmen ESC G
	CALL	HBINPR
	RET	Z

	LD	B,A
	LD	(ATTRIB),A
	AND	00111111B	;ATRFLG Flag fuer schnelle Erkennung von Attributen
	XOR	00110000B
	LD	(ATRFLG),A	;bei Zeichengenerierung

	LD	A,8		;Breitschrift gesetzt ?
	BIT	6,B
	JR	Z,ATREN1
	LD	A,(CSP)		;nur gerade Spalten erlaubt bei Breitschrift
	AND	11111110B
	LD	(CSP),A
	CALL	CURADR
	LD	A,16
ATREN1:	LD	(BRTFLG),A
	CALLB	SETZPT		;setze Zeichensatzpointer neu CHSET
	JP	STDRT
;-----------------------
	ENDIF
	IF	EPAGE EQ 1
TBWSET:	LD	BC,0
	LD	A,(MODUS)	;Farbmodus an ?
	RL	A
	RL	C
	LD	A,(STAT1)	;Tektronixmodus an ?
	RL	A
	RL	C
	RL	C
	JPNI	TBWSE1
	SET	3,C		;8 addieren im Interlaced Modus 
TBWSE1:	LD	HL,TBWTAB	;fuer andere Charactergenerierung
	ADD	HL,BC
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	LD	(CHRPRG),DE
	RET

TBWTAB:	DW	TBWTVI,TXWRT,TBWTVC,TXCWRT
	DW	TBITVI,TXWRT,TBITVC,TXCWRT
	ENDIF
;-----------------------
	IF	EPAGE EQ 0
	IF	DEBUG
	DB	'ERPGR'
	ENDIF

ERPGR:	JPI	ERPGI
	LD	A,(CZL)		;erase to end of screen
	LD	B,A
	LD	A,(ZLANZ)
ERPGR2:	INC	B
	SUB	B		;A= Nr of Lines to erase
	LD	D,0

	IF	BLOCKS EQ 96
	 LD	B,5		;A * 96 = Nr of colums to erase
ERPGR1:	 SLA	A
	 RL	D
	 DJNZ	ERPGR1
	 LD	H,D
	 LD	L,A
	 SLA	A
	 RL	D
	 LD	E,A
	 ADD	HL,DE		;HL=Lines * 96
	ELSE
	.PRINTX * ACHTUNG - BLOCKS FALSCH BERECHNET! *
	ENDIF
	JR	ERZR1
;-----------------------
ERZR:	LD	HL,0
	JPI	ERZRI

ERZR1:	LD	A,(CSP)		;Rest einer Zeile loeschen
	LD	C,A		;ab Cursorposition
	LD	A,BLOCKS
	SUB	C
	LD	C,A		;HL = Anzahl zu loeschender Spalten 
	LD	B,0		;ab Cursorposition
	ADD	HL,BC
	SLA	L		;Byteanzahl = Spaltenanzahl * 8
	RL	H
	SLA	L
	RL	H
	SLA	L
	RL	H
	LD	B,H
	LD	C,L
	LD	HL,(CURPT)
	JP	LOE1

ERZRI:	LD	A,(CSP)		;Rest einer Zeile loeschen
	LD	C,A		;ab Cursorposition
	LD	A,BLOCKS
	SUB	C
	LD	C,A		;HL = Anzahl zu loeschender Spalten 
	LD	B,0		;ab Cursorposition
	ADD	HL,BC
	SLA	L		;Byteanzahl = Spaltenanzahl * 8
	RL	H
	SLA	L
	RL	H
	SLA	L
	RL	H
	LD	B,H
	LD	C,L
	LD	HL,(CURPT)
ERSP:	PUSH	BC		;ERASE Einzel	zeichen
	PUSH	HL
	CALL	LOE1
	POP	HL
	LD	BC,PITCH	;auch untere Zeichenhaelfte loeschen
	ADD	HL,BC
	POP	BC
	JP	LOE1
;-----------------------
ERPGI:	CALL	ERZR		;erase to end of screen
	LD	A,(CZL)		;zunaechst bis Ende der Zeile loeschen
	LD	D,A
	LD	A,(ZLANZ)
ERPGI2:	INC	D
	SUB	D		;A= Nr of Lines to erase
	RET	Z

	LD	HL,0		;Anzahl der Bytes berechnen
	LD	BC,(ZLSIZE)
ERPGI3:	ADD	HL,BC
	DEC	A
	JR	NZ,ERPGI3
	PUSH	HL

	LD	HL,(DSPST)	;Beginnadresse berechnen
ERPGI4:	ADD	HL,BC
	DEC	D
	JR	NZ,ERPGI4

	LD	BC,(DSPANF)
	ADD	HL,BC
	POP	BC
	JP	LOE1		;loeschen
;-----------------------
CURATR:	CALL	VPSUB		;Cursor Attribute setzen
CURAW:	CALL	HBFRD
	RET	Z
	SUB	30H
	RLCA			;*2
	LD	C,A
	LD	B,0
	LD	HL,MSKTB
	ADD	HL,BC
	LD	A,(STAT4)
	AND	(HL)
	INC	HL
	OR	(HL)
	LD	(STAT4),A
	JP	STDRT

MSKTB:	DB	6CH,00H		;Cursor unsichtbar
	DB	5CH,50H		;Cursor blinkender Block
	DB	1CH,10H		;stehender Block
	DB	7CH,70H		;blinkende Linie
	DB	3CH,30H		;stehende Linie
	DB	5CH,0D0H	;selbstdefiniert blinkend
	DB	1CH,090H	;selbstdefiniert stehend
	DB	5DH,0D1H
;--------------------------
CUR?:	CALL	VPSUB		;Cursorposition abfragen
	CALL	HBPLZ
	RET	NZ
	LD	A,(CZL)		;Zeile aussenden
	ADD	A,20H
	OR	80H
	CALL	HBFLD
	CALL	VPSUB
	CALL	HBPLZ
	RET	NZ
	LD	A,(CSP)		;Spalte aussenden
	ADD	A,20H
	OR	80H
	CALL	HBFLD
	CALL	VPSUB
	CALL	HBPLZ
	RET	NZ
	LD	A,8DH		;CR
	CALL	HBFLD
	JP	STDRT
;-----------------------
CURPOS:	CALL	VPSUB		;Cursor positionieren
	CALL	HBINH
	CP	2
	RET	C
	CALL	HBFRD
	SUB	20H
	LD	B,A
	LD	A,0
	JR	C,CCPO2		;Zeile < $20 ?
	LD	A,(ZLANZ)
	DEC	A
	CP	B		;unerlaubte Zeilenenposition
	JR	C,CCPO2		;Zeile > ZLANZ
	LD	A,B
CCPO2:	LD	(CZL),A
	CALL	HBFRD
	LD	HL,BRTFLG
	JPBITZ	4,(HL),CCPO3
	AND	11111110B	;bei Breitschrift nur gerade Spalten
CCPO3:	SUB	20H
	LD	B,A
	LD	A,0		;zu kleine und zu grosse Werte ignorieren
	JR	C,CCPO1
	LD	A,(SPANZ)
	DEC	A
	CP	B
	JR	C,CCPO1
	LD	A,B
CCPO1:	LD	(CSP),A		;Zeilenposition setzen
	CALL	CURADR
	JP	STDRT
;-----------------------
ADRVDC:	REPT	3		;Memory- in VDC-Adresse umrechnen
	 SRL	H
	 RR	L
	ENDM
	LD	A,H
	XOR	00010000B
	LD	H,A
	RET
;-----------------------
	IF	DEBUG
	DB	'INSLIN'
	ENDIF

INSLIN:	CALL	PCR		;Cursor an Zeilenanfang
	LD	A,(CZL)
	LD	B,A
	LD	A,(ZLANZ)
	DEC	A
	SUB	B
	JP	Z,INSLI3
	LD	HL,0000H	;Anzahl der zu verschiebenden Bytes
	LD	BC,(ZLSIZE)	;berechnen aus (ZLANZ-CZL)*ZLSIZE
INSLI1:	ADD	HL,BC
	DEC	A
	JR	NZ,INSLI1
	PUSH	HL		;HL Anzahl der Bytes insgesamt
	LD	HL,(DSPST)	;Endadresse des Blocks berechen
	LD	BC,(DSPANF)	;(DSPST)+(DSPANF)+(ZLANZ)*ZLSIZE
	ADD	HL,BC
	LD	BC,(ZLSIZE)
	LD	A,(ZLANZ)
	DEC	A
INSLI2:	ADD	HL,BC
	DEC	A
	JR	NZ,INSLI2
	LD	D,H
	LD	E,L
	ADD	HL,BC
	EX	DE,HL
	POP	BC
	CALL	BLKDWN		;Block verschieben
INSLI3:	LD	A,(CZL)		;Zeile ueber Cursor loeschen
	JP	ZLOE
;-----------------------
ERLIN:	CALL	PCR		;<ER> Zeile loeschen
	LDB	B,(CZL)
	LDB	C,(ZLANZ)
	SUB	B
	DEC	A
	LD	D,A		;Zeilen im unteren Teil
	JP	Z,UZLOE
	SRL	C		;ZLANZ/2
	LD	A,B		;CZL
	CP	C		;Mehr als 1/2 Schirm scrollen?
	IF	HD6345
	 JR	C,ERLIN2	;Dann Methode 2
	ENDIF
	LD	HL,0		;Evtl. Verbesserung: hier auch
	LD	BC,(ZLSIZE)	;Soft Scroll mit Scr 2+3!
ERLIN3:	ADD	HL,BC
	DEC	D
	JR	NZ,ERLIN3
	PUSH	HL
	LD	HL,(CURPT)	;Zieladresse
	PUSH	HL
	ADD	HL,BC		;Startadresse
	POP	DE
	POP	BC		;Blocklaenge
	CALL	BLKUP		;Eine Zeile kopieren
UZLOE:	LD	A,(ZLANZ)
	DEC	A
	CALL	ZLOE		;unterste Zeile loeschen
	LD	HL,STAT2
	BIT	2,(HL)
	CALL	NZ,ST2EIN		;STZ2 rekonstruieren
	RET

WTFLG	EQU	ARBF
SC2POS	EQU	ARBF+1
SC2ADR	EQU	ARBF+2

ERLIN2:	IF	HD6345		;Smooth Scroll
	 LD	HL,STAT3
	 RES	5,(HL)		;entkoppeln
	 LD	A,(VDCR31)
	 AND	01001111B
	 CALL	VDCW31		;Scroll nur Scr 3

	 LD	A,(CZL)
	 DEC	A
	 CALL	ZLPOS		;In absolute Position umrechnen
	 LD	(SC2POS),A
	 LD	HL,(CURPT)
	 CALL	ADRVDC		;In VDC-Adresse umrechnen
	 LD	(SC2ADR),HL	;Dorthin wird 1. Block kopiert

	 LD	A,(SCRCNT)
	 OR	A		;Scroll aktiv?
	 JR	NZ,ERLIN9	;Dann Scr 3 nicht setzen
	
	 SETRHL	22		;Scr 3 Start Adr
	 LD	A,(SC2POS)
	 SETRA	21		;Scr 3 Start Pos

ERLIN9:	 LD	HL,SCRTIM
	 LD	A,(HL)
ERLI92:	 LD	(HL),5		;Timer retriggern
	 LD	HL,WTFLG
	 INC	(HL)
	 JR	Z,ERLI92	;Bei Ueberlauf auf 6
	 OR	A		;Einzelscroll?
	 JR	NZ,ERLI91
	 LD	(HL),A		;Dann WTFLG resetten

ERLI91:	 JPI	ERLIN5
	 FLAG	5,ZWZL		;Smooth Scroll enabled?
	 JR	NZ,ERLI51

ERLIN5:	 DI
	 LD	A,22
	 CALL	VDCRHL
	 CALL	INCVAD		;Hard Scroll: Scr 3 erhoehen
	 SETRHL	22
	 EI
	ENDIF
ERLI51:	CALL	SCRLBU		;Ganzes Bild nach oben
	IF	HD6345
	 JPI	ERLII6
	 FLAG	5,ZWZL		;Smooth Scroll enabled?
	 JR	Z,ERLII6

	 LD	HL,SCRCNT	;scrollen
	 INC	(HL)

	 LD	HL,(DSPST)	;In Puffer (vor 1. Zeile) kopieren
	 LD	BC,ZLSIZN	;BC = Laenge
	 SUBHL	BC
	 EX	DE,HL
	 LD	HL,(CURPT)	;HL = Start
	 SUBHL	BC
	 CALL	BLKDWN		;1 Zeile in Buffer kopieren

	 LD	HL,(VDCST)
	 CALL	DC2VAD
	 SETRHL	25		;Scr 4 Start Adr.
	 LD	HL,(SC2ADR)
	 CALL	DECVAD
	 LD	(SC2ADR),HL	;Scr 2 jetzt 1 Zeile hoeher
	 LD	A,(SC2POS)
	 DEC	A
	 LD	(SC2POS),A
	 SETRA	24		;Scr 4 Start Pos.

	 LD	HL,(CURPT)
	 PUSH	HL
	 LD	BC,ZLSIZN
	 SUBHL	BC
	 LD	(CURPT),HL
	 CALL	BLKDLP		;Rest direkt kopieren (1 Zeile weniger)
	 POP	HL
	 LD	(CURPT),HL

	 LD	A,(WTFLG)
	 CP	3
	 CALL	C,SLWSCL	;Langsam scrollen
	 CALL	WTSCRL		;Evtl warten bis fertiggescrollt

	 LD	DE,(CURPT)	;Ziel
	 LD	HL,(DSPST)
	 LD	BC,ZLSIZN
	 SUBHL	BC
	 CALL	BLKDWN		;Zeile zurueckkopieren
	 SETR	24,-1		;Scr 4 abschalten
	 JR	ERLIN8
	ENDIF

ERLII6:	CALL	BLKDLP		;Obere Zeilen kopieren

ERLIN8:	LD	HL,(VDCST)
	SETRHL	12
	IF	HD6345
	 SETR	18,-1		;Scr 2 abschalten
	ENDIF
	RET
;-------------------------------------
BLKDLP:	LD	HL,(CURPT)	;Von CURPT bis DSPST herunterkopieren
	LD	D,H		;DE:=Zieladresse
	LD	E,L
	LD	BC,(ZLSIZE)
	SUBHL	BC		;1 Zeile zurueck
	PUSH	HL		;Startadresse
	LD	HL,(CURPT)
	LD	BC,(DSPST)

BLKDL1:	SUBHL	BC
	RES	7,H
	LD	B,H		;Laenge
	LD	C,L
	POP	HL		;Start
	LD	A,B
	OR	C
	RET	Z		;Fertig, Laenge = 0

	PUSH	BC
	PUSH	HL
	PUSH	DE
	LD	BC,(ZLSIZE)
	CALL	BLKDWN		;Eine Zeile kopieren
	CALL	SCRNUP		;Gleichzeitig Screens umschalten
	LD	BC,(ZLSIZE)
	POP	HL
	SUBHL	BC
	EX	DE,HL		;DE = Ziel
	POP	HL
	SUBHL	BC
	EX	(SP),HL		;(SP) = Start, HL = Laenge
	JR	BLKDL1
;-----------------------
SCRNUP:	IF	HD6345		;Bewege Screen synchron zum Kopieren
	 LD	A,(WTFLG)
	 CP	3		;Vereinzeltes Scrollen?
	 CALL	C,WTSYNC	;Damit Bild nicht zuckt
	 LD	A,(SC2POS)
	 OR	A
	 RET	Z		;Schon ganz oben
	 DEC	A
	 JPNI	SCRNU1
	 OR	A
	 RET	Z		;Schon ganz oben
	 DEC	A
SCRNU1:	 LD	(SC2POS),A
 	 SETRA	18
	 LD	HL,(SC2ADR)
	 SETRHL	19
	 CALL	DECVAD		;1 Zeile zurueck
	 LD	(SC2ADR),HL
	 LD	HL,SCRTIM
	 LD	(HL),4		;Nachlaufzeit fuer Scroll
	ENDIF
	RET
;-----------------------
ZPADR:	LD	HL,(DSPST)	;Berechne Zeilenadresse in HL, ZLSIZE in BC
	LD	BC,(ZLSIZE)	;Zeile (abs.) in A
	OR	A
	JR	Z,ZPADR2
ZPADR1:	ADD	HL,BC
	DEC	A
	JR	NZ,ZPADR1
ZPADR2:	FLAG	0,ITLFLG
	RET	NZ
	SET	7,H
	RET
;-----------------------
ZLPOS:	LD	HL,STAT2	;Berechne abs. Zeilenposition
	BIT	1,(HL)		;STZ 1 an?
	JR	Z,ZLPOS1
	ADD	A,2
ZLPOS1:	FLAG	0,ITLFLG
	RET	Z
	RLCA			;(CZL+1)*2
	INC	A
	RET
;-----------------------
BLKDWN:	JPI	BLKDWI
	DEC	DE
	DEC	HL
	SET	7,H
	SET	7,D
	LD	A,(MODUS)
	JPBITZ	7,A,BLKDW2

	IF	XR
	 LD	A,20H
	 OUT	(XRFLGS),A
	 XRBRES			;Bitcounter reset
	ENDIF	
BLKCDW:	CALL	BLKCOL
	DEC	DE
	DEC	HL
	SET	7,H
	SET	7,D
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,BLKCDW
	IF	XR
	 LD	A,27H
	 OUT	(XRFLGS),A
	ENDIF
	RET
;------------------------------------------------------------------------
; Achtung BLKDW2 ist total zeitoptimiert, voreilige Aenderungen vermeiden
;------------------------------------------------------------------------	
BLKDW2:	PUSH	BC		;Laenge des Blocks
	LD	(LDADR),HL
	DEC	BC
	SUBHL	BC		;Ladeadresse  - Laenge < 8000 ?
	BIT	7,H
	JR	NZ,BLKDW4

BLKDW3:	LD	HL,(LDADR)	;Ladeadresse -7FFFH = Laenge des 1.Blocks
	LD	BC,7FFFH
	SUBHL	BC
	LD	B,H
	LD	C,L
	LD	HL,(LDADR)
	PUSH	BC
	LDDR
	SET	7,H		;HL=FFFFH
	LD	(LDADR),HL
	POP	BC		;Laenge - Laenge1 =Restlaenge
	POP	HL
	SUBHL	BC
	LD	B,H
	LD	C,L
	PUSH	BC

	DEC	BC
BLKDW4:	LD	H,D		;Zieladresse - Restlaenge < 0000 ?
	LD	L,E
	SUBHL	BC
	BIT	7,H
	JR	NZ,BLKDW1

	LD	H,D		;0000-Zieladresse = Laenge 2
	LD	L,E
	LD	BC,7FFFH
	SUBHL	BC
	LD	B,H
	LD	C,L
	LD	HL,(LDADR)	;HL=FFFFH
	PUSH	BC
	LDDR
	LD	(LDADR),HL
	SET	7,D		;DE=FFFFH
	POP	BC		;Restlaenge-Laenge2 = Restlaenge 2
	POP	HL
	SUBHL	BC
	LD	B,H
	LD	C,L
	PUSH	BC

BLKDW1:	POP	BC
	LD	HL,(LDADR)
	LDDR			;verschieben
	RET
;-----------------------
BLKDWI:	IF	XR
	 LD	A,(MODUS)
	 BIT	7,A
	 JR	Z,BLKDI2
	 LD	A,20H
	 OUT	(XRFLGS),A
	 XRBRES			;Bitcounter reset
	ENDIF	
	
BLKDI2:	PUSH	BC
	LD	BC,8
	SUBHL	BC
	EX	DE,HL
	SUBHL	BC
	EX	DE,HL
	POP	BC
	LD	A,(MODUS)
	JPBIT	7,A,BLICDW
	CALL	BLKMVI
	JR	BLKDI1

BLICDW:	CALL	BLKCLI
BLKDI1:	LD	A,B
	OR	C
	JR	NZ,BLKDWI
	IF	XR
	 LD	A,27H
	 OUT	(XRFLGS),A
	ENDIF
	RET
;-----------------------	
BLKUP:	JPI	BLIUP
	SET	7,H
	LD	A,(MODUS)
	JPBITZ	7,A,BLKUP2

	IF	XR
	 LD	A,20H
	 OUT	(XRFLGS),A
	 XRBRES			;Bitcounter reset
	ENDIF	
BLKCUP:	CALL	BLKCOL
	INC	DE
	INC	HL
	SET	7,H
	SET	7,D
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,BLKCUP
	IF	XR
	 LD	A,27H
	 OUT	(XRFLGS),A
	ENDIF
	RET

;------------------------------------------------------------------------
; Achtung BLKUP2 ist total zeitoptimiert, voreilige Aenderungen vermeiden
;------------------------------------------------------------------------	
BLKUP2:	PUSH	BC		;wenn Ladeadresse + BC
	DEC	BC
	LD	(LDADR),HL	;und Zieladresse + BC <= FFFF dann LDIR
	ADD	HL,BC
	JR	NC,BLKUP4

BLKUP3:	LD	HL,0000H	;bis LDADR Seite ueberschreitet
	LD	BC,(LDADR)	;0000-Ladeadresse =Anzahl zu verschieben
	SUBHL	BC
	LD	B,H
	LD	C,L
	LD	HL,(LDADR)
	PUSH	BC
	LDIR
	SET	7,H		;HL = hier immer 0000
	LD	(LDADR),HL
	POP	BC		;Anzahl gerade verschobener Bytes von
	POP	HL		;Gesamtanzahl abziehen
	SUBHL	BC
	LD	B,H		;= Restzahl
	LD	C,L
	PUSH	BC

	DEC	BC
BLKUP4:	LD	H,D		;Teste ob Ladeadresse + Restanzahl Seite 
	LD	L,E
	ADD	HL,BC		;ueberschreitet
	JR	NC,BLKUP1	;wenn nein ab jetzt LDIR durchfuehren

	LD	HL,0000H
	LD	B,D
	LD	C,E
	SUBHL	BC
	LD	B,H		;BC Laenge bis ZLADR zur Seitengrenze
	LD	C,L
	LD	HL,(LDADR)
	PUSH	BC
	LDIR
	SET	7,D
	LD	(LDADR),HL
	POP	BC		;verbleibende Restlaenge berechnen
	POP	HL
	SUBHL	BC
	LD	B,H
	LD	C,L
	PUSH	BC

BLKUP1:	POP	BC
	LD	HL,(LDADR)
	LDIR
	RET
;-----------------------
BLIUP:	IF	XR
	 LD	A,(MODUS)
	 BIT	7,A
	 JR	Z,BLIUP3
	 LD	A,20H
	 OUT	(XRFLGS),A
	 XRBRES			;Bitcounter reset
	ENDIF
BLIUP3:	LD	A,(MODUS)
	JPBIT	7,A,BLICUP
BLIUP1:	CALL	BLKMVI
	JR	BLIUP2

BLICUP:	CALL	BLKCLI
BLIUP2:	PUSH	BC
	LD	BC,8
	ADD	HL,BC
	EX	DE,HL
	ADD	HL,BC
	EX	DE,HL
	POP	BC
	LD	A,B
	OR	C
	JR	NZ,BLIUP3
	IF	XR
	 LD	A,27H
	 OUT	(XRFLGS),A
	ENDIF
	RET
;-----------------------
	IF	XR
BLKCOL:	PUSH	BC		;Block kopieren im Bitmodus
	LD	B,8
BLKCO1:	LD	A,(HL)
	LD	(DE),A
	XRBIT
	DJNZ	BLKCO1
	POP	BC
	RET

	ELSE
BLKCOL: LD	A,01001111B	;Lesen aus 1. Farbebene Schreibfarbe Schwarz
	OUT	(CLRG1),A
	LD	A,WHITE		;Zielbyte in Colorkarte zuerst loeschen
	LD	(DE),A

	LD	A,(HL)
	PUSH	AF
	LD	A,11001111B	;Lese aus 2. Farbebene
	OUT	(CLRG1),A
	POP	AF
	OR	(HL)
	PUSH	AF
	LD	A,00001111B	;Lese aus 3.Farbebene
	OUT	(CLRG1),A
	POP	AF
	OR	(HL)
	PUSH	AF
	LD	A,(COLRG1)
	OUT	(CLRG1),A
	POP	AF
	LD	(DE),A
	RET
	ENDIF
;-----------------------
BLKMVI:	PUSH	HL
	PUSH	DE
	LD	DE,CHRBUF
	LD	A,H
	OUT	(PAGE),A
	PUSH	BC
	SET	7,H
	REPT	8
	 LDI
	ENDM
	POP	BC
	POP	DE
	PUSH	DE
	LD	HL,CHRBUF
	LD	A,D
	OUT	(PAGE),A
	SET	7,D
	REPT	8
	 LDI
	ENDM
	POP	DE
	POP	HL
	RET
;-----------------------
	IF	XR
BLKCLI:	LD	A,C
	SUB	8
	LD	C,A
	JR	NC,BLKCI3
	DEC	B
BLKCI3:	PUSH	BC		;Push BC-8
	PUSH	HL		;danach Quelladresse
	PUSH	DE		;danach Zieladresse 

	LD	A,H		;HL ist Quelladresse VideoRam
	OUT	(PAGE),A
	SET	7,H
	LD	DE,PIXBUF
	LD	C,8
BLKCI4:	LD	B,8
BLKCI1:	LD	A,(HL)		;insgesamt 64 byte Bildinformation in Zwischenpuffer
	LD	(DE),A
	XRBIT
	INC	DE
	DJNZ	BLKCI1
	INC	HL
	DEC	C
	JR	NZ,BLKCI4

	POP	DE
	PUSH	DE

	LD	A,D
	OUT	(PAGE),A
	SET	7,D
	LD	HL,PIXBUF
	LD	C,8
BLKCI5:	LD	B,8
BLKCI2:	LD	A,(HL)
	LD	(DE),A
	XRBIT
	INC	HL
	DJNZ	BLKCI2
	INC	DE
	DEC	C
	JR	NZ,BLKCI5

	POP	DE
	POP	HL
	POP	BC		;HL, DE ist gleich BC um niedriger
	RET

	ELSE
BLKCLI:	LD	A,H		;verschiebt ein 8*8 Farb-Block im VideoRam
	OUT	(PAGE),A	;VideoPage Quelladresse waehlen
	LD	A,C
	SUB	8
	LD	C,A
	JR	NC,BLKCI3
	DEC	B
BLKCI3:	PUSH	BC		;Push BC-8
	PUSH	HL		;danach Quelladresse
	PUSH	DE		;danach Zieladresse 

	SET	7,H
	PUSH	HL

	LD	DE,CHRBUF
	LD	BC,8
	LD	A,01001111B	;Lesen von Farbebene 1
	OUT	(CLRG1),A
	LDIR

	POP	HL
	PUSH	HL

	LD	DE,CHRBUF
	LD	B,8
	LD	A,11001111B	;verodern mit Farbebene 2
	OUT	(CLRG1),A
BLKCI2:	LD	A,(DE)
	OR	(HL)
	LD	(DE),A
	INC	DE
	INC	HL
	DJNZ	BLKCI2

	POP	HL

	LD	DE,CHRBUF
	LD	B,8
	LD	A,00001111B	;verodern mit Farbebene 3
	OUT	(CLRG1),A
BLKCI1:	LD	A,(DE)
	OR	(HL)
	LD	(DE),A
	INC	DE
	INC	HL
	DJNZ	BLKCI1

	POP	DE
	PUSH	DE

	LD	HL,CHRBUF
	LD	A,D
	OUT	(PAGE),A
	SET	7,D
	LD	B,8
BLKCI4:	LD	A,00001111B
	OUT	(CLRG1),A
	LD	A,WHITE
	LD	(DE),A
	LD	A,(COLRG1)
	OUT	(CLRG1),A
	LD	A,(HL)
	LD	(DE),A
	INC	DE		;HL, DE sind um 8 erhoeht
	INC	HL
	DJNZ	BLKCI4

	POP	DE		;HL DE sind gleich
	POP	HL
	POP	BC
	RET
	ENDIF
;-----------------------
ZLOE:	PUSH	HL
	PUSH	BC
	PUSH	AF
	LD	HL,(DSPST)	;eine Zeile loeschen
	LD	BC,(DSPANF)	;Zeilennr. in A
	ADD	HL,BC
	LD	BC,(ZLSIZE)
	OR	A
	JR	Z,ZLOE1
ZLOE2:	ADD	HL,BC
	DEC	A
	JR	NZ,ZLOE2
ZLOE1:	SETNI	7,H
	CALL	LOE1
	POP	AF
	POP	BC
	POP	HL
	RET
;-----------------------
URLOE:	LD	A,(ZLANZ)	;loescht alle unsichtbaren Zeilen
ULOE:	LD	B,A
	LD	A,(STAT2)	;Eine Zeile spaeter beginnen wenn STZ2
	JPBITZ	2,A,ULOE1
	INC	B
ULOE1:	LD	C,42
	JPBITZ	1,A,ULOE2	;2 Zeilen weniger loeschen wenn STZ1
	DEC	C
	DEC	C
ULOE2:	LD	A,B
	CP	C		;loescht von Zeile A-42 
	RET	NC
	CALL	ZLOE
	INC	B
	JR	ULOE2
;-----------------------
SPLOE:	LD	HL,(DSPST)
	LD	B,VBLMAX	;in VBLMAX Zeilen je 1 Spalte loeschen
	LD	D,0
	SLA	A		;Spaltenzahl * 8
	RL	D
	SLA	A
	RL	D
	SLA	A
	RL	D
	LD	E,A

SPLOE1:	ADD	HL,DE
	SETNI	7,H
	PUSH	HL
	PUSH	BC
	LD	A,(BRTFLG)
	LD	C,A
	LD	B,0
	JPNI	SPLOE2
	CALL	ERSP
	JR	SPLOE3
SPLOE2:	CALL	LOE1
SPLOE3:	POP	BC
	POP	HL
	LD	DE,(ZLSIZE)	;Cursor eine Zeile tiefer setzen
	DJNZ	SPLOE1
	RET
;****************************************************************************
;MODUL DESC
;****************************************************************************
;Doppel Escape-Sequenz Tabelle

DESCCH:	DB	'!$Oo0123456789AaSsTtCcDdEeFfGgIiJHhMmLQRrUuPpVvWwXxYyZz'
LDESCH	EQU	$-DESCCH
DESCTB:	DW	CLRCOL	;Farbkarte komplett loeschen
	DW	CLRVID	;Video-Ram komplett loeschen
	DW	COLRVM	;Blinkfarbton fuer Mischfarben
	DW	COLRVP	;Blinkfarbton fuer Reinfarben
	DW	TXFARB	;Tectronix Farbmodus 
	DW	TXFARB	;Tektronix Farbmodus 
	DW	COLMIX	;Farbton fuer Mischfarben
	DW	COLPUR	;Farbton fuer Reinfarben
	DW	EBNDEF	;Ebene definieren
	DW	COLDFT	;Farbe einstellen transparent
	DW	SETPAD	;setze Patchadresse
	DW	PTRES	;Pointer reset
	DW	UHR?	;Uhr abfragen
	DW	UHRSET	;Uhr stellen
	DW	ITLCHG	;Interlaced, Non-interlaced selection
	DW	ININEU	;Neuinitialisierung
	DW	MONTST	;Monitortestbild
	DW	LPEN	;Light Pen
	DW	USRRNB	;Userprogramm ausfuehren
	DW	USRRUN	;Userprogramm ausfuehren
	DW	DRKDEF	;definiere Drucker fuer Hardcopy
	DW	HRDCOP	;Grafik-Hardcopy
	DW	SETUZS	;Zeichen definieren bei dem User-ZSATZ beginnt
	DW	RAMDFB	;wie RAMDEF aber binaer
	DW	RAMDEF	;definiere Video-Ram Adresse
	DW	QURECB	;Zeichen binaer vom Quellpuffer schicken
	DW	QUREC	;Zeichen vom Quellpuffer schicken
	DW	ZLSNDB	;Zeichen binaer zum Zielpuffer schicken
	DW	ZLSND	;Zeichen zum Zielpuffer schicken
	DW	QU1BB	;1 byte binaer von Quellenkanal
	DW	QU1B	;1 Byte vom Quellkanal
	DW	ZL1BB	;1 Byte zum Zielkanal
	DW	ZL1B	;1 byte zum Zielkanal binaer
	DW	QUDEF	;Quellkanal definieren
	DW	ZLDEF	;Zielkanal def.
	DW	TTXI	;TEKTRONIX Grundmodus 
	DW	TTXI	; "	
	DW	STLAUS	;Statuszeilen ausschalten
	DW	STLINE	;Statuszeilen ein/ausschalten
	DW	TVICOL	;TVI Farbmodus
	DW	TVISTD	;TVI-Modus
	DW	MONAPS	;Monitoranpassung
	DW	SCRFRM	;Bildschirmformat
	DW	ZSZDEF	;Zeichensatz def.
	DW	SETPXZ	;Pixelzeilen setzen
	DW	SPLDEF	;Spoolerzuordnung
	DW	TKANAL	;Tastaturkanal def.
	DW	TBAUD	;def. Tastatur-Baudrate
	DW	V24DEF	;V24-Spezifikationen
	DW	V24SND	;V24 Sendebaudrate
	DW	V24EMP	;"  Empfangsbaudrate
	DW	OUTADB	;OUT bin{r
	DW	OUTADR	;OUT ASCII
	IF	XR
	 DW	XRGETS	;XR Status abfragen
	 DW	XRSEL	;select XR-Konfiguration
	ELSE
	 DW	NOOP
	 DW	NOOP
	ENDIF

NOOP:	RET		;no operation

	IF	XR
XRCH:	DB	'()ADKkMQRSUVvWXYZ'		;XR-Befehlssatz ESC ESC ! X Y
XRLEN	EQU	$-XRCH

XRTB:	DW	XRCDF,XRBLOF,XRPIC,XRBLAU,XRKNTR,XRGRUN,XRROT,XRDIRB,XRSPB,XRSPLB
	DW	XRMASK,XRMTRX,XRKOVL,XRDKOV,XRALSG,XRGEOF,XRGENL

XRSEL:	CALL	VPSUB		;<EE!>
	CALL	HBINPR
	RET	Z
	CALL	STDRT		;Masterroutine wiedereinsetzen
	LD	HL,XRCH
	LD	DE,XRTB
	LD	BC,XRLEN
	CPIR
	JP	Z,TABEXA	;Kommandos aus Tabelle XRTB ausfuehren
	
	LD	B,A
	AND	11110000B
	CP	00110000B	;$30-$3F XR-Karten selektieren
	RET	NZ		;keine Aktion bei ungueltigem Zeichen

	CALLB	XRSELA
	CALL	STLGEN
	RET

;----------------------
XRBLOF:	CALLB	BLNKOF
	RET
;-----------------------
XRCDF:	CALL	VPSUB		;Colortabelle auf Defaultfarben setzen <EE!Z> a
	CALL	HBINPR
	RET	Z
	CP	'0'
	JR	NZ,XRCDF1
	CALLB	SETCDF		;lineare Farbscala
	JR	XRCDF4
XRCDF1:	CP	'1'
	JR	NZ,XRCDF2
	CALLB	XRGRAU		;Grauwerte
	JR	XRCDF4
XRCDF2:	CP	'2'
	JR	NZ,XRCDF3
	CALLB	XRBONB		;Bonbon Farben
	JR	XRCDF4
XRCDF3:	CP	'3'
	JR	NZ,XRCDF4
	CALLB	XRSPKT		;Continuierliches Spektrum
XRCDF4:	JP	STDRT
;-----------------------
XRGETS:	CALL	VPSUB		;XR-Status abfragen
	CALL	HBPLZ
	RET	NZ

	LD	A,31		;VDC Statusregister lesen
	CALL	VDCIN
	SRL	A
	AND	00000011B	;Even Field und vertikal Blanking ausmaskieren
	LD	B,A
	LD	HL,XRSTAT
	LD	A,(HL)
	AND	00111111B
	RES	5,(HL)		;RY zuruecksetzen
	OR	B
	OR	80H		;8. Bit setzen Unterscheidung zu Keyboardzeichen
	CALL	HBFLD
	JP	STDRT
;------------------------
XRKNTR:	CALL	VPSUB		;Kontrast fuer Hardcopy einstellen
	CALL	HBINPR
	RET	Z
	LD	(HRDKTR),A
	JP	STDRT
;-----------------------
XRALSG:	CALL	VPSUB
	CALL	HBINPR
	RET	Z
	AND	00000001B	;Antialiasing fuer RGB Komprimierung wenn <> 0
	LD	(ALIASG),A
	JP	STDRT
;------------------------
XRMASK:	CALL	VPSUB
	CALL	HBINPR
	RET	Z
	LD	B,A
	LD	A,(XRRDC)
	OUT	(XRFLGS),A
	LD	A,B
	OUT	(XRCLU2),A
	LD	A,(XRRD)
	OUT	(XRFLGS),A
	JP	STDRT
;------------------------
WAITVS:	LD	A,(VDCR-8)	;Test auf Interlaced oder pseudo-interlaced
	BIT	0,A		;Wait for End of Frame Routine
	JR	NZ,WAITV3
WAITV1:	IN	A,(GPIP)
	JPBITZ	1,A,WAITV1
WAITV2:	IN	A,(GPIP)
	JPBIT	1,A,WAITV2	;Synchronisyerung abgeschlossen wenn VSYNC neg. edge
	RET
WAITV3:	LD	A,31
	CALL	VDCIN		;read VDC Statusregister
	JPBITZ	2,A,WAITV3	;wait until even Field ready
WAITV4:	LD	A,31
	CALL	VDCIN		;read VDC Statusregister
	JPBIT	2,A,WAITV4	;wait until odd field ready
	RET
;------------------------
XRPIC:	LD	A,20H
	OUT	(XRFLGS),A	;auf Bitmodus umschalten
	LD	A,6
	CALL	VDRIGT
	CALL	WAITVS
	LD	A,37H		;Scan Modus waehrend genau eines VSYNC Impuls
	OUT	(XRFLGS),A
	LD	A,67H
	OUT	(XRFLGS),A
	CALL	WAITVS
	LD	A,6
	CALL	VDLEFT

	CALL	XRNORM
	LD	A,27H		;auf Maskenmodus zurueckschalten
	OUT	(XRFLGS),A
	LD	HL,XRSTAT
	SET	5,(HL)		;RY Flag setzen
	CALL	STLGEN
	RET
;------------------------
XRNORM:	LD	A,(XRVID)	;Zustand der VID0 VID1 Flags wiederherstellen
	LD	B,A		;nach Bild einlesen
	AND	00001111B
	OR	60H
	OUT	(XRFLGS),A
	LD	A,B
	SRL	A
	SRL	A
	SRL	A
	SRL	A
	OR	30H
	OUT	(XRFLGS),A
	RET
;-----------------------
XRDIRB:	CALL	WAITVS
	LD	A,37H
	OUT	(XRFLGS),A
	LD	A,60H		;Direktbild-Modus einschalten
	OUT	(XRFLGS),A
	LD	A,70H
	LD	(XRVID),A
	JP	SCACTV

XRSPB:	CALL	WAITVS
	LD	A,30H
	OUT	(XRFLGS),A
	LD	A,60H		;Speicherbild Modus einschalten
	OUT	(XRFLGS),A
	XOR	A
	LD	(XRVID),A
	JP	SCINAC

XRSPLB:	CALL	WAITVS
	LD	A,30H
	OUT	(XRFLGS),A
	LD	A,67H		;Speicherbild mit eingestanztem Direktbild einschalten
	OUT	(XRFLGS),A
	LD	A,07H
	LD	(XRVID),A
	JP	SCACTV
;------------------------
XRGENL:	LD	HL,XRSTAT
	BIT	2,(HL)
	RET	Z		;keine Kamera angeschlossen
	BIT	3,(HL)
	RET	NZ		;already GENLOCK
	SET	3,(HL)
	
	LD	A,(VDCR-0)	;horizontal total Lines
	DEC	A
	DEC	A
	LD	(VDCR-0),A
	LD	C,0
	CALL	VDCWRA		;horizontal Total verk}rzen wegen Einsynchronisierung
	LD	A,1
	CALL	VDRIGT

	LD	A,(VDCR-8)	;Test for Interlace or pseudointerlace
	BIT	0,A
	JR	NZ,XRGNI
	LD	A,(VDCR30)
	OR	11000000B	;TV sync mode display disabled
	CALL	VDCW30
	LD	A,40H
	OUT	(XRFLGS),A
	LD	A,51H
	OUT	(XRFLGS),A	;XR auf SLAVE-Mode schalten um VSYNC zu bekommen
	CALL	WAITVS
	CALL	WAITVS
	LD	A,(VDCR30)
	RES	6,A		;TV Slave mode display enabled
	CALL	VDCW30
	RET

XRGNI:	LD	A,(VDCR30)
	OR	11000000B	;TV sync mode display disabled
	CALL	VDCW30
	LD	A,41H		;zunaechst auf Interlace Sync Mode schalten
	OUT	(XRFLGS),A
	LD	A,51H
	OUT	(XRFLGS),A
XRGNI1:	IN	A,(GPIP)
	JPBITZ	1,A,XRGNI1	;Wait for VSYNC High
XRGNI2:	IN	A,(GPIP)
	JPBIT	1,A,XRGNI2	;Wait for VSYNC Low
XRGNI3:	IN	A,(GPIP)
	JPBITZ	1,A,XRGNI3	;Wait for VSYNC High
XRGNI4:	IN	A,(GPIP)
	JPBIT	1,A,XRGNI4	;Wait for VSYNC Low
	LD	A,(VDCR30)
	RES	6,A		;TV Slave mode display enabled
	CALL	VDCW30
	LD	A,40H		;Schalte nach Einsynchronisierung auf normal SLAVE Mode
	OUT	(XRFLGS),A
	RET

;------------------------
XRGEOF:	LD	HL,XRSTAT
	BIT	3,(HL)		;Test on GenLock aktiv
	RET	Z
	RES	3,(HL)
	LD	A,40H
	OUT	(XRFLGS),A	;XR auf MASTER-Mode zurueckschalten
	LD	A,50H
	OUT	(XRFLGS),A
	LD	A,(VDCR30)
	AND	00111011B
	CALL	VDCW30		;auf Mastermodus zur}ckschalten
	LD	A,(VDCR-0)
	INC	A
	INC	A
	LD	(VDCR-0),A
	LD	C,0
	CALL	VDCWRA
	LD	A,1
	JP	VDLEFT
;------------------------
XRSCON:	LD	A,20H
	OUT	(XRFLGS),A
	LD	A,37H
	OUT	(XRFLGS),A
	LD	A,67H
	OUT	(XRFLGS),A

SCACTV:	LD	HL,XRSTAT
	BIT	4,(HL)
	RET	NZ		;Scan bereits aktiv ?
	SET	4,(HL)		;Scan aktiv
	LD	A,6
	JP	VDRIGT

XRSCOF:	CALL	WAITVS
	LD	A,30H
	OUT	(XRFLGS),A
	LD	A,60H
	OUT	(XRFLGS),A
	LD	A,27H
	OUT	(XRFLGS),A

SCINAC:	LD	HL,XRSTAT
	BIT	4,(HL)		;Scan bereits inaktiv ?
	RET	Z
	RES	4,(HL)		;Scan inaktiv
	LD	A,6
	JP	VDLEFT
;------------------------
VDRIGT:	LD	B,A
	LD	A,(VDCR-2)	;verschiebe Bild nach rechts
	SUB	B
	LD	(VDCR-2),A
	LD	C,2
	CALL	VDCWRA
	RET
VDLEFT:	LD	B,A
	LD	A,(VDCR-2)	;verschiebe Bild nach links
	ADD	A,B
	LD	(VDCR-2),A
	LD	C,2
	CALL	VDCWRA
	RET
;------------------------
	IF	DEBUG
	DB	'XRROT'
	ENDIF
XRROT:	JPI	XRRETN		;Farbauszug komprimieren und in Page 2 zwischenspeichern
	XOR	A		;Color Offset wird in L uebergeben
	LD	HL,ADDA
	LD	(RGBA+1),HL
	CALLB	XRCOMP
	RET

XRGRUN:	JPI	XRRETN		;Farbauszug komprimieren und in Page 2 zwischenspeichern
	LD	A,CSTEPS
	LD	HL,ADDB
	LD	(RGBA+1),HL
	CALLB	XRCOMP
	RET

XRBLAU:	JPI	XRRETN		;Farbauszug komprimieren und in Page 2 zwischenspeichern
	LD	A,CSTEPS*2
	LD	HL,ADDC
	LD	(RGBA+1),HL
	CALLB	XRCOMP
XRRETN:	RET
;------------------------------
XRMTRX:	CALL	VPSUB		;Koeffizientenmatrix laden
	CALL	HBINH
	CP	12		;warte auf 12 Byte von Host
	RET	C

	LD	HL,KVMTRX
	LD	B,10
XRMTR3:	PUSH	HL
	PUSH	BC
	CALL	HBFRD
	POP	BC
	POP	HL
	CP	60H
	JR	C,XRMTR1
	AND	00000111B
	CPL
	JR	XRMTR2
XRMTR1:	AND	00000111B	;positiv
XRMTR2:	LD	(HL),A
	INC	HL
	DJNZ	XRMTR3
	CALL	HBFRD
	LD	(KVCLIP),A	;Klippingkonstante L,H
	CALL	HBFRD
	LD	(KVCLIP+1),A
	JP	STDRT
;------------------------
XRKOVL:	LD	A,0C3H
	LD	(KOV),A
	LD	HL,KOVOL
	LD	(KOV+1),HL
	CALLB	XRKOVB
	RET
XRDKOV:	LD	A,0C3H
	LD	(KOV),A
	LD	HL,DKOVOL
	LD	(KOV+1),HL
	CALLB	XRKOVB
	RET
;------------------------
	ENDIF	;XR
	ENDIF	;EPAGE EQ 0

	IF	(EPAGE EQ 1) and XR
;------------------------
XRSELA:	LD	A,B		;4 bit select-Flags abspeichern
	AND	00000111B
	LD	(XRWR),A
	OUT	(XRFLGS),A
	OR	00010000B	;Farbregisterzugriff auf alle gewaehlten XR-Karten
	LD	(XRRDC),A
	BIT	0,A		;Da lesen nur auf einer Karte moeglich
	JR	Z,XRSEL1	;Karte mit niedrigster Nummer auswaehlen
	LD	A,00010001B
	JR	XRSEL3
XRSEL1:	BIT	1,A
	JR	Z,XRSEL2
	LD	A,00010010B
	JR	XRSEL3
XRSEL2:	AND	00000100B	;verbleibende Karte ist in Bit 2 oder gar keine
	OR	00010000B
XRSEL3:	LD	(XRRD),A
	OUT	(XRFLGS),A
	LD	A,(XRCOL)
	OUT	(XRCLRG),A
	LD	HL,MODUS
	RES	7,(HL)
	LD	A,B
	AND	00000111B
	JR	Z,XRSEL4
	SET	7,(HL)		;Farbmodusbit setzen wenn mindestens eine XR-Karte
	
XRSEL4:	LD	HL,STAT1
	RES	3,(HL)		;Hintergrundfarbe immer 0 in Grundebene
	SET	4,(HL)		;Vordergrundfarbe immer 1 in Grundebene
	RES	5,(HL)		;beide transparent, wenn Grundebene nicht selektiert
	RES	6,(HL)
	BIT	3,B		;wenn Grundebene selektiert
	JR	Z,XRSEL5
	SET	5,(HL)		;beide nicht transparent
	SET	6,(HL)
XRSEL5:	CALL	TBWSET
	RET

;------ Routinen SETRGB --------
	IF	DEBUG
	DB	'XRCOMP'
	ENDIF

;---------------------------------------------------------------
; ACHTUNG ! Die nachfolgende Routine XRCOMP ist zeitptimiert und
; registeroptimiert. Voreilige Aenderungen vermeiden
; XRCOMP berechnet aus 3 Farbauszuegen ein Farbbild mit Antialiasing
;---------------------------------------------------------------
XRCOMP:	LD	E,A		;Farboffset wird in A uebergeben
	LD	HL,(DSPST2)	;Zieladresse in 2. Registersatz ab DSPST2 Farben verrechnen
	EXX
	LD	HL,(DSPST)	;ab Bildschirmstartadresse
	LD	A,(STAT5)
	LD	E,A		;Quelladresse und Quellpage im 1.Registersatz

	LD	A,20H		;Bitmodus einschalten
	OUT	(XRFLGS),A
	XRBRES			;Bitcounter reset

	LD	A,0C3H		;JP OpCodes einsetzen
	LD	(RGBA),A
	LD	(RGBB),A
	LD	(RGBC),A
	CALL	NXTRGB		;RGBB RGBC generieren
	CALL	NXTRGB
	
	LD	C,35		;35 Zeilen
XRCOM4:	LD	B,96		;96 Spalten verrechnen
	PUSH	HL
	LD	HL,0
	LD	(RGBBUF),HL	;SpaltenPuffer loeschen
	LD	(RGBBUF+2),HL
	LD	(RGBBUF+4),HL
	LD	(RGBBUF+6),HL
	CALL	NXTRGB		;ADDD rausschmeissen
	POP	HL

XRCOM3:	XRBRES			;$$$ not necessary if Bitcounter reliable
	LD	IY,RGBBUF
	CALL	RGBA	;darf BC und E nicht veraendern, HL, HL' wird incrementiert
	CALL	RGBB
	CALL	RGBC	;damit keine senkrechten Linien zu sehn sind
	CALL	RGBA
	CALL	RGBB
	CALL	RGBC
	CALL	RGBA
	CALL	RGBB

	CALL	NXTRGB		;waehle naechstes RGB Programm aus
	DJNZ	XRCOM3		;naechste Zeile
	DEC	C
	JR	NZ,XRCOM4

	LD	A,E		;normale ArbeitsPage einschalten
	OUT	(PAGE),A
	LD	A,27H		;Maskenmodus wieder einschalten
	OUT	(XRFLGS),A
	RET
;-------------------------------
ADDA:	LD	A,E
	OUT	(PAGE),A
	CALL	ADDPIX		;ADDA verrechnet die Bildpunkte x im Byte
	LD	(RGBVAL),A	;  .x..x..x
	CALL	ADDPIX		;bilde fuer jedes x den Mittelwert aus den
	LD	(RGBVAL+1),A	;benachbarten Punkten.
	LD	D,0
	LD	A,(ALIASG)
	OR	A
	JR	NZ,ADDA4	;Mit Antialiasing ?
	XRBIT
	LD	A,(HL)
	SLA	A
	RL	D
	ADD	A,(HL)
	XRBIT
	JR	ADDA5

ADDA4:	LD	A,(HL)		;fuer x ganz rechts liegt der Nachbarpunkt
	XRBIT			;im naechsten Byte
	ADD	A,(HL)
	JR	NC,ADDA1
	INC	D
ADDA1:	XRBIT
	EX	AF,AF'
	PUSH	HL
	LD	A,L
	ADD	A,8
	JR	NC,ADDA2
	INC	H
	SET	7,H
ADDA2:	LD	L,A
	EX	AF,AF'
	ADD	A,(HL)
	POP	HL
ADDA5:	JR	NC,ADDAA
	INC	D
ADDAA:	SRL	D		;Einsprung von ADDD
	RR	A		;Ergebnissumme ist in DE wird durch 16 geteilt
	SRL	D		;ab hier ist D immer 0
	RR	A
	SRL	A
	SRL	A
	LD	(RGBVAL+2),A
	INC	HL		;naechste Bildschirmadresse berechnen
	SET	7,H
	LD	A,E
	XOR	0FFH
	OUT	(PAGE),A
	EXX
	XRBIT
	LD	A,(RGBVAL)
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	XRBIT
	LD	A,(RGBVAL+1)
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	XRBIT
	LD	A,(RGBVAL+2)
	ADD	A,E
	LD	(HL),A
	XRBIT
	INC	HL
	SET	7,H
	EXX
	RET

ADDB:	LD	A,E
	OUT	(PAGE),A
	XRBIT			;ADDB verrechnet die Bildpunkte x im Byte
	CALL	ADDPIX		; ..x..x..
	LD	(RGBVAL),A
	CALL	ADDPIX
	LD	(RGBVAL+1),A
	LD	A,(HL)
	LD	(IY+0),A	;Da der Punkt ganz rechts in ADDC als Nachbarpunkt
	INC	IY		;gebraucht wird, speichere ihn nach (IY)
	XRBIT	
	INC	HL
	SET	7,H
	LD	A,E
	XOR	0FFH
	OUT	(PAGE),A	; ..x..x..
	EXX
	XRBIT
	XRBIT
	LD	A,(RGBVAL)	;setze an der Position x die beiden Farbwerte
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	XRBIT
	LD	A,(RGBVAL+1)
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	XRBIT
	INC	HL
	SET	7,H
	EXX
	RET

ADDC:	LD	A,E
	OUT	(PAGE),A
	LD	D,0		;ADDC verrechnet die Bildpunkte im Byte
	LD	A,(ALIASG)	; x..x..x.
	OR	A
	JR	NZ,ADDC3	;Mit Antialiasing ?
	LD	A,(HL)
	SLA	A
	RL	D
	ADD	A,(HL)
	XRBIT
	JR	ADDC4
	
ADDC3:	LD	A,(IY+0)
	INC	IY
	ADD	A,(HL)		;hole Nachbarpunkt von x ganz links aus Puffer (IY)
	JR	NC,ADDC1
	INC	D
ADDC1:	XRBIT			;bilde Summe aus .x.
	ADD	A,(HL)
ADDC4:	JR	NC,ADDC2
	INC	D
ADDC2:	XRBIT
	SRL	D
	RR	A
	SRL	D		;ab hir ist D immer 0
	RR	A
	SRL	A
	SRL	A
	LD	(RGBVAL),A
	CALL	ADDPIX		;bilde Farbwerte aus den anderen .x.
	LD	(RGBVAL+1),A
	CALL	ADDPIX
	LD	(RGBVAL+2),A
	INC	HL
	SET	7,H
	LD	A,E
	XOR	0FFH
	OUT	(PAGE),A
	EXX
	LD	A,(RGBVAL)
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	XRBIT
	LD	A,(RGBVAL+1)
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	XRBIT
	LD	A,(RGBVAL+2)
	ADD	A,E
	LD	(HL),A
	XRBIT
	XRBIT
	INC	HL
	SET	7,H
	EXX
	RET

ADDD:	LD	A,E
	OUT	(PAGE),A
	CALL	ADDPIX		;ADDD verrechnet die Bildpunkte im Byte
	LD	(RGBVAL),A	; .x..x..x aehnlich wie ADDA jedoch
	CALL	ADDPIX		;ist das Byte am rechten Rand wo kein rechter
	LD	(RGBVAL+1),A	;Nachbarpunkt existiert
	LD	D,0
	LD	A,(HL)
	XRBIT
	ADD	A,(HL)
	JR	NC,ADDD1
	INC	D
ADDD1:	XRBIT
	JP	ADDAA		;ab hier weiter wie in ADDA
;-----------------------------
ADDPIX:	LD	D,0		;ADDPIX bildet den Farbmittelwert aus drei
	LD	A,(ALIASG)	;Nachbarpunkten .x.
	OR	A
	JR	NZ,ADDPI3	;Mit Antialiasing ?
	XRBIT
	LD	A,(HL)
	SLA	A
	RL	D
	ADD	A,(HL)
	XRBIT
	JR	ADDPI4
	
ADDPI3:	LD	A,(HL)
	XRBIT
	ADD	A,(HL)
	JR	NC,ADDPI1
	INC	D
ADDPI1:	XRBIT
	ADD	A,(HL)
ADDPI4:	JR	NC,ADDPI2
	INC	D
ADDPI2:	XRBIT			;Die Summe wird durch 16 geteilt.
	SRL	D
	RR	A
	SRL	D		;ab hier ist D immer 0
	RR	A
	SRL	A
	SRL	A		;Ergebnis ist Farbwert von 0-47
	RET
;-------------------------------------------------------------------
; Achtung ! Zeitoptimiert und ablaufoptimiert, spielt zusammen mit XRCOMP
; Die Reihenfolge der Tests ist significant
;--------------------------------------------------------------------
NXTRGB:	PUSH	HL
	LD	HL,(RGBB+1)
	LD	(RGBC+1),HL
	LD	HL,(RGBA+1)
	LD	(RGBB+1),HL
	LD	A,(RGBA+1)	;berechne zyklisch naechste RGB Routine	
	CP	LOW ADDB	;B muss Spaltenzaehler 96 -> 0 enthalten
	JR	Z,NXTRG1
	CP	LOW ADDC
	JR	Z,NXTRG2
	LD	HL,ADDB		;RGBA war entweder ADDA oder ADDD
	LD	(RGBA+1),HL
	POP	HL
	RET

NXTRG1:	LD	HL,ADDC
	LD	(RGBA+1),HL
	POP	HL
	RET

NXTRG2:	LD	A,B		;$$$ Test ADDD fuer letzte Spalte ist nicht vollstaendig
	CP	2		;wird jedoch nicht sichtbar wegen Hardwareproblem
	JR	NZ,NXTRG3
	LD	HL,ADDD
	LD	(RGBA+1),HL
	POP	HL
	RET

NXTRG3:	LD	HL,ADDA
	LD	(RGBA+1),HL
	POP	HL
	RET

;----------------------------
	IF	DEBUG
	DB	'XRKOVB'
	ENDIF

KOVZL	EQU	ARBF
KOVSP	EQU	ARBF+2
KOVRAM	EQU	ARBF+3

XRKOVB:	LD	A,20H		;XR Bitmodus
	OUT	(XRFLGS),A
	XRBRES			;XR Bitcounter reset

	XOR	A		;Kovolution eines gesamten Bildes durchfuehren
	LD	(KOVSP),A	;beginne bei DSPST Spalte 0 - 95 Pixelzeile 0 - (35*8-1)
	LD	HL,KVLSPB	;Spaltenpuffer loeschen
	LD	DE,KVLSPB+1
	LD	BC,35*16-1	;komplett loeschen schadet nicht in non-interlaced
	LD	(HL),0
	LDIR
	LD	HL,(DSPST)	;beginne ab Display Start

XRKO14:	LD	DE,KVLSPB	;KVLBuffer Pointer zeigt auf Beginn KVL Spaltenbuffer
	LD	(KVLBPT),DE
	LD	DE,0000		;Zeile beginnt mit 0
	PUSH	HL		;naechste Bytespalte berechnen

XRKO10:	LD	(KOVRAM),HL	;Kovolution VideoRamPointer setzen
	LD	(KOVZL),DE
	LD	A,D
	OR	E
	JR	NZ,XRKOV2	;teste ob Zeile=0

	LD	HL,KVLBF	;bei Zeile 0 oberen Rand mit 0 fuellen 10 Byte
	LD	DE,KVLBF+1
	LD	BC,10-1
	LD	(HL),0
	LDIR
	LD	DE,KVLBF+10
	LD	HL,(KOVRAM)
	CALL	KVPIXR		;10 Byte Pixelwerte von (HL) nach (DE) einlesen
	JR	XRKOV3

XRKOV2:	LD	DE,KVLBF	;bei Zeile >=1 20 Byte aufruecken
	LD	HL,KVLBF+10
	LD	BC,20
	LDIR

	LD	HL,35*8-1
	JPNI	XRKOV6
	LD	HL,35*16-1
XRKOV6:	LD	DE,(KOVZL)
	LD	A,D
	CP	H		;teste ob letzte Zeile
	JR	NZ,XRKOV3
	LD	A,E
	CP	L
	JR	NZ,XRKOV3

	LD	HL,KVLBF+20	;bei letzter Zeile unteren Rand mit 0 fuellen
	LD	DE,KVLBF+21
	LD	BC,10-1
	LD	(HL),0
	LDIR
	JR	XRKOV5

XRKOV3:	LD	DE,KVLBF+20	;sonst Zeile darunter in Buffer lesen
	LD	HL,(KOVRAM)
	INC	HL
	LD	A,L
	AND	7
	JR	NZ,XRKOV4
	LD	BC,ZLSPR-1
	ADD	HL,BC
	SETNI	7,H
XRKOV4:	CALL	KVPIXR

XRKOV5:	LD	A,(KOVSP)
	CP	95		;bei Spalte 95
	JR	NZ,XRKOV8
	XOR	A
	LD	(KVLBF+9),A	;rechten Rand mit 0 fuellen
	LD	(KVLBF+19),A
	LD	(KVLBF+29),A

XRKOV8:	CALL	KOV		;KVLBF ist ok berechne Kovolution und setze VideoRAM
				;KOV zeigt auf KOVOL oder DKOVOL
	LD	HL,(KOVRAM)	;naechste Zeile, bei Zeile mod 7 Zeilensprung durchfuehren
	INC	HL
	LD	A,L
	AND	7
	JR	NZ,XRKOV9
	LD	BC,ZLSPR-1
	ADD	HL,BC
	SETNI	7,H
XRKOV9:	LD	BC,35*8		;HL muss erhalten bleiben in Schleife deshalb CP
	JPNI	XRKO11
	LD	BC,35*16
XRKO11:	LD	DE,(KOVZL)
	INC	DE
	LD	A,D
	CP	B		;teste ob letzte Zeile
	JP	NZ,XRKO10
	LD	A,E
	CP	C
	JP	NZ,XRKO10	;alle Zeilen sind berechnet

	POP	HL
	LD	BC,8
	ADD	HL,BC
	SETNI	7,H
	LD	A,(KOVSP)	;naechste Spalte rechts
	INC	A
	LD	(KOVSP),A
	CP	96
	JP	NZ,XRKO14	;Kovolution beendet
	
	LD	A,27H		;Maskenmodus
	OUT	(XRFLGS),A
	RET
;----------------------------
	IF	DEBUG
	DB	'KVPIXR'
	ENDIF

KVPIXR:	PUSH	DE	;ein Byte mit angrenzenden Bits aus VideoRam in KVLBF einlesen
	INC	DE	;beginne bei KVLBF+1 mit Byte bit 7
	XRBRES		;$$$ not necessary if Bitcounter reliable
	LD	B,8
	LD	C,H	;rette Page bit der VideoRamAdresse nach C
	JPNI	KVP1
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
KVP1:	LD	A,(HL)		;8 Pixel aus VideoRam
	LD	(DE),A		;in KVLBF einlesen
	INC	DE
	XRBIT			;increment Bitcounter
	DJNZ	KVP1

	LD	H,C		;Page Bit
	LD	BC,8
	ADD	HL,BC
	LD	B,A		;Pixel 0 rechts an Bytegrenze wird in KVLSPB eingetragen
	JPNI	KVP2
	LD	A,H
	OUT	(PAGE),A
KVP2:	SET	7,H
	LD	A,(HL)		;Pixel rechts neben Bytegrenze
	LD	(DE),A		;in KVLBF einlesen

	POP	DE
	LD	HL,(KVLBPT)	;Kovolution-Bufferpointer
	LD	A,(HL)	;lade bit vor der linken Bytegrenze aus Zwischenspeicher
	LD	(DE),A
	LD	(HL),B	;setze bit vor Bytegrenze mit neuem Wert fuer naechsten Durchlauf
	INC	HL
	LD	(KVLBPT),HL
	RET
;----------------------------
	IF	DEBUG
	DB	'DKOVOL'
	ENDIF
DKOVOL:	LD	B,8
	LD	DE,KVLBF

DKOV11:	LD	HL,0
	PUSH	BC
	PUSH	DE
	LD	A,(DE)	;Pixel links oben
	EX	DE,HL
	LD	BC,22
	ADD	HL,BC
	SUB	(HL)	;minus Pixel rechts unten
	JR	NC,DKOVL6
	NEG		;bilde Absolutwert
DKOVL6:	EX	DE,HL
	LD	C,A
	LD	B,0
	LD	A,(H11)		;mit Faktor H11 verrechnen
	OR	A
	JR	Z,DKOV12
	JP	P,DKOV41	;Faktor positiv ?
	JR	DKOV42
DKOVN1:	SLA	C
	RL	B
DKOV42:	INC	A
	JR	NZ,DKOVN1
	SUBHL	BC		;subtrahiere wenn Faktor negativ
	JR	DKOV12
DKOVL1:	SLA	C
	RL	B
DKOV41:	DEC	A
	JR	NZ,DKOVL1
	ADD	HL,BC		;addiere wenn Faktor positiv

DKOV12:	POP	DE
	PUSH	DE
	INC	DE		;Pixel oben Mitte
	LD	A,(DE)
	EX	DE,HL
	LD	BC,20
	ADD	HL,BC
	SUB	(HL)		;subtrahiere Pixel unten Mitte
	JR	NC,DKOVL7
	NEG
DKOVL7:	EX	DE,HL
	LD	C,A
	LD	B,0
	LD	A,(H12)
	OR	A
	JR	Z,DKOV13
	JP	P,DKOV43
	JR	DKOV44
DKOVN2:	SLA	C
	RL	B
DKOV44:	INC	A
	JR	NZ,DKOVN2
	SUBHL	BC
	JR	DKOV13
DKOVL2:	SLA	C
	RL	B
DKOV43:	DEC	A
	JR	NZ,DKOVL2
	ADD	HL,BC

DKOV13:	POP	DE
	PUSH	DE
	INC	DE
	INC	DE		;Pixel oben rechts
	LD	A,(DE)
	EX	DE,HL
	LD	BC,18
	ADD	HL,BC
	SUB	(HL)		;subtrahiere Pixel unten links
	JR	NC,DKOVL8
	NEG
DKOVL8:	EX	DE,HL
	LD	C,A
	LD	B,0
	LD	A,(H13)
	OR	A
	JR	Z,DKOV21
	JP	P,DKOV45
	JR	DKOV46
DKOVN3:	SLA	C
	RL	B
DKOV46:	INC	A
	JR	NZ,DKOVN3
	SUBHL	BC
	JR	DKOV21
DKOVL3:	SLA	C
	RL	B
DKOV45:	DEC	A
	JR	NZ,DKOVL3
	ADD	HL,BC

DKOV21:	EX	DE,HL
	LD	BC,10
	SUBHL	BC
	LD	A,(HL)	;Pixel Mitte links
	INC	HL
	INC	HL
	SUB	(HL)	;subtrahiere Pixel Mitte rechts
	JR	NC,DKOVL9
	NEG
DKOVL9:	EX	DE,HL
	LD	C,A
	LD	B,0
	LD	A,(H21)
	OR	A
	JR	Z,DKOV22
	JP	P,DKOV47
	JR	DKOV48
DKOVN4:	SLA	C
	RL	B
DKOV48:	INC	A
	JR	NZ,DKOVN4
	SUBHL	BC
	JR	DKOV22
DKOVL4:	SLA	C
	RL	B
DKOV47:	DEC	A
	JR	NZ,DKOVL4
	ADD	HL,BC

DKOV22:	DEC	DE		;Mittelpunkt
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H22)
	OR	A
	JR	Z,DKOV23
	JP	P,DKOV49
	JR	DKOV50
DKOVN5:	SLA	C
	RL	B
DKOV50:	INC	A
	JR	NZ,DKOVN5
	SUBHL	BC
	JR	DKOV23
DKOVL5:	SLA	C
	RL	B
DKOV49:	DEC	A
	JR	NZ,DKOVL5
	ADD	HL,BC


DKOV23:	LD	BC,(KVCLIP)	;Klippingkonstante addieren
	ADD	HL,BC

	LD	A,(KVFAKT)	;Teilerfaktor verrechnen
	OR	A
	JR	Z,DKOV14
	JP	P,DKOV51
	JR	DKOV52
DKOVN6:	SRA	H
	RR	L
DKOV52:	INC	A
	JR	NZ,DKOVN6
	LD	A,H		;Zweierkomplement von HL bilden
	CPL
	LD	H,A
	LD	A,L
	CPL
	LD	L,A
	INC	HL
	JR	DKOV14
DKOV15:	SRA	H
	RR	L
DKOV51:	DEC	A
	JR	NZ,DKOV15

DKOV14:	BIT	7,H
	JR	Z,DKOV17
	LD	L,0		;Bei Unterlauf 00 setzen
	JR	DKOV16
DKOV17:	LD	A,H
	OR	A
	JR	Z,DKOV16	;Bei Ueberlauf FF setzen
	LD	L,0FFH
DKOV16:	LD	B,L
	LD	HL,(KOVRAM)
	JPNI	DKOV18
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
DKOV18:	LD	(HL),B
	OUT	(XRCLU0),A	;Bitcounter increment

	POP	DE
	INC	DE
	POP	BC
	DEC	B
	JP	NZ,DKOV11

	RET
;---------------------------
	IF	DEBUG
	DB	'KOVOL'
	ENDIF
KOVOL:	LD	B,8
	LD	DE,KVLBF	;beginne mit Pixel links oben

KOVH11:	LD	HL,0		;Summenwert auf 0 setzen
	PUSH	DE
	PUSH	BC
	LD	A,(DE)		;hole Original-Farbwert nach BC
	LD	C,A
	LD	B,0
	LD	A,(H11)		;Faktor H11
	OR	A
	JR	Z,KOVH12	;ist Faktor 0 dann keine Verrechnung noetig
	JP	P,KOVO41	;Faktor positiv ?
	JR	KOVO42
KOVON1:	SLA	C
	RL	B
KOVO42:	INC	A
	JR	NZ,KOVON1
	SUBHL	BC
	JR	KOVH12
KOVOL1:	SLA	C		;Farbwert mit Faktor multiplizieren
	RL	B
KOVO41:	DEC	A
	JR	NZ,KOVOL1
	ADD	HL,BC		;aufaddieren

KOVH12:	INC	DE		;Pixel Mitte oben
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H12)
	OR	A
	JR	Z,KOVH13
	JP	P,KOVO43
	JR	KOVO44
KOVON2:	SLA	C
	RL	B
KOVO44:	INC	A
	JR	NZ,KOVON2
	SUBHL	BC
	JR	KOVH13
KOVOL2:	SLA	C
	RL	B
KOVO43:	DEC	A		;mit Koeffizient H12 multiplizieren
	JR	NZ,KOVOL2
	ADD	HL,BC		;aufaddieren

KOVH13:	INC	DE		;Pixel rechts oben
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H13)
	OR	A
	JR	Z,KOVH21
	JP	P,KOVO45
	JR	KOVO46
KOVON3:	SLA	C
	RL	B
KOVO46:	INC	A
	JR	NZ,KOVON3
	SUBHL	BC
	JR	KOVH21
KOVOL3:	SLA	C
	RL	B
KOVO45:	DEC	A
	JR	NZ,KOVOL3
	ADD	HL,BC

KOVH21:	EX	DE,HL		;8 addieren DE zeigt auf Pixel Mitte links
	LD	BC,8
	ADD	HL,BC
	LD	C,(HL)
	EX	DE,HL
	LD	B,0
	LD	A,(H21)
	OR	A
	JR	Z,KOVH22
	JP	P,KOVO47
	JR	KOVO48
KOVON4:	SLA	C
	RL	B
KOVO48:	INC	A
	JR	NZ,KOVON4
	SUBHL	BC
	JR	KOVH22
KOVOL4:	SLA	C
	RL	B
KOVO47:	DEC	A
	JR	NZ,KOVOL4
	ADD	HL,BC

KOVH22:	INC	DE		;DE zeigt auf Pixel im Zentrum der Matrix
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H22)
	OR	A
	JR	Z,KOVH23
	JP	P,KOVO49
	JR	KOVO50
KOVON5:	SLA	C
	RL	B
KOVO50:	INC	A
	JR	NZ,KOVON5
	SUBHL	BC
	JR	KOVH23
KOVOL5:	SLA	C
	RL	B
KOVO49:	DEC	A
	JR	NZ,KOVOL5
	ADD	HL,BC

KOVH23:	INC	DE		;Pixel Mitte rechts
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H23)
	OR	A
	JR	Z,KOVH31
	JP	P,KOVO51
	JR	KOVO52
KOVON6:	SLA	C
	RL	B
KOVO52:	INC	A
	JR	NZ,KOVON6
	SUBHL	BC
	JR	KOVH31
KOVOL6:	SLA	C
	RL	B
KOVO51:	DEC	A
	JR	NZ,KOVOL6
	ADD	HL,BC

KOVH31:	EX	DE,HL		;wieder 8 addieren fuer untere Reihe der Matrix
	LD	BC,8
	ADD	HL,BC
	LD	C,(HL)
	EX	DE,HL
	LD	B,0
	LD	A,(H31)
	OR	A
	JR	Z,KOVH32
	JP	P,KOVO53
	JR	KOVO54
KOVON7:	SLA	C
	RL	B
KOVO54:	INC	A
	JR	NZ,KOVON7
	SUBHL	BC
	JR	KOVH32
KOVOL7:	SLA	C
	RL	B
KOVO53:	DEC	A
	JR	NZ,KOVOL7
	ADD	HL,BC

KOVH32:	INC	DE		;Pixel unten Mitte
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H32)
	OR	A
	JR	Z,KOVH33
	JP	P,KOVO55
	JR	KOVO56
KOVON8:	SLA	C
	RL	B
KOVO56:	INC	A
	JR	NZ,KOVON8
	SUBHL	BC
	JR	KOVH33
KOVOL8:	SLA	C
	RL	B
KOVO55:	DEC	A
	JR	NZ,KOVOL8
	ADD	HL,BC

KOVH33:	INC	DE		;Pixel unten rechts
	LD	A,(DE)
	LD	C,A
	LD	B,0
	LD	A,(H33)
	OR	A
	JR	Z,KOVCLP
	JP	P,KOVO57
	JR	KOVO58
KOVON9:	SLA	C
	RL	B
KOVO58:	INC	A
	JR	NZ,KOVON9
	SUBHL	BC
	JR	KOVCLP
KOVOL9:	SLA	C
	RL	B
KOVO57:	DEC	A
	JR	NZ,KOVOL9
	ADD	HL,BC		;HL enthaelt Summe der Multiplikationen

KOVCLP:	LD	BC,(KVCLIP)	;Klippingkonstante addieren
	ADD	HL,BC

	LD	A,(KVFAKT)	;Teilerfaktor verrechnen
	OR	A
	JR	Z,KOVO14	;kein Teilerfaktor
	JP	P,KOVO59
	JR	KOVO60
KOVN13:	SRA	H
	RR	L
KOVO60:	INC	A
	JR	NZ,KOVN13
	LD	A,H
	CPL
	LD	H,A
	LD	A,L
	CPL
	LD	L,A
	INC	HL
	JR	KOVO14
KOVO13:	SRA	H
	RR	L
KOVO59:	DEC	A
	JR	NZ,KOVO13

KOVO14:	BIT	7,H		;Ergebnis negativ ?
	JR	Z,KOVO11	;Bei Unterlauf 00 setzen
	LD	L,0
	JR	KOVO12
KOVO11:	LD	A,H		;Ergebnis > 255 ?
	OR	A
	JR	Z,KOVO12	;Bei Ueberlauf FF setzen
	LD	L,0FFH
KOVO12:	LD	B,L
	LD	HL,(KOVRAM)	;Ergebnis in Bildspeicher schreiben
	JPNI	KOVO15
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
KOVO15:	LD	(HL),B
	XRBIT			;Bitcounter increment

	POP	BC
	POP	DE
	INC	DE		;Pointer auf ein Pixel weiter rechts setzen
	DEC	B		;insgesamt 8 mal
	JP	NZ,KOVH11

	RET
	ENDIF	;(EPAGE EQ 1) and XR
;----------------------------
	IF	EPAGE EQ 0

RAMDFB:	CALL	VPSUB		;<EEi> Video-Ram Zielpointer einstellen
	CALL	HBINH		;binaer ESC ESC i bb
	CP	2
	RET	C
	CALL	HBFRD
	LD	L,A
	PUSH	HL
	CALL	HBFRD
	POP	HL
	LD	H,A
	JR	RAMDW1
RAMDEF:	CALL	VPSUB
RAMDW:	CALL	ADLD		;Adresse laden in HL (HEX aus Hostpuffer)
	RET	Z
RAMDW1:	LD	B,H
	LD	C,L

	IF	XR

	LD	A,L		;berechne VRAMZL und VRAMSP
	AND	00000111B
	LD	(VRAMZL),A	;VRAMZL between 0-7
	LD	A,L
	AND	11111000B
	LD	L,A
	JPI	VRPOS5
	RES	7,H
VRPOS5:	OR	H
	JR	Z,VRPOS2	;Adress between 0-7

	XOR	A
	LD	DE,PITCH
VRPOS3:	SUBHL	DE
	JR	Z,VRPOS2
	JR	NC,VRPOS3
	ADD	HL,DE	;Adress between 8 - 02F8 left
	LD	DE,8
VRPOS4:	INC	A
	SUBHL	DE
	JR	NZ,VRPOS4
VRPOS2:	LD	(VRAMSP),A
	ENDIF	;XR

	LD	HL,(DSPST)	;mit Bildstartadresse verrechnen
	JPNI	RAMDW3
	ADD	HL,BC
	JR	RAMDW4

RAMDW3:	JPBITZ	7,B,RAMDW2
	LD	HL,(DSPST2)
RAMDW2:	ADD	HL,BC		;verrechnen
	LD	A,(STAT3)	;Bit 15=1 schreibt in unsichtbare Page
	XOR	B
	RL	H
	RL	A
	RR	H
RAMDW4:	LD	(VRAMAD),HL
	IF	XR
	 LD	A,8
	 LD	(EBNLP),A
	 LD	(EBNVP),A
	 XRBRES			;reset Bitcounter
	ELSE
	 LD	HL,FRBPUF
	 LD	(EBNLP),HL
	 LD	A,4
	 LD	(EBNVP),A
	ENDIF
	JP	STDRT
;-----------------------
SETPAD:	CALL	VPSUB		;<EEp> System patchadresse einlesen
	CALL	ADLD
	RET	Z
	LD	(PTCHLP),HL
	LD	A,(MODUS+1)	;wenn Zielkanal Systemadresse
	AND	00001111B	;Quellverarbeitungspointer setzen
	CP	0AH
	JR	NZ,SETPA1
	LD	(QULVP),HL
SETPA1:	JP	STDRT
;-----------------------
PTRES:	LD	HL,0		;<EEP> Spooler loeschen
	LD	(SPLINH),HL
	LD	HL,SPOLBF
	LD	(SPOLLP),HL
	LD	(SPOLVP),HL
PTRES1:	RET
;-----------------------
OUTADR:	CALL	VPSUB		;<EEO>
	CALL	ADLD
	RET	Z
	LD	C,H
	LD	A,L
	JR	OUTAD1
OUTADB:	CALL	VPSUB		;<EEo>
	CALL	HBINH
	CP	2
	RET	C
	CALL	HBFRD
	PUSH	AF
	CALL	HBFRD
	POP	BC
	LD	C,B
OUTAD1:	OUT	(C),A
	JP	STDRT
;-----------------------
QUDEF:	CALL	VPSUB		;<EEc> Quellkanal definieren
	CALL	HBINPR
	RET	Z
	CP	'A'
	JR	C,QUDEF1
	SUB	7
QUDEF1:	AND	00001111B	;4 unterste Bits def. Quellkanal
	LD	C,A
	LD	A,(MODUS+1)
	AND	11110000B	;unterste 4 Bits loeschen
	OR	C		;neu einsetzen
	LD	(MODUS+1),A

	LD	A,C
	CP	4		;je nach Quellkanal Quell-Lesepointer
	JR	NZ,QUDEF4	;entsprechend setzen
	LD	DE,(EXZSLP)
	LD	(QULVP),DE
QUDEF4:	CP	5
	JR	NZ,QUDEF2
	LD	DE,USRBUF
	LD	(QULVP),DE
QUDEF2:	CP	6
	JR	NZ,QUDEF3
	LD	DE,SKVTAB
	LD	(QULVP),DE
QUDEF3:	CP	7
	JR	NZ,QUDEF5
	LD	DE,MELPUF
	LD	(QULVP),DE
QUDEF5:	CP	9
	JR	NZ,QUDEF6
	LD	DE,STL2BF
	LD	(QULVP),DE
QUDEF6:	CP	10
	JR	NZ,QUDEF7
	LD	DE,(PTCHLP)
	LD	(QULVP),DE
QUDEF7:	CP	11
	JR	NZ,QUDEF8
	LD	DE,HRDCBF
	LD	(QULVP),DE

QUDEF8:	LD	B,0		;C enthaelt Quellkanalnummer
	LD	HL,QULTAB	;Verarbeitungsprogramme
	CALL	PRDF
	LD	(QUVAP),DE
	CALL	MODDSP
	JP	STDRT

QULTAB:	DW	QUOFF,QUECB,QUV24,QUVRAM,QUMEM,QUMEM,QUMEM,QUMEM
	DW	QUCRAM,QUMEM,QUMEM,QUMEM,QUPKB,QUSKB,QUIKB
;-----------------------
QU1BB:	LD	HL,STAT2	;empfange binaer
	SET	0,(HL)
	JR	QU1B1
QU1B:	LD	HL,STAT2
	RES	0,(HL)		;empfange im HEX-Format
	RES	5,(HL)
QU1B1:	LD	HL,1
	LD	(UEZHL),HL
	LD	HL,ABLMRK+1
	SET	4,(HL)		;Einzelbyte-Flag  damit kein CR gesendet wird
	JP	QUCOM
;-----------------------
QURECB:	LD	HL,STAT2	;binaer Flag setzen
	SET	0,(HL)
	CALL	VPSUB		;ESC ESC g bb
	CALL	HBINH		;auf 2 byte warten Uebertragungsanzahl
	CP	2
	RET	C
	CALL	HBFRD		;Uebertragungszahl L,H einlesen
	LD	L,A
	PUSH	HL
	CALL	HBFRD
	POP	HL
	LD	H,A
	JR	QUREC1
;-----------------------
QUREC:	LD	HL,STAT2	;<EEG>
	RES	0,(HL)
	RES	5,(HL)
	CALL	VPSUB
QURW:	CALL	ADLD		;4 stellige Uebertragungszahl nach HL lesen
	RET	Z		;warte auf Eingabe

QUREC1:	LD	(UEZHL),HL
	LD	HL,ABLMRK+1
	RES	4,(HL)		;kein Einzelbyte CR darf gesendet werden

QUCOM:	LD	HL,(UEZHL)
	LD	A,H
	OR	L
	JP	Z,QUEND
	LD	HL,(QUVAP)	;Verweis auf Quellpufferprogramm
	JP	(HL)
;-----------------------
QUOFF:	XOR	A		;sendet immer 00 Dummy Kanal
	JP	QUOUT
;-----------------------
QUMEM:	LD	HL,(QULVP)	;Quellkanal Memory location
	LD	A,(HL)		;get byte from memory
	INC	HL
	RES	7,H		;kein lesen von VideoRam
	LD	(QULVP),HL
QUOUT:	LD	(OUTCHR),A
	CALL	VPSUB
	CALL	HBFLDH		;send HEX or binary to Host
	RET	NZ		;wait for HOST

QUNEXT:	LD	HL,(UEZHL)	;DEC Number of bytes to send
	DEC	HL
	LD	(UEZHL),HL
	JP	QUCOM		;next Byte to send or Stop
;-----------------------
QUECB:	CALL	ECBIPL
	OR	A
	JP	Z,QUFAIL
	CALL	ECBIP1
	JP	QUOUT
;-----------------------
QUV24:	CALL	SINIPL
	OR	A
	JP	Z,QUFAIL
	CALL	SINIP1
	JP	QUOUT
;-----------------------
QUPKB:	LD	HL,KYBLP
	CALL	KBFIPA
	OR	A
	JP	Z,QUFAIL
	LD	HL,KYBLP
	CALL	KBFINA
	JP	QUOUT
;-----------------------
QUSKB:	LD	HL,KYBSLP
	CALL	KBFIPA
	OR	A
	JP	Z,QUFAIL
	LD	HL,KYBSLP
	CALL	KBFINA
	JP	QUOUT
;-----------------------
QUIKB:	LD	HL,KYBILP
	CALL	KBFIPA
	OR	A
	JP	Z,QUFAIL
	LD	HL,KYBILP
	CALL	KBFINA
	JP	QUOUT
;-----------------------
QUFAIL:	LD	HL,STAT2	;Puffer leer Uebertragung abbrechen
	JPBIT	0,(HL),QUOFF	;bei Binaer EEe EEg Nullen senden
	JR	QUEND2		;sonst CR senden
	
QUEND:	LD	HL,STAT2	;bei binaer kein CR senden
	JPBIT	0,(HL),QUEND1
	LD	HL,ABLMRK+1
	JPBIT	4,(HL),QUEND1	;bei Einzelbyte HEX normales Ende kein CR

QUEND2:	CALL	VPSUB
	CALL	HBPLZ
	RET	NZ
	LD	A,8DH		;CR bei Transferende in HEX
	CALL	HBFLD

QUEND1:	JP	STDRT
;-----------------------
	IF	DEBUG
	DB	'QUCRAM'
	ENDIF
	IF	XR
QUCRAM:	LD	HL,(VRAMAD)	;Farbbild von Host einlesen
	LD	A,H
	OUT	(PAGE),A	;oberstes Bit (Page) bleibt erhalten
	LD	A,20H
	OUT	(XRFLGS),A	;Bitmodus aktivieren
	SET	7,H
	LD	B,(HL)		;Byte einlesen nach XR im Bitmodus
	XRBIT			;increment Bitcounter
	LD	HL,EBNVP	;zaehlt von 8-0
	DEC	(HL)
	JP	NZ,QUCRA1	;insgesamt 8 Byte an gleiche Stelle schreiben
	LD	(HL),8
	CALL	INCVRA		;Increment VideoRamAdress
QUCRA1:	LD	A,27H
	OUT	(XRFLGS),A
	JP	QUVOUT

	ELSE
QUCRAM:	LD	A,(EBNVP)
	DEC	A
	PUSH	AF
	CALL	SETEBA
	POP	AF
	LD	(EBNVP),A
	JR	NZ,QUCRA1
	LD	A,4
	LD	(EBNVP),A
	JP	QUVRMA		;Byte aus Grundebene ausgeben und
				;Pointer erhoehen
QUCRA1:	LD	HL,(VRAMAD)
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	LD	B,(HL)
	JP	QUVOUT	
	ENDIF

;-----------------------
QUVRAM:	IF	XR
	 LD	A,10H
	 OUT	(XRFLGS),A	;lesen immer von Grundebene
	ELSE
	 CALL	SETEBN		;Farbebene auswaehlen zum Lesen
	ENDIF
QUVRMA:	LD	HL,(VRAMAD)
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	LD	B,(HL)		;byte aus Video-Ram holen
	JPI	QUVRA3
	INC	HL
	RL	H		;oberstes Bit beibehalten
	RLA			;fuer gleiche Page
	RR	H
	LD	(VRAMAD),HL
QUVOUT:	LD	A,(STAT5)
	OUT	(PAGE),A
	JR	QUVRA2
QUVRA3:	LD	H,A
	INC	HL
	LD	(VRAMAD),HL

QUVRA2:	IF	XR
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ELSE
	 CALL	FRBRES
	ENDIF

	LD	A,B
	LD	HL,STAT3
	JPBITZ	6,(HL),QUVRA1	;invertiert senden ?
	CPL
QUVRA1:	JP	QUOUT
;-----------------------
;A in HEX- oder BIN- Format in Hostpuffer
HBFLDH:	CALL	HBPLZ		;Platz in Hostbuffer ?
	RET	NZ

	LD	A,(OUTCHR)
	LD	L,A
	LD	A,(STAT2)
	JPBIT	0,A,HBFLD1	;binaer ?

	LD	A,L
	CALL	PUT		;HEX A->HL
	LD	A,(STAT2)
	JPBIT	5,A,HBFLD3	;High byte bereits gesendet ?
	SET	5,A
	LD	(STAT2),A
	LD	A,H		;nein sende High byte
	SET	7,A		;HEX von Quellenkanal immer mit 7.bit
	CALL	HBFLD
	JR	HBFLDH		;try to send Low byte

HBFLD3:	RES	5,A		;Low byte senden
	LD	(STAT2),A
	SET	7,L		;HEX von Quellenkanal immer mit 7.bit
HBFLD1:	LD	A,L
	CALL	HBFLD
	CP	A		;Z byte ist komplett uebertragen
	RET
;-----------------------
ZLDEF:	CALL	VPSUB		;<EEC> Zielkanal einstellen
	CALL	HBINPR
	RET	Z
	CALL	STDRT
	CP	'A'
	JR	C,ZLDEF9
	SUB	7
ZLDEF9:	AND	00001111B	;4 unterste Bits def. Zielkanal
	CP	12
	RET	NC		;falsche Zahl

	LD	C,A
	RRCA
	RRCA
	RRCA
	RRCA
	LD	B,A
	LD	A,(MODUS+1)
	AND	00001111B	;oberste 4 Bits loeschen
	OR	B		;neu einsetzen
	LD	(MODUS+1),A

	LD	HL,STDRT	;Abbruchprogramme waehlen
	LD	A,C
	CP	4
	JR	NZ,ZLDEF8
	LD	HL,ZSLEND	;Checksumme bilden nach Zeichensatzveraenderung
	JR	ZLDEF3
ZLDEF8:	CP	5
	JR	NZ,ZLDEF4
	LD	DE,USRBUF	;Pointer auf Beginn des Userprogramms setzen
	LD	(USRLP),DE
	PUSH	AF
	LD	A,0C9H		;Userprogramm loeschen durch RET
	LD	(DE),A
	POP	AF
	JR	ZLDEF3
ZLDEF4:	CP	6		;bei Zielkanal Umcodetabelle
	JR	NZ,ZLDEF2
	LD	HL,MODUS	;Umcodierung abschalten
	RES	2,(HL)
	LD	HL,SKVTAB	;Pointer auf Beginn der Tabelle setzen
	LD	(SKVLP),HL
	LD	HL,STKVND	;Tastenumcodierung nach Empfang einschalten
	JR	ZLDEF3
ZLDEF2:	CP	7		;bei Zielkanal Melodiepuffer
	JR	NZ,ZLDEF7
	LD	HL,MELPUF	;Pointer auf Beginn des Melodiepuffers
	LD	(MELLP),HL
	LD	HL,MELND	;Melodie Starten
	JR	ZLDEF3
ZLDEF7:	CP	9		;bei Zielkanal 2.Statuszeile
	JR	NZ,ZLDEF5
	PUSH	BC
	CALL	SL2CLR		;Text der 2. Statuszeile loeschen
	POP	BC
	LD	HL,SLDEND
	JR	ZLDEF3
ZLDEF5:	CP	11
	JR	NZ,ZLDEF3
	LD	DE,HRDCBF
	LD	(HRDCLP),DE
ZLDEF3:	LD	(ABPROG+1),HL

	LD	B,0		;A,C=Nr des Zielkanals
	CP	3
	JR	NC,ZLDEF6	;bei Zielkanal CX,ECB,V24

	PUSH	BC
	SLA	A
	LD	C,A
	LD	HL,SPLZTB
	CALL	PRDF
	LD	(ZLPLZ+1),DE	;Zielkanal Spoolerroutinen einsetzen
	LD	E,(HL)
	INC	HL
	LD	D,(HL)		;Programm
	LD	(ZLBLD+1),DE
	POP	BC

	LD	A,(STAT1)
	BIT	1,A
	JR	Z,ZLDEF6	;bei Spooler ZLSPOL setzen

	LD	C,12		;ZLSPOL
ZLDEF6:	LD	HL,ZVPTAB	;Tabelle der Zielpufferprogramme
	CALL	PRDF
	LD	(ZLVAP),DE	;Zielkanalroutine einsetzen
	CALL	MODDSP		;Modusdisplay
	RET
;-----------------------
PRDF:	SLA	C		;*2
	ADD	HL,BC		;Programmvariante feststellen
	LD	E,(HL)
	INC	HL
	LD	D,(HL)		;Programm
	INC	HL
	RET
;-----------------------
SPLZTB:	DW	CXOPL,CXOUT,ECBOPL,ECBOUT,V24OPL,V24OUT

ZVPTAB:	DW	ZLCX,ZLECB,ZLV24,ZLVRAM,ZLZSZ,ZLUPR,ZLSTKV,ZLMEL
	DW	ZLVCOL,ZLSTZL,ZLPTCH,ZLHRDC,ZLSPOL
;-----------------------
;Einzelbyte zum Zielpuffer
ZL1B:	LD	HL,STAT2
	RES	0,(HL)		;sende im HEX-Format
	RES	5,(HL)
	JR	ZL1B1

ZL1BB:	LD	HL,STAT2	;sende binaer
	SET	0,(HL)
	LD	HL,1		;sende Einzelbyte binaer zum Zielkanal
	LD	(BYTCNT),HL
ZL1B1:	LD	HL,STDRT
	LD	(ZLRET+1),HL	;Return mit Kommandoende identisch
	LD	(ABPROG+1),HL	;Standardabbruch ohne Sonderaktion
	JP	ZLJUMP
;-----------------------
ZLSND:	LD	HL,STAT2	;Zeichenfolge als ASCII zum Zielpuffer
	RES	0,(HL)
	RES	5,(HL)
	JP	ZLSND1

ZLSNDB:	CALL	VPSUB		;2 byte Anzahl der Zeichen einlesen
	CALL	HBINH
	CP	2
	RET	C

	CALL	HBFRD
	LD	(BYTCNT),A	;read Nr of Bytes to send L,H
	CALL	HBFRD
	LD	(BYTCNT+1),A

	LD	HL,STAT2	;Zeichenfolge binaer zum Zielpuffer
	SET	0,(HL)

	LD	A,(MODUS)	;Test ob schnelles VIDEO-Ram laden moeglich
	AND	00000011B	;Hostkanal ECB ?
	CP	00000001B
	JP	NZ,ZLSND1

	DI
	LD	A,(MODUS+1)
	AND	11110000B	;Zielkanal Video-Ram ?
	CP	00110000B
	JR	NZ,ZLSND2
	LD	HL,RETURN
	LD	(ZLRET+1),HL
	LDW	(INTVKT+30),SWBILD	;Schwarz-Weiss Laden
	LDW	(HBFRD+1),ECBRD		;Hostbuffer read ohne enable ECB-Int.

ZLSND5:	CALL	RDBIN		;bis Puffer leer Bytes in VideoRam lesen
	JR	Z,ZLSND4
	JP	M,ZLVEND	;Uebertragung beendet alle Bytes waren im ECB Puffer
	CALL	ZLDIR		;zum Zielkanal
	JR	ZLSND5

ZLSND2:	CP	10000000B	;Zielkanal VideoRam Farbe
	JP	NZ,ZLSND1
	LD	HL,RETURN
	LD	(ZLRET+1),HL
	LDW	(INTVKT+30),CLBILD	;Colorbild Laden
	LDW	(HBFRD+1),ECBRD		;Hostbuffer read ohne enable ECB-Int.
ZLSND6:	CALL	RDBIN		;Host Input-Puffer leer ?
	JR	Z,ZLSNDV
	JP	M,ZLVEND	;Uebertragung beendet alle Bytes waren im ECB Puffer
	CALL	ZLDIR
	JR	ZLSND6

ZLSNDV:	IF	XR
	 LD	A,20H
	 OUT	(XRFLGS),A	;Bitmodus aktivieren
	ENDIF
ZLSND4:	LD	HL,ABLMRK+1
	SET	7,(HL)		;DMA- ECB-> ViedeoRam enable
	EI
ZLSND3:	BIT	7,(HL)		;warte bis Bild Uebertragen ist
	JR	NZ,ZLSND3
	LD	A,(STAT5)	;Arbeitspage einschalten
	OUT	(PAGE),A
	IF	XR
	 LD	A,27H		;zurueck in Maskenmodus schalten
	 OUT	(XRFLGS),A
	ELSE
	 CALL	FRBRES
	ENDIF
	JP	STDRT		;CLBILD,SWBILD setzen ECBINT wieder ein

ZLVEND:	LDW	(INTVKT+30),ECBINT
	LDW	(HBFRD+1),ECBIP1
	EI
	JP	STDRT
;--------------------------
ECBRD:	LD	HL,(ECBILP)	;1 Byte aus ECB-Input Puffer laden
	LD	DE,(ECBIVP)
	LD	B,LOW ECIEND
	LD	C,LOW ECBIBF
	CALL	BFVA		;Z bei Puffer leer, sonst Byte in A
	LD	(ECBIVP),DE
	RET
;--------------------------
ZLSND1:	EI
	LD	HL,ZLJUMP
	LD	(ZLRET+1),HL
ZLJUMP:	CALL	VPSUB
	CALL	RDBYT		;1 Byte (2 HEXbytes) vom Hostpuffer in A
	RET	Z		;noch nicht bereit, warten
	JP	M,ABPROG	;Ende wenn CR oder Anzahl erreicht

ZLDIR:	LD	HL,(ZLVAP)
	JP	(HL)		;Absprung zum Zielverarbeitungsprogramm
;-----------------------
RDBYT:	LD	HL,STAT2
	JPBIT	0,(HL),RDBIN	;binaeres Senden
	JPBIT	5,(HL),RDBYT2
	CALL	HBINH		;1. Byte ASCII einlesen
	CP	1
	JR	C,RDNEG

	CALL	HBFRD
	CP	CR
	JP	Z,RDABR
	LD	(HBYT),A
	LD	HL,STAT2
	SET	5,(HL)
RDBYT2:	CALL	HBINH		;2. Byte ASCII einlesen
	CP	1
	JR	C,RDNEG

	LD	HL,STAT2
	RES	5,(HL)
	CALL	HBFRD
	CP	CR
	JP	Z,RDABR
	LD	L,A
	LD	A,(HBYT)
	LD	H,A
	CALL	GET
	JR	RDPOS

RDBIN:	LD	DE,(BYTCNT)	;Abbruch bei BYTCNT=0
	LD	A,E
	OR	D
	JR	Z,RDABR
	CALL	HBINH
	CP	1
	JR	C,RDNEG

	CALL	HBFRD
	LD	DE,(BYTCNT)
	DEC	DE
	LD	(BYTCNT),DE

RDPOS:	LD	C,0		;NZ wenn Zeichen von Host gekommen
	INC	C
	RET
RDNEG:	CP	A		;Z wenn kein Zeichen
	RET
RDABR:	XOR	A		;Negativ wenn Abbruch durch CR oder Anzahl
	DEC	A
	RET
;-----------------------
ZLCX	EQU	$
ZLECB	EQU	$
ZLV24:	LD	(WRKCHR),A
	CALL	VPSUB
	CALL	ZLPLZ
	RET	NZ
	LD	A,(WRKCHR)
	CALL	ZLBLD
	JP	ZLRET
;--------------------------------------------------------
; Zielkanal VideoRam NON-INTERLACED
;--------------------------------------------------------
ZLVRAM:	CALL	ZLVRMW		;Zielbyte in Video-Ram Schwarz-weiss
	JP	ZLRET
;-----------------------
	IF	DEBUG
	DB	'ZLVCOL'
	ENDIF
	IF	XR
ZLVCOL:	LD	HL,(VRAMAD)	;Farbbild von Host einlesen
	LD	B,A		;wird in der jeweiligen Farbe geschrieben
	LD	A,H
	OUT	(PAGE),A	;oberstes Bit (Page) bleibt erhalten
	LD	A,20H
	OUT	(XRFLGS),A	;Bitmodus aktivieren
	SET	7,H
	LD	(HL),B		;Byte einlesen nach XR im Bitmodus
	XRBIT			;increment Bitcounter
	LD	HL,EBNLP	;zaehlt von 8-0
	DEC	(HL)
	JP	NZ,ZLVCO1	;insgesamt 8 Byte an gleiche Stelle schreiben
	LD	(HL),8
	CALL	INCVRA		;Increment VideoRamAdress
ZLVCO1:	LD	A,27H
	OUT	(XRFLGS),A
	LD	A,(STAT5)
	OUT	(PAGE),A
	JP	ZLRET

	ELSE
ZLVCOL:	LD	HL,(EBNLP)	;Zielkanal VideoRam Farbbild
	LD	(HL),A		;Pointer zeigt auf Farbbytepuffer
	INC	HL
	LD	A,LOW (FRBPUF+4);wenn 4 Byte empfangen sind, Farben berechnen
	CP	L
	JR	NZ,ZLVRC1
	LD	HL,FRBPUF
ZLVRC1:	LD	(EBNLP),HL
	JP	NZ,ZLRET	;warte auf insgesamt 4 byte fuer 4 Farbebenen

	LD	C,(HL)
	INC	HL
	LD	D,(HL)
	INC	HL
	LD	E,(HL)
	LD	HL,(VRAMAD)
	LD	A,H
	OUT	(PAGE),A
	SET	7,H
	CALL	CLBLDA
	CALL	ZLVRMW
	LD	A,(COLRG1)
	OUT	(CLRG1),A
	JP	ZLRET
	ENDIF
;----------------------------------------------------
ZLVRMW:	LD	HL,(VRAMAD)	;Viedeo-Ram Zielkanal
	LD	B,A		;wird in der jeweiligen Farbe geschrieben
	LD	A,H
	OUT	(PAGE),A	;oberstes Bit (Page) bleibt erhalten in A
	SET	7,H
	LD	(HL),B
	JPI	ZLVRM1
	INC	HL
	RL	H
	RLA
	RR	H
	LD	(VRAMAD),HL	;beschreiben zyklisch in derselben Page
	LD	A,(STAT5)
	OUT	(PAGE),A
	RET
	
ZLVRM1:	LD	H,A
	INC	HL
	LD	(VRAMAD),HL
	RET
;-----------------------
ZLZSZ:	LD	HL,0400H	;Zeichendefinition nur im aktuellen Zeichensatz
	JPNI	ZLZSZ1
	LD	HL,0800H
ZLZSZ1:	LD	BC,(CHSET)
	ADD	HL,BC
	EX	DE,HL
	LD	HL,EXZSLP
	CALL	RLI
	JP	ZLRET

ZSLEND:	LD	HL,STAT5	;Checksumme bilden
	SET	3,(HL)
	JP	STDRT
;-----------------------
ZLUPR:	LD	HL,USRLP
	LD	DE,USREND
	LD	BC,USRBUF
	CALL	RLI		;Pufferladen mit Ablauf und Grenzkontrolle
	JP	ZLRET
;-----------------------
ZLSTKV:	LD	HL,SKVLP	;Ladepointer auf Stringkonvertierungstabelle
	LD	DE,SKVEND	;Grenze der Stringtabelle
	LD	BC,SKVTAB
	CALL	RLI
	JP	ZLRET

STKVND:	LD	HL,MODUS
	SET	2,(HL)		;STRKVT-Flag
	CALL	MODDSP
	JP	STDRT
;-----------------------
ZLMEL:	LD	HL,MELLP	;Melodiepointer
	LD	DE,MLBEND	;Melodiepuffergrenze
	LD	BC,MELPUF	;Melodiepufferanfang
	CALL	RLI
	JP	ZLRET

MELND:	LD	HL,8A89H	;Melodiezeichen setzen
	LD	DE,MELFLD
	CALL	SMSG
	LD	A,1		;Startsignal an ITIMER Routine
	LD	(MELDAU),A
	JP	STDRT
;-----------------------
ZLSTZL:	LD	HL,ST2LPT
	LD	DE,STL2BF+BLOCKS
	LD	BC,STL2BF
	CALL	RLI
	JP	ZLRET

SLDEND:	LD	HL,STAT2
	SET	2,(HL)
	LD	HL,STAT5	;Checksumme bilden
	SET	3,(HL)
	CALL	STLGEN
	JP	STDRT
;-----------------------
ZLPTCH:	LD	HL,PTCHLP	;SystemPatch
	LD	DE,RAMEND
	LD	BC,RAM		;zyklisch im RAM
	CALL	RLI
	JP	ZLRET
;-----------------------
ZLHRDC:	LD	HL,HRDCLP
	LD	DE,HRDCLN
	LD	BC,HRDCBF
	CALL	RLI
	JP	ZLRET
;-----------------------
ZLSPOL:	LD	(WRKCHR),A
	CALL	VPSUB
	CALL	SPOL		;beim Spooler fuellen bereits ausgeben
ZLSPLA:	LD	HL,SPLLEN	;Spooler voll ?
	LD	BC,(SPLINH)
	SUBHL	BC
	JR	NZ,SPLHRC
	OR	0FFH		;NZ
	RET

SPLHRC:	LD	A,(WRKCHR)
	LD	HL,(SPLINH)	;Spoolerinhalt erhoehen
	INC	HL
	LD	(SPLINH),HL
	LD	HL,SPOLLP
	LD	DE,SPOLND
	LD	BC,SPOLBF

ZLVSET:	PUSH	AF		;Byte in 2. Videopage laden
	SET	7,A
	OUT	(PAGE),A
	IF	NOT XR
	 LD	A,10110000B	;Spooler nur in der Grundebene
	 OUT	(CLRG1),A
	 OUT	(CLRG2),A
	ENDIF
	POP	AF
	CALL	RLI		;Byte eintragen
	CALL	FRBRES
	LD	A,(STAT5)	;auf normale Schreibpage zurueckschalten
	OUT	(PAGE),A
	CP	A
	JP	ZLRET
;-----------------------
RLI:	PUSH	HL		;Zielpufferladeroutine
	PUSH	DE
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	LD	(DE),A
	INC	DE
	POP	HL
	SUBHL	DE
	JR	NZ,RLI1
	LD	D,B
	LD	E,C
RLI1:	POP	HL
	LD	(HL),E
	INC	HL
	LD	(HL),D
	RET
;-----------------------
SPOL:	LD	HL,(SPLINH)	;Routine Spooler im Ablauffeld
	LD	A,H
	OR	L
	RET	Z		;Spooler leer

	CALL	ZLPLZ		;Spoolerverarbeitung
	RET	NZ		;Platz im Zielpuffer ?

	SET	7,A		;auf Spoolerpage umschalten
	OUT	(PAGE),A	;PAGE 1

	LD	HL,(SPOLVP)
	LD	A,(HL)		;Ausgabebyte holen
	PUSH	HL
	CALL	ZLBLD		;zum Zielpuffer
	POP	HL
	LD	DE,1		;Verarbeitungspointer incr.
	ADD	HL,DE
	JR	NC,SPL1
	LD	HL,SPOLBF
SPL1:	LD	(SPOLVP),HL
	LD	HL,(SPLINH)	;Spoolerinhalt decr.
	DEC	HL
	LD	(SPLINH),HL	;zurueckschalten auf write-page

	LD	A,(STAT5)	;auf Arbeitspage zurueckschalten
	OUT	(PAGE),A
	RET
	ENDIF
;-----------------------
KLICK:	LD	A,(STAT5)
	AND	01100000B
	RET	Z		;Klick ist ausgeschaltet
	LD	HL,MELPUF
	LD	DE,(MELVP)
	SUBHL	DE
	RET	NZ

	LD	A,04H		;hoerere Frequenz bei Klick
	OUT	(TBDR),A	;Konstante fuer 5000 Hz
	IN	A,(TABCR)
	AND	0F0H
	OR	7		;Prescale 200
	OUT	(TABCR),A
	CALL	BELLON
	LD	BC,0800H
KLICK1:	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,KLICK1
	JP	MELOFA
;-----------------------	
	IF	EPAGE EQ 0
BELL:	LD	HL,MELPUF
	LD	DE,(MELVP)
	SUBHL	DE
	RET	NZ		;kein Bell bei laufender Melodie

	LD	HL,MELPUF
	LD	DE,(MELLP)
	SUBHL	DE
	JR	Z,BELL3		;wenn Melodiepuffer nicht leer

	LD	HL,8A89H
	LD	DE,MELFLD
	CALL	SMSG
	LD	A,1		;Melodie starten
	LD	(MELDAU),A
	RET

BELL3:	LD	HL,8483H	;Glockenzeichen schreiben
	LD	DE,TONFLD
	CALL	SMSG		;Symboldisplay
	LD	C,3		;2/50 sec.

	LD	A,10
	OUT	(TBDR),A	;Konstante fuer 2000 Hz
	IN	A,(TABCR)
	AND	0F0H
	OR	7		;Prescale 200
	OUT	(TABCR),A

	LD	HL,SEC50	;Synchron zu TIMER Interrupt Ton Starten
	LD	A,(HL)		;fuer gleichmaessigen Bell
BELL4:	CP	(HL)	
	JR	Z,BELL4

	LD	A,C		;Parameter C fuer Dauer
	LD	(MELDAU),A

	ENDIF
BELLON:	LD	A,(STAT5)	;Einsprung von KLICK in INT
	AND	01100000B
	JR	NZ,BELL2
	OR	00100000B	;Mindestlautstaerke fuer Bell
BELL2:	RLA
	OUT	(VOL1),A
	RLA
	OUT	(VOL0),A	;sonst Lautstaerke wie Keyboard-Klick
	RET			;Abschalten durch MELO
;----------------------------
	IF	EPAGE EQ 0
MELO:	LD	HL,0118H	;MELO aus Ablauffeld entfernen
	LD	(HPRTG),HL

	LD	HL,(MELLP)
	LD	DE,(MELVP)
	LD	B,LOW MLBEND
	LD	C,LOW MELPUF
	CALL	BFVA		;1 byte aus Melodiepuffer holen
	JR	Z,MELOFF
	OR	A
	JR	Z,MELOFF
	CALL	FQDEF		;Frequenz bestimmen und Timer starten
	CALL	BFVA		;2. Byte Lautstaerke und Dauer
	JR	Z,MELOFF
	OR	A
	JR	Z,MELOFF	;Tondauer = 0 beendet Melodie

	LD	(MELVP),DE
	JP	LSTDAU		;Lautstaerke und Dauer bestimmen

MELOFF:	LD	HL,2020H	;Notenzeichen loeschen
	LD	DE,MELFLD
	CALL	SMSG
	LD	HL,2020H	;Glockenzeichen loeschen
	LD	DE,TONFLD
	CALL	SMSG
	ENDIF

MELOFA:	XOR	A		;Ton abschalten
	OUT	(VOL1),A
	OUT	(VOL0),A
	IN	A,(TABCR)
	AND	0F0H		;Timer A unberuehrt
	OUT	(TABCR),A	;Timer B Stop
	LD	HL,MELPUF	;Melodiepuffer logisch loeschen
	LD	(MELVP),HL
	RET
;-----------------------
	IF	EPAGE EQ 0
LSTDAU:	LD	B,A
	RLA
	DI
	OUT	(VOL1),A
	RLA
	OUT	(VOL0),A
	LD	A,B
	AND	1FH
	LD	(MELDAU),A
	EI
	RET
;-----------------------
FQDEF:	PUSH	AF
	JPBIT	0,A,NF		;niedrige Frequenz
	IN	A,(TABCR)
	AND	0F0H		;Timer A bleibt unveraendert
	OR	3		;Prescale 16 = 250 kHz (4 MHZ- TAKT)
	OUT	(TABCR),A
	JR	MDAU
NF:	IN	A,(TABCR)
	AND	0F0H
	OR	0FH		;Prescale 200 = 20 kHz
	OUT	(TABCR),A
MDAU:	POP	AF		;Frequenzbyte
	OUT	(TBDR),A	;Lautstaerke noch 0
	RET
;-----------------------
	IF	NOT XR
SETEBN:	LD	A,(EBENE)
SETEBA:	LD	HL,EBNTAB
	AND	00000111B
	SLA	A
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	A,(COLRG1)
	AND	00011111B
	OR	(HL)
	OUT	(CLRG1),A
	INC	HL
	LD	A,(COLRG2)
	AND	00011111B
	OR	(HL)
	OUT	(CLRG2),A
	RET
EBNTAB:	DB	10100000B,10100000B	;Lesen Gerundebene
	DB	01000000B,10000000B	;1.Ebene Karte 1
	DB	11000000B,10000000B	;2.
	DB	00000000B,10000000B	;3.
	DB	10000000B,01000000B	;1.Ebene Karte 2
	DB	10000000B,11000000B	;2.
	DB	10000000B,00000000B	;3.
	DB	01000000B,10000000B	;1. Ebene Karte 1, von 3 Ebenen
	ENDIF
;-----------------------
HRDCOP:	LD	A,(MODUS+1)	;Hardcopy
	AND	11110000B
	CP	00110000B
	RET	NC		;keine Aktion bei ungueltigem Zielkanal

	IF	NOT XR
	 CALL	SETEBN		;Farbebene waehlen fuer Colorkarte
	ENDIF

	LD	A,(HRDCBF)	;Einzelspalte ausgeben oder Gesamthardcopy ?
	JPBITZ	5,A,HRDGES
	LD	A,(DRKSPL)
	CALLB	HRDLIN
	JP	FRBRES
	RET

HRDGES:	LD	A,1		;Gesamthardcopy ab Druckerspalte 1
HRDGS1:	PUSH	AF
	CALLB	HRDLIN
	POP	AF
	INC	A

	LD	HL,HRDCBF+15
	BIT	1,(HL)
	JR	Z,HRDGS2
	LD	C,A
	LDB	B,(TXOFFS)
	INC	B
	SLA	B
	INC	B
	LD	A,C
	SLA	A
	ADD	A,C
	CP	B
	LD	A,C
	JR	C,HRDGS1
	JR	HRDGS3

HRDGS2:	CP	BLOCKS+1	;fertig nach 96 Zeilen
	JR	C,HRDGS1

HRDGS3:	LD	E,CR
	CALL	ESEND
	LD	E,LF
	CALL	ESEND

	JP	FRBRES		;Ebene zuruecksetzen
	RET
	ENDIF			;EPAGE EQ 0
;-----------------------
	IF	EPAGE EQ 1
HRDLIN:	LD	HL,HRDCBF+15	;Eine Hardcopy Druckzeile ausgeben
	BIT	1,(HL)
	JP	NZ,NECQER	;Hardcopy quer fuer NEC P6 ?

	LD	HL,STAT2	;Druckerspalte (A) ausgeben
	RES	4,(HL)

	LD	HL,(DSPST)	;beginne mit letzter Bildschirmzeile
	LD	BC,34*ZLSIZN+7
	JPNI	HRDLI3
	LD	BC,34*ZLSIZI+PITCH+7
HRDLI3:	ADD	HL,BC
	LD	BC,8		;Pointer HL auf gewaehlte Grip-Spalte setzen

HRDLI2:	DEC	A		;A=Spaltennummer
	JR	Z,HRDLI1
	ADD	HL,BC
	JR	HRDLI2

HRDLI1:	CALL	HEADER		;Druckerinitialisierung fuer Graphik

	LDB	B,(TXOFFS)	;jede Spalte besteht aus (TXOFFS) 8*8 Bloecken
	JPNI	HRDEP5
	SLA	B
HRDEP5:	PUSH	BC
	PUSH	HL

	IF	XR
	LD	A,20H		;Bitmodus aktiv
	OUT	(XRFLGS),A
	XRBRES			;reset Bitcounter

	LD	A,(HRDCBF+15)	;bit fuer Graustufenausdruck
	BIT	0,A
	JR	Z,HRDLI6
	CALL	GRBLK		;Hardcopy Block lesen und als Grauwert aussenden
	JR	HRDLI7
	ENDIF

HRDLI6:	CALL	HRDBLK		;Hardcopy Block lesen und aussenden
HRDLI7:	POP	HL
	LD	BC,PITCH	;(HL) auf naechst hoeheren
	SUBHL	BC			;8*8 Block
	POP	BC
	DJNZ	HRDEP5
	IF	XR
	 LD	A,27H		;Maskenmodus aktiv
	 OUT	(XRFLGS),A
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ENDIF
	RET
;-----------------------
HRDBLK:	JPNI	HRDBL3		;HL enthaelt Pointer auf Videoramadresse
	LD	A,H
	OUT	(PAGE),A
HRDBL3:	SET	7,H
	LD	D,8		;8 mal
HRDBL1:	CALL	HRDRDB		;Byte aus Videoram lesen

	LD	A,(HRDCBF)	;muss Byte gespiegelt werden ?
	BIT	7,A
	JR	NZ,HRDBL2	;Sprung wenn nicht gespiegelt
	LD	B,8		;byte von A nach E spiegeln
	LD	A,E
HRDBL4:	RL	A
	RR	E
	DJNZ	HRDBL4

HRDBL2:	LD	A,(STAT3)	;invertieren ?
	JPBITZ	6,A,HRDBL5	;Sprung wenn nein
	LD	A,E
	CPL
	LD	E,A
HRDBL5:	JPI	HRDBL6
	CALLA	ESEND		;soll jeder Punkt zweimal
	LD	A,(HRDCBF)	;ausgegeben werden ?
	JPBITZ	6,A,HRDBL6	;Sprung wenn ja
	LD	E,0		;sonst eine Leerzeile
HRDBL6:	CALLA	ESEND		;um mit interlaced kompatibel zu sein
	LD	A,(HRDCBF)
	JPBITZ	4,A,HRDBL7	;wenn gewuenscht

	LD	A,(STAT2)	;jede zweite Druckerspalte doppelt senden
	XOR	00010000B
	LD	(STAT2),A
	JPBITZ	4,A,HRDBL7
	CALLA	ESEND
HRDBL7:	DEC	HL		;naechsthoehere Pixelzeile
	DEC	D
	JR	NZ,HRDBL1
	RET
;------------------------
	IF	XR
	IF	DEBUG
	DB	'GRBLK'
	ENDIF
GRBLK:	JPNI	GRBLK1		;ein Graublock 8*8 Pixel an Drucker ausgeben
	LD	A,H		;HL enthaelt Pointer auf Videoramadresse
	OUT	(PAGE),A
GRBLK1:	SET	7,H
	LD	D,8		;an jeder Bitposition (8 mal)

GRBLK4:	JPI	GRBLK6
	CALL	GRAUBT		;ein Graubyte ausgeben als 6 byte an Drucker
GRBLK6:	CALL	GRAUBT		;doppelt um mit interlaced kompatibel zu sein
	LD	A,(HRDCBF)
	JPBITZ	4,A,GRBLK7	;wenn gewuenscht

	LD	A,(STAT2)	;jede zweite Druckerspalte doppelt senden
	XOR	00010000B
	LD	(STAT2),A
	JPBITZ	4,A,GRBLK7
	CALL	GRAUBT
GRBLK7:	DEC	HL		;naechsthoehere Pixelzeile
	DEC	D
	JR	NZ,GRBLK4
	RET
;---------------------------------
GRAUBT:	PUSH	DE
	LD	DE,GRAUBF
	LD	B,2
GRAUB8:	PUSH	BC
	PUS	HL
	PUSH	DE

	LD	B,4
GRAUB2:	LD	C,(HL)		;lade Byte aus Video-Ram
	XRBIT			;Bitcounter increment
	
	LD	A,(STAT3)	;invertieren ?
	JPBITZ	6,A,GRAUB5	;Sprung wenn nein
	LD	A,C
	CPL
	LD	C,A
GRAUB5:	PUSH	BC		;Spraydichte berechnen
	CALLA	INISPR
	CP	C
	RL	E
	CALLA	INISPR
	CP	C
	RL	E
	CALLA	INISPR
	CP	C
	RL	D
	CALLA	INISPR
	CP	C
	RL	D
	POP	BC
	DJNZ	GRAUB2

	POP	HL
	LD	(HL),E
	INC	HL
	LD	(HL),D
	INC	HL
	EX	DE,HL
	POP	HL
	POP	BC
	DJNZ	GRAUB8

	LD	A,(GRAUBF)	;je 3 byte pro Druckerspalte senden 24 Nadelmodus
	LD	E,A
	CALLA	ESEND
	LD	A,(GRAUBF+2)
	LD	E,A
	CALLA	ESEND
	LD	E,0		;Nadel 17-24 sind 0
	CALLA	ESEND
	LD	A,(GRAUBF+1)
	LD	E,A
	CALLA	ESEND
	LD	A,(GRAUBF+3)
	LD	E,A
	CALLA	ESEND
	LD	E,0
	CALLA	ESEND
	POP	DE
	RET
	ENDIF
;----------------------------
HRDRDB:	IF	XR
	LD	A,(EBENE)	;Byte fuer Hardcopy aus Videoram lesen nach E-register
	OR	A
	JR	NZ,HRDXR1
	LD	A,10H		;lese von Grundebene
	OUT	(XRFLGS),A
	LD	E,(HL)
	RET

HRDXR1:	LD	B,8		;extrahiere aus 8 Bildbytes jeweils ein Bi
	XRBRES			;$$$ not necessary if Bitcounter reliable
HRDXR2:	LD	A,(EBENE)
	CP	9
	JR	C,HRDXR5	;wenn Ebene > 8 dann Kontrastausdruck
	LD	A,(HRDKTR)
	SUB	(HL)		;carry ist gesetzt wenn Bildbyte > KONTRAST
	JR	HRDXR6

HRDXR5:	LD	C,(HL)		;lese im Bitmodus aus XR-Karte
HRDXR3:	SRL	C		;extrahiere ein Bit aus Farbwert = Farb Ebene
	DEC	A
	JR	NZ,HRDXR3
HRDXR6:	RR	E
	XRBIT			;increment XR Bitcounter
	DJNZ	HRDXR2
	RET			;Ergebnis in E

	ELSE
	LD	A,(EBENE)	;Read byte from VideoRAM for Hardcopy
	CP	9
	JR	NC,HRDRD1	;EBENE > 9 ist alle Ebenen verodern
	LD	E,(HL)
	RET

HRDRD1:	LD	A,10101111B	;lese Grundebene
	OUT	(CLRG1),A
	LD	E,(HL)
	LD	A,01001111B
	OUT	(CLRG1),A	;lese 1. Ebene
	LD	A,(HL)
	OR	E
	LD	E,A
	LD	A,11001111B	;lese 2. Ebene
	OUT	(CLRG1),A	
	LD	A,(HL)
	OR	E
	LD	E,A
	LD	A,00001111B	;lese 3.Ebene
	OUT	(CLRG1),A
	LD	A,(HL)
	OR	E
	LD	E,A
	LD	A,(COLRG1)	;normale Farbe wiederherstellen
	OUT	(CLRG1),A
	RET
	ENDIF
;------------------------------------------------------------
; Hardcopy Druckzeile quer fuer NEC P6 ausgeben
;------------------------------------------------------------
NECQER:	LD	HL,(DSPST)	;beginne mit Bildschirmzeile A
	JPI	NECQE3
NECQE4:	DEC	A
	JR	Z,NECQE1
	LD	BC,PITCH+4
	ADD	HL,BC
	DEC	A
	JR	Z,NECQE1
	LD	BC,2*PITCH-4
	ADD	HL,BC
	JR	NECQE4

NECQE3:	LD	BC,3*PITCH	;eine Drueckzeile entspricht 3 Bildzeilen 24*8 Pixel
NECQE2:	DEC	A		;A=Spaltennummer
	JR	Z,NECQE1
	ADD	HL,BC
	JR	NECQE2

NECQE1:	CALL	HEADER		;Druckerinitialisierung fuer Graphik

	LD	B,96		;jede Zeile besteht aus 96 24*8 Bloecken
NECQE5:	PUSH	BC
	PUSH	HL

	IF	XR
	LD	A,20H		;Bitmodus aktiv
	OUT	(XRFLGS),A
	XRBRES			;reset Bitcounter
	ENDIF

	CALL	NECBLK		;gibt ein 24*8 Block aus

	POP	HL
	LD	BC,8		;(HL) auf naechst hoeheren
	ADD	HL,BC		;8*8 Block
	POP	BC
	DJNZ	NECQE5

	IF	XR		;Ende der Druckzeile erreicht, 96 Bloecke sind ausgegeben
	 LD	A,27H		;Maskenmodus aktiv
	 OUT	(XRFLGS),A
	 LD	A,(XRRD)
	 OUT	(XRFLGS),A
	ENDIF
	RET
;--------------------------
NECBLK:	LD	D,8		;8 mal 24 Pixels
NECBL4:	PUSH	HL
	LD	B,3		;3 Byte
NECBL2:	PUSH	HL
	JPNI	NECBL3		;gibt ein 24*8 Pixelblock an Drucker aus
	LD	A,H		;HL enthaelt Pointer auf Videoramadresse
	OUT	(PAGE),A
NECBL3:	SET	7,H

	CALL	NECRDB		;Byte quer aus VideRAM lesen

	LD	A,(STAT3)	;invertieren ?
	JPBITZ	6,A,NECBL1	;Sprung wenn nein
	LD	A,E
	CPL
	LD	E,A
NECBL1:	LD	A,E
	CALLA	ESEND		;an Drucker senden

	POP	HL
	PUSH	BC
	JPI	NECBL5
	BIT	2,L
	JR	NZ,NECBL6
	LD	BC,4
	JR	NECBL7
NECBL6:	LD	BC,PITCH-4
	JR	NECBL7

NECBL5:	LD	BC,PITCH	;Videorampointer auf naechte Bildzeile setzen
NECBL7:	ADD	HL,BC
	POP	BC
	DJNZ	NECBL2

	POP	HL
	DEC	D		;naechste Pixelspalte
	JR	NZ,NECBL4
	RET
;-----------------------
NECRDB:	IF	XR		;Byte aus Videoram quer auslesen Pixelspalte in D
	LD	A,(EBENE)
	OR	A
	JR	NZ,NECXR1
	LD	A,10H		;lese von Grundebene
	OUT	(XRFLGS),A

	PUSH	BC
	LD	B,8
NECRD3:	PUSH	DE
	LD	A,(HL)
NECRD1:	SLA	A		;ein Bit davon extrahieren
	DEC	D
	JR	NZ,NECRD1
	RL	C		;Bit nach Register C
	JPI	NECRD2
	LD	A,C
	SRL	A
	RL	C		;non interlaced jede Pixelzeile doppelt
	DEC	B
NECRD2:	POP	DE
	INC	HL		;naechste Pixelzeile
	DEC	B
	JR	NZ,NECRD3
	LD	E,C		;Ergebnis nach E
	POP	BC
	RET

NECXR1:	PUSH	BC

	LD	B,8		;extrahiere aus 8 Bildbytes jeweils ein Bi
	XRBRES
NECXR8:	PUSH	DE
	LD	A,8
NECXR7:	CP	D
	JR	Z,NECXR2
	INC	D
	XRBIT			;XR Bitcounter vorruecken auf Bitpositin D
	JR	NECXR7

NECXR2:	POP	DE

NECXR9:	PUSH	DE
	LD	A,(EBENE)
	CP	9
	JR	C,NECXR5	;wenn Ebene > 8 dann Kontrastausdruck
	LD	A,(HRDKTR)
	SUB	(HL)		;carry ist gesetzt wenn Bildbyte > KONTRAST
	JR	NECXR6

NECXR5:	LD	D,A
	LD	A,(HL)		;lese im Bitmodus aus XR-Karte
NECXR3:	SRL	A		;extrahiere ein Bit aus Farbwert = Farb Ebene
	DEC	D
	JR	NZ,NECXR3
NECXR6:	RL	C		;Bit nach Register C
	JPI	NECXR4
	LD	A,C
	SRL	A
	RL	C		;non interlaced jede Pixelzeile doppelt
	DEC	B
NECXR4:	POP	DE
	INC	HL		;naechste Pixelzeile
	DEC	B
	JR	NZ,NECXR9
	LD	E,C
	POP	BC
	RET

	ELSE			;NOT XR
	PUSH	BC
	LD	B,8
NECRD3:	PUSH	DE
	CALL	HRDRDB		;Byte lesen von Grundebene oder COLOR-karte
	LD	A,E
NECRD1:	SLA	A		;ein Bit davon extrahieren
	DEC	D
	JR	NZ,NECRD1
	RL	C		;Bit nach Register C
	JPI	NECRD2
	LD	A,C
	SRL	A
	RL	C		;non interlaced jede Pixelzeile doppelt
	DEC	B
NECRD2:	POP	DE
	INC	HL		;naechste Pixelzeile
	DEC	B
	JR	NZ,NECRD3

	LD	E,C		;Ergebnis nach E
	POP	BC
	RET
	ENDIF		;XR
;-------------------------
	IF	DEBUG
HLOUT:	PUSH	AF
	LD	A,H
	CALL	AOUT
	LD	A,L
	CALL	AOUT
	LD	A,' '
	CALL	DRKOUT
	POP	AF
	RET
;---------------------
AOUTS:	PUSH	AF
	CALL	AOUT
	LD	A,' '
	CALL	DRKOUT
	POP	AF
	RET
;---------------------
AOUT:	PUSH	AF
	SRL	A
	SRL	A
	SRL	A
	SRL	A
	CALL	DIGOUT
	POP	AF
	PUSH	AF
	CALL	DIGOUT
	POP	AF
	RET
;------------------
DIGOUT:	AND	0FH
	OR	30H
	CP	3AH
	JR	C,HEXOU1
	ADD	A,7
HEXOU1:	JP	DRKOUT
;-----------------
DRKOUT:	PUSH	AF
DRKOU1:	IN	A,(GPIP)	;Centronix Ausgabe
	AND	00001000B	;Busy ?
	JR	NZ,DRKOU1	;bei NZ, warten
	POP	AF
	OU	(CNTRX),A
	OUT	(CXSTB),A
	XOR	A
	OUT	(STR),A
	LD	A,0FFH
	OUT	(STR),A
	RET
	ENDIF		;DEBUG
;-----------------------
HEADER:	PUSH	HL
	LD	HL,HRDCBF	;1.Haelfte Graphik und LF
	LD	A,(HL)
	AND	0FH		;maskiere obere 4 bits
	LD	B,A
HEAD2:	INC	HL
	LD	E,(HL)
	CALLA	ESEND
	DJNZ	HEAD2
	POP	HL
	RET
	ENDIF	;EPAGE 1
;-----------------------
	IF	EPAGE EQ 0
ESEND:	PUSH	HL
	PUSH	DE
	PUSH	BC
	JPI	ESEND1		;Sende Inhalt von E zum Zielkanal
	LD	A,(STAT1)
	BIT	1,A		;Hardcopy ueber Spooler ?
	JR	Z,ESEND1

	LD	HL,RETURN		;normal RET from ZLSPLA
	LD	(ZLRET+1),HL
ESEND2:	PUSH	DE
	CALL	SPOL		;Spooler soll bereits ausgeben
	POP	DE
	LD	A,E
	LD	(WRKCHR),A
	CALL	ZLSPLA		;byte in Spooler eintragen
	JR	NZ,ESEND2	;nochmals Versuch Byte in Spooler einzutragen
	JR	ESEND3

ESEND1:	PUSH	DE
ESEND4:	CALL	ZLPLZ		;Platz im Zielpuffer ?
	JR	NZ,ESEND4
	POP	DE

	LD	A,E
	CALL	ZLBLD		;Byte ausgeben
ESEND3:	POP	BC
	POP	DE
	POP	HL
RETURN:	RET
;-----------------------
	IF	XR
COLMOD:	LD	HL,MODUS
	LD	B,00000001B	;XR-1 selektieren
	JPBIT	7,(HL),COLMO1
	LD	B,00001000B
COLMO1:	CALLB	XRSELA
	RET

	ELSE
COLMOD:	LD	HL,MODUS
	JPBIT	7,(HL),COLMO1
	LD	H,00010000B
	JR	COLMO2
COLMO1:	LD	H,00001000B
COLMO2:	LD	A,(COLRG1)	;TVI TTX Farb oder Gundmodus waehlen
	AND	11100111B
	OR	H		;H uebergibt OR Maske
	LD	(COLRG1),A
	OUT	(CLRG1),A
	LD	A,(COLRG2)
	AND	11100111B
	OR	H
	LD	(COLRG2),A
	OUT	(CLRG2),A
	RET
	ENDIF
;----------------------
	IF	XR
TXFARB	EQU	$
TTXI:	LD	A,(STAT1)
	SET	7,A
	LD	(STAT1),A

	ELSE
TXFARB:	LD	HL,MODUS	;Farbmodus Bit setzen
	SET	7,(HL)
	JR	TTXENT

TTXI:	LD	HL,MODUS	;Grundmodus
	RES	7,(HL)
TTXENT:	LD	A,(STAT1)
	SET	7,A
	LD	(STAT1),A
	CALL	COLMOD		;Colormodus einstellen aus MODUS
	ENDIF

	LD	A,(ZWZL)
	LD	C,A
	AND	0F0H		;8 Zeilen setzen
	OR	08H
	CP	C		;Schon vorher 8 Zeilen?
	JR	Z,TTXEN1
	CALL	SETZWA
	CALL	INIVDC

TTXEN1:	LD	HL,TXCHR	;TTX Kommandotabellen aktivieren
	LD	(ESCCHR),HL
	LD	HL,TXESC	;=TXKOM
	LD	(ESCTAB),HL
	LD	HL,TXKOM
	LD	(KOMTAB),HL
	LD	A,LTXCHR
	LD	(LESCCH),A

	CALL	INITXN
	CALLB	TBWSET
	CALL	STLGEN
	CALL	LTYPVL		;Durchgezogene Linien
	CALL	ORFKT		;Write-Mode
	LD	A,0C3H		;JP-Befehl
	LD	(MOVL),A
	LD	(MOVH),A
	LD	HL,STAT4
	RES	4,(HL)		;Cursor aus
	RES	2,(HL)
	JP	VKTMOD		;Vektormodus aktivieren mit neuem Master
;-----------------------
INITXN:	CALL	SETDSP		;Sichtbare Zeilen setzen
	LD	HL,(DSPST)
	LD	BC,(ZLSIZE)
	LD	A,(TXOFFS)
	AND	00111111B
	JR	NZ,INITX2
	INC	A
INITX2:	ADD	HL,BC
	DEC	A
	JR	NZ,INITX2
	LD	BC,-ZLSIZN+7
	ADD	HL,BC
	LD	(TXNULL),HL
	SETNI	7,H
INIPOS:	LD	(GCPOS),HL
INIMSK:	LDB	(GCMSK),01H
	RET
;-----------------------
	IF	XR
TVICOL	EQU	$
TVISTD:	LD	A,(STAT1)	;TTX Bit ruecksetzen
	RES	7,A
	LD	(STAT1),A

	ELSE
TVICOL:	LD	HL,MODUS
	SET	7,(HL)
	JR	TVIENT

TVISTD:	LD	HL,MODUS	;TVI-Standard Mode eintragen
	RES	7,(HL)
TVIENT:	LD	A,(STAT1)	;TTX Bit ruecksetzen
	RES	7,A
	LD	(STAT1),A
	CALL	COLMOD
	ENDIF

	CALL	SETZWZ		;Zeilen normal setzen
	LD	A,(ZWZL)
	AND	0FH
	CP	8
	CALL	NZ,INIVDC
	CALL	NRMVDC
	CALL	SETDSP		;sichtbare Zeilen setzen
	CALL	CHOME
	CALL	CURRD
	CALL	URLOE
	LD	HL,STESCH	;ESC-Table
	LD	(ESCCHR),HL
	LD	A,LSTECH	;Laenge
	LD	(LESCCH),A
	LD	HL,STDESC	;ESC ESC-Table
	LD	(ESCTAB),HL
	LD	HL,STDTAB
	LD	(KOMTAB),HL
	LD	HL,EXHBF
	LD	(MASTER),HL	;TVI-Masterprogramm aktivieren
	LD	(HAUPT+1),HL
	LDB	(WTFLG),0
	CALLB	TBWSET
	CALL	STLGEN
	LD	HL,STAT4
	SET	4,(HL)		;Cursor sichtbar
	RET
;----------------------
STLINE:	CALL	VPSUB		;<EES>
	CALL	HBINPR
	RET	Z
	PUSH	AF
	CALL	URLOE		;Rest loeschen
	POP	AF
	CALL	STLINA
	CALL	NRMVDC
	JP	STDRT
;-----------------------
STLAUS:	XOR	A
STLINA:	AND	00000011B	;Statuszeilen an/ausschalten
	SLA	A
	LD	B,A
	LD	A,(STAT2)
	LD	C,A
	AND	11111001B
	OR	B
	LD	(STAT2),A	;Bits in Stat2 neu setzen
	XOR	C

	JPBITZ	1,A,STLIN6	;Statuszeile 1 blieb gleich

	PUSH	AF
	JPBIT	1,C,STLIN2	;bei Statuszeile jetzt an
	LD	HL,(ZLSIZE)	;Cursor Home Position in 2. Zeile legen
	ADD	HL,HL
	JPI	STLIN4
	LD	A,(CZL2)
	SUB	2
	JR	NC,STLIN7
	XOR	A
STLIN7:	LD	(CZL2),A

STLIN4:	LD	A,(CZL)
	SUB	2		;Zeilennummer -2	
	JR	NC,STLI10
	XOR	A		;oder 0
STLI10:	LD	(CZL),A
	JR	STLIN3

STLIN2:	LD	HL,(ZLSIZE)	;wenn Statuszeile 1 jetzt aus
	ADD	HL,HL
	LD	B,H
	LD	C,L
	CALL	LOE		;Statuszeilenbereich loeschen
	LD	HL,0		;HOME ganz oben links
	JPI	STLIN9
	LD	A,(CZL2)
	ADD	A,2
	LD	B,A
	LD	A,(ZLANZ)
	DEC	A
	CP	B
	JR	C,STLIN8
	LD	A,B
STLIN8:	LD	(CZL2),A	
STLIN9:	LD	A,(CZL)		;Cursorzeilennummer um 2 erhoehen
	ADD	A,2
	LD	B,A
	LD	A,(ZLANZ)
	DEC	A
	CP	B
	JR	C,STLIN3
	LD	A,B
	LD	(CZL),A
STLIN3:	LD	(DSPANF),HL
	LD	(DSPAN2),HL
	CALL	CURADR


	LD	A,(STAT2)	;wenn 2.Statuszeile an, voruebergehend ausschalten
	JPBITZ	2,A,STLIN5
	CALL	ST2LOE

STLIN5:	POP	AF
STLIN6:	JPBITZ	2,A,STLIN1	;hat 2.Statuszeile sich geaendert ?
	CALL	ST2LOE

STLIN1:	CALL	ST2POS		;2.Statuszeile Position berechnen
	CALL	SETDSP
	JP	STLGEN		;Statuszeilen neu generieren
;-----------------------
ST2LOE:	LD	HL,(DSPST)
	LD	BC,(SL2FLD)
	ADD	HL,BC
	LD	BC,(ZLSIZE)
	JP	LOE1
;-----------------------
ST2POS:	LD	HL,(DSPANF)
	LD	A,(ZLANZ)
	LD	BC,(ZLSIZE)
ST2PO1:	ADD	HL,BC
	DEC	A
	JR	NZ,ST2PO1
	LD	(SL2FLD),HL
	RET
;-----------------------
ITLCHG:	CALL	VPSUB		;<EEr>
	CALL	HBINPR
	RET	Z
	CALL	STDRT
	AND	00000001B
ITLCHA:	LD	HL,ITLFLG
	CP	(HL)
	RET	Z		;keine Umschaltung wenn Modus gleichgeblieben
	PUSH	AF
	CALL	INIVID
	POP	AF
	LD	(ITLFLG),A
	CALL	INIITL
	CALL	STLGEN
	CALLB	JPCHKS		;Checksumme bilden
	LD	(CHKSJP),BC
	RET
;-----------------------
MONTST:	CALL	BCLEAR		;<EEQ>
	JPNI	MONTS2
	LD	A,BLOCKS
	LD	(SPCNT),A
MONTS2:	LD	DE,(DSPST)	;Monitortestbild ausgeben
	LD	BC,15*BLOCKS+100H
	CALL	PLUS

	LD	HL,VZSATZ	;512 Zeichen Zeichensatz abbilden
	LD	BC,256
	JPI	MONTS1
	LD	BC,512
MONTS1:	PUSH	BC
	LD	BC,8
	CALL	CHWRI
	POP	BC
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,MONTS1

	LD	BC,14*BLOCKS+64+256+100H	;Restschirm
	JPI	MONTS3
	LD	BC,14*BLOCKS+64+100H
MONTS3:	CALL	PLUS
	JP	STLGEN
;-----------------------
PLUSTB:	DB	0FFH,81H,81H,81H,81H,81H,81H,0FFH
PLSTBI:	DB	0FFH,0FFH,81H,81H,81H,81H,81H,81H,81H,81H,81H,81H,81H,81H,0FFH,0FFH
;-----------------------
PLUS:	LD	HL,PLUSTB		;33 Zeilen + Zeichen generieren
	JPNI	PLUS1
	LD	HL,PLSTBI
PLUS1:	PUSH	BC
	LD	BC,8
	CALL	CHWRI
	POP	BC
	DEC	C
	JR	NZ,PLUS
	DJNZ	PLUS
	RET
;-----------------------
CHWRI:	JPI	CHWRI1
	CALL	CHRWRT
	SET	7,D
	RET

CHWRI1:	CALL	CHRWTI
	EX	DE,HL		;DE auf naechste Spalte vorruecken
	LD	BC,PITCH-8
	SUBHL	BC
	EX	DE,HL
	LD	A,(SPCNT)	;Spaltenzaehler
	DEC	A
	LD	(SPCNT),A
	RET	NZ
	LD	A,BLOCKS
	LD	(SPCNT),A
	EX	DE,HL
	LD	BC,PITCH
	ADD	HL,BC
	EX	DE,HL
	RET
;-----------------------
LPEN:	CALL	VPSUB		;Lichtgriffelregister abfragen
	CALL	HBPLZ
	RET	NZ
	IN	A,(STATR)
	LD	C,A
	AND	0FH		;unterste 4 Bit bleiben
	LD	B,A
	LD	A,C
	SRL	A		;Jumperinf. uebershiften
	SRL	A
	AND	0F0H
	OR	B		;4 unterste Bits wiedereinsetzen
	SET	7,A		;8. bit zur Unterscheidung von Keyboarddaten
	CALL	HBFLD		;zum Hostausgabepuffer
	CALL	VPSUB
	CALL	HBPLZ
	RET	NZ
	LD	A,10H		;Ermittlung der Lichtgriffeladresse
	CALL	VDCRHL
	LD	A,H
	AND	0FH		;s.u.
	LD	H,A		;LPEN-Reg.HWB
	LD	DE,(VDCST)
	LD	A,D
	AND	1FH		;nur unterste 4 Bits des HWB relevant
	JPI	LPEN2
	AND	0FH
LPEN2:	LD	D,A
	SUBHL	DE			;Distanz zum Displayanfang
	CALL	BETRAG
ZLE:	LD	BC,BLOCKS	;Ermittlung der Zeile
	XOR	A
ZLL:	SUBHL	BC
	JR	C,SPE
	INC	A
	JR	ZLL
SPE:	ADD	HL,BC		;Divisionsrest ergibt Spaltenadresse
	PUSH	HL		;Spalte in L sichern
	ADD	A,0A0H		;Reihe 20H-42H
	CALL	HBFLD		;Reihenadresse aendern
LPEN1:	CALL	HBPLZ
	JR	NZ,LPEN1
	POP	HL
	LD	A,L
	ADD	A,0A0H		;Spalte 20H-7FH
	CALL	HBFLD		;Spaltenadresse ausgeben
	OUT	(LRS),A		;Lichtgriffel scharf
	JP	STDRT
;-----------------------
UHR?:	CALL	VPSUB	;Uhrzeit aussenden als 3 byte mit 8.bit gesetzt
	CALL	HBPLZ	;zur Unterscheidung von Keyboard Daten
	RET	NZ
	LD	A,(STD)
	ADD	A,0A0H
	CALL	HBFLD
	CALL	VPSUB
	CALL	HBPLZ
	RET	NZ
	LD	A,(MIN)
	ADD	A,0A0H
	CALL	HBFLD
	CALL	VPSUB
	CALL	HBPLZ
	RET	NZ
	LD	A,(SEC)
	ADD	A,0A0H
	CALL	HBFLD
	JP	STDRT
;-----------------------
USRRNB:	LD	HL,STAT2
	SET	0,(HL)
	JR	USRRN2
USRRUN:	LD	HL,STAT2
	RES	0,(HL)
USRRN2:	LD	HL,STAT2
	JPBITZ	0,(HL),PUSREX
	CALL	VPSUB
	CALL	HBINPR
	RET	Z
	JR	USRRN3

PUSREX:	CALL	VPSUB		;Userprogramm starten
	CALL	HBINH
	CP	2
	RET	C
	CALL	HBPLZ
	CP	2
	RET	C
	CALL	HBFRD
	PUSH	AF
	CALL	HBFRD
	POP	HL
	LD	L,A
	CALL	GET
USRRN3:	CALL	USRBUF		;Userprogramm in USRBUF
	LD	IX,RESDAT	;falls durch UP zerstoert
	EI
	LD	HL,STAT2
	JPBIT	0,(HL),USRRN4
	LD	(OUTCHR),A
	CALL	VPSUB
	CALL	HBFLDH
	RET	NZ
USRRN4:	JP	STDRT
;-----------------------
SETUZS:	CALL	VPSUB
	CALL	HBINPR		;setze Ladepointer fuer ext. Zeichensatz
	RET	Z		;auf Zeichen in VZSATZ im 8k Ram
	LD	B,0
	SLA	A
	RL	B
	SLA	A
	RL	B
	SLA	A
	RL	B
	JPNI	SETUZ2
	SLA	A
	RL	B
SETUZ2:	LD	C,A
	LD	HL,(CHSET)
	ADD	HL,BC
	LD	(EXZSLP),HL
	LD	A,(MODUS+1)	;wenn Quellkanal Userzeichensatz
	AND	0FH		;Quellpointer sofort neu setzen
	CP	4
	JR	NZ,SETUZ1
	LD	(QULVP),HL
SETUZ1:	JP	STDRT
;-----------------------
MONAPS:	CALL	VPSUB		;<EE9> Monitoranpassung
	CALL	HBINPR
	RET	Z		;bei Erfolg A in WRKCHR
	LD	(MONITR),A
	CALL	SETMON
	JP	CHKRT
;-----------------------
SETMON:	LD	A,(MONITR)
	LD	D,A
	LD	A,(VDCR-8)	;Interlace Register
	AND	11111110B
	RL	D
	RL	D
	ADC	A,0		;Bit 6(D) -> Bit 0(A)
	LD	C,8		;Pseudo-Interlace
	FLAG	0,ITLFLG
	CALL	Z,VDCWRA
	LD	HL,TBSYNC
	CALL	VDCP
	LD	A,(HL)
	LD	C,3		;Register 3
	CALL	VDCWRA

	LD	HL,TBHOR
	CALL	VDCP
	LD	A,(VDCR-2)
	ADD	A,(HL)
	LD	C,2
	CALL	VDCWRA

	LD	HL,TBVER
	CALL	VDCP
	LD	A,(VDCR-7)
	ADD	A,(HL)
	LD	C,7
	JP	VDCWRA

VDCP:	LD	BC,0
	RL	D
	RL	C
	RL	D
	RL	C
	ADD	HL,BC
	RET

TBVER:	DB	+1,0,-1,-2
	IF	HD6345
TBHOR:	 DB	+2,0,-2,-4
TBSYNC:	 DB	12H,33H,66H,0CCH
	ELSE
TBHOR:	 DB	+3,0,-2,-4
TBSYNC:	 DB	0,5,10,15
	ENDIF
;-----------------------
SCRFRM:	CALL	VPSUB		;<EE8> Zeilen x Spaltenformat waehlen
	CALL	HBINH
	CP	2
	RET	C

SCRFR2:	CALL	HBFRD
	SUB	20H
	INC	A
	LD	E,A
	LD	A,1
	JR	C,SCRFR1	;<1
	LD	A,VBLMAX	;Zeilen-Maximum
	CP	E
	JR	C,SCRFR1	;>=VBLMAX
	LD	A,E
SCRFR1:	LD	DE,(ZLANZ)
	LD	(ZLANZ),A
	CP	E
	JR	C,SCRFR7
	LD	A,E
SCRFR7:	CALL	ULOE		;Ab ZLANZ-Minimum loeschen
	LD	A,(ZLANZ)
	DEC	A
	LD	E,A
	LD	A,(CZL)
	CP	E		;Cursor zu tief?
	JR	C,SCRFR6
	LDB	(CZL),E		;Dann Cursorzeile = Maxzeile
SCRFR6:	CALL	PCR
	JPI	SCRFR4
	XOR	A
	LD	(CSP2),A	;Home in Page 2
	LD	(CZL2),A

SCRFR4:	CALL	HBFRD
	SUB	20H		;maximal 96 Spalten pro Zeile
	LD	B,A
	LD	A,1
	JR	C,SCRFR3
	LD	A,B
	INC	A
SCRFR3:	LD	(SPANZ),A
	CALL	ST2POS		;Position der 2.Statuszeile berechnen
	CALL	STLGEN		;Statuszeile 2 unter Textfeld setzen
	CALL	SETDSP
	JP	STDRT
;-----------------------
SETDSP:	CALL	GETVBL		;Sichtbare Zeilen anzeigen
	IF	HD6345
	 JPNI	SETDS1
	 ADD	A,A		;Zeilen verdoppeln
	ENDIF
SETDS1:	LD	HL,VDCR-4
	CP	(HL)		;Zeilen <= Total?
	JP	C,SETDS2
	LD	A,(HL)
SETDS2:	LD	(VDCR-6),A
	SETRA	6		;Displayed Rows neu setzen
	RET
;-----------------------
ZSZDEF:	CALL	VPSUB		;Zeichensatz waehlen
	CALL	HBINPR
	RET	Z
	CALLB	ZSZDFB
	JP	CHKRT
;------------------------
SETPXZ:	CALL	VPSUB		;<EE6> Anzahl der Pixelzeilen pro Zeichen
	CALL	HBINPR		;plus Smooth Scroll
	RET	Z
	LD	(ZWZL),A
	CALL	SETZWZ
	CALL	SCROFA
	CALL	INIVDC
	JP	CHKRT
;-----------------------
SETZWZ:	LD	A,(ZWZL)
SETZWA:	LD	HL,VDCR31
	RES	3,(HL)		;RI Flag
	LD	HL,VDCI
	JPI	SETPX
	LD	HL,VDC7
	BIT	4,A		;Double Size?
	JR	NZ,SETZW2	;nein
	LD	HL,VDCR31
	SET	3,(HL)		;RI Flag
	LD	HL,VDC7DS
SETZW2:	AND	00001111B	;ZWZ 7-11
	CP	7
	RET	C
	CP	12
	RET	NC
	LD	BC,VDC8-VDC7
	SUB	7
SETZW1:	JR	Z,SETPX
	ADD	HL,BC
	DEC	A
	JR	SETZW1

SETPX:	LD	BC,3
	LD	DE,VDCR-11
	LDIR		;R11,10,9 laden
	INC	DE	;R8 ueberspringen
	LDI		;R7 laden
	INC	DE	;R6 ueberspringen
	LDI		;R5
	LDI		;R4
	JP	SETDSP

		;-> VDCR 11,10,9,7,5,4
VDC7:	DB	6,6,6,VBLKS,4,43
VDC8:	DB	7,7,7,VBLKS,0,38
VDC9:	DB	8,8,8,VBLKS-4,6,33
VDC10:	DB	9,9,9,VBLKS-7,2,30
VDC11:	DB	10,10,10,VBLKS-10,4,27
	IF	HD6345
VDCI:	 DB	6,6,6,VBLKS*2,4,38*2
VDC7DS:	 DB	6,6,6,20,2,21
VDC8DS:	 DB	7,7,7,18,4,18
VDC9DS:	 DB	8,8,8,16,3,16
VDC10DS: DB	9,9,9,14,6,14
VDC11DS: DB	10,10,10,13,2,13
	ELSE
VDCI	 EQU	VDC8
VDC7DS	 EQU	VDC7
	ENDIF
;-----------------------
DRKDEF:	CALL	VPSUB		;definiere Hardcopy-Geraet
	CALL	HBINPR
	RET	Z
	CALL	STDRT
	CP	'0'
	JR	NC,DRKDF1
	CP	'!'
	JR	NZ,DRKDF2
	LD	A,(DRKSPL)
	INC	A
	CP	96+1
	JR	C,DRKDF3

DRKDF2:	LD	A,1
DRKDF3:	LD	(DRKSPL),A
	RET

DRKDF1:	LD	(HRDDRK),A

SETDFB:	LD	A,(HRDDRK)
	AND	00000111B
	CP	6
	RET	NC
	LD	B,0
	SLA	A
	SLA	A
	SLA	A
	SLA	A
	LD	C,A
	LD	HL,DRKTAB
	LD	DE,HRDCBF
	ADD	HL,BC
	LD	BC,16
	LDIR
	RET

DRKTAB:	DB	09,ESC,'J',18H,CR,ESC,'*',5	;0 = Epson
	DW	560
	DB	0,0,0,0,0,0
	DB	08,ESC,'J',10H,CR,ESC,'L'	;1 = Gemini
	DW	560
	DB	0,0,0,0,0,0,0
	DB	9+80H,CR,LF,ESC,'[0560y'	;2 = Siemens PT 88
	DB	0,0,0,0,0,0
	DB	09,ESC,'J',18H,CR,ESC,'*',0	;3 = NEC P6/P7
	DW	560
	DB	0,0,0,0,0,0
	DB	09,ESC,'J',10H,CR,ESC,'*',39	;4 = NEC P6/P7 Graustufenausdruck
	DW	2*560
	DB	0,0,0,0,0,1			;Bit 0 Graustufenausdruck
	DB	14,ESC,'J',18H,CR,'     ',ESC,'*',39	;5 = NEC P6/P7 quer
	DW	768
	DB	2			;Bit 1 quer
;-----------------------
SPLDEF:	CALL	VPSUB		;<EE5> Spoolerzuordnung definieren
	CALL	HBINPR		;warte auf Eingabe
	RET	Z
	JPI	STDRT		;nicht in Interlaced moeglich
	AND	00000111B	;Eingabe von '0'-'6' erlaubt
	SLA	A
	LD	C,A
	LD	B,0
	LD	HL,SPADTB
	ADD	HL,BC
	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A
	JP	(HL)

SPADTB:	DW	SPLAD0,SPLAD1,SPLAD2,SPLAD3,SPLAD4,CHGPAG,RAMCHG,STDRT

SPLAD0:	CALL	SPLON
	CALL	WRTPG1
	CALL	SCRON
	JP	STDRT

SPLAD1:	CALL	SPLON
	CALL	WRTPG1
	CALL	SCROFF
	JP	STDRT

SPLAD2:	CALL	SPLOFF
	CALL	WRTPG1
	CALL	SCROFF
	JP	STDRT

SPLAD3:	CALL	SPLOFF
	CALL	WRTPG1
	CALL	SCRON
	JP	STDRT

SPLAD4:	CALL	SPLOFF
	CALL	WRTPG2
	CALL	SCRON
	JP	STDRT

CHGPAG:	LD	A,(STAT5)	;Schreibpage wechseln lassen
	LD	B,A
	CALL	WRTPG
	CALL	SCROFA
	LD	A,(STAT3)	;Anzeigepage wechseln
	XOR	80H
	LD	(STAT3),A
	OUT	(DPAGE),A
	LD	HL,(VDCST)	;jede Page hat ihre eigene VideoStartadresse
	LD	DE,(VDCST2)	;damit Scrollen unabhaengig moeglich ist
	LD	(VDCST2),HL
	LD	(VDCST),DE
CHGVST:	CALL	SETVDC
	CALL	SCRONA
	JP	STDRT

RAMCHG:	CALL	SCROFA
	IN	A,(GPIP)
	XOR	00000100B	;Ram XA8 High-Page wechseln
	OUT	(GPIP),A
	LD	HL,(DSPST4)
	LD	DE,(DSPST)
	LD	(DSPST4),DE
	LD	(DSPST),HL
	CALL	ADRVDC
	LD	(VDCST),HL
	JR	CHGVST
;-----------------------
WRTPG1:	LD	A,(STAT5)	;Write-Page = sichtbare Page
	LD	B,A
	LD	A,(STAT3)
	XOR	B
	BIT	7,A		;Anzeige und Arbeitspage stimmen
	RET	Z		;bereits ueberein
	JR	WRTPG

WRTPG2:	LD	A,(STAT5)	;Schreiben in Page 2
	LD	B,A
	LD	A,(STAT3)	;Anzeigepage und Arbeitspage sind
	XOR	B		;bereits verschieden
	BIT	7,A
	RET	NZ

WRTPG:	LD	A,B
	XOR	80H
	LD	(STAT5),A
	OUT	(PAGE),A

	LD	B,CHGPLN	;Cursorpositionen tauschen
	LD	HL,CSP
	LD	DE,CSP2
WRTPG3:	LD	A,(HL)
	LD	C,A
	LD	A,(DE)
	LD	(HL),A
	LD	A,C
	LD	(DE),A
	INC	HL
	INC	DE
	DJNZ	WRTPG3
	CALL	INITXN		;GCPOS und TXNULL neu berechnen
	JP	CURADR

SPLOFF:	LD	HL,(SPLINH)	;nur wenn Spooler leer
	LD	A,L
	OR	H
	RET	NZ

	LD	HL,STAT1
	RES	1,(HL)
	LD	HL,0118H	;Routine SPOL aus Ablauffeld entfernen
	LD	(HPRTH),HL

	CALL	ZLKSET		;normale Zielkanalroutine einsetzen
	JR	SPLZCH		;Spoolerzeichen schreiben

SPLON:	LD	A,(MODUS+1)
	AND	11110000B
	CP	00110000B
	RET	NC		;Spooler nur bei geeignetem Zielkanal

	LD	HL,STAT1
	SET	1,(HL)

	LD	A,0CDH		;Spoolerroutine einsetzen in Ablauffeld
	LD	HL,SPOL
	LD	(HPRTH),A
	LD	(HPRTH+1),HL

	LD	HL,SPOLBF	;Spoolerpointer auf Anfang
	LD	(SPOLLP),HL
	LD	(SPOLVP),HL
	LD	HL,0000H	;Spoolerinhalt 0 bytes
	LD	(SPLINH),HL
	LD	HL,ZLSPOL	;statt Zielkanalroutine ZLSPOL
	LD	(ZLVAP),HL

SPLZCH:	FLAG	0,ITLFLG
	RET	NZ
	LD	HL,8887H	;entweder Spooler leer
	LD	DE,(SPLINH)
	LD	A,D
	OR	E
	JR	Z,SPLCH1
	LD	HL,8685H	;oder Spooler voll
SPLCH1:	LD	A,(STAT1)
	BIT	1,A
	JR	NZ,SPLCH2
	LD	HL,2020H	;oder Spooler aus
SPLCH2:	LD	DE,SPLFLD	;neues Spoolerzeichen schreiben
	CALL	SMSG
	RET
;-----------------------
ZLKSET:	LD	A,(MODUS+1)	;Zielverarbeitungsroutine fuer
	RLCA			;einfachen Zielkanalbetrieb
	RLCA			;einschalten 
	RLCA
	RLCA
	AND	00001111B
	LD	C,A
	LD	B,0
	LD	HL,ZVPTAB
	CALL	PRDF
	LD	(ZLVAP),DE
	RET
;-----------------------
V24DEF:	CALL	VPSUB		;Definition V24-Parameter
	CALL	HBINPR
	RET	Z
	CALLB	V24DFA
	CALL	MODDSP
CHKRT:	CALLB	JPCHKS		;Checksumme bilden
	LD	(CHKSJP),BC
	JP	STDRT
;-----------------------
V24EMP:	CALL	VPSUB		;Empfang V24-INPUT
	CALL	HBINPR
	RET	Z
	CALLB	V24EI
	JP	CHKRT
;-----------------------
V24SND:	CALL	VPSUB		;Transfer V24-OUT
	CALL	HBINPR
	RET	Z
	CALLB	V24SI
	JP	CHKRT
;-----------------------
	ENDIF
	IF	EPAGE EQ 1
V24DFA:	LD	(V24PAR),A
	AND	00000001B	;XON/XOF Protokollflag Bit 0
	RRCA
	RRCA
	LD	B,A		;Protokoll ein bei 1
	LD	A,(MODUS)
	AND	10111111B
	OR	B		;in MODUS einsetzen
	LD	(MODUS),A
	LD	A,(V24PAR)
	AND	01111110B	;Divisor und DMA enable ausblenden
	LD	B,A
	IN	A,(UCR)
	AND	10000000B
	OR	B
	OUT	(UCR),A
	LD	HL,XOFLG	;XON initialisieren
	RES	6,(HL)
	RET
;-----------------------
V24EI:	LD	(V24EB),A
	CALL	BRPOS		;TAB-Position in HL (PRESC,CONST.)
	IN	A,(PVR)
	AND	0F8H
	OR	7		;TCDCR
	OUT	(PVR),A
	IN	A,(IDR)		;Timer C/D Kontrollwort
	AND	0F0H		;Timer C unveraendert
	OR	(HL)		;Timer D Prescale laden
	OUT	(IDR),A
	INC	HL
	IN	A,(PVR)
	AND	0F8H
	OR	1		;TDDR
	OUT	(PVR),A	
	LD	A,(HL)
	OUT	(IDR),A		;Timer D Konstante
	RET
;-----------------------
V24SI:	LD	(V24SB),A
	CALL	BRPOS
	IN	A,(PVR)
	AND	11111000B
	OR	00000111B	;TCDCR
	OUT	(PVR),A
	IN	A,(IDR)		;Timer C/D Kontrollwort
	AND	0FH		;Timer D unveraendert
	LD	B,A
	LD	A,(HL)
	RLCA			;Timer C prescale laden
	RLCA
	RLCA
	RLCA			;in HWHB fuer Timer C
	OR	B		;Timer D Control unveraendert
	OUT	(IDR),A
	INC	HL
	IN	A,(PVR)
	AND	11111000B
	OR	00000010B	;TCDR
	OUT	(PVR),A	
	LD	A,(HL)
	OUT	(IDR),A		;Timer C Konstante
	RET
;-----------------------
BRPOS:	SUB	31H
	JR	NC,JBI		;Baudrate wie JUMPER ?
	LD	A,(JUMPER)	;Jumperauswertung
	RRCA
	RRCA
	RRCA
	RRCA
	RRCA
	AND	00000111B
	LD	HL,JMPTAB
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	A,(HL)
	DEC	A
JBI:	LD	C,A
	LD	B,0
	LD	HL,TRTAB	;Timerregistertabelle fuer Baudraten
	SLA	C
	ADD	HL,BC		;Eintraege zu 2 Bytes:PRESC,TDATA
	RET

JMPTAB:	10,10,9,0,7	;9600,9600,4800,dummy,1200
;-----------------------
	IF	DEBUG
	DB	'TRTAB'
	ENDIF

TRTAB:	DB	3,146	;50	Baudraten fuer V24
	DB	3,98	;75
	DB	3,67	;110
	DB	1,195	;150
	DB	1,98	;300
	DB	1,49	;600
	DB	1,24	;1200
	DB	1,12	;2400
	DB	1,6	;4800
	DB	1,3	;9600
	DB	1,1	;29300

;----------------------------
TBAUDA:	LD	(TASTBD),A
	LD	C,A
	SLA	C
	ADD	A,C
	LD	C,A
	LD	B,0
	LD	HL,TSTAB	;Timerregistertabelle fuer Baudraten
	ADD	HL,BC		;3 Bytes: PRESC,TDATA/2,TDATA
	LD	A,(HL)
	LD	(TABC),A	;sichern bis Timer Start
	INC	HL
	LD	A,(HL)		;Baudkonstante 1/2 bit
	LD	(SKDRH),A
	INC	HL
	LD	A,(HL)		;Baudkonstante 1 bit
	LD	(SKDR),A
	RET

TSTAB:	DB	70H,255,255	;50	;Tastaturbaudraten
	DB	70H,125,250	;75
	DB	70H, 92,184	;110
	DB	60H,125,250	;150
	DB	50H, 98,196	;300
	DB	50H, 49, 98	;600
	DB	50H, 24, 48	;1200
	DB	50H, 12, 24	;2400
	DB	10H, 64,192	;4800	;Halbbit empirisch optimiert
	DB	10H, 01, 96	;9600
	DB	10H, 01, 96	;9600
;----------------------------------------------------------------
;Einstellen der Tastaturparameter, Bedeutung der Bits in A
; 7=IBM-Umcodierung aktiv 6=Tastaturwortlaenge7,8 bit 5=invertiert 4,3=Tastaturart
; 2=Hostwortlaenge 7,8 Bit 1,0=Tastenklick-Lautstaerke
;----------------------------------------------------------------
TKSET:	LD	(TASTAT),A	;bit 7 setzt IBM-Umkodierung aktiv
	LD	B,A		;Einsprung von JSTAT x in A
	LD	HL,STAT5
	LD	A,(HL)
	AND	11111011B	;Host Ausgabewortlaenge 7,8 bit
	LD	C,A
	LD	A,B
	AND	00000100B
	OR	C
	LD	(HL),A

	LD	HL,SKBW		; Keyboard Wortlaenge 7,8 bit
	JPBITZ	6,B,WORT8
WORT7:	LD	(HL),7
	JR	TKSET1
WORT8:	LD	(HL),8

TKSET1:	LD	A,B
	AND	00111000B
	LD	C,A
	LD	A,(MODUS)	;Bit 3,4,5 fuer Tastaturanschluss
	AND	11000111B
	OR	C
	LD	(MODUS),A
	AND	00100000B	;Test auf invertierte Daten
	LD	B,A
	IN	A,(PVR)		;adresse Active Edge Register via PVR
	AND	11111000B
	OR	00000011B
	OUT	(PVR),A
	IN	A,(IDR)		;falling edge active bei normal
	AND	11011111B
	OR	B		;rising edge  activ bei Invers ser. KB
	OUT	(IDR),A

	LD	A,C		;which Keyboard ?
	AND	00011000B
	CP	00011000B
	JR	Z,TKSET2	;no keyboard
	LD	C,A
	LD	B,0
	LD	HL,KYBF		;Pointer auf Keyboardpointerfeld setzen
	ADD	HL,BC
	LD	(KYBPT),HL

TKSET2:	LD	A,(TASTAT)	;Keyboard KLICK setzen
	AND	3
	RRCA
	RRCA
	RRCA			;Bits 5,6 STAT5
	LD	B,A
	LD	A,(STAT5)
	AND	10011111B
	OR	B
	LD	(STAT5),A
	RET
;-----------------------
	ENDIF
	IF	EPAGE EQ 0
TBAUD:	CALL	VPSUB		;Definition der Tastatur-Baudrate
	CALL	HBINPR
	RET	Z
	SUB	31H
	JP	C,STDRT
	CALLB	TBAUDA
	JP	STDRT
;-----------------------
	IF	DEBUG
	DB	'TKANAL'
	ENDIF

TKANAL:	CALL	VPSUB		;definiere Tastaturkanal <EE4>
	CALL	HBINPR		;ESC ESC '4' x
	RET	Z

	LD	B,A
	AND	00011000B	;teste ob IBM-Tastatur eingestellt wird
	CP	00001000B
	JR	NZ,TKANA1
	JPBITZ	5,B,TKANA2	;wenn ja wird Invertierflag 5 zum Umkodierflag 7
	SET	7,B		;wenn 5 gesetzt setze 7, ruecksetze 5
	RES	5,B		;IBM-Tastatur ist immer nicht invertiert
	JR	TKANA1
TKANA2:	RES	7,B		;wenn 5 rueckgesetzt ruecksetze auch 7
TKANA1:	LD	A,B
	CALLB	TKSET
	CALL	MODDSP
	CALL	KBFDSP		;neue Keyboardpufferanzeige
	CALL	KLZDSP
	JP	CHKRT
;-----------------------
UHRSET:	CALL	VPSUB
	CALL	HBINH
	CP	3
	RET	C		;3 byte Parameter abwarten
	LD	HL,STD
	LD	B,3
UHRSE1:	PUSH	HL
	PUSH	BC
	CALL	HBFRD
	SUB	20H
	POP	BC
	POP	HL
	LD	(HL),A
	INC	HL
	DJNZ	UHRSE1

	LD	A,50		;Starte mit voller Sekunde
	LD	(SEC50),A
	LD	A,0CDH
	LD	HL,THPT		;neue Uhrzeit anzeigen
	LD	(HPRTD),A
	LD	(HPRTD+1),HL
	JP	STDRT
;****************************************************************************
;MODUL TTX
;****************************************************************************
;TECTRONIX Kommandotabellen

TXKOM:	DW	RETM,RETM,RETM,RETM,RETM,RETM,RETM
	DW	VDZ		;Vektor doch zeichnen,$07
	DW	CURLTX,CURGTX
	DW	PLFTX
	DW	CURATX,RETM
	DW	ALCR		;Alphamode mit CR
	DW	RETM,RETM
	DW	REPFKT
	DW	DELFKT		;loeschen
	DW	XORFKT		;XOR-Funktion
	DW	ORFKT
	DW	RETM,RETM,RETM,RETM,RETM,RETM,RETM
	DW	ESCAPE
	DW	PUNKT		;Punktmodus
	DW	VKTMOD		;Vektormodus
	DW	INCMOD		;Incrementalmodus
	DW	ALPOS		;Alphamodus,Cursor bleibt

TXCHR:	DB	'%$1234ABFGPSTVvWw',0CH,'`abcd'
LTXCHR	EQU	$-TXCHR

;ESC-Sequenzen TTX

TXESC:	DW	LTYPLG	;Langgestrichelte Linien
	DW	LTYPKZ	;Kurzgestrichelt
	DW	LTYPSP	;Strich-Punkt
	DW	LTYPPT	;gepunktet
	DW	LTYPVL	;volle Linien
	DW	ALNEU	;Alpha, neues Bild
	DW	HGFDEF	;Hintergrundfarbe
	DW	COLDEF	;Vordergrundfarbe
	DW	HGFDFT
	DW	COLDFT
	DW	TRIGON	;Trigon-Fill
	DW	SETSPR	;Spray setzen
	DW	SETPAT	;Muster setzen
	DW	ATRIBU	;Schriftattribute ^Gx
	DW	FFILL	;Flaechenfuellen
	DW	BLKSET	;Blockfill enable
	DW	SETOFS	;Offset definieren
	DW	SCRLFT	;Scrollbefehle
	DW	SCRLUP
	DW	SCRIGT
	DW	SCRDWN
	DW	STGRON
	DW	STGROF
;-----------------------
SETOFS:	CALL	VPSUB		;<EA>
	CALL	HBINPR		;Offset holen
	RET	Z
	SUB	20H
	JP	C,STDRT		;<=20H
	JP	Z,STDRT
	LD	(TXOFFS),A
	CALL	INITXN		;Nullpunkt neu
	JP	CHKRT
;---- Alternative fuer VKTPRG,Vektorverarbeitung --------

VKTGEN: LD	HL,(X1)		;teste ob vertikaler Vektor
	LD	DE,(X2)
	SUBHL	DE
	JR	NZ,VKTGE1
	CALL	VERLIN		;schnelle vertikale Linie
	JR	EPGPWX

VKTGE1: LD	HL,(Y1)
	LD	DE,(Y2)
	SUBHL	DE
	JR	NZ,VKTGE2
	CALL	INIFIL		;Y1=Y2: HORLIN initialisieren Horizontaler Vektor
	LDW	(TRGPOS),(ENDPOS)
	LDB	(TRGMSK),(ENDMSK)
	LD	HL,(X2)
	LD	A,L
	AND	0F8H
	LD	L,A
	LD	DE,(X1)
	LD	A,E
	AND	0F8H
	LD	E,A
	SUBHL	DE
	SRL	H	;Differenz (X2 and F8 - X1 and F8)/8 ist Anzahl Bytes der Linie
	RR	L
	SRL	H
	RR	L
	SRL	H
	RR	L
	LD	A,L
	LD	(LINCNT),A	;Laenge der Horizontalen Linie in bytes
	CALL	HORLIN
	JR	EPGPWX

VKTGE2:	CALL	VKTPAR	;Parameter fuer "VEKTOR"
	CALL	VEKTOR	;Zeichenprogramm, zurueck ins Ablauffeld
EPGPWX:	LDW	(GCPOS),(ENDPOS)	;Endpunkt neuer Startpunkt
	LDB	(GCMSK),(ENDMSK)
EPGPW1:	LDW	(X1),(X2)
	LDW	(Y1),(Y2)
	RET
;-----------------------
TRIGON:	LDW	(VKTSAV),(VKTPRG)	;<ET>	Startet TRIGON-Fill
	LDW	(VKTPRG),TRGFIL
	LDB	(KOOCNT),3		;TRGFIL wartet jetzt auf 3 Eckpunkte
	RET
;-----------------------
BLKSET:	LDW	(VKTPRG),BLKFIL		;<EB> Startet Blockfill-Modus
	RET

;===== Masterprogramme TECTRONIX-Modus =====

TTXVA:	CALL	HBINPR		;Masterprogramm fuer Vektormodus
	RET	Z
	LD	DE,KOOLD
	JR	VACOM

INCVA:	CALL	HBINPR		;Masterprogramm fuer Incrementalmodus
	RET	Z
	LD	DE,INCVV

VACOM:	LD	HL,ABLMRK
	BIT	1,(HL)		;ESC-Sequenz laeuft ?
	JP	NZ,ESCEX
	CP	20H
	JP	C,KOMEX		;Controlcodeausfuehrung
	BIT	7,A
	JP	NZ,EXHBI	;zum Zielkanal
	EX	DE,HL
	JP	(HL)		;Graphikverarbeitung
;-----------------------
INCVV:	LD	HL,IMCTAB	;Steuercode-Tabelle
	LD	BC,LIMCT
	CPIR
	JP	Z,IMEX
	RET			;keine Aktion
;-----------------------
PUNKT:	LD	HL,PPLOT	;Punktmodus Einschaltroutine
PUNKTI:	LD	(VKTPRG),HL
PKTI2:	LD	HL,TTXVA	
MPROG:	LD	(HAUPT+1),HL
	LD	(MASTER),HL
	RET
;-----------------------
INCMOD:	XOR	A		;Incrementalmodus Einschaltroutine
	LD	(BLDB),A
	LDW	(VKTPRG),SETIN
	LD	HL,STAT4
	RES	4,(HL)		;Cursor aus
	LD	HL,INCVA
	JR	MPROG
;-----------------------
VKTMOD:	LD	HL,VKLEER
	JR	PUNKTI
;----------------------- Alphamodus-Einschaltroutinen
ALCR:	LD	HL,(TXNULL)	;Cursor an Zeilenanfang
	LD	DE,(GCPOS)
	LD	BC,-ZLSIZN
	JR	ALCR2

ALCR1:	ADD	HL,BC
	SETNI	7,H
ALCR2:	LD	A,H
	SUB	D
	CP	3		;Zielzeile erreicht?
	JR	NC,ALCR1

	LD	A,L		;Bits 0-2 von E nach L kopieren
	AND	11111000B
	LD	L,A
	LD	A,E
	AND	00000111B
	OR	L
	LD	L,A
	JR	ALPHL
;-----------------------
ALNEU:	CALL	ERASE		;Alpha-Modus mit Bildschirm loeschen
	LD	HL,(VDPT)
	LD	BC,(ZLSIZE)
	ADD	HL,BC		;Position unter Zeichen
ALPHL:	CALL	INIPOS

ALPOS:	LD	HL,EXHBF
	JP	MPROG		;Sprung zum Master-Programm
;-----------------------
APOS	EQU	ARBF	;Anfangsposition des letzten Linienfill
AMSK	EQU	ARBF+2
EPOS	EQU	ARBF+10	;Endposition des letzten Linienfill
EMSK	EQU	ARBF+12
;----------------------------
INIFIL:	IF	NOT XR
	 CALL	SETEBN
	ENDIF
	LD	HL,FILLN	;Pixelroutinen setzen
	JPNI	FPROG0
	LD	HL,FILLI
FPROG0:	IF	XR
	 LD	A,(MODUS)	;im Farbmodus XR neue Routinen setzen
	 JPBITZ	7,A,FPROG2
	 LD	BC,24
	 ADD	HL,BC
	ENDIF
FPROG2:	LD	DE,SETFIL
	LD	BC,6
	LDIR
	LD	A,(STAT3)
	BIT	6,A		;Invertieren?
	JR	Z,FPROG1
	PUSH	HL
	LD	C,3
	LD	DE,GETFIL	;Invert-GETFIL setzen
	LDIR
	POP	HL
FPROG1:	LD	A,(PFKT)
	CP	6		;Replace?
	RET	NZ
	LD	C,3
	ADD	HL,BC
	LD	DE,SETFIL	;Replace-SETFIL setzen
	LDIR
	RET
;----------------------------------
FILLN:	JP	SETPXN
	JP	GETPXN
	JP	GETPVN		;INVERT
	JP	SETRXN		;REPLACE

FILLI:	JP	SETPXI
	JP	GETPXI
	JP	GETPVI
	JP	SETRXI

	IF	XR
XFILLN:	JP	SETPXN
	JP	XGETPN
	JP	XGETVN		;INVERT
	JP	SETRXN		;REPLACE

XFILLI:	JP	SETPXI
	JP	XGETPI
	JP	XGETVI
	JP	SETRXI
	ENDIF

GETPXN:	SET	7,H	;Byte aus Video-Ram lesen
	LD	A,(HL)
	OR	A
	LD	B,A
	RET
GETPXI:	LD	A,H	
	OUT	(PAGE),A
	LD	B,H
	SET	7,H
	LD	A,(HL)
	LD	H,B
	OR	A
	LD	B,A
	RET

GETPVN:	SET	7,H		;Invertiert lesen
	LD	A,(HL)
	XOR	0FFH
	LD	B,A
	RET
GETPVI:	LD	A,H
	OUT	(PAGE),A
	LD	B,H
	SET	7,H
	LD	A,(HL)
	LD	H,B
	XOR	0FFH
	LD	B,A
	RET

	IF	XR
XGETPX:	LD	A,(EBENE)
	OR	A
	JR	NZ,XGETP7
	LD	A,10H		;Lesen von Grundebene
	OUT	(XRFLGS),A
	LD	E,(HL)
	LD	A,(XRRD)
	OUT	(XRFLGS),A
	LD	A,E
	RET

XGETP7:	LD	B,8		;extrahiere aus 8 Bildbytes jeweils ein Bi
	LD	A,20H
	OUT	(XRFLGS),A
	XRBRES			;reset Bitcounter
XGETP2:	LD	A,(EBENE)
	CP	9
	JR	C,XGETP5	;wenn Ebene > 8 dann alle Ebenen verodern
	LD	A,(HRDKTR)
	SUB	(HL)		;carry ist gesetzt wenn Bildbyte > KONTRAST
	JR	XGETP6

XGETP5:	LD	D,(HL)		;lese im Bitmodus aus XR-Karte
XGETP3:	RR	D		;extrahiere ein Bit aus Farbwert = Farb Ebene
	DEC	A
	JR	NZ,XGETP3
XGETP6:	RR	E
	XRBIT			;increment XR Bitcounter
	DJNZ	XGETP2
	LD	A,27H		;Maskenmodus
	OUT	(XRFLGS),A
	LD	A,E
	RET

XGETPN:	SET	7,H
	PUSH	DE
	CALL	XGETPX
	POP	DE
	OR	A
	LD	B,A
	RET

XGETVN:	CALL	XGETPN
	XOR	0FFH
	LD	B,A
	RET

XGETPI:	PUSH	HL
	LD	A,H	
	OUT	(PAGE),A
	SET	7,H
	PUSH	DE
	CALL	XGETPX
	POP	DE
	POP	HL
	OR	A
	LD	B,A
	RET

XGETVI:	CALL	XGETPI
	XOR	0FFH
	LD	B,A
	RET

	ENDIF		;XR

SETRXN:	LD	A,(LINTR)	;REPLACE-Modus
	CPL
	AND	B
	LD	(BLDBS),A	;Schwarzmaske
SETPXN:	LD	A,(LINTR)	;Pixelbyte schreiben
	AND	B
	LD	B,A
	SET	7,H
	JP	PIXLOG

SETRXI:	LD	A,(LINTR)
	CPL
	AND	B
	LD	(BLDBS),A
SETPXI:	LD	A,H
	OUT	(PAGE),A
	LD	A,(LINTR)
	AND	B
	LD	B,A
	PUSH	HL
	SET	7,H
	CALL	PIXLOG
	POP	HL
	RET
;-----------------------------
FFILL:	CALL	INIFIL		;Pixelroutinen setzen
	LD	HL,(GCPOS)
	LD	BC,(GCMSK)
	CALL	LFIL		;Erste Linie fuellen
	RET	NZ		;Wenn GC-Pixel schon gesetzt
	CALL	LCHKU		;Linie darunter checken
	LD	A,C
	PUSH	AF		;Abspeichern fuer spaeter
	PUSH	HL
FPROG4:	CALL	LCHKO
	JR	NZ,FPROG3	;Wenn Rand, unten weiter fuellen
	CALL	LFIL		;Oben fuellen
	JR	FPROG4
FPROG3:	POP	HL		;Position
	POP	AF		;Maske
	RET	NZ		;Falls unten Rand
	LD	C,A
FPROG5:	CALL	LFIL
	CALL	LCHKU
	JR	Z,FPROG5
	JP	FRBRES

;Linie fuellen --------------
;HL=POS,C=MSK irgendwo in Linie
LFIL:	CALL	INILTY		;LINTR setzen
	CALL	GETFIL
	JR	Z,LFIL11
	AND	C		;Pixel schon gesetzt?
	JR	Z,LFIL15	;Nein: Rand suchen
	RET
;Bitmaske auf linken Rand setzen
LFIL14:	LD	A,B
	AND	C
	JR	NZ,LFIL13	;Rand gefunden
LFIL15:	RRC	C
	JR	NC,LFIL14
;byteweise bis zum linken Rand
LFIL11:	LD	DE,-8		;1 Byte nach links
LFIL2:	ADD	HL,DE
	CALL	GETFIL
	JR	Z,LFIL2
	LD	C,80H		;Bit ganz rechts
	JR	LFIL14
;Rand gefunden - abspeichern
LFIL13:	RLC	C		;Korrektur zum Abspeichern
	LD	DE,8
	JR	NC,LFIL12	;Ueberlauf ueber Byte - NZ
	ADD	HL,DE
	CALL	GETFIL		;Neues Pixelbyte
LFIL12:	LD	(APOS),HL	;Erstes Nullbit
	LDB	(AMSK),C
	JR	Z,LFIL3		;Neues Pixelbyte = 0
;jetzt von links fuellen	
LFIL4:	LD	E,B		;Pixelbyte
	LD	B,0		;Maske in B aufbauen
LFIL5:	LD	A,E
	AND	C		;Gesetztes Pixel?
	JR	NZ,LFIL6	;dann Rand erreicht - Ende
	LD	A,B
	OR	C		;Bit setzen
	LD	B,A
	RLC	C
	JR	NC,LFIL5	;Weiter schieben

	CALL	SETFIL		;Maske schreiben
	LD	DE,8
LFIL31:	ADD	HL,DE		;Naechstes Byte
	CALL	GETFIL
	JR	NZ,LFIL4	;Bitweise, wenn am Rand (C=01H)
LFIL3:	LD	BC,0FF01H	;Sonst byteweise
	CALL	SETFIL
	JR	LFIL31

LFIL6:	RRCA			;Korrektur (Maske noch in A)
	JR	NC,LFIL61	;Ueberlauf ueber Byte
	LD	DE,-8
	ADD	HL,DE
	SCF
LFIL61:	LD	(EPOS),HL
	LD	(EMSK),A
	CALL	NC,SETFIL	;Nicht schreiben, wenn Ueberlauf
	XOR	A		;Z = O.K.
	RET

;Linie oben/unten checken auf Nullbits zwischen APOS und EPOS --------------
;/HL=POS,C=MSK,Z=Nullbits gefunden
LCHKO:	LD	HL,(EPOS)
	LD	BC,-1		;nach oben
	LD	A,L
	AND	00000111B
	JR	NZ,LCHK
	LD	BC,-PITCH+7
	JR	LCHK
LCHKU:	LD	HL,(EPOS)
	LD	BC,1		;nach unten
	LD	A,L
	INC	A
	AND	00000111B
	JR	NZ,LCHK
	LD	BC,PITCH-7
;Anfang und Ende berechnen --------------
LCHK:	ADD	HL,BC		;BC=Richtung
	EX	DE,HL		;DE=Endpos
	LD	HL,(APOS)
	ADD	HL,BC		;HL=Anfangspos
	LDB	C,(AMSK)
	SUBHL	DE		;Anfangspos=Endpos?
	JR	Z,LCHK4		;wenn ja, gleich Endcheck
	ADD	HL,DE		;Anfangspos 
;Linienanfang checken --------------------
	CALL	GETFIL		;Anfangsbyte
LCHK5:	LD	A,B
	AND	C
	RET	Z		;Nullbit gefunden
	RLC	C	
	JR	NC,LCHK5	;Bis zum Anschlag
;Linenmitte checken -----------------------
LCHK2:	LD	BC,8
	ADD	HL,BC		;naechstes Vollbyte
	LD	C,01H
	SUBHL	DE		;Endpos erreicht?
	JR	NC,LCHK4	;wenn ja, Endcheck
	ADD	HL,DE
	CALL	GETFIL
	CP	0FFH
	JR	Z,LCHK2		;wenn ja, weitersuchen
	JR	LCHK5		;leeres Bit finden
;Linienende checken ----------------------
LCHK4:	EX	DE,HL		;HL=Endpos
	LDB	E,(EMSK)
	CALL	GETFIL
LCHK6:	LD	A,B
	AND	C
	RET	Z		;Nullbit gefunden
	LD	A,E
	AND	C
	RET	NZ		;Endbit erreicht, nichts gefunden
	RLC	C
	JR	LCHK6		;Weitersuchen
;Ende Flaechenfuellen
;================================================
VKLEER:	CALL	VDZ		;Leervektor,naechster Vektor wird gezeichnet
	JP	EPGPWX		;Koordinaten Endpunkt nach Startpunkt
;-----------------------
VDZ:	LDW	(VKTPRG),VKTGEN	;Vektor doch zeichnen
	RET
;-----------------------
PPLOT:	CALL	EPGPWX		;Nur Endpunkt zeichnen
	CALL	SETIN
	JP	BTPUF		;1 Pixel (Endpunkt) zeichnen
;-----------------------
BETRAG:	BIT	7,H		;Betrag von HL
	RET	Z		;Zero Flag gesetzt wenn positiv
	LD	A,H
	CPL
	LD	H,A
	LD	A,L
	CPL
	LD	L,A
	INC	HL
	RET
;-----------------------
XPROG:	JR	Z,XRPOS		;DX positiv
	LDW	(MOVL+1),XDEC
	RET
XRPOS:	LDW	(MOVL+1),XINC
	RET
YPROG:	JR	Z,YRPOS		;DY positiv
	LDW	(MOVH+1),VDOWN
	RET
YRPOS:	LDW	(MOVH+1),VUP
	RET
TXPROG:	JR	Z,TXRPOS	;DX positiv X-Routinen fuer TRIGON-FILL
	LDW	(MOVL+1),TXDEC
	RET
TXRPOS:	LDW	(MOVL+1),TXINC
	RET
;-----------------------
VKTPAR:	LD	HL,(X2)		;Vektorprogramm mit Parametern versorgen
	LD	BC,(X1)
	SUBHL	BC
	CALL	BETRAG
	LD	(BDX),HL
	CALL	XPROG
	LD	HL,(Y2)
	LD	BC,(Y1)
	SUBHL	BC
	CALL	BETRAG
	LD	(BDY),HL
	CALL	YPROG
	LD	HL,(BDY)
	LD	BC,(BDX)
	SUBHL	BC		;BDY-BDX
	RET	NC		;Parameter stehen richtig bei BDY>=BDX
	ADD	HL,BC		;Parameter tauschen
	LD	(BDY),BC
	LD	(BDX),HL
	LD	HL,(MOVL+1)
	LD	DE,(MOVH+1)
	LD	(MOVH+1),HL
	LD	(MOVL+1),DE
	RET
;-----------------------
VDOWN:	CALL	BTPUF		;DE darf nicht veraendert werden
GDWN:	LD	HL,(GCPOS)
	LD	A,L
	INC	A
	AND	7
	JR	Z,ZBD	;Zeilenblock ADD
	INC	HL
	LD	(GCPOS),HL
	RET
ZBD:	PUSH	BC
	LD	BC,ZLSPR
	ADD	HL,BC
	LD	(GCPOS),HL
	POP	BC
	RET
;------------------
VUP:	CALL	BTPUF		;im Bild nach oben
GUP:	LD	HL,(GCPOS)	;DE darf nicht veraendert werden
	LD	A,L
	AND	7
	JR	Z,ZSP
	DEC	HL
	LD	(GCPOS),HL
	RET
ZSP:	PUSH	BC
	LD	BC,-ZLSPR
	ADD	HL,BC
	LD	(GCPOS),HL
	POP	BC
	RET
;------------------
TVUP:	LD	HL,(TRGPOS)	;Y-Pixelincrement fuer Trigonfill
	LD	A,L
	AND	7
	JR	Z,TZSP
	DEC	HL
	LD	(TRGPOS),HL
	RET
TZSP:	PUSH	BC
	LD	BC,-ZLSPR
	ADD	HL,BC
	LD	(TRGPOS),HL
	POP	BC
	RET
;------------------
XDEC:	LD	HL,GCMSK
	RRC	(HL)
	RET	NC
	CALL	BTPUF
VDI:	LD	HL,(GCPOS)
	LD	BC,-8
	ADD	HL,BC
	LD	(GCPOS),HL
	LD	HL,LINCNT
	INC	(HL)
	RET
;------------------
XINC:	LD	HL,GCMSK
	RLC	(HL)
	RET	NC
	CALL	BTPUF
VII:	LD	HL,(GCPOS)
	LD	BC,8
	ADD	HL,BC
	LD	(GCPOS),HL
	LD	HL,LINCNT
	DEC	(HL)
	RET
;------------------
TXDEC:	LD	HL,TRGMSK
	RRC	(HL)
	RET	NC
	LD	HL,(TRGPOS)
	LD	BC,-8
	ADD	HL,BC
	LD	(TRGPOS),HL
	LD	HL,LINCNT
	DEC	(HL)
	RET
;------------------
TXINC:	LD	HL,TRGMSK
	RLC	(HL)
	RET	NC
	LD	HL,(TRGPOS)
	LD	BC,8
	ADD	HL,BC
	LD	(TRGPOS),HL
	LD	HL,LINCNT
	INC	(HL)
	RET
;------------------
;Programmparameter und Arbeitsfeld
MOVH	EQU	ABLCON
MOVL	EQU	ABLCON+3
BDY	EQU	ABLCON+6
BDX	EQU	ABLCON+8

TRGPOS	EQU	ARBF	;Trigon-Fill Grafikcursorposition
TRGMSK	EQU	ARBF+2
KOOCNT	EQU	ARBF+5	;Zaehler fuer 3 Koordinaten
LINCNT	EQU	KOOCNT	;Linienlaenge in HORLIN

TRGPKT	EQU	ARBF+10	;
TRGPX0	EQU	ARBF+10	;Trigon Eckpunkte sortiert nach Y
TRGPY0	EQU	ARBF+12	;         P2 
TRGPX1	EQU	ARBF+14	;   P1    /
TRGPY1	EQU	ARBF+16	;    \   /
TRGPX2	EQU	X2	;     \ /
TRGPY2	EQU	Y2	;     P0

TRXCNT	EQU	ARBF+6
VKTSAV	EQU	ARBF+18	;Vektorprogramm vor Trigonfill

BLDB	EQU	ARBF+3	;Wei~maske
BLDBS	EQU	ARBF+4	;Schwarzmaske
LINTR	EQU	ARBF+8
;-----------------------
VEKTOR:	CALL	INILTG		;LTR setzen nach GCPOS
	LD	HL,(BDY)	;BDH
	PUSH	HL
	POP	IY		;IY = Schrittcounter
	LD	D,H
	LD	E,L
	SRL	H		;Anfangswert BDY/2
	RR	L		;fuer symmetrische Steigung
	PUSH	HL

SET:	LD	HL,LINTR
	RLC	(HL)
	LD	A,(GCMSK)
	LD	HL,BLDB
	JR	C,WHSET
	INC	HL		;HL=BLDBS
WHSET:	OR	(HL)
	LD	(HL),A		;Wei~/Schwarzmaske setzen
	POP	HL
	LD	BC,(BDX)
	ADD	HL,BC		;Anfangswert + BDX
	PUSH	HL
	OR	A
	SBC	HL,DE
	JR	C,UEBER		;DH >= VA
	
	EX	(SP),HL		;VA-Restwert im Stack
	CALL	MOVL		;Pixelbewegung Nebenrichtung
UEBER:	CALL	MOVH		;Pixelbewegung Hauptrichtung
	LD	BC,-1	
	ADD	IY,BC		;Schrittcounter decrement
	JR	C,SET		;IY<>0
	POP	HL
	JP	BTPUF		;letztes Bildbyte
;-----------------------
TRGFIL:	LD	HL,KOOCNT	;3 Koordinaten einlesen
	DEC	(HL)
	JP	Z,TRGFI1

	LD	C,(HL)		;C=2 oder 1
	DEC	C		
	LD	B,0

	SLA	C		;(KOOCNT)*4
	RL	B
	SLA	C
	RL	B
	LD	HL,TRGPKT	;<ET> Trigon-Fill Befehl
	ADD	HL,BC		;2 Eckpunkte nach TRGPKT abspeichern
	LD	DE,(X2)		;3.Eckpunkt in X2,Y2 = TRGX2 TRGY2
	LD	(HL),E
	INC	HL
	LD	(HL),D
	INC	HL
	LD	DE,(Y2)
	LD	(HL),E
	INC	HL
	LD	(HL),D
	RET	

TRGFI1:	LD	HL,(GCPOS)	;aktuellen Grafikcursor retten
	PUSH	HL
	LD	A,(GCMSK)
	PUSH	AF
	CALL	YSORT		;3 Eckpunkte nach Y sortieren
	CALL	TRINIA		;unteres Teildreieck initialisieren
	CALL	TRIGNA		;zeichnen
	CALL	TRINIB		;oberes Teildreieck initialisieren
	CALL	TRIGNB		;zeichnen
	LDW	(VKTPRG),(VKTSAV)	;zurueckschalten auf vorigen Modus
	POP	AF		;Grafikcursor wiederherstellen
	LD	(GCMSK),A
	POP	HL
	LD	(GCPOS),HL
	RET
;-----------------------
YSORT:	LD	HL,(TRGPY1)	;sortiert die drei Eckpunkte nach Y
	LD	DE,(TRGPY0)	;Y1 >= Y0 
	SUBHL	DE
	JR	NC,YSORT1
	ADD	HL,DE
	LD	(TRGPY0),HL	;tauschen
	LD	(TRGPY1),DE
	LD	DE,(TRGPX0)
	LDW	(TRGPX0),(TRGPX1)
	LD	(TRGPX1),DE
YSORT1:	LD	HL,(TRGPY2)	;Y2 >= Y0
	LD	DE,(TRGPY0)
	SUBHL	DE
	JR	NC,YSORT2
	ADD	HL,DE
	LD	(TRGPY0),HL	;tauschen
	LD	(TRGPY2),DE
	LD	DE,(TRGPX0)
	LDW	(TRGPX0),(TRGPX2)
	LD	(TRGPX2),DE
YSORT2:	LD	HL,(TRGPY2)	;Y2 >= Y1
	LD	DE,(TRGPY1)
	SUBHL	DE
	JR	NC,YSORT3
	ADD	HL,DE
	LD	(TRGPY1),HL	;tauschen
	LD	(TRGPY2),DE
	LD	DE,(TRGPX1)
	LDW	(TRGPX1),(TRGPX2)
	LD	(TRGPX2),DE
YSORT3:	RET			;Y0 <= Y1 <= Y2
;-----------------------
TRINIA:	XOR	A
	LD	(LINCNT),A
	CALL	INIFIL		;Pixelroutinen fuer Horlin setzen
	LD	DE,(TRGPX0)
	LD	BC,(TRGPY0)
	LD	HL,(TXNULL)	;Trigon Startpunkt koordinate setzen
	SETNI	7,H
	LD	A,01H		;Koordinatennullpunkt Ecke unten links
	CALL	ADWDL		;berechnen der Ram-Adresse Startpunkts X0,Y0
	LD	(GCPOS),HL
	LD	(GCMSK),A	;Ram-Adresse des unteren TrigonPunkts
	LD	(TRGPOS),HL
	LD	(TRGMSK),A

	LD	HL,(TRGPX2)	;Trigonvektor P0-P2 mit Parametern versorgen
	LD	BC,(TRGPX0)
	SUBHL	BC
	CALL	BETRAG
	LD	(TRBDX),HL
	CALL	TXPROG		;berechnet TRBDX;XPROG in MOVL; YPROG immer TVUP
	LDW	(MOVH+1),(MOVL+1)	;fuer P0-P2

	LD	HL,(TRGPY2)
	LD	BC,(TRGPY0)
	SUBHL	BC
	CALL	BETRAG
	LD	(TRBDY),HL

	LD	HL,(TRGPX1)	;Trigonvektor P0-P1 mit Parametern versorgen
	LD	BC,(TRGPX0)
	SUBHL	BC
	CALL	BETRAG
	LD	(BDX),HL
	CALL	XPROG		;berechnet BDX;XPROG in MOVL; YPROG immer VUP

	LD	HL,(TRGPY1)
	LD	BC,(TRGPY0)
	SUBHL	BC
	CALL	BETRAG
	LD	(BDY),HL
	PUSH	HL		;Y-Zeilenzaehler in IY setzen Hoehe des TRIGON
	POP	IY
	DEC	IY		;erstes Dreieck ohne obere Begrenzungslinie
	RET
;-----------------------
TRINIB:	LD	HL,(TRGPX2)	;Trigonvektor P1-P2 mit Parametern versorgen
	LD	BC,(TRGPX1)
	SUBHL	BC
	CALL	BETRAG
	LD	(BDX),HL
	CALL	XPROG		;berechnet BDX;XPROG in MOVL; YPROG immer VUP

	LD	HL,(TRGPY2)
	LD	BC,(TRGPY1)
	SUBHL	BC
	CALL	BETRAG
	LD	(BDY),HL
	PUSH	HL		;Y-Zeilenzaehler in IY setzen Hoehe des TRIGON
	POP	IY
	RET			;fuer P1-P2
;-----------------------
TRIGNA:	LD	HL,(TRBDY)	;Einsprung untere Haelfte Trigon
	SRL	H		;Anfangswert halbieren fuer symmetrische Treppen
	RR	L		;von P0-P2
	LD	(TRXCNT),HL

TRIGNB:	LD	HL,(GCPOS)
	LD	HL,(BDY)	;Einsprung fuer obere Haelfte Trigon
	LD	A,H		;Teildreieck ist flach
	OR	L
	JR	NZ,TRIGN7

	LD	DE,(BDX)	;bei flachem Dreieck nur 1 Linie ziehen
TRIGN8:	LD	A,D		;von Startpunkt nach Startpunkt-BDX
	OR	E
	JP	Z,HORLIN
	CALL	MOVL
	DEC	DE
	JR	TRIGN8

TRIGN7:	SRL	H		;Anfangswert halbieren fuer symmetrische Treppen
	RR	L		;von P0-P1 bzw. P1-P2

TRGSET:	PUSH	HL
	CALL	HORLIN		;ziehe Linie, erwartet GCPOS und TRGPOS bereits horizontal
TRIGN5:	CALL	VUP		;Y-Position erhoehen GCPOS P0-P1  bzw. P1-P2
	CALL	TVUP		;Y-Position erhoehen TRGPOS P0-P2
	POP	HL
	LD	DE,(BDY)
	LD	BC,(BDX)
	ADD	HL,BC
TRIGN3:	SUBHL	DE
	JR	C,TRIGN1
	PUSH	HL
	CALL	MOVL		;setzt GCPOS und MSK fuer P0-P1 bzw. P1-P2
	POP	HL
	JR	TRIGN3

TRIGN1:	ADD	HL,DE
	PUSH	HL

	LD	HL,(TRXCNT)
	LD	DE,(TRBDY)
	LD	BC,(TRBDX)
	ADD	HL,BC
TRGN4:	SUBHL	DE
	JR	C,TRIGN2
	PUSH	HL
	CALL	MOVH		;setzt TRGPOS und TRMSK fuer P0-P2
	POP	HL
	JR	TRGN4

TRIGN2:	ADD	HL,DE
	LD	(TRXCNT),HL
	POP	HL
	LD	BC,-1		;Teste Y-Zeile auf Ende des Teildreiecks
	ADD	IY,BC		;Schrittcounter decrement
	JR	C,TRGSET	;IY<>0
	RET
;-----------------------
HORLIN:	CALL	INILTG		;zeichnet horizontalen Vektor von GCPOS-TRGPOS
	LD	A,(LINCNT)	;Zeichenrichtung links nach rechts ?
	BIT	7,A
	JR	Z,HORLI1	

HORLI4:	LD	A,(TRGMSK)	;beginne Linie mit TRGPOS
	CALL	LFTEND
	LD	C,B
	LD	HL,(TRGPOS)
	CALL	LRLIN
	LD	A,(GCMSK)
	JR	HORLI2

HORLI1:	OR	A
	JR	NZ,HORLI3
	LD	A,(GCMSK)	;Vektor ist innerhalb eines Bytes
	LD	B,A		;stelle fest in welcher Richtung die Masken liegen
	LD	A,(TRGMSK)
	CP	B
	JR	C,HORLI4
HORLI3:	LD	A,(GCMSK)	;sonst zeichnen von GCPOS nach TRGPOS
	CALL	LFTEND
	LD	C,B		;zeichnet einen horizontalen Vektor von GCPOS-TRGPOS
	LD	HL,(GCPOS)
	CALL	LRLIN		;liefert in C Wert des vorhergehenden BildBytes
	LD	A,(TRGMSK)
HORLI2:	CALL	RGTEND		;zeichne letztes Byte der horizontalen Linie
	LD	A,B
	AND	C		;AND falls Anfang und Ende im selben Byte
	LD	B,A
	JP	SETFIL
;------------------------
LRLIN:	SETNI	7,H		;Mittlere Linie von links nach rechts
	LD	A,(LINCNT)
	OR	A
	JR	Z,LRLIN4	;Linie ist innerhalb eines Bytes

	BIT	7,A
	JR	Z,LRLIN5
	NEG
LRLIN5:	PUSH	AF
	CALL	SETFIL		;Bildbyte in B GCPOS oder TRGPOS in HL
	LD	BC,8		;Naechstes Byte nach rechts
	ADD	HL,BC
	SETNI	7,H
	POP	AF
	DEC	A
	JR	Z,LRLIN1
	DEC	B		;B wird FF zeichne Mitte des Vektors mit FF
	JR	LRLIN5

LRLIN1:	LD	C,0FFH
LRLIN4:	RET
;-----------------------
RGTEND:	CPL			;Ergebnis in B, C darf nicht veraendert werden
	LD	B,0
	SCF
RGTEN2:	RL	B
	RRA
	JR	C,RGTEN2
	RET
LFTEND:	CPL
	LD	B,0
	SCF
LFTEN1:	RR	B		;Maske in B
	RLA
	JR	C,LFTEN1
	RET
;--------------------------------------------------------------------------
; Achtung! Diese Routine VERLIN ist zeitoptimiert. Voreilige Aenderungen vermeiden !
; Optimiert fuer durchgezogene Linien
;---------------------------------------------------------------------------
	IF	DEBUG
	DB	'VERLIN'
	ENDIF
VERLIN:	CALL	INILTG		;zeichnet vertikalen Vektor, initialisiere Linetype
	LD	DE,(GCPOS)	;GCPOS verbleibt immer in DE
	LD	A,(GCMSK)	;Maske bleibt immer in C
	LD	C,A
	EXX
	LD	A,(LINTR)	;Linetype in zweitem Registersatz
	LD	C,A
	LD	HL,(Y2)
	LD	DE,(Y1)		;Anzahl der vertikalen Bildzeilen vorberechnen in HL
	SUBHL	DE
	CALL	BETRAG		;setzt Z-Flag wenn positiv
	INC	HL		;Damit Endpunkt mitgezeichnet wird
	JR	Z,VERLI1	;DY positiv

VERLI3:	RLC	C	;LINTR	;Vektor von oben nach unten zeichnen
	EXX
	LD	A,C	;GCMSK
	JR	C,VERLI2
	LD	(BLDBS),A
	XOR	A
VERLI2:	LD	B,A	;GCMSK
	LD	H,D		;GCPOS nach HL umladen
	LD	L,E
	JPNI	VERLI7
	LD	A,H
	OUT	(PAGE),A
VERLI7:	SET	7,H
	CALL	PIXLOG		;Pixel-Funktion anspringen DE bleibt unveraendert
	LD	A,E		;DE enthaelt GCPOS
	INC	A
	AND	7
	JR	Z,VERLI4	;Zeilenblock ADD
	INC	DE
	JR	VERLI5
VERLI4:	LD	HL,ZLSPR
	ADD	HL,DE
	EX	DE,HL
VERLI5:	EXX			;Anzahl der Pixelzeilen decrementieren
	DEC	HL
	LD	A,L
	OR	H
	JR	NZ,VERLI3
	RET

VERLI1:	RLC	C	;Vektor von unten nach oben zeichnen
	EXX
	LD	A,C	;GCMSK
	JR	C,VERLI9
	LD	(BLDBS),A
	XOR	A
VERLI9:	LD	B,A	;GCMSK
	LD	H,D		;GCPOS nach HL umladen
	LD	L,E
	JPNI	VERL11
	LD	A,H
	OUT	(PAGE),A
VERL11:	SET	7,H
	CALL	PIXLOG		;Pixel-Funktion anspringen DE bleibt unveraendert
	LD	A,E
	AND	7
	JR	Z,VERL12
	DEC	DE
	JR	VERLI6
VERL12:	LD	HL,-ZLSPR
	ADD	HL,DE
	EX	DE,HL
VERLI6:	EXX			;Anzahl der vertikalen Zeilen decrementieren
	DEC	HL
	LD	A,L
	OR	H
	JR	NZ,VERLI1
	RET
;------------------
BLKFIL:	CALL	INIFIL
	LD	HL,(Y2)	;Blockfill zeichnet rechteckigen Block
	LD	DE,(Y1)
	SUBHL	DE
	PUSH	HL	;Y Differenz wird spaeter gebraucht als Zaehler
	ADD	HL,DE
	JR	NC,BLKFI1
	EX	DE,HL
BLKFI1:	PUSH	DE	;Y Koordinate DE ist <= Y Koordinate in HL
	LD	HL,(X2)
	LD	A,L
	AND	0F8H
	LD	L,A
	LD	DE,(X1)
	LD	A,E
	AND	0F8H
	LD	E,A
	SUBHL	DE	;(X2 and F8 - X1 and F8)/8 ist Anzahl der Bytes im horizontalen Vektor
	SRL	H
	RR	L
	SRL	H
	RR	L
	SRL	H
	RR	L
	LD	A,L
	LD	(LINCNT),A	;Laenge des Hor. Vektors.
	LD	HL,(X2)
	LD	DE,(X1)
	POP	BC		;kleinerer Y-Wert Y1 oder Y2
	PUSH	BC
	LD	HL,(TXNULL)
	SETNI	7,H
	LD	A,01H
	CALL	ADWDL
	LD	(GCPOS),HL
	LD	(GCMSK),A
	LD	DE,(X2)
	POP	BC		;kleinerer Y-Wert Y1 oder Y2
	LD	HL,(TXNULL)
	SETNI	7,H
	LD	A,01H
	CALL	ADWDL
	LD	(TRGPOS),HL
	LD	(TRGMSK),A
	POP	HL		;Delta Y Hoehe des Blocks
	CALL	BETRAG
	INC	HL		;oberste Linie mitzeichnen
BLKFI3:	PUSH	HL
	CALL	HORLIN		;Horizontale Linie zeichnen
	CALL	TVUP		;rechts und links 1 Pixel nach oben
	CALL	VUP
	POP	HL
	DEC	HL
	LD	A,H
	OR	L
	JR	NZ,BLKFI3
	CALL	EPGPWX		;Block ist gefuellt Anfangspunkt nach Endpunkt
	RET	
;-----------------------
BTPUF:	LD	HL,BLDB
	LD	B,(HL)
	LD	(HL),0
	LD	HL,(GCPOS)	;Graphikbyte in Bildschirm schreiben
	JPNI	BTPUF1
	LD	A,H
	OUT	(PAGE),A
BTPUF1:	SET	7,H
	JP	PIXLOG		;Pixel-Funktion anspringen Maske in B
;----------------------
ADTRN:	LD	A,L	;Zerlegung der Adr. in HL in Block und Distanz (A)
	RES	2,L
	RES	1,L
	RES	0,L
	AND	7
	RET
;-----------------------
;Adressumwandlung	Eingabe:
;HL: Startadresse,Byte	A: Start-BIT,Maske
;DE: X-Koordinate (+/-)  BC: Y-Koordinate (+/-)
;			Ausgabe:
;HL: neue Speicheradresse   A: neue BIT-Maske
;+/- in Wort-Komplementdarstellung
;-----------------------
ADWDL:	PUSH	AF
	PUSH	DE
	PUSH	HL		;Y-Adresse in BC sofort verarbeiten
	LD	H,B
	LD	L,C
	LD	A,(ABLMRK)
	AND	9FH		;BIT 5,6 reset	(X,Y positiv)
	LD	(ABLMRK),A
	BIT	7,H		;Y negativ ?
	CALL	NZ,YMIN
	CALL	ADTRN		;Adresse trennen
	CALL	HLBLK		;Blockadresse ber. fuer Y
	OR	L		;rel.Blockadr. in neue Blockadr. einsetzen
	LD	L,A
	EX	DE,HL		;Y-Adresse in DE
	POP	HL		;Startadresse
				;Adressaddition in Y-Richtung
ADADY:	CALL	ADTRN		;HL+DE->HL
	LD	C,A
	EX	DE,HL
	CALL	ADTRN
	LD	B,A		;in BC sichern B=REL-BYTE-SUBHL	BC-ADR
	LD	A,(ABLMRK)
	JPBITZ	6,A,SDHAB	;Y positiv ? im Display nach oben
ADHAB:	ADD	HL,DE		;negative Y-Richtung, Adressaddition
	LD	A,C
	ADD	A,B
	CP	8
	JR	C,XKBER
	SUB	8
	LD	BC,PITCH
	ADD	HL,BC
	JR	XKBER
SDHAB:	EX	DE,HL		;Vertauschung wieder rueckgaengig
	SUBHL	DE
	LD	A,C
	SUB	B
	JR	NC,XKBER
	ADD	A,8
	LD	BC,PITCH
	SUBHL	BC
XKBER:	OR	L		;Berechnung der X-Richtung
	LD	L,A
	EX	(SP),HL		;lauf. Adresstand in Stack,X-Koo. in HL
	BIT	7,H		;X negativ ?
	CALL	NZ,XMIN
	CALL	ADTRN		;Bitadresse 0-7 in A
	EX	DE,HL		;X-Segment-Koo. in DE
	POP	HL		;laufende Rechenadresse
	LD	B,A		;relative X-Adresse (BIT)
	LD	A,(ABLMRK)
	LD	C,A		;Vorzeichen in C
	POP	AF		;Startmaske
	JPBIT	5,C,SDHVR	;X negativ ?
				;HL,A (Maske) + DE,B (Zahl) -> HL,A (Maske)
				;BAE	:neue Bitadr. ermitteln
ADHVR:	ADD	HL,DE
BAE:	INC	B
DJLM:	DJNZ	MVL
	JR	HBST		;Programm verlassen
MVL:	RLCA			;Bitpos. nach rechts !
	CALL	C,AD8		;8 Bytes ADD.
	JR	DJLM
SDHVR:	SUBHL	DE
	INC	B
DJRM:	DJNZ	MVR
HBST:	SETNI	7,H
	RET			;Programm verlassen 
;-----------------------
MVR:	RRCA			;Bitpos. nach links!
	CALL	C,SB8		;8 Bytes SUB.
	JR	DJRM
YMIN:	EX	DE,HL
	LD	HL,ABLMRK	;Parameter in BC
	SET	6,(HL)		;Y negativ-Flag
	JR	MPCOM
XMIN:	EX	DE,HL
	LD	HL,ABLMRK	;Parameter in BC
	SET	5,(HL)
MPCOM:	LD	HL,0
	SUBHL	DE		;positive Zahl durch Komplement
	RET			;Ergebnis in HL
HLBLK:	PUSH	DE
	IF	BLOCKS EQ 96	;64*HL+32*HL=96*HL -> HL
	 ADD	HL,HL		;Koordinaten -> Speicheradressen
	 ADD	HL,HL
	 ADD	HL,HL
	 ADD	HL,HL
	 LD	D,H
	 LD	E,L
	 ADD	HL,HL
	 ADD	HL,DE
	 ADD	HL,HL
	ELSE
	.PRINTX * ACHTUNG - BLOCKS FALSCH BERECHNET! *
	ENDIF
	POP	DE
	RET
AD8:	PUSH	BC
	LD	BC,8
	ADD	HL,BC
	POP	BC
	RET
SB8:	PUSH	BC
	LD	BC,-8
	ADD	HL,BC
	POP	BC
	RET
;****** Routinen PIXLOG *******************
;HL=Pos; B: Maske; HL,DE,C: unveraendert

PCLXOR	EQU	$		;Transparent Vordergrundfarbe OR,XOR
PCLOR:	LD	(HL),B		;im Colormodus automatisch OR
	RET

PXXREP:	CALL	HGFS		;Transparent REPLACE
PCLDEL:	IF	XR
	 LD	A,(XRHGF)
	 OUT	(XRCLRG),A
	ELSE
	 LD	A,(HGFRG1)	;Transparent Hintergrundfarbe
	 OUT	(CLRG1),A
	 LD	A,(HGFRG2)
	 OUT	(CLRG2),A
	ENDIF
	LD	(HL),B
	JP	FRBRES
;-----------------------	
P0OR:	CALL	PCLFKT		;Grundebene loeschend OR
	OR	(HL)		;DELETE im Grundmodus
	XOR	B
	LD	(HL),A
	JP	WRTRES

P1OR:	CALL	PCLFKT		;Grundebene setzend OR
	OR	(HL)		;OR in Grundmdus
	LD	(HL),A
	JP	WRTRES

P0DEL:	CALL	HGFFKT		;Deckend mit Hintergrundfarbe GE 0
	OR	(HL)		;DELETE im Grundmodus
	XOR	B
	LD	(HL),A
	JP	WRTRES

P1DEL:	CALL	HGFFKT		;Deckend mit Hintergrundfarbe GE 1
	OR	(HL)		;OR in Grundmdus
	LD	(HL),A
	JP	WRTRES

P1XOR	EQU	$		;Grundebene invertierend
P0XOR:	CALL	PCLFKT
	XOR	(HL)		;XOR in Grundmodus
	LD	(HL),A
	JP	WRTRES
;----------------------------------------------------------
; Routinen fuer Replacemodi, Replace bedeutet, dass
; Luecken in unterbrochenen Vektoren geloescht werden
;----------------------------------------------------------
PX0REP:	CALL	HGFS	;VG CE
	CALL	HGFFKT	;HG CE
	OR	(HL)	;HG GE DEL
	XOR	B
	LD	(HL),A
	JP	WRTRES

PX1REP:	CALL	HGFS
	CALL	HGFFKT
	OR	(HL)
	LD	(HL),A
	JP	WRTRES

P0XREP:	CALL	PCLFKT	;VG CE
	OR	(HL)	;VG GE DEL
	XOR	B
	LD	(HL),A
	CALL	HGMS
	CALL	WRTRES
	JP	PCLDEL	;HG CE

P1XREP:	CALL	PCLFKT	;VG CE
	OR	(HL)	;VG GE OR 
	LD	(HL),A
	CALL	HGMS
	CALL	WRTRES
	JP	PCLDEL	;HG CE
;------------------------------
P00REP:	CALL	PVG0
	JR	PHG0
P01REP:	CALL	PVG0
	JR	PHG1
P10REP:	CALL	PVG1
	JR	PHG0
P11REP:	CALL	PVG1
PHG1:	CALL	HGMS
	CALL	HGFFKT	;HG CE
	OR	(HL)	;HG GE OR
	LD	(HL),A
	JP	WRTRES

PVG0:	CALL	PCLFKT	;VG CE
	OR	(HL)	;VG GE DEL
	XOR	B
	LD	(HL),A
	RET

PVG1:	CALL	PCLFKT	;VG CE
	OR	(HL)	;VG GE OR 
	LD	(HL),A
	RET

PHG0:	CALL	HGMS
	CALL	HGFFKT	;HG CE
	OR	(HL)	;HG GE DEL
	XOR	B
	LD	(HL),A
	JP	WRTRES
;----------------------------------
HGFS:	LD	(HL),B		;Schreibe CE
HGMS:	LD	A,(BLDBS)	;Setze Hintergrundmaske
	LD	B,A
	XOR	A
	LD	(BLDBS),A
	RET

HGFFKT:	IF	XR
	 LD	A,(XRHGF)
	 OUT	(XRCLRG),A
	ELSE
	 LD	A,(HGFRG1)	;Setze Hintergrundfarbe
	 OUT	(CLRG1),A
	 LD	A,(HGFRG2)
	 OUT	(CLRG2),A
	ENDIF
PCLFKT:	LD	(HL),B		;Umschalten auf write GE
	IF	XR
	 LD	A,00H
	 OUT	(XRFLGS),A	;lesen und Schreiben von/auf Grundebene
	 LD	A,10H
	 OUT	(XRFLGS),A
	ELSE
	 LD	A,10110111B
	 OUT	(CLRG1),A
	ENDIF
	LD	A,B
	RET
;-----------------------
POR:	LD	A,B
	OR	(HL)		;OR in Grundmdus
	LD	(HL),A
	RET
;-----------------------
PXOR:	LD	A,B
	XOR	(HL)		;XOR in Grundmodus
	LD	(HL),A
	RET
;-----------------------
PDEL:	LD	A,B
	OR	(HL)		;DELETE im Grundmodus
	XOR	B
	LD	(HL),A
	RET
;-----------------------
PREP:	LD	A,B
	OR	(HL)		;REPLACE im Grundmodus
	LD	(HL),A
	LD	A,(BLDBS)
	CPL
	AND	(HL)
	LD	(HL),A
	XOR	A
	LD	(BLDBS),A
	RET

	IF	XR
WRTRES:	LD	A,(XRRD)
	OUT	(XRFLGS),A
	LD	A,(XRWR)
	OUT	(XRFLGS),A
	JP	FRBRES
	ELSE
WRTRES:	JP	FRBRES
	ENDIF	
;--------------------------------------------------------------
;Ende der PIXLOG Routinen
;--------------------------------------------------------------
INILTG:	LD	HL,(GCPOS)
INILTY:	XOR	A
	LD	(BLDB),A
	LD	(BLDBS),A
	LD	A,(STAT3)	;Init LINTR; HL zeigt auf GCPOS!
	BIT	0,A		;SPRAY?
	JR	NZ,INISPR
	BIT	1,A		;Muster?
	JR	NZ,INIPAT
	LDB	(LINTR),(LINTYP);Normale Linie
	RET
INISPR:	LD	A,R		;Refresh-Register entkoppeln
	SLA	A
	ADC	A,D
	ADC	A,E
	ADC	A,B
	ADC	A,C
	ADC	A,(HL)
	LD	R,A
	RET
INIPAT:	LD	DE,VZSATZ+127*8	;7F-Muster
	JPNI	INIPA0
	LD	DE,VZSATZ+127*16
INIPA0:	LD	A,L		;Muster setzen
	AND	07H
	ADD	A,E
	LD	E,A
	LD	A,(DE)		;Mustermaske
	LD	(LINTR),A
	RET
;-----------------------
SETPAT:	LD	HL,STAT3
	RES	0,(HL)		;SPRAY inaktiv
	SET	1,(HL)		;Muster aktiv
	RET
;-----------------------
SETSPR:	CALL	VPSUB	
	CALL	HBINPR		;Grauwert holen
	RET	Z
	CALL	STDRT
	AND	15		;0..15
	JP	Z,LTYPOO	;Entspricht schwarzer Linie
	CP	15
	JP	Z,LTYPVL	;Entspricht voller Linie
	LD	HL,STAT3
	SET	0,(HL)		;Spray aktiv
	RES	1,(HL)		;Muster inaktiv
	LD	L,A		;SPRAY-Grauwert
	RLCA
	RLCA
	LD	H,A
	LD	(SPRAY),HL
	LDB	(PIXLG1),0C9H	;RET hierher
	CALL	SPRY		;LINTR setzen
	JP	SETFKT		;PIXLOG neu setzen

PIXLBG:	LDB	(PIXLG1),0C3H	;JP PIXLOG
	LDW	(PIXLG1+1),(PIXLOG+1)
	LDW	(PIXLOG+1),SPRY	;PIXLOG umbiegen auf PIXLG1
	RET

SPRY:	LD	A,R		;Zufallswert bilden
	ADC	A,L
	SBC	A,H
	ADC	A,C
	LD	R,A
	PUSH	HL
	PUSH	BC
	LD	HL,(SPRAY)	;H=SPRAY*4,L=SPRAY
	LD	B,4
SPRY1:	AND	00001111B
	CP	L		;SPRAY
	RR	C		;Bit setzen, wenn R < SPRAY 
	LD	A,R
	AND	00111100B
	CP	H		;SPRAY*4
	RR	C
	LD	A,R	
	DJNZ	SPRY1
	LDB	(LINTR),C	;Graumuster neu setzen
	POP	BC
	POP	HL
	LD	A,B		;Maske wieder setzen
	JP	PIXLG1		;Dort steht JP (PIXLOG)
;-----------------------
LTYPOO:	XOR	A
	JR	LTI
LTYPLG:	LD	A,0E7H		;Linienkommandos
	JR	LTI
LTYPKZ:	LD	A,0C3H
	JR	LTI
LTYPSP:	LD	A,09CH
	JR	LTI
LTYPPT:	LD	A,0AAH
	JR	LTI
LTYPVL:	LD	A,0FFH
LTI:	LD	(LINTYP),A
	LD	HL,STAT3
	RES	0,(HL)		;Spray inaktiv
	RES	1,(HL)		;Muster inaktiv
	JR	SETFKT		;PIXLOG wieder setzen
;-----------------------
SETIN:	LD	A,(GCMSK)
	LD	(BLDB),A
	RET
;-----------------------
ORFKT:	XOR	A		;Logikkommandos
	JR	VLAEV
DELFKT:	LD	A,2
	JR	VLAEV
XORFKT:	LD	A,4
	JR	VLAEV
REPFKT:	LD	A,6
VLAEV:	LD	(PFKT),A

SETFKT:	LD	A,(MODUS)
	JPBITZ	7,A,SETFK1	;Grundmodus unkompliziert
;Farbmodus aktiv
	LD	A,(PFKT)
	CP	2
	JR	Z,SETFK2	;DEL
	CP	6
	JR	Z,SETFK3	;REP
;OR,XOR gewaehlt
	LD	A,(STAT1)
	JPBITZ	6,A,SETFK6	;Vordergrund transparent
	JPBITZ	4,A,SETFK7	;Grundebenenbit Vordergrund
	JR	SETFK4		
;REP gewaehlt
SETFK3:	LD	A,(STAT1)
	LD	HL,PFKTBR	;REP-Tabelle Farbmodus
	RRCA
	RRCA
	AND	00011110B
	JR	SETFK0

;DEL gewaehlt
SETFK2:	LD	A,(STAT1)
	JPBITZ	5,A,SETFK6	;Hintergrund transparent
	JPBITZ	3,A,SETFK7	;Grundebenenbit Hintergrund

SETFK4:	LD	HL,PFKTB1	;Grundebene = 1
	JR	SETFK8
SETFK7:	LD	HL,PFKTB0	;Grundebene = 0
	JR	SETFK8
SETFK6:	LD	HL,PFKTAB	;Transparent
	JR	SETFK8

SETFK1:	LD	HL,PFKTBG	;Grundmodus s/w
SETFK8:	LD	A,(PFKT)
SETFK0:	LD	C,A
	LD	B,0

SETFK5:	ADD	HL,BC		;PIXLOG setzen
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	LD	(PIXLOG+1),DE
	LD	HL,STAT3
	BIT	0,(HL)		;SPRAY?
	CALL	NZ,PIXLBG	;dann PIXLOG umbiegen auf PIXLG1
	LD	A,(PFKT)	;Normaltabelle fuer CHRFKT
	LD	C,A
	LD	HL,CFKTAB
	ADD	HL,BC
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	LD	(CHRFKT+1),DE
	LD	(CHRFKS),DE
	RET

PFKTAB:	DW	PCLOR,PCLDEL,PCLXOR
PFKTB0:	DW	P0OR,P0DEL,P0XOR
PFKTB1:	DW	P1OR,P1DEL,P1XOR
PFKTBG:	DW	POR,PDEL,PXOR,PREP
PFKTBR: DW	PXXREP,PXXREP,PXXREP,PXXREP	;HG,VG transparent
	DW	PX0REP,PX1REP,PX0REP,PX1REP	;VG transparent, HG nicht
	DW	P0XREP,P0XREP,P1XREP,P1XREP	;HG transparent, VG nicht
	DW	P00REP,P01REP,P10REP,P11REP	;HG, VG nicht transparent
CFKTAB:	DW	CHROR,CHRDEL,CHRXOR,CHRREP
;-----------------------
COMPR:	LD	A,L
	RLCA
	RLCA
	RLCA			;BIT 5 jetzt linksbuendig
	REPT	3
	 SRL	H
	 RRA			;jetzt 10 Bits rechtsbuendig in HL
	ENDM
	LD	L,A
	RET
;-----------------------
KOOLD:	LD	A,(WRKCHR)	;Koordinatenaufnahme
	AND	60H
	SRL	A
	SRL	A
	SRL	A
	SRL	A		;Koordinatenalternative als Zahl 2,4,6
	LD	C,A
	LD	B,0
	LD	HL,(ZPTR)	;Zustandspointer
	ADD	HL,BC
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	LD	A,(WRKCHR)
	AND	1FH
	EX	DE,HL
	JP	(HL)
;-----------------------
P0P:	DW	0,PHY,PLX,PLY
PLYP:	DW	0,PHX,PLX,PLY
PHYP:	DW	0,PHY,PLX,PLY
PHXP:	DW	0,PHX,PLX,PLY
;-----------------------
PLY:	LD	(VLY),A		;Koordinate Y NWB laden
	LD	HL,PLYP
	JR	PTL
PHX:	LD	(VHX),A		;X HWB
	LD	HL,PHXP
	JR	PTL
PHY:	LD	(VHY),A		;Y HWB
	LD	HL,PHYP
PTL:	LD	(ZPTR),HL
	RET
;-----------------------
PLX:	LD	(VLX),A		;X NWB Abschluss
	LD	HL,P0P		;Zustand 0 ,Startzustand
	LD	(ZPTR),HL
	LD	HL,(VLX)	;H=VHX,L=VLX
	CALL	COMPR		;komprimieren auf 10 Bit
	LD	(X2),HL
	EX	DE,HL		;X-Koordinate in DE
	LD	HL,(VLY)
	CALL	COMPR
	JPI	PLX1
	SRL	H
	RR	L
PLX1:	LD	(Y2),HL
	PUSH	HL		;Y-Koordinate
	LD	HL,(TXNULL)
	SETNI	7,H
	LD	A,01H		;Koordinatennullpunkt Ecke unten links
	POP	BC		;Y-Koordinate
	CALL	ADWDL		;berechnen der Ram-Adresse des Endpunkts
	LD	(ENDPOS),HL
	LD	(ENDMSK),A	;Ram-Adresse des (End)Punkts
	LD	HL,(VKTPRG)	;ausfuehrendes Programm
	JP	(HL)
;-----------------------
IMEX:	LD	HL,IMXTAB	;ausfuehrende Programme
	SLA	C
	RL	B
	ADD	HL,BC
	LD	D,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,D
	LD	DE,(X1)
	LD	BC,(Y1)
	JP	(HL)

;========== Incrementalmodus Kommandotabelle ==========

IMCTAB:	DB	' PQRDEAIHJBF'
LIMCT	EQU	$-IMCTAB
IMXTAB:	DW	BLO,BL,BLU,BU,BRU,BR,BRO,BO,BINV,BDEL,BVOLL,BLEER

;-----------------------
BRU:	CALL	GINC	;1 Pixel nach rechts, BC gesichert
	JR 	BU
BR:	CALL	GINC
	JR	PZCH
BRO:	CALL	GINC
	JR	BO
BLU:	CALL	GDEC
BU:	DEC	BC
	LD	A,(ITLFLG)
	OR	C
	BIT	0,A
	CALL	NZ,GDWN		;1 Pixel down bei ungerader Koordinate
	JR	PZCHB
BL:	CALL	GDEC		;1 Pixel nach links
	JR	PZCH
BLO:	CALL	GDEC		;GCPOS 1 Pixel in -X-Richtung
BO:	INC	BC
	LD	A,(ITLFLG)
	CPL
	AND	C
	BIT	0,A
	CALL	Z,GUP		;1 Pixel hoch bei gerader Koordinate
PZCHB:	LD	(Y1),BC
PZCH:	LD	HL,BTPUF	;VKTPRG Return direkt nach BTPUF
	PUSH	HL
	LD	HL,(VKTPRG)	;hier SETIN oder RET
	JP	(HL)
;-----------------------
GDEC:	DEC	DE
	LD	(X1),DE
GDECA:	LD	HL,GCMSK
	RRC	(HL)
	RET	NC
	PUSH	BC
	CALL	VDI
	POP	BC
	RET

GINC:	INC	DE
	LD	(X1),DE
GINCA:	LD	HL,GCMSK
	RLC	(HL)
	RET	NC
	PUSH	BC
	CALL	VII
	POP	BC
	RET
;-----------------------
SETNON:	POP	HL
	RET
;-----------------------
BVOLL:	CALL	ORFKT
	JR	VLAE
BINV:	CALL	XORFKT
	JR	VLAE
BDEL:	CALL	DELFKT
	JR	VLAE
BLEER:	LD	HL,SETNON	;Leeroperation
	JR	VLAE1

VLAE:	LD	HL,SETIN
VLAE1:	LD	(VKTPRG),HL
	RET

	IF	$ GT 4000H
	 PRINTS <PAGE A zu gro~! >,%($-4000H)
	ELSE
	 PRINTS	<PAGE A frei: >,%(4000H-$)
	ENDIF

	ENDIF
;*********************************************************
;* MODUL EPR2     ab hier Programmteile in EPROM-Haelfte 1    ****
;*********************************************************
	IF	EPAGE EQ 1

SYSTST:	LD	SP,STKH		;Interner Systemtest wenn VDC nicht bestueckt
	LD	A,15		;VDC-Register beschreiben
	OUT	(VDCAR),A
	LD	A,5AH
	OUT	(VDCWR),A
	IN	A,(VDCRD)	;wieder lesen
	CP	5AH
	JP	Z,INIJMP	;VDC-Chip vorhanden ?

SYST1:	LD	A,7
	OUT	(TABCR),A
	LD	A,10
	OUT	(TBDR),A	;1000Hz
	LD	A,80H
	OUT	(VOL1),A
	XOR	A		;teste VIDEO-Ram
	LD	IX,SYSTS3	;IX als Ruecksprungadresse, da Stack nicht
	JR	RAMTST		;vorhanden
SYSTS3:	JR	NZ,SYST2
	LD	A,80H		;teste SPOOLER-Ram
	LD	IX,SYSTS4
	JR	RAMTST
SYSTS4:	JR	NZ,SYST2
	LD	A,20
	OUT	(TBDR),A	;500Hz wenn Ram OK
SYST2:	OUT	(14H),A
	OUT	(2FH),A
	OUT	(30H),A
	IN	A,(40H)		;Portadressen zyklisch selectieren
	OUT	(50H),A
	OUT	(60H),A
	IN	A,(71H)
	JR	SYST2
;-----------------------
RAMTST:	OUT	(PAGE),A	;Ram Page selektieren
	LD	HL,8000H	;32 Kbyte testen
	LD	BC,8000H
	LD	A,5AH
RTHL:	LD	(HL),A
	CP	(HL)
	JR	NZ,RAMTS1
	INC	HL
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,RTHL
RAMTS1:	JP	(IX)		;Ruecksprung ohne Stack
;-----------------------
;CHRGNB schreibt Statuszeile-Zeichen aus GZSATZ/GRAFIT

	IF	XR
CHRGNB:	CALL	ZADRB		;Pointer auf Character in CHSET
	LD	DE,(VDPT)	;Pointer auf VideoRam
	LD	BC,8
	LD	A,(XRHGF)
	PUSH	AF
	XOR	A
	LD	(XRHGF),A
	JPI	TBITVB

TBWTVB:	CALLA	FBECLR		;vor jedem Zeichen Feld in Farbebene loeschen
	LD	A,0FFH		;Statuszeile immer weiss
	OUT	(XRCLRG),A
	REPT	8
	 LDI			;schneller als LDIR !
	ENDM
	POP	AF
	LD	(XRHGF),A
	JP	XRCRES

;-------------------------- Char-gen fuer TVI-Farbmodus Interlaced
TBITVB:	CALLA	FBECLI		;vor jedem Zeichen Feld in Farbebene loeschen
	LD	A,0FFH		;Statuszeile immer weiss
	OUT	(XRCLRG),A
	LD	A,D
	OUT	(PAGE),A
	PUSH	DE
	SET	7,D
	REPT	8
	 LDI			;schneller als LDIR !
	ENDM
	POP	DE
	LD	A,D
	ADD	A,HIGH PITCH
	LD	D,A
	OUT	(PAGE),A
	PUSH	DE
	SET	7,D
	REPT	8
	 LDI			;schneller als LDIR !
	ENDM
	POP	DE
	POP	AF
	LD	(XRHGF),A
XRCRES:	LD	A,(XRCOL)	;damit Bitcounter nicht incrementiert wird
	OUT	(XRCLRG),A
	RET
;--------------------------
	ELSE
CHRGNB:	CALL	ZADRB		;Pointer auf Character in CHSET
	LD	DE,(VDPT)	;Pointer auf VideoRam
	LD	A,10110000B	;nur in Grundebene schreiben
	OUT	(CLRG1),A
	OUT	(CLRG2),A
	JPI	TBITVB

	REPT	8
	 LDI			;schneller als LDIR !
	ENDM
	JR	CHRGB1

TBITVB:	LD	A,D
	OUT	(PAGE),A
	PUSH	DE
	SET	7,D
	REPT	8
	 LDI			;schneller als LDIR !
	ENDM
	POP	DE
	LD	A,D
	ADD	A,HIGH PITCH
	LD	D,A
	OUT	(PAGE),A
	PUSH	DE
	SET	7,D
	REPT	8
	 LDI			;schneller als LDIR !
	ENDM
	POP	DE

CHRGB1:	LD	A,(COLRG2)	;Colorregister wieder normal
	OUT	(CLRG2),A
	LD	A,(COLRG1)
	OUT	(CLRG1),A
	RET
	ENDIF	;XR
;-----------------------
ZADRB:	JPI	ZADRBI
	LD	HL,ZSATZ
	LD	C,A	;Pointer HL auf Zeichen im Zeichensatz setzen
	XOR	A	;HL=Zeichensatzanfang
	SLA	C	;A =Zeichen 0-7F
	RLA
	SLA	C
	RLA
	SLA	C
	RLA		;Hexwert*8=relative Zeichensatzadr.
	LD	B,A
	ADD	HL,BC
	RET

ZADRBI:	JPBITZ	7,A,ZADBI1	;Sonderzeichen fuer Statuszeile
	RES	7,A		;aus GRAFIK Zeichensatz holen
	LD	HL,GRAFIT
	JR	ZADBI2
ZADBI1:	LD	HL,ZSATZI	;sonst aus aktuellem Zeichensatz
ZADBI2:	LD	C,A	;Pointer HL auf Zeichen im Zeichensatz setzen
	XOR	A	;HL=Zeichensatzanfang
	SLA	C	;A =Zeichen 0-7F
	RLA
	SLA	C
	RLA
	SLA	C
	RLA		;Hexwert*8=relative Zeichensatzadr.
	SLA	C
	RLA
	LD	B,A
	ADD	HL,BC
	RET
;----------------------------
STGOFB:	LD	HL,ZSATZ+'A'*8
	JPNI	STGR
	LD	HL,ZSATZI+'A'*16
	LD	DE,VZSATZ+'A'*16
	LD	BC,16*26
STLDR:	LDIR
	RET
;-----------------------
STGONB:	LD	HL,IGZSTZ
STGR:	LD	DE,VZSATZ+'A'*8
	LD	BC,26*8
	JPNI	STLDR
	LD	HL,IGZSTZ
	LD	DE,VZSATZ+'A'*16
	LD	BC,8*26
	LDIR
	LD	HL,VZSATZ+'A'*16+8*26-1
	LD	DE,VZSATZ+'A'*16+16*26-1
	LD	BC,8*26
	JP	ZSDOP
;-----------------------
ZSZDFB:	JPNI	ZSZDFN		;Zeichensatz auswaehlen 

	CP	'8'		;Zeichensatz komplett aus ROM-kopieren
	JR	NC,ZSIDF1
	LD	B,A
	LD	A,(MSCHST)
	CP	'8'
	LD	A,B
	JR	NZ,ZSZDF9	;wenn vorher Griechisch gewaehlt war
	PUSH	AF
	CALL	LDZROM		;ASCII Satz aus ROM neu laden
	LD	A,'0'		;ASCII
	LD	(MSCHST),A
	POP	AF
	JP	ZSZDF9

ZSIDF1:	JR	NZ,ZSIDF2
	LD	(MSCHST),A
	CALL	LDGROM		;Lade Griechisch aus anderer ROM-Haelfte
	JP	ZSZDF4
	
ZSIDF2:	CP	'9'
	JR	NZ,ZSIDF5
	CALL	LDZROM
	JP	ZSZDF4

ZSIDF5:	LD	DE,(CHSET)
	LD	HL,ZSATZI	;4 verschiedene Zeichensaetze in Ram kopieren
	CP	':'
	JR	Z,ZSIDF3
	LD	HL,IZSZI	;Index
	CP	';'
	JR	NZ,ZSIDF8
ZSIDF3:	LD	BC,0800H
	LDIR
	LD	A,(MSCHST)
	CALL	SPZCHG
	JR	ZSZDF4

ZSIDF8:	LD	HL,ZSZGRK	;Griechisch aus andere EPROM Haelfte laden
	CP	'<'
	JR	Z,ZSIDF7
	LD	HL,IGZSTZ	;Index Griechisch
	CP	'='
	RET	NZ		;unerlaubtes Zeichen

ZSIDF7:	LD	BC,0400H
	LDIR
	LD	HL,(CHSET)
	LD	BC,03FFH
	ADD	HL,BC
	PUSH	HL
	INC	BC
	ADD	HL,BC
	POP	DE
	EX	DE,HL
	CALL	ZSDOP
	JP	ZSZDF4
;-----------------------
ZSZDFN:	CP	'9'		;Zeichensatz komplett aus ROM-kopieren
	JR	NC,ZSZDF1
ZSZDF9:	CALL	SPZSET		;setze nationale Zeichen
	CALL	SETZPT		;setze Zeichensatzpointer CHSET
	RET

ZSZDF1:	JR	NZ,ZSZDF2
	CALL	LDZROM
	JR	ZSZDF4
	
ZSZDF2:	LD	DE,(CHSET)
	LD	HL,ZSATZ	;4 verschiedene Zeichensaetze in Ram kopieren
	CP	':'
	JR	Z,ZSZDF3
	LD	HL,ZSZGRK	;Griechisch
	CP	'<'
	JR	Z,ZSZDF3
	LD	HL,IZSATZ	;Index
	CP	';'
	JR	Z,ZSZDF3
	LD	HL,IGZSTZ	;Index Griechisch
	CP	'='
	RET	NZ		;unerlaubtes Zeichen

ZSZDF3:	LD	BC,0400H
	LDIR
ZSZDF4:	LD	HL,STAT5
	SET	3,(HL)		;spaeter Checksumme bilden 
	RET
;-----------------------
LDZROM:	LD	HL,ZSATZ	;ASCII Norm und Index aus ROM kopieren
	JPNI	LDZRO1
	LD	HL,ZSATZI
LDZRO1:	LD	DE,VZSATZ
	LD	BC,1000H
	LDIR
	LD	A,(MSCHST)
	CALL	SPZCHG
	RET
;-----------------------
;SPEZIELLE ZEICHENZUORDNUNG
SPZPTB:	DW	SPZASC,SPZBRT,SPZGER,SPZDN,SPZFB,SPZSF,SPZIT,SPZSP

SPZASC:	DB	23H,40H,5BH,5CH,5DH,5EH,60H,7BH,7CH,7DH,7EH	;CODE
SPZBRT:	DB	04H,40H,5BH,5CH,5DH,5EH,60H,7BH,7CH,7DH,7EH	;Britisch
SPZGER:	DB	23H,10H,0BH,0CH,0EH,5EH,60H,1BH,1CH,1EH,11H	;Deutsch
SPZDN:	DB	23H,40H,0AH,0FH,0DH,5EH,60H,1AH,1FH,1DH,7EH	;Dae/Norw.
SPZFB:	DB	04H,12H,05H,18H,10H,5EH,60H,17H,16H,13H,06H	;Franz/Belg.
SPZSF:	DB	23H,08H,0BH,0CH,0DH,0EH,17H,1BH,1CH,1DH,1EH	;Schwed/Finn.
SPZIT:	DB	23H,10H,05H,18H,17H,5EH,16H,12H,15H,13H,14H	;Italien
SPZSP:	DB	23H,40H,02H,09H,03H,5EH,60H,06H,19H,7DH,7EH	;Spanien
;-----------------------
	IF	DEBUG
	DB	'SPZSET'
	ENDIF

SPZSET:	PUSH	AF
	LD	A,(MSCHST)	;zuerst zuruecktauschen
	CALL	SPZCHG
	POP	AF
	LD	(MSCHST),A
	CALL	SPZCHG		;dann nationale Zeichen austauschen
	RET
;-----------------------
SPZCHG:	AND	07H		;nationale Zeichen untereinander austauschen
	SLA	A		;ohne Verlust von geaenderten Zeichen
	LD	HL,SPZPTB	;'8' wird als dummy wie '0' behandelt ! AND 07H
	LD	C,A
	LD	B,0
	ADD	HL,BC
	LD	E,(HL)		;HL is Pointer to new Set
	INC	HL
	LD	D,(HL)

	LD	HL,SPZASC	;DE is Pointer to Position of Char.
	EX	DE,HL
	LD	B,11		;11 Char. to change
SPZST1:	PUSH	DE
	PUSH	BC
	PUSH	HL
	LD	B,0
	LD	HL,VZSATZ
	LD	A,(DE)
	SLA	A
	RL	B
	SLA	A
	RL	B
	SLA	A
	RL	B
	JPNI	SPZST2
	SLA	A
	RL	B
SPZST2:	LD	C,A
	ADD	HL,BC
	EX	DE,HL		;DE Points to Position to change
	POP	HL
	PUSH	HL
	LD	B,0
	LD	A,(HL)		;HL Points to new Character
	LD	HL,VZSATZ
	SLA	A
	RL	B
	SLA	A
	RL	B
	SLA	A
	RL	B
	JPNI	SPZST3
	SLA	A
	RL	B
SPZST3:	LD	C,A
	ADD	HL,BC
	PUSH	HL
	PUSH	DE
	LD	BC,0800H	;Pointer auf Indexzeichensatz richten
	ADD	HL,BC
	EX	DE,HL
	ADD	HL,BC
	EX	DE,HL
	CALL	EXCHGZ		;2 Zeichen tauschen von (DE) <-> (HL) 8 byte
	POP	DE
	POP	HL
	CALL	EXCHGZ		;2 Zeichen tauschen von (DE) <-> (HL) 8 byte
	
	POP	HL
	POP	BC
	POP	DE
	INC	HL
	INC	DE
	DJNZ	SPZST1		;tausche 11 Zeichen
	RET
;-----------------------
EXCHGZ:	LD	B,8
	JPNI	SPZCH1
	LD	B,16
SPZCH1:	LD	C,(HL)		;tausche nationale Zeichen
	LD	A,(DE)		;sowohl in Norm als auch Indexzeichensatz
	LD	(HL),A
	LD	A,C
	LD	(DE),A
	INC	HL
	INC	DE	
	DJNZ	SPZCH1
	RET
;-----------------------
SETZPT:	LD	HL,VZSATZ
	LD	A,(ATTRIB)
	AND	00110000B
	CP	00110000B
	JR	Z,SETZP1
	LD	BC,0800H
	ADD	HL,BC
SETZP1:	JPI	SETZP2
	LD	A,(MSCHST)
	CP	'8'
	JR	NZ,SETZP2
	LD	BC,0400H
	ADD	HL,BC
SETZP2:	LD	(CHSET),HL
	RET	
;-----------------------
LDGROM:	LD	HL,ZSZGRK	;lade Griechisch aus anderer EPROM Page
	LD	DE,VZSATZ
	LD	BC,0400H
	LDIR
	LD	HL,IGZSTZ
	LD	BC,0400H
	LDIR
	LD	HL,VZSATZ+07FFH
	LD	DE,VZSATZ+0FFFH
	LD	BC,0800H
ZSDOP:	LD	A,(HL)
	LDD
	LD	(DE),A
	DEC	DE
	JP	PE,ZSDOP
	RET
;----------------------------
	IF	$ GT GRAFIT
	.PRINTX *** ERROR: Page B zu gro~! ***
	ELSE
	 PRINTS	<PAGE B frei: >,%(GRAFIT-$)
	ENDIF

	ENDIF

	IF	$ LT 4000H
	REPT	4000H-$
	DB	0FFH
	ENDM
	ENDIF

	END
