 **************************************************************************
;
; Filename : ACIA_6551.ASM
; ------------------------
;
; (c) 1993 by Thomas Lehmann
;
;
; Jackophone V5.00
;
;
; Funktionen für ACIA 6551
;
;
;**************************************************************************

MODUL_START	set	*	; Größe des Moduls berechnen





; =========================================================================
;
; Funktion	: ACIA initialisieren
;
; Eingang	: -------
;
; Ausgang	: -------
;
; Register	: -------
;
; (c) by Thomas Lehmann März 1993
;
; =========================================================================

acia_init	stz Acia+ACIA_RES	ACIA Reset

	; XXXX Baud, gleiche Baud Rate für Receiver und Transmitter
	; 8 Bits, Parity, 1 Stop BIT
	; -->> %1001XXXX
	; ---------------------------------------------------------
	lda #BAUD|CTRL_RCS
	sta Acia+ACIA_CTRL	; Control Register setzen

	; enable IRQ, Transmitter disabled, disable Receiver Echo Mode
	; enable Parity Mode, even Parity
	; -->> %01100001
	; ------------------------------------------------------------
	lda #CMD_DTR|CMD_PME|CMD_PMC0
	sta Acia+ACIA_CMD	; Command Register setzen

	lda txen_rl23	akt. Zustand Rl2/RL3 laden
	ora #TX_ENABLE	V11 Treiber enable
	sta txen_rl23	wird von Tastatur Abfrage gesetzt
	rts


; =========================================================================
;
; Funktion	: ACIA Interrupt testen/behandeln
;
; Eingang	: -------
;
; Ausgang	: -------
;
; Register	: -------
;
; (c) by Thomas Lehmann März 1993
;
; =========================================================================

acia_irq
	block
	lda Acia+ACIA_STS	; ACIA Status Register lesen, IRQ löschen
	bit #STS_IRQ	; hat ACIA Irq ausgelöst ?
	beq end		; nö, dann auch nicht behandeln


	; Datenempfang testen
	; -------------------
	bit #STS_RXD	; Daten empfangen ?
	beq acia_txd	; nö

	pha		; ACIA Status retten
	jsr rxd_read	; Receiver leeren
	pla


	; Transmitter ready testen
	; ------------------------
acia_txd	bit #STS_TXD	; Transmitter empty ?
	beq end		; nö, ist wohl noch am Senden

	pha		; ACIA Status retten
	jsr txd_fill	; Transmitter füllen
	pla

end	rts
	bend





	; ========================================
	; empfangenes Zeichen in RX-Buffer stellen
	; ========================================
rxd_read	ldy Acia+ACIA_RXD	Receiver lesen, Fehler löschen

	and #STS_ERRMSK	Fehler aufgetreten ?
	bne rxd_end	ja, Ende

	ldx rxd_cnt	Daten Empfang mitteilen
 bra rxd_0
	bbs TTY_CON,tty_sts,rxd_0	Terminal Modus ist aktiv

	cpx #SIZE_RXD-10	ist noch genügend Platz im RX Buffer ?
	bcc rxd_1	ja, direkt in Buffer eintragen

	lda #XOFF	XOFF senden
	sta xon_xoff
	jsr enable_txd
rxd_0	cpx #SIZE_RXD	ist überhaupt noch Platz im Buffer ?
	bcs rxd_end	nein, dann auch nichts eintragen


rxd_1	tya		;empfangenes Zeichen
	ldx rxd_i_offs	Offset auf RX Buffer holen (IRQ)
	sta rxd_buff,x	empfangenes Zeichen ablegen
	inc rxd_cnt	Anzahl Zeichen im Buffer
	jsr rxd_nxt	nächste Position einstellen
	stx rxd_i_offs

	lda #$ff
	sta led_ram+LD_RXD	RX LED einschalten

rxd_end	rts







	; =================================
	; Transmitter empty, ggf. auffüllen
	; =================================
txd_fill	lda xon_xoff	soll XON / XOFF gesendet werden ?
	beq txd_0	nö, normale Ausgabe testen

	; XON / XOFF senden
	; -----------------
	stz xon_xoff	Status == gesendet
	sta Acia+ACIA_TXD	XON/XOFF in Transmitter geben
	rts

txd_0	ldx txd_cnt	sind noch Zeichen im Buffer
	bne txd_1	ja, nächstes Zeichen senden

	stz led_ram+LD_TXD	TX LED löschen
	jmp disable_txd	Transmitter sperren

txd_1	ldx txd_i_offs	Offset auf TX Buffer holen (IRQ)
	lda txd_buff,x	nächstes Zeichen aus Buffer holen
	dec txd_cnt	Anzahl Zeichen im TX Buffer-1
	sta Acia+ACIA_TXD	Zeichen in Transmitter geben
	jsr txd_nxt	nächste Position einstellen
	stx txd_i_offs	akt. Position des TX Buffers (IRQ)
	rts






; =========================================================================
;
; Funktion	: Transmitter Interrupt freigeben / sperren
;
; Eingang	: -------
;
; Ausgang	: -------
;
; Register	: Accu
;
; (c) by Thomas Lehmann März 1993
;
; =========================================================================

	; Transmitter freigeben
	; =====================
enable_txd	pha
	lda Acia+ACIA_CMD	akt. Status Command Register holen
	ora #CMD_TIC0	Transmitter IRQ freigeben, RTS low
	sta Acia+ACIA_CMD
	pla
	rts


	; Transmitter sperren
	; ===================
disable_txd	pha
	lda Acia+ACIA_CMD	akt. Status Command Register holen
HLP	set CMD_TIC0|CMD_TIC1
	and #$ff^HLP	Transmitter IRQ sperren, RTS high
	sta Acia+ACIA_CMD
	pla
	rts



	; Offset auf nächstes Zeichen im TX Buffer ermitteln
	; akt. Offset in X
	; ==================================================
txd_nxt	inx		; Offset auf nächstes Zeichen
	cpx #SIZE_TXD	Buffer Ende erreicht ?
	bcc txd_nxt_end	nö

	ldx #$00	wieder 1. Position einstellen
txd_nxt_end	rts



	; Offset auf nächstes Zeichen im RX Buffer ermitteln
	; akt. Offset in X
	; ==================================================
rxd_nxt	inx
	cpx #SIZE_RXD	Buffer Ende erreicht ??
	bcc rxd_nxt_end	nö

	ldx #$00		wieder 1. Position einstellen
rxd_nxt_end	rts


; =========================================================================
;
; Funktion	: einzelnes Zeichen auf Console ausgeben
;
; Eingang	: zu sendenes Zeichen im Accu
;
; Ausgang	: -------
;
; Register	: -------
;
; (c) by Thomas Lehmann März 1993
;
; =========================================================================

con_putch
	block
	phx
wait	ldx txd_cnt	Anzahl Zeichen im Buffer
	cpx #SIZE_TXD	Buffer voll ????
	bcc putch_1	nö, eintragen

	; --------------------------------------------------
	; 2400 Baud a`10BITs je Byte == 240 Characters / Sec
	; 240 / 100 = 2.4 Characters / 10mS
	; Buffersize / 3 == Zeit bis Buffer wieder fast leer
	; --------------------------------------------------
	pha
	lda #SIZE_TXD/3	Anzahl der 10mS Zeiteinheiten
	jsr task_delay	und ein bischen schlafen
	pla
	bra wait

putch_1	ldx txd_offs	Offset auf Transmit Buffer holen
	sta txd_buff,x	Zeichen in TX Buffer schreiben
	inc txd_cnt	Anzahl zu sendene Zeichen
	jsr txd_nxt	nächste Position ermitteln
	stx txd_offs
	ldx #$ff
	stx led_ram+LD_TXD	TX LED einschalten
	plx
	jmp enable_txd	Transmitter freigeben, Zeichen senden
	bend



	; =================================
	; Carrige Return / Line Feed senden
	; =================================
con_newline	lda #$0d
	jsr con_putch
	lda #$0a
	jmp con_putch


	; ==========================
	; Space auf Console ausgeben
	; ==========================
con_space	lda #" "
	jmp con_putch



; =========================================================================
;
; Funktion	: ASCII String auf Console bis \0 ausgeben
;
; Eingang	: Adr. high/low in Accu/Y
;
; Ausgang	: ------
;
; Register	: Accu
;
; (c) by Thomas Lehmann April 1993
;
; =========================================================================

con_puts	sta puts_adr+1	Adresse absetzen
	sty puts_adr

puts_loop	lda (puts_adr)	Zeichen aus String holen
	bne puts_out	kein String Ende, Zeichen ausgeben

	rts

puts_out	jsr con_putch	und senden
	?inc16 puts_adr	nächstes Zeichen einstellen
	bra puts_loop



; =========================================================================
;
; Type	: Unterprg.
;	: Hex-Zahl auf Console ausgeben
;
; Eingang	: Wert im Accu
;
; Ausgang	: ------
;
; Register	: ------
;
; (c) by Thomas Lehmann April 1993
;
; =========================================================================

con_puthex
	block
	pha
	jsr conhex_0
	pla
	rts

conhex_0	pha		; Wert retten
	lsr		; oberes Nibble in unteres schieben
	lsr
	lsr
	lsr
	jsr conhex_1	; und ASCII ausgeben
	pla
	and #%00001111	; oberes Nibble ausblenden

conhex_1	clc
	cmp #$0a	; ist Wert <9
	bcc conhex_asc	; ja

	adc #6		; Hex A-F erzeugen
conhex_asc	adc #48		; ASCII dazu
	jmp con_putch	; und auf Console
	bend




; --------------------------------------------------------------------------

HLP	set	*
_ACIA_6551	equ	HLP-MODUL_START		; Größe des Moduls


