Source file: /~heha/Mikrocontroller/avr-inc.zip/vt100.i90

;VT100/ANSI-Funktionen für ATmega auf (Hyper)Terminal
#ifndef VT100_I90
#define VT100_I90

;Benötigt:
;	getchar()	Zeichen lesen (blockierend) - Ergebnis in UART_InChar
;	putchar(r16)	Zeichen schreiben (blockierend)
;	UART_InChar	Register >R16
;Wenn Symbol COLOR_CACHED definiert:
;	CurrentColor	Register >R0

;Bietet (diverses):
;	div10b(r16)	Division Byte durch 10, lausig wie 8051...
;	div10(r17:r16)	Division Word durch 10
;	SendByte(r16)	Ausgabe 1 Byte dezimal
;	SendSpace()	Leerzeichen senden
;	SendCSI()	CSI (ESC"[") senden
;	SendVisible(r16)`if (r16==0x7F || r16<' ') r16='_';´ und ausgeben
;	SendXM(r16)	r16 und 'm' ausgeben
;	SendM()		'm' ausgeben
;	Send07(r16)	'0'..'7' (je nach 3 Bits von R16) ausgeben
;	Send09(r16)	'0' ODERn und ausgeben

;Bietet (Terminal-Hilfe):
;	GetKey()	Tastenkode lesen mit VT100-Umrechnung der Kursortasten
;	GotoXY(x,y)	Gehe zur Position
;	SendColor(r17)	Farbe setzen (mit oder ohne Cache-Funktion je nach COLOR_CACHED)

;##############################
;## Zahlen und Zeichenketten ##
;##############################
div10b:
	clr	r17
div10:
;Division 16bit/10 = 8 bit Rest 8 bit
;PE: R17:R16=Dividend
;PA: R16=Quotient, R17=Rest
;VR: R16-R17
	push	r18
	 ldi	r18,8	;Schleifenzähler
div1:	 lslw	r17,r16
	 cpi	r17,10
	 brcs	div2
	 subi	r17,10
	 inc	r16	;LSB im Divisionsergebnis setzen
div2:	 dec	r18
	 brne	div1
	pop	r18
	ret

SendByte:	;Byte R16 dezimal ausgeben
;VR: R16-R17
	push	r18
	 ldi	r18,1
sb1:	 cpi	r16,10
	 brlo	sb3	;Letzte Division vermeiden
	 rcall	div10b
;Fertig mit Division, aus Rest ASCII-Zeichen machen
	 push	r17
	 inc	r18	;PUSH mitzählen
	 rjmp	sb1
sb2:	 pop	r16
sb3:	 rcall	Send09	;Ausgabe '0'..'9'
	 dec	r18
	 brne	sb2
	pop	r18
	ret

;#########################
;## VT100/ANSI-Routinen ##
;#########################
GetKey:
;Tastenabfrage mit Konvertierung von Kursortasten u.ä., blockierend
;VR: R16
	rcall	getchar
dontknow:
	cpi	UART_InChar,0x00;Müll von HyperTerminal
	breq	GetKey
	cpi	UART_InChar,0x1B;ESC
	breq	handle_esc
	ret
handle_esc:	;Idee: Nur ESC nach einemm TimeOut erzeugt ^C!
	rcall	getchar		;Folgezeichen
	cpi	UART_InChar,'['
	breq	handle_esc
	cpi	UART_InChar,'O'
	breq	handle_esc
	;Steuertasten
	cpi	UART_InChar,0x1B;ESC (2x)
	ldi	r16, 0x03	;^C
	breq	chr_r16
	cpi	UART_InChar,'H'	;Pos1
	ldi	r16, 0x01	;^A
	breq	chr_r16
	cpi	UART_InChar,'K'	;Ende
	ldi	r16, 0x05	;^E
	breq	chr_r16
	;...fehlt noch: BildAuf und BildAb, gibts aber erst ab VT200...
	;Pfeiltasten
	cpi	UART_InChar,'A'	;Pfeil hoch
	ldi	r16, 0x10	;^P
	breq	chr_r16
	cpi	UART_InChar,'B'	;Pfeil runter
	ldi	r16, 0x0E	;^N
	breq	chr_r16
	cpi	UART_InChar,'C'	;Pfeil rechts
	ldi	r16, 0x06	;^F
	breq	chr_r16
	cpi	UART_InChar,'D'	;Pfeil links
	ldi	r16, 0x02	;^B
	;Funktionstasten
	breq	chr_r16
	cpi	UART_InChar,'P'	;F1..F4
	brlo	dontknow
	cpi	UART_InChar,'S'+1
	brsh	dontknow
	subi	UART_InChar,'P'+0x1C	;µC-interne Kodes
	ret
chr_r16:
	mov	UART_InChar,r16
	ret

SendSemi:	;Semikolon ausgeben
	ldi	r16,';'
	rjmp	putchar
SendCSI:	;CSI (ESC'[') ausgeben
	ldi	r16,0x1B
	rcall	putchar
	ldi	r16,'['
	rjmp	putchar
SendSpace:
	ldi	r16,' '
	rjmp	putchar
	
SendVisible:
	cpi	r16,0x7F
	breq	sv1
	cpi	r16,' '
	brsh	sv2
sv1:	ldi	r16,'_'		;Alle "unangenehmen" Zeichen ersetzen!
sv2:	rjmp	putchar

GotoXY:	;Setze Kursor auf Position
;PE: R16 = X-Position (0 = erste Spalte links)
;    R17 = Y-Position (0 = erste Zeile oben)
;VR: R16-R17
	push	r16
	 rcall	SendCSI
	 mov	r16,r17
	 inc	r16
	 rcall	SendByte
	 rcall	SendSemi
	pop	r16
	inc	r16
	rcall	SendByte
	ldi	r16,'H'
	rjmp	putchar
	
Send07:	;Ausgabe von '0' bis '7' (für ANSI-Farben)
	andi	r16,0x07
Send09:	ori	r16,'0'
	rjmp	putchar

#ifdef COLOR_CACHED

SendSemiCheck:
	brtc	ssc1		;Semikolon ausgeben, wenn T-Flag gesetzt
	rcall	SendSemi
ssc1:	set			;Beim nächsten Mal immer ein Semikolon ausgeben
sce:	ret

SendColor:	;Setze Farbe für folgende Ausgaben, kürzestmögliche Sequenz mit Cache
;Besonders für langsame serielle Verbindungen oder häufigen Farbwechseln gut
;PE: R17 = Farbkode
;	Bit3:0 = Vordergrund (Bit 3 = Intensitätsbit)
;	Bit6:4 = Hintergrund
;	Bit7 = Blinken
;    CurrentColor = momentane Farbe (>R0)
;VR: R16, T-Flag, CurrentColor=R17
;Farb-Bitzuordnung anders als in DOS!! Bit 0=rot, Bit 1=grün, Bit2=blau
;Unterstreichung wird hier nicht gehandhabt.
	clt
	cp	CurrentColor,r17
	breq	sce		;Nichts zu tun!
	rcall	SendCSI
;Das "Rücksetzen von Attributen" ist nur notwendig, wenn ein Intensitäts-
;oder ein Blinkbit verschwindet - oder kurzerhand wenn grau-auf-weiß gewünscht
	cpi	r17,0x07	;Standard?
	breq	sc0		;Nur CSI"0m" ausgeben
	mov	r16,r17
	com	r16		;Null-Bits zu 1
	and	r16,CurrentColor
	andi	r16,0x88	;Intensität oder Blinken Übergang 1->0?
	breq	sc1		;Kein derartiger Fall: Null überspringen
sc0:	ldi	r16,'0'
	rcall	putchar
	set
	ldi_	CurrentColor,0x07;Jetzt ist's grau auf schwarz
sc1:
	sbrc	r17,7		;Immer überspringen, wenn Blink-Bit zu löschen
	 sbrc	CurrentColor,7	;RJMP überspringen, wenn Blink-Bit gelöscht war
	rjmp	sc2		;Heißer Kode!!
	rcall	SendSemiCheck
	ldi	r16,'5'
	rcall	putchar		;wenn Blink-Bit hinzukommt
sc2:
	mov	r16,r17
	eor	r16,CurrentColor
	andi	r16,0x70	;Hintergrundfarbe
	breq	sc3		;unverändert
	rcall	SendSemiCheck
	ldi	r16,'4'		;Hintergrundfarbe
	rcall	putchar
	mov	r16,r17
	swap	r16
	rcall	Send07		;wenn Hintergrundfarbe sich ändert
sc3:
	sbrc	r17,3
	 sbrc	CurrentColor,3
	rjmp	sc4
	rcall	SendSemiCheck
	ldi	r16,'1'
	rcall	putchar		;wenn Intensitäts-Bit hinzukommt
sc4:
	mov	r16,r17
	eor	r16,CurrentColor
	andi	r16,0x07	;Textfarbe
	breq	sc5		;unverändert
	rcall	SendSemiCheck
	ldi	r16,'3'		;Textfarbe
	rcall	putchar
	mov	r16,r17
	rcall	Send07		;wenn Textfarbe sich ändert
sc5:
	mov	CurrentColor,r17
;	rjmp	SendM
;SendXM:	rcall	putchar		;SendXM wird von Input.h gebraucht
SendM:	ldi	r16,'m'
	rjmp	putchar

#else

SendColor:	;Setze Farbe für folgende Ausgaben, ohne Cache
;PE: R17 = Farbkode
;	Bit3:0 = Vordergrund
;	Bit6:4 = Hintergrund
;	Bit7 = Blinken
;VR: R16
;Farb-Bitzuordnung anders als in DOS!! Bit 0=rot, Bit 1=grün, Bit2=blau
;Unschön: Verschwindet das Blinken, wenn man "intensiv" eingeschaltet hat?
	rcall	SendCSI
	ldi	r16,'0'
	sbrc	r17,3		;Intensitäts-Bit
	 inc	r16
	rcall	putchar
	rcall	SendSemi
	ldi	r16,'3'		;Textfarbe
	rcall	putchar
	mov	r16,r17		;Vordergrundfarbe
	rcall	Send07
	rcall	SendSemi
	ldi	r16,'4'		;Hintergrundfarbe
	rcall	putchar
	mov	r16,r17
	swap	r16		;Hintergrundfarbe
	rcall	Send07
	jbrc	r17,7, SendM	;Blink-Bit
	rcall	SendSemi
	ldi	r16,'5'
SendXM:	rcall	putchar
SendM:	ldi	r16,'m'
	rjmp	putchar
#endif

#endif//VT100_H
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded