CENI    ASM;---------------------------------
;Druckertreiber aus BASCODER V1.5
;
;abge{ndert f}r CENTRONICS-M021
;und externe V.24-Tastatur
;Programm nur f}r KC85/4
;EPSON-Drucker an CENTRONICS-Modul
;Hardcopy mit ESC,*,5 f}r 9-Nadler!
;Men}wortfreigabe }ber Selbststart,
;nur wenn M021 vorhanden
;
;Adressen: BA00 BD80 BC0B
;
;
;CENI.ASM	` ML-Soft 20.11.93
;---------------------------------
ARGN	EQU	0B781H
HCADR	EQU	0B799H
UOUT1	EQU	0B7BDH
PV1	EQU	0F003H
KBDZ	EQU	0EH
 
LF	EQU	0AH
CR	EQU	0DH
ESC	EQU	1BH
 
PIOAD	EQU	90H
PIOBD	EQU	91H
PIOAS	EQU	92H
PIOBS	EQU	93H
 
	ORG	0BA00H
;-------
;Fenster mit Tastatur einstellen:
 
WINDOW:	CALL	INVWI	;invertieren
	XOR	A	;schnell
WIN0	LD	(TIME),A
WIN1	LD	A,(IX+13)
	OR	A	;warten bis
	JR	NZ,WIN1	;keine Taste!
WIN2	LD	A,(TIME)
	OR	A	;schnell?
	LD	A,(IX+13)
	JR	Z,WIN3	;ja
	CALL	PV1
	DB	KBDZ	;Tastaturrepeat
	JR	NC,WIN2	;keine Taste
WIN3	OR	A
	JR	Z,WIN2	;Code 00
	CP	8
	JR	NZ,WIN4
	LD	HL,(COL1)	;<CUL>
	LD	A,H
	OR	L
	JR	Z,WIN2
	DEC	HL
	LD	(COL1),HL
	CALL	LINKS
	JR	WIN2
WIN4	CP	9
	JR	NZ,WIN5
	LD	HL,(COL2)	;<CUR>
	LD	DE,319
	CALL	CPHL
	JR	Z,WIN2
	INC	HL
	LD	(COL2),HL
	CALL	RECHTS
	JR	WIN2
WIN5	CP	0AH
	JR	NZ,WIN6
	LD	A,(LIN2)	;<CUD>
	CP	0FFH
	JR	Z,WIN2
	INC	A
	LD	(LIN2),A
	CALL	UNTEN
	JR	WIN2
WIN6	CP	0BH
	JR	NZ,WIN7
	LD	A,(LIN1)	;<CUU>
	OR	A
	JR	Z,WIN2
	DEC	A
	LD	(LIN1),A
	CALL	OBEN
	JR	WIN2
WIN7	CP	19H
	JR	NZ,WIN8
	LD	HL,(COL2)	;<SCUL>
	LD	DE,(COL1)
	CALL	CPHL
	JR	Z,WIN2
	CALL	RECHTS
	DEC	HL
	LD	(COL2),HL
	JP	WIN2
WIN8	CP	18H
	JR	NZ,WIN9
	LD	HL,(COL1)	;<SCUR>
	LD	DE,(COL2)
	CALL	CPHL
	JP	Z,WIN2
	CALL	LINKS
	INC	HL
	LD	(COL1),HL
	JP	WIN2
WIN9	CP	12H
	JR	NZ,WIN10
	LD	A,(LIN2)	;<SCUD>
	LD	B,A
	LD	A,(LIN1)
	CP	B
	JP	Z,WIN2
	CALL	OBEN
	INC	A
	LD	(LIN1),A
	JP	WIN2
WIN10	CP	11H
	JR	NZ,WIN11
	LD	BC,(LIN2)	;<SCUU>
	LD	A,C
	CP	B
	JP	Z,WIN2
	CALL	UNTEN
	DEC	A
	LD	(LIN2),A
	JP	WIN2
WIN11	CP	20H
	JR	NZ,WIN13
	LD	A,(TIME)	;<Space>
	CPL		;wechseln
	JP	WIN0
WIN13	CP	CR
	JR	Z,INVWI		;<CR>
	CP	10H
	CALL	Z,INVWI		;<HOME>
	JP	WIN2
;-------
;Fenster invertieren:
 
INVWI:	LD	A,(TIME)
	PUSH	AF
	LD	A,-1
	LD	(TIME),A;ohne Verz|ger.
	LD	BC,(LIN2)
	LD	A,C
	LD	HL,(COL1)
	LD	DE,(COL2)
INVW1	CP	B
	JR	Z,INVW2	;letzte Zeile
	CALL	INVLIN
	DEC	A
	JR	INVW1
INVW2	CALL	INVLIN
	POP	AF
	LD	(TIME),A
	RET
;-------
;linke Linie invertieren:
 
LINKS:	PUSH	HL
	LD	HL,(COL1)
	JR	LR1
;-------
;rechte Linie invertieren:
 
RECHTS:	PUSH	HL
	LD	HL,(COL2)
LR1	LD	A,(LIN2)
	LD	B,A
	LD	A,(LIN1)
	CALL	INVCOL	;Spalte
	POP	HL
	RET
;-------
;obere Linie invertieren:
 
OBEN:	PUSH	AF
	LD	A,(LIN1)
	JR	TB1
;-------
;untere Linie invertieren:
 
UNTEN:	PUSH	AF
	LD	A,(LIN2)
TB1	LD	HL,(COL1)
	LD	DE,(COL2)
	CALL	INVLIN	;Zeile
	POP	AF
	RET
;-------
;Spalte negieren:
;PE:	HL	Spalte
;	A	von Zeile
;	B	bis Zeile
 
INVCOL:	PUSH	DE
	PUSH	AF
	PUSH	HL
	PUSH	BC
	CALL	IRMAD	;IRM-Adresse
	EX	AF
	XOR	A
	INC	B	;Bitadresse
	SCF
INVC1	RRA		;Bit einschieben
	DJNZ	INVC1
	EX	AF	;in A'
	POP	BC
	POP	HL
	PUSH	HL
	CALL	PIXBT	;Bytespalte
	DEC	A
INVC2	INC	A	;n{chste Zeile
	PUSH	HL
	LD	H,L
	SET	7,H	;IRM
	LD	L,A	;Zeile
	EX	AF
	PUSH	AF
	XOR	M	;negieren!
	LD	M,A	;eintragen
	POP	AF
	EX	AF
	POP	HL
	CP	B
	JR	NZ,INVC2
	LD	A,(LIN1)
	DEC	A
	SUB	B
	CALL	PAUSE	;Verz|gerung
	POP	HL
	POP	AF
	POP	DE
	RET
;-------
;Zeile negieren:
;PE:	A	Zeile
;	HL	von Spalte
;	DE	bis Spalte
 
INVLIN:	PUSH	DE
	PUSH	HL
	PUSH	BC
	PUSH	AF
	EX	DE,HL
	CALL	IRMAD	;IRM-Adresse 2
	LD	C,B	;Bitadr. 2
	EX	DE,HL
	CALL	IRMAD	;IRM-Adresse 1
	CALL	CPHL
	JR	Z,INVL2	;Adr1=Adr2
	PUSH	BC
	LD	C,7	;erstes Zeichen
	CALL	BMASK	;bis rechts
	POP	BC
	LD	B,0	;letztes Zeichen
	XOR	M	;mit Maske
INVL1	LD	M,A	;negieren
	INC	H
	CALL	CPHL
	JR	Z,INVL2	;letzte Adresse
	LD	A,M
	CPL		;voll negieren
	JR	INVL1
INVL2	CALL	BMASK
	XOR	M	;letzte Adr.
	LD	M,A	;negieren
	LD	A,(TIME)
	CPL
	CALL	PAUSE	;Verz|gerung
	POP	AF
	POP	BC
	POP	HL
	POP	DE
	RET
;-------
;Berechnung der IRM-Adresse aus
;Spalte und Zeile
;PE:	HL	Spalte
;	A	Zeile
;PA:	HL	IRM-Adresse
;	B	Bitadresse
 
IRMAD:	PUSH	DE
	LD	D,H
	LD	E,L
	CALL	PIXBT	;Bytespalte
	PUSH	HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	EX	DE,HL
	SBC	HL,DE
	LD	B,L	;Bitadresse
	POP	HL
	LD	H,L
	SET	7,H	;IRM
	LD	L,A
	POP	DE
	RET
;-------
;Umrechnung Pixelspalte in Byteadr.
;PE:	HL	Pixelspalte
;PA:	HL	Bytespalte
 
PIXBT:	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	LD	L,H
	LD	H,0
	RET
;-------
;Maske f}r Spaltenadresse berechnen
;PE:	B	Bitadresse links
;	C	Bitadresse rechts
;PA:	A	Bitmaske
 
BMASK:	PUSH	BC
	LD	A,C
	SUB	B
	INC	A
	LD	C,B
	LD	B,A	;Anzahl Bits
	LD	A,C
	OR	A
	JR	NZ,BMA1
	LD	C,8	;0=8
BMA1	XOR	A
BMA2	SCF		;1-Bits
	RRA		;einschieben
	DJNZ	BMA2
	LD	B,C
BMA3	RRCA		;an richtige
	DJNZ	BMA3	;Stelle
	POP	BC
	RET
;-------
;Vergleicht HL mit DE:
 
CPHL:	OR	A
	SBC	HL,DE
	ADD	HL,DE
	RET
;-------
;Variable Zeitschleife:
;PE:	A	Zeitfaktor
 
PAUSE:	AND	A
	RET	Z
	PUSH	BC
	LD	B,2
PAUS	DJNZ	PAUS
	POP	BC
	DEC	A
	JR	PAUSE
;-------
;Aufruf CEN-Routine:
 
CENI:	DW	0
	DB	'CENI',1
	LD	HL,ARGN
	LD	DE,HORIZ;Parameter
	LD	B,M
	INC	B	;Args+1
	JR	CENI2
CENI1	LD	A,M
	LD	(DE),A	;eintragen
	INC	DE
	INC	HL
CENI2	INC	HL
	DJNZ	CENI1
	XOR	A	;Freigabe
	LD	(ENABL),A
START:	LD	A,0CFH
	OUT	(PIOBS),A
	XOR	A
	OUT	(PIOBS),A
	LD	A,55H
	OUT	(PIOBD),A
	IN	A,(PIOBD)
	CP	55H	;Modul vorh.?
	JR	Z,CENI5
CENI4	LD	A,-1	;gesperrt
	LD	(ENABL),A
	RET
CENI5	LD	HL,7F7FH ;Men}wort
	LD	(CENI),HL;freigeben
	LD	HL,PRINT
	LD	(UOUT1+1),HL
	LD	HL,HCOPY
	LD	(HCADR),HL
	DI
	LD	A,0CFH
	OUT	(PIOAS),A
	LD	A,7FH
	OUT	(PIOAS),A
	LD	A,80H	;STROBE passiv
	OUT	(PIOAD),A
	EI
	IN	A,(PIOAD)
	BIT	6,A	;busy?
	JR	NZ,CENI4;nicht bereit
	LD	HL,DRINI;Drucker init.
	LD	B,8	;8 Bytes
CENI6	LD	A,M
	INC	HL
	CALL	DRUCK
	DJNZ	CENI6
	JP	PRI_NL	;LF,CR
;-------
;Ausgabe eines Zeichens zum Drucker:
 
DRUCK:	PUSH	AF
DRU1	IN	A,(PIOAD)
	BIT	6,A	;BUSY?
	JR	Z,DRU2	;bereit
	LD	A,(ENABL)
	OR	A
	JR	NZ,DRU3;kein Druck!
	LD	A,-1
	CALL	PAUSE	;warten
	JR	DRU1
DRU2	XOR	A
	LD	(ENABL),A
	POP	AF
	PUSH	AF
	OUT	(PIOBD),A;Zeichen
	XOR	A
	OUT	(PIOAD)
	LD	A,80H	;Strobe-Impuls
	OUT	(PIOAD)
DRU3	POP	AF
	RET
;-------
HCOPY:	PUSH	DE	;Fenster
	CALL	WINDOW	;ausw{hlen
	LD	A,(HORIZ)
	LD	B,A	;Faktor
	LD	HL,(COL2)
	LD	DE,(COL1)
	OR	A
	SBC	HL,DE
	INC	HL
	EX	DE,HL
	LD	HL,0
HCOP1	ADD	HL,DE
	DJNZ	HCOP1
	LD	(DRCOL),HL;Druckspalten
	LD	A,(VERTI)
	LD	B,A	;Faktor
	LD	A,(LIN1)
	LD	C,A	;akt. Zeile
HCOP2	LD	HL,(COL1)
	LD	(TIME),HL
	LD	A,(IX+13)
	CP	3
	JR	Z,HCOP8	;->BRK
	CALL	GRAPH	;ESC,*,5
HCOP3	PUSH	BC
	LD	D,8	;8 Nadeln
	XOR	A
	LD	(LFLAG),A
HCOP4	CALL	RDBIT	;Bit lesen
	EX	AF
	RRC	E
	RLA		;einschieben
	EX	AF
	DJNZ	HCOP5	;vert. Faktor
	LD	A,(VERTI)
	LD	B,A	;neu
	INC	C	;n{chste Zeile
HCOP5	DEC	D
	JR	NZ,HCOP4;alle Nadeln
	LD	A,(HORIZ)
	PUSH	BC
	LD	B,A
	EX	AF
HCOP6	CALL	DRUCK	;Code zum Druck
	DJNZ	HCOP6	;horiz. Faktor
	POP	BC
	PUSH	DE
	LD	HL,(TIME)
	LD	DE,(COL2)
	CALL	CPHL
	POP	DE
	JR	Z,HCOP7	;letzte Zeile
	POP	BC
	INC	HL	;weiter in Zeile
	LD	(TIME),HL
	JR	HCOP3
HCOP7	POP	HL
	CALL	LAST
	JR	Z,HCOP2	;noch eine Zeile
HCOP8	POP	DE
	RES	0,(IX+8);Taste (BRK)
	RET		;quittieren
;-------
;Bit aus IRM lesen:
;PE:	C	akt. Zeile
;	(TIME)	akt. Spalte
;PA:	E=0	Bit nicht gesetzt
;	E=-1	Bit gesetzt
 
RDBIT:	PUSH	DE
	PUSH	BC
	CALL	LAST
	JR	NZ,BIT2
	LD	HL,(TIME)
	LD	A,C
	CALL	IRMAD	;IRM-Adresse
	INC	B	;Bitadresse
	LD	A,M	;Byte lesen
BIT1	RLA		;Bit ermitteln
	DJNZ	BIT1
BIT2	POP	BC
	JR	C,BIT3
	POP	DE
	LD	E,0
	RET
BIT3	POP	DE
	LD	E,-1
	RET
;-------
;Abfrage letzte Zeile:
;PA:	Z=0	nach letzter Zeile
 
LAST:	LD	A,(LIN2)
	CP	C	;letzte Zeile?
	JR	Z,LAST1	;ja
	LD	A,(LFLAG)
	OR	A
	RET
LAST1	LD	A,-1	;merken
	LD	(LFLAG),A
	RET
;-------
;Druckzeile im Grafikmodus er|ffnen:
 
GRAPH:	CALL	PRI_NL	;LF,CR
	LD	A,ESC
	CALL	DRUCK
	LD	A,'*'
	CALL	DRUCK
	LD	A,5	;1:1-Druck
	CALL	DRUCK
	LD	HL,(DRCOL)
	LD	A,L
	CALL	DRUCK
	LD	A,H	;Anzahl
	JP	DRUCK
;-------
;Zeichenausgabe:
 
PRINT:	CP	CR
	JP	NZ,DRUCK
	JR	PRCR1	;CR & li. Rand
 
PRI_NL:	LD	A,LF
	CALL	DRUCK
PRCR1	PUSH	HL
	PUSH	AF
	PUSH	BC
	LD	A,CR
	CALL	DRUCK
	LD	A,(SPAC)
	LD	B,A
	INC	B	;Anzahl
	LD	A,' '	;Leerzeichen
	JR	PRCR3
PRCR2	CALL	DRUCK
PRCR3	DJNZ	PRCR2
	POP	BC
	POP	AF
	POP	HL
	RET
;-------
;Druckereinstellung:
 
DRINI	DB	ESC,40H	  ;Reset
	DB	ESC,'R',0 ;USA-Zsatz
	DB	ESC,'A',8 ;8/72"
 
;Parameter:
HORIZ	DB	1	;hor. Faktor
VERTI	DB	1	;vert. Faktor
SPAC	DB	10	;Anzahl Spaces
 
COL2	DW	123	;bis Spalte
COL1	DW	0	;von Spalte
LIN2	DB	187	;bis Zeile
LIN1	DB	3	;von Zeile
 
TIME	DB	0	; 0=schnell
			;-1=langsam
	DB	0	;akt. Zeile bei
			;Druck
LFLAG	DB	0	;Flag f}r
			;letzte Zeile
DRCOL	DW	0	;Druckspalten
ENABL	DB	0	; 0=Freigabe
			;-1=gesperrt
e bei
			;Druck
LFLAG	DB	0	;Flag f}r
			;letzte Zeile
DRCOL	DW	0	;Druckspalten
ENABL	DB	0	; 0=Freigabe
			;-1=gesperrt
