st7/

;------------------------------------------------------------------------------
; PROGRAM REALIZUJACY KOMUNIKACJE "MIKROSTEROWNIK => PC"
; Z KONFIGUROWALNYM REJESTREM RCCR
;------------------------------------------------------------------------------

	.NOLIST
	#INCLUDE "ST7FLITE25.inc"
	.LIST

	MOTOROLA           	

; Przypisania pinow --------------------
; PA3 => TxD
; PB0 <= SW3
; PA0 <= SW2
; PB3 <= SW1
; --------------------------------------

	#define	TxD	$3			; wyjscie TxD
	#define	BW	$0			; bajt wyslany?

    	segment byte at 80-FF		'ram0'
    	segment byte at 100-1FF		'stack'
    	segment byte at 200-27F		'ram1'
    	segment byte at FC00-FFDF	'rom'
    	segment byte at FFE0-FFFF	'vectit'
    
        BYTES
        segment 'ram0'

.bajt    	DS.B    1		; wysylany bajt
.licznik	DS.B	1		; licznik cykli AT timera
.status		DS.B	1		; status transmisji

        WORDS
        segment 'rom'
          
; Tekst do wyswietlenia na komputerze
.text		DC.B	" !dlrow ,olleH"

;------------------------------------------------------------------------------
; START PROGRAMU
;------------------------------------------------------------------------------
.main
	ld		A, #$80			; poczatkowa dokladnosc zegara
	ld		RCCR, A			; równa polowie przedzialu
	call 	sci_init		; inicjalizacja ukladu
		
nic
	wfi						; czekaj na przerwanie
	jp 		nic

;------------------------------------------------------------------------------
; INICJALIZACJA PORTÓW
;------------------------------------------------------------------------------
.sci_init
	
	ld		A, #%10100010
	ld		EICR, A			; ustaw opadajace zbocze
	bset	PBOR, #0		; PB0 = pull up; interrupt; input
	bres	PBDDR, #0
	bset	PBOR, #3		; PB3 = pull up; interrupt; input
	bres	PBDDR, #3
	bset	PAOR, #0		; PA0 = pull up; interrupt; input
	bres	PADDR, #0
	
	bset	PADDR,#TxD      ; PA3 = TxD; output; push-pull
    bset	PAOR,#TxD
	bset	PADR,#TxD       ; ustawiamy stan Idle
	
	rim
 
	ret

;------------------------------------------------------------------------------
; PROCEDURA TXD
;------------------------------------------------------------------------------
.wyslij
	
	bres	PBOR, #0
	bres	PBOR, #3
	bres	PAOR, #0
	clr		licznik			; zeruj licznik wyslanych bitow
	clr		status			; wyczysc status transmisji
	
	; start zegara
	
	sim
	ld 		A, #$12
	ld		ATCSR, A		; OVFIE enabled, F = F_cpu
	ld		A, #$BE			; wczytaj wartosc poczatkowa licznika
	ld		ATRL, A			; 8 000 000 / 9600 = 341 h
	ld		A, #$0C			; FFF - 341 = CBE
	ld		ATRH, A
	rim						; odblokuj przerwania
	
.loop_transm
	wfi						; wfi - wait for interrupt
	btjf 	status, #BW, loop_transm	; sprawdz czy skonczylo sie nadawanie
	
	sim						; zablokuj przerwania
	
	ld 		A, #$00
	ld		ATCSR, A		; OVFIE enabled, F = F_osc
	bset	PBOR, #0
	bset	PBOR, #3
	bset	PAOR, #0
	clr		EICR			; wyczysc oczekujace przerwania
	ld		A, #%10100010
	ld		EICR, A			; ustaw opadajace zbocze
	rim
	ret

;------------------------------------------------------------------------------
; PRZERWANIE TIMERA
;------------------------------------------------------------------------------
.timer
	ld		A, ATCSR		; wyczysc flage przerwania OVFIE
		
	ld		A, licznik		; wczytaj licznik...
	cp 		A, #0			; ...jesli jest zerem to wyslij bit startu,
	jreq	bit_startu
	cp 		A, #9			; jesli jest rowny 9 to wyslij bit stopu
	jreq	bit_stopu
	cp 		A, #10			; jesli jest rowny 10 to zakoncz transmisje
	jreq	koniec_transmisji

dane						; w przeciwnym przypadku wysylaj dane
	ld		A, bajt			; wczytaj wysylany bajt
	rrc		A				; obroc w prawo przez carry
	jrc		dane_wyslij_1	; jesli w carry jest "1" to wystaw na port "1"
	bres	PADR, #TxD		; w przeciwnym przypadku wystaw 0
	jp		koncz_d
	
dane_wyslij_1
	bset	PADR, #TxD
	
koncz_d
	ld 		bajt, A			; zapisz obrocony bajt
	jp		koncz

bit_startu
	bres	PADR, #TxD		; bit startu - "0"
	jp		koncz

bit_stopu
	bset	PADR, #TxD		; bit stopu - "1"
	jp		koncz

koniec_transmisji
	bset	status, #BW		; ustaw zmienna "status"

koncz
	inc licznik
	iret

;------------------------------------------------------------------------------
; PRZERWANIE PRZYCISKU ZMNIEJSZAJACEGO RCCR
;------------------------------------------------------------------------------

.butB0
	ld		A, RCCR
	sub		A, #$10
	ld		RCCR, A
	iret
	
;------------------------------------------------------------------------------
; PRZERWANIE PRZYCISKU WYPISUJACEGO "HELLO, WORLD!"
;------------------------------------------------------------------------------

.butB3
	ld		X, #13			; wyslanie "Hello, world!" do portu
wpisz_hello			      	
	ld	A,(text,X)
	ld 		bajt, A
	call 	wyslij
	dec	X
	jrne	wpisz_hello   
	iret

;------------------------------------------------------------------------------
; PRZERWANIE PRZYCISKU ZWIEKSZAJACEGO RCCR
;------------------------------------------------------------------------------

.butA0
	ld		A, RCCR
	add		A, #$10
	ld		RCCR, A
	iret

;------------------------------------------------------------------------------
; PRZERWANIA
;------------------------------------------------------------------------------
.dummy   iret           	; pusta funkcja obslugi przerwania

        segment 'vectit'

                DC.W    dummy          	;FFE0-FFE1h location 
                DC.W    dummy           ;FFE2-FFE3h location
                DC.W    dummy           ;FFE4-FFE5h location  
.sci_it         DC.W    dummy           ;FFE6-FFE7h location  
.timb_it        DC.W    timer	       	;FFE8-FFE9h location  
.tima_it        DC.W    dummy           ;FFEA-FFEBh location  
.spi_it         DC.W    dummy           ;FFEC-FFEDh location               
                DC.W    dummy           ;FFEE-FFEFh location
                DC.W    dummy           ;FFF0-FFF1h location                 
.ext3_it        DC.W    butB0           ;FFF2-FFF3h location                       
.ext2_it        DC.W    butB3           ;FFF4-FFF5h location  
.ext1_it        DC.W    dummy           ;FFF6-FFF7h location             
.ext0_it        DC.W    butA0           ;FFF8-FFF9h location 
                DC.W    dummy           ;FFFA-FFFBh location                      
.softit         DC.W    dummy           ;FFFC-FFFDh location                       
.reset          DC.W    main            ;FFFE-FFFFh location


	END
