V24I    ASM;---------------------------------
;Druckertreiber aus BASCODER V1.5
;
;Programm nur f}r KC85/4
;EPSON-Drucker an V24-Modul Kanal 1
;Hardcopy mit ESC,*,5 f}r 9-Nadler!
;
;Adressen: BA00 BD80
;
;reassembliert:		19.11.93
;
;V24I.ASM		` ML-Soft
;---------------------------------
ARGN	EQU	0B781H
HCADR	EQU	0B799H
UOUT1	EQU	0B7BDH
PV1	EQU	0F003H
KBDZ	EQU	0EH
WAIT	EQU	14H
 
LF	EQU	0AH
CR	EQU	0DH
ESC	EQU	1BH
 
	ORG	0BA00H
;-------
;Fenster mit Tastatur einstellen:
 
WINDOW:	CALL	INVWI	;invertieren
WIN0	HALT
	LD	A,(IX+13)
	OR	A	;warten bis
	JR	NZ,WIN0	;keine Taste!
	XOR	A
	LD	(TIME),A;schnell
WIN1	HALT
	LD	A,(TIME)
	OR	A	;schnell?
	JR	Z,WIN2	;ja
	CALL	PV1
	DB	KBDZ	;Tastaturrepeat
	JR	NC,WIN1;keine Taste
	JR	WIN3
WIN2	LD	A,(IX+13);Code
	OR	A
	JR	Z,WIN1	;Code 00
WIN3	CP	8
	JR	NZ,WIN4
	LD	HL,(COL1)	;<CUL>
	LD	A,H
	OR	L
	JR	Z,WIN1
	DEC	HL
	LD	(COL1),HL
	CALL	LEFT
	JR	WIN1
WIN4	CP	9
	JR	NZ,WIN5
	LD	HL,(COL2)	;<CUR>
	LD	DE,319
	CALL	SHLDE	;HL-DE
	JR	Z,WIN1
	INC	HL
	LD	(COL2),HL
	CALL	RIGHT
	JR	WIN1
WIN5	CP	0AH
	JR	NZ,WIN6
	LD	A,(LIN2)	;<CUD>
	CP	0FFH
	JR	Z,WIN1
	INC	A
	LD	(LIN2),A
	CALL	BOTTOM
	JR	WIN1
WIN6	CP	0BH
	JR	NZ,WIN7
	LD	A,(LIN1)	;<CUU>
	OR	A
	JR	Z,WIN1
	DEC	A
	LD	(LIN1),A
	CALL	TOP
	JR	WIN1
WIN7	CP	19H
	JR	NZ,WIN8
	LD	HL,(COL2)	;<SCUL>
	LD	DE,(COL1)
	CALL	SHLDE	;HL-DE
	JR	Z,WIN1
	CALL	RIGHT
	DEC	HL
	LD	(COL2),HL
	JP	WIN1
WIN8	CP	18H
	JR	NZ,WIN9
	LD	HL,(COL1)	;<SCUR>
	LD	DE,(COL2)
	CALL	SHLDE	;HL-DE
	JP	Z,WIN1
	CALL	LEFT
	INC	HL
	LD	(COL1),HL
	JP	WIN1
WIN9	CP	12H
	JR	NZ,WIN10
	LD	A,(LIN2)	;<SCUD>
	LD	B,A
	LD	A,(LIN1)
	CP	B
	JP	Z,WIN1
	CALL	TOP
	INC	A
	LD	(LIN1),A
	JP	WIN1
WIN10	CP	11H
	JR	NZ,WIN11
	LD	A,(LIN1)	;<SCUU>
	LD	B,A
	LD	A,(LIN2)
	CP	B
	JP	Z,WIN1
	CALL	BOTTOM
	DEC	A
	LD	(LIN2),A
	JP	WIN1
WIN11	CP	16H
	JR	NZ,WIN13
WIN12	HALT			;<CAPS>
	LD	A,(IX+13)
	OR	A
	JR	NZ,WIN12;noch gedr}ckt!
	LD	A,(TIME)
	CPL		;wechseln
	LD	(TIME),A
	JP	WIN1
WIN13	CP	CR
	JR	Z,INVWI		;<CR>
	CP	10H
	CALL	Z,INVWI		;<HOME>
	JP	WIN1
;-------
;Fenster invertieren:
 
INVWI:	LD	A,(LIN1)
	LD	B,A
	LD	A,(LIN2)
	LD	HL,(COL1)
	LD	DE,(COL2)
INVW1	CP	B
	JR	Z,INVW2	;letzte Zeile
	CALL	INVLIN
	DEC	A
	JR	INVW1
INVW2	CALL	INVLIN
	RET
;-------
;linke Linie invertieren:
 
LEFT:	PUSH	HL
	LD	HL,(COL1)
	JR	LR1
;-------
;rechte Linie invertieren:
 
RIGHT:	PUSH	HL
	LD	HL,(COL2)
LR1	LD	A,(LIN2)
	LD	B,A
	LD	A,(LIN1)
	CALL	INVCOL	;Spalte
	POP	HL
	RET
;-------
;obere Linie invertieren:
 
TOP:	PUSH	AF
	LD	A,(LIN1)
	JR	TB1
;-------
;untere Linie invertieren:
 
BOTTOM:	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
	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
	PUSH	HL
	OR	A
	SBC	HL,DE
	POP	HL
	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	CPHLDE
	JR	Z,INVL2	;letzte Adresse
	LD	A,M
	CPL		;voll negieren
	JR	INVL1
INVL2	CALL	BMASK
	XOR	M	;letzte Adr.
	LD	M,A	;negieren
	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:
 
CPHLDE	PUSH	HL
	OR	A
	SBC	HL,DE
	POP	HL
	RET
;-------
;Aufruf V24-Routine:
 
V24I:	DW	7F7FH
	DB	'V24I',1
	LD	HL,ARGN
	LD	DE,HORIZ;Parameter
	LD	B,M
	INC	B	;Args+1
	JR	V24I2
V24I1	LD	A,M
	LD	(DE),A	;eintragen
	INC	DE
	INC	HL
V24I2	INC	HL
	DJNZ	V24I1
	XOR	A	;Freigabe
	LD	(ENABL),A
	LD	BC,80H
V24I3	IN	A,(C)
	CP	0EEH	;M003?
	JR	Z,V24I5	;gefunden
	DJNZ	V24I3
V24I4	LD	A,-1	;gesperrt
	LD	(ENABL),A
	RET
V24I5	LD	HL,7F7FH ;Men}wort
	LD	(V24I),HL;freigeben
	LD	A,1
	OUT	(C),A	;Modul ein
	LD	HL,PRINT
	LD	(UOUT1+1),HL
	LD	HL,HCOPY
	LD	(HCADR),HL
	LD	BC,020CH
	LD	HL,MINIT
	DI
	OTIR		;-> CTC
	LD	BC,060AH
	OTIR		;-> SIO
	EI
	LD	HL,DRINI;Drucker init.
	LD	B,8	;8 Bytes
V24I6	PUSH	BC
	LD	A,1
	CALL	PV1
	DB	WAIT
	POP	BC
	IN	A,0AH
	BIT	2,A
	JR	Z,V24I4	;nicht bereit
	LD	A,M
	OUT	8	;Ausgabe
	INC	HL
	DJNZ	V24I6
	JP	PRI_NL	;LF,CR
;-------
;Ausgabe eines Zeichens zum Drucker:
 
DRUCK:	PUSH	AF
DRU1	IN	A,0AH
	BIT	2,A	;ready?
	JR	NZ,DRU2;ja
	LD	A,(ENABL)
	OR	A
	JR	NZ,DRU3;kein Druck!
	PUSH	BC
	LD	A,1
	CALL	PV1
	DB	WAIT	;warten
	POP	BC
	JR	DRU1
DRU2	XOR	A
	LD	(ENABL),A
	POP	AF
	OUT	8
	RET
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	SHLDE	;HL-DE
	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
;-------
;Hilfsoperation f}r SUB HL,DE:
 
SHLDE:	PUSH	HL
	OR	A	;CY=0
	SBC	HL,DE
	POP	HL
	RET
;-------
;Init-Daten M003:
 
MINIT	DB	47H	;CTC
	DB	5BH
	DB	4,4	;SIO
	DB	3,20H
	DB	5,6AH
;-------
;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
	NOP	;frei
	NOP	;frei
À@Àt(Àp6g f}r
			;letzte Zeile
DRCOL	DW	0	;Druckspalten
ENABL	DB	0	; 0=Freigabe
			;-1=gesperrt
	NOP	;frei
	NOP	;frei
À@Àt(Àp6