$TITLE (SATELLITE NAVIGATOR remote display driver, Ver 0.0)  
$DATE (11.11.89)
$PROCESSOR  (8051)
$PAGEWIDTH  (110)
$PAGELENGTH (65)
$NOSYMBOLS
$NOLIST
;$XREF

;AUTOR	Leon Kos, Cerknica C.4.MAY 11A, 61380 Cerknica, Tel:(061)791084 YU


START_UP	CODE	0032H
TIMER0_INT	CODE	000BH
TIMER1_INT	CODE	001BH
SERIAL_INT	CODE	0023H



LAT	EQU	8000H	;naslov za LATITUDE 	vrsto
LON	EQU	8001H	;naslov za LONGITUDE 	vrsto
HDG	EQU	8002H	;naslov za HEADING 	vrsto
SPD	EQU	8003H	;naslov za SPEED 	vrsto
MUX	EQU	8004H	;naslov za MULTIPLEX 	kolono


DA_LSB	BIT	P3.3	;LSB D/A konverterja za osvetlitev displaya
DA_NSB	BIT	P3.4	;NSB D/A
DA_MSB	BIT	P3.5	;MSB D/A


;Timer_0 reload value; Cas v ms za refresh displaya
T0_REL	  EQU	0FFFFH - 1667 + 1     	;100Hz refresh za display
T0_REL_HI EQU 	HIGH T0_REL		;High reload value 1667 <- 1e6/[6*100]
T0_REL_LO EQU	LOW  T0_REL		;Low  reload value


;Timer_1 reload value za baud rate generator serijskega interfacea
;Timer_1 se uporablja kot "16 bit cascaded" pri hitrostih pod 300 BAUD
;Sicer je Timer_1 uporabljen kot "auto reload" za visje hitrosti prenosa

RCAP1L	  EQU	R6		    	;Uporabimo R6 in R7 za reload
RCAP1H	  EQU	R7			;timerja_1


BUF_LEN	  EQU	30			;Velikost serijskega bufferja


WENS	DATA	2FH			;WestEastNorthSouth maska
NORTH	BIT	7EH			;Bit naslov za sever indikator
WEST	BIT	7FH			;Bit naslov za zahod indikator


;Jumperji za nastavitev konfiguracije imajo sledece funkcije
; X6, X13, X14  == P1.2, P1.1, P1.0  >> osem nivojev osvetlitve displaya
; X2, X4, X5    == P1.5, P1.4, P1.3  >> osem hitrosti prenosa podatkov
;					50,100,110,150,300,1200,2400,4800 BAUD
; X7		== P1.6 	     >> rezerva
;

TIPKA	BIT	P1.7			;Bit naslov tipke za nastavitev svetlobe




DSEG	AT	30H

;Tabela 7 segmentnih vrednosti za display refresh
COL_0:	DS	4  			;tabela za refresh displaya
COL_1:	DS	4			;je orientirana po kolonah
COL_2:	DS 	4			;od leve proti desni
COL_3:	DS	4
COL_4:	DS	4
COL_5:	DS	4
RFSHC:	DS	1			;stevec za refresh
KEYC :  DS 	1			;stevec za tipko
LIGHT:  DS	1			;trenutna osvetlitev
BUF_BEG:DS	1			;kazalec na zacetek serijskega bufferja
BUF_END:DS	1			;kazalec na konec bufferja
BUFFER:	DS	BUF_LEN			;buffer sa serijski port
STACK:					




CSEG 	AT	RESET
	JMP	START_UP

CSEG	AT	TIMER0_INT		;Skok v rutino za
	JMP 	REFRESH			;osvezevanje displayev 
	JMP	DISPLAY_SERVER		;To je samo testiranje


CSEG	AT	TIMER1_INT		;Baud rate generator za hitrosti
	MOV	TL1,RCAP1L		;50, 100, 110 in 150 baud
	MOV	TH1,RCAP1H
	RETI


CSEG	AT	SERIAL_INT
	JMP	SERIAL_SERVER		;Klici Rutino za polnjenje bufferja
    

CSEG 	AT	START_UP		; START_UP()
	
	CLR	EA			;onemogoci prekinitve

	MOV	SP,#STACK		;Nastavi Sklad

	CALL	CLRD			;Brisi Display oz. iskljuci MUX


	MOV	BUF_BEG,#BUFFER	   	;Nastavimo kazalec na zacetek bufferja
	MOV	BUF_END,BUF_BEG		;Kazalec na konec tabele je enak zacetku
		     
	CALL	CLR_TAB			;Brisi tabelo	
     
	MOV	RFSHC,#0		;Nastavi stevec za refresh

	CALL	CLRD			;Brisi Display oz. iskljuci MUX

	CALL	INIT_TIMER_0		;Nastavi in pozeni Timer_0
	
	CALL	SET_BAUD		;Nastavimo Baud Rate serijskega porta

	SETB	EA			;Omogoci prekinitve
       
	SETB	TR0			;Pozeni Timer_0

	MOV	A,P1			;Beremo jakost displaya
	CALL	INI_LIT			;in klicemo nastavitev osvetlitve

	MOV	WENS,#00H		;Brisi WENS

	CALL	OUT_OLEO


;	MOV 	R0,#100			;4.0s zakasnitve
;	CALL	DELAY

CYC:	CALL	OBT_KEY
	JMP	CYC

	CALL	DUMP_HEX
	
	JMP $


; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

OBT_KEY:				; OBT_KEY()
	JB	TIPKA,OBK_OUT		;skoci ce ni tipka pritisnjena
	MOV	A,#20			;tipka je pritisnjena
	CJNE	A,KEYC,OBK_NE		;ali je doseznen cas med pritiski
OBK_NE: JNC	OBK_LOW			;IF zahtevan cas > trenutni cas
	

	CPL 	WEST
	CPL	NORTH

	INC	LIGHT			;povecaj osvetlitev
	MOV	A,LIGHT			;pripravi podatek
	CALL	SET_LIT			;in nastavi osvetlitev
OBK_LOW:MOV	KEYC,#0			;resetiraj stevec
OBK_OUT:RET



;Nastavi Timer_0 za osvezevanje displaya in ga pozeni
;Timer0 in Timer_1 16 bit cascaded
INIT_TIMER_0:
	MOV	TMOD,#00010001B	       	;Nastavi nacin dela
	MOV	TH0,#0FFH   		;Timer bo takoj po zagonu preknil in
	MOV	TL0,#253		;izvedel refresh
	SETB	ET0			;Omogoci prekinitve Timerja_0
	RET



;Nastavimo Baud Rate Serijskega porta
;Brez parametrov - podatek se bere z porta P1 in jumperjev
;Uporablja A, DPTR, R0, R1, R2
SET_BAUD:    				; SET_BAUD()
	MOV	COL_0,#NOT 01111100B	;B izpise na display
	MOV	COL_1,#NOT 01110011B	;P {BPS = bits per second}
	MOV	COL_2,#NOT 11101101B	;S
	MOV	COL_5,#NOT 00111111B	;0
	MOV	COL_5+2,#NOT 00111111B	;0
	
	CLR	TR1			;Ustavi timer_1
	CLR	ET1			;Onemogoci prekinitve timerja_1
	CLR	ES			;Onemogoci prekinitve serijskega porta
	
	MOV 	SCON,#01011100B		;Mode 1, Enable reception,CLR TI & RI
	
	MOV	A,P1			;Beri P1 
	RR	A			;premakni 3 bite v desno
	RR	A
	RR	A
	ANL	A,#111B			;brisi odvecne bite
	MOV	DPTR,#SB_JMPTBL		;Nastavi kazalec na tabelo
	MOVC	A,@A+DPTR		;Izracunaj skok
	JMP	@A+DPTR			;Skoci v rutino
SB_JMPTBL:  				;Tabela skokov
	DB	SB_50	- SB_JMPTBL
	DB	SB_100  - SB_JMPTBL
	DB	SB_110  - SB_JMPTBL
	DB	SB_150  - SB_JMPTBL
	DB	SB_300  - SB_JMPTBL
	DB	SB_1200 - SB_JMPTBL
	DB	SB_2400 - SB_JMPTBL
	DB	SB_4800 - SB_JMPTBL

 
SB_50:	MOV	TMOD, #00010001B	;Timer_1 in Timer_0 16bit casc.
	MOV	PCON, #10000000B	;SETB SMOD ;Tocno 2403.84615 BAUD
      	MOV	RCAP1L,#LOW (0FFFFH - 1250 +1)
	MOV	RCAP1H,#HIGH(0FFFFH - 1250 +1)	 ;Tocno 50.0000 BAUD
	MOV	PCON,#10000000B		;SETB SMOD
	SETB	PT1  			;Timer_1 ima najvecjo prioriteto
	SETB	TR1			;Pozeni Timer_1
	SETB	ET1			;Omogoci prekinitve Timerja_1
	SETB	ES			;Enable serial

	MOV	A,#5			;Izpisi '5' na display
	PUSH 	ACC
	CALL	HEX_TO_7
	POP	COL_5
	RET				;vrni se


SB_100:	MOV	TMOD, #00010001B	;Timer_1 in Timer_0 16bit casc.
	MOV 	RCAP1L,#LOW (0FFFFH - 625 +1)   ;6.25ms = 1/100/16*1e6
	MOV	RCAP1H,#HIGH(0FFFFH - 625 +1)	;Tocno 100.0000 BAUD
	MOV	PCON,#10000000B		;SETB SMOD 
	SETB	PT1  			;Timer_1 ima najvecjo prioriteto
	SETB	TR1			;Pozeni Timer_1
	SETB	ET1			;Omogoci prekinitve Timerja_1
	SETB	ES			;Enable serial

	MOV	A,#1			;Izpisi '1' na display
	PUSH 	ACC
	CALL	HEX_TO_7
	POP	COL_4
	RET 				;vrni se


SB_110:	MOV	TMOD, #00010001B	;Timer_1 in Timer_0 16bit casc.
	MOV 	RCAP1L,#LOW (0FFFFH - 568 +1)   ;5.68ms = 1/110/16*1e6
	MOV	RCAP1H,#HIGH(0FFFFH - 568 +1)	;Tocno 110.03521 BAUD
	MOV	PCON,#10000000B		;SETB SMOD
	SETB	PT1  			;Timer_1 ima najvecjo prioriteto
	SETB	TR1			;Pozeni Timer_1
	SETB	ET1			;Omogoci prekinitve Timerja_1
	SETB	ES			;Enable serial

	MOV	A,#1			;Izpisi '110' na display
	PUSH 	ACC
	CALL	HEX_TO_7
	POP	COL_4
     	INC	SP
	POP	COL_5
	RET


SB_150:	MOV	TMOD, #00010001B	;Timer_1 in Timer_0 16bit casc.
	MOV 	RCAP1L,#LOW (0FFFFH - 417 +1)
	MOV	RCAP1H,#HIGH(0FFFFH - 417 +1)  ;Tocno 149.88001 BAUD
	MOV	PCON,#1000000B		;SETB SMOD
	SETB	PT1  			;Timer_1 ima najvecjo prioriteto
	SETB	TR1			;Pozeni Timer_1
	SETB	ET1			;Omogoci prekinitve Timerja_1
	SETB	ES			;Enable serial

	MOV	A,#1			;Izpisi '150' na display
	PUSH 	ACC
	CALL	HEX_TO_7
	POP	COL_4
	MOV	A,#5
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_5
	RET

SB_300:	MOV	PCON, #10000000B	;SETB SMOD ;Tocno 300.48077 BAUD
	MOV	TMOD, #00100001B	;Timer_1 autoreload, Timer_0 16bit casc.
	MOV	TH1,#48			;Reload vrednost Timerja_1
	SETB	TR1			;Pozeni Timer_1
	CLR	ET1			;Onemogoci prekinitev timerja_1
	CLR	PT1			;Brisi visjo prioriteto Timerja_1
	SETB	ES			;Enable serial
      
	MOV	A,#3			;Izpisi 300 na display
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_4
	RET

SB_1200:MOV	PCON, #10000000B	;SETB SMOD ;Tocno 1201.92308 BAUD
	MOV	TMOD, #00100001B	;Timer_1 autoreload, Timer_0 16bit casc.
	MOV	TH1,#204		;Reload vrednost Timerja_1
	SETB	TR1			;Pozeni Timer_1
	CLR	ET1			;Onemogoci prekinitev timerja_1
	CLR	PT1			;Brisi visjo prioriteto Timerja_1
	SETB	ES			;Enable serial
      
	MOV	A,#1			;Izpisi 1200 na display
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_3
	MOV	A,#2
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_4
	RET

SB_2400:MOV	PCON, #10000000B	;SETB SMOD ;Tocno 2403.84615 BAUD
	MOV	TMOD, #00100001B	;Timer_1 autoreload, Timer_0 16bit casc.
	MOV	TH1,#230		;Reload vrednost Timerja_1
	CLR	ET1			;Onemogoci prekinitev timerja_1
	CLR	PT1			;Brisi visjo prioriteto Timerja_1
	SETB	TR1			;Pozeni Timer_1
	SETB	ES			;Enable serial
  	
	MOV	A,#2			;Izpisi 2400 na display
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_3
	MOV	A,#4
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_4
	RET

SB_4800:MOV	PCON, #10000000B	;SETB SMOD ;Tocno 4807.69231 BAUD
	MOV	TMOD, #00100001B	;Timer_1 autoreload, Timer_0 16bit casc.
	MOV	TH1,#243		;Reload vrednost Timerja_1
	SETB	TR1			;Pozeni Timer_1
	CLR	ET1			;Onemogoci prekinitev timerja_1
	CLR	PT1			;Brisi visjo prioriteto Timerja_1
	SETB	ES			;Enable serial
      
	MOV	A,#4			;Izpisi 4800 na display
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_3
	MOV	A,#8
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_4
	RET				;Vrni se



;Set Light - Nastavitev jakosti osvetlitve displaya
;v A registru podamo osvetlitev
;Uporablja: A, DPTR
INI_LIT:				; SET_LIT(A)
	MOV	COL_0+1,#NOT 00111000B	; L - izpis na display
	MOV	COL_1+1,#NOT 00000110B 	; I
	MOV	COL_2+1,#NOT 01111101B	; G
	MOV	COL_3+1,#NOT 01110110B	; H
	MOV	COL_4+1,#NOT 11111000B	; t
SET_LIT:ANL	A,#111B			;Odrezi odvecne bite
	MOV	LIGHT,A			;zapisi trenutno osvetlitev v spomin
	PUSH	ACC			;Izpisi jakost na display [0..7]
	CALL	HEX_TO_7
	POP	COL_5+3			
	MOV	DPTR,#SL_JMPTBL		;Nastavi kazalec na tabelo
	MOVC	A,@A+DPTR		;Izracunaj skok
	JMP	@A+DPTR			;Skoci v rutino
SL_JMPTBL:				;Tabela skokov
	DB	SL_0 - SL_JMPTBL
	DB	SL_1 - SL_JMPTBL
	DB	SL_2 - SL_JMPTBL
	DB	SL_3 - SL_JMPTBL
	DB	SL_4 - SL_JMPTBL
	DB	SL_5 - SL_JMPTBL
	DB	SL_6 - SL_JMPTBL
	DB	SL_7 - SL_JMPTBL
SL_0:	SETB	DA_LSB		     	;Rutin za nastavljanje
	SETB	DA_NSB			;jakosti displaya
	SETB	DA_MSB
	RET
SL_1:	CLR	DA_LSB
	SETB	DA_NSB
	SETB	DA_MSB
	RET
SL_2:	SETB	DA_LSB
	CLR	DA_NSB
	SETB	DA_MSB
	RET
SL_3:	CLR	DA_LSB
	CLR	DA_NSB
	SETB	DA_MSB
	RET
SL_4:	SETB	DA_LSB
	SETB	DA_NSB
	CLR	DA_MSB
	RET
SL_5:	CLR	DA_LSB
	SETB	DA_NSB
	CLR	DA_MSB
	RET
SL_6:	SETB	DA_LSB
	CLR	DA_NSB
	CLR	DA_MSB
	RET
SL_7:	CLR	DA_LSB
	CLR	DA_NSB
	CLR	DA_MSB
	RET




;Brisi tabelo 7 segmentnih podatkov za display
;Uporablja: R0 ,R1

CLR_TAB:				; CLR_TAB()
	MOV 	R0,#24		       	;24 polj brisi
	MOV	R1,#COL_0		;zacni s prvim elementom tabele
 CLR_TC: MOV	@R1,#0FFH	 	;vstavljaj 0FFH
	 INC	R1			;in povecuj kazalec
	 DJNZ	R0,CLR_TC		;ponavljaj se za naslednje
	RET


;Brisi display
;Uporablja: DPTR, A

CLRD:					; CLR_D()
	MOV	DPTR,#MUX		;izberi MUX kolone
	MOV	A,#00H			;
	MOVX	@DPTR,A			;Azuriraj MUX
	RET				;vrni se



;Konverzija iz ASCII v HEX (0..9)
;Na skladu je vhodni in izhodni podatek
;Uporablja R0

ASC_HEX:				;Function ASC_HEX(A)
	MOV 	R0,SP  			;Pripravi kazalec na skladu
	DEC 	R0
	DEC 	R0
	XCH 	A,@R0			;Zamenjaj A in ASCII podatek
	CLR	C			;Brisi C
	SUBB	A,#'0'			;Odstej 
	XCH	A,@R0			;Izmenjaj HEX in ACC na skladu
	RET				;Vrni se



;Konverzija iz HEX v 7 segment
;Na skladu je vhodni in izhodni podatek
;Uporablja R0

HEX_TO_7:				;Function HEX_TO_7(A)
	MOV	R0,SP			;Beri sklad	  	
	DEC	R0			;Nastavi R0 za
	DEC	R0			;parameter
	XCH	A,@R0
	ANL    	A,#0FH
	ADD	A,#2
	MOVC	A,@A+PC
	XCH	A,@R0
	RET
SEVTBL:	DB	NOT 00111111B 	;Char 0
	DB	NOT 00000110B	;Char 1
	DB	NOT 01011011B	;Char 2
	DB	NOT 01001111B	;Char 3
	DB	NOT 01100110B	;Char 4
	DB	NOT 01101101B	;Char 5
	DB	NOT 01111101B	;Char 6
	DB	NOT 00000111B 	;Char 7
	DB	NOT 01111111B	;Char 8
	DB	NOT 01101111B	;Char 9
	DB	NOT 01110111B	;Char A
	DB	NOT 01111100B	;Char B
	DB	NOT 00111001B	;Char C
	DB	NOT 01011110B	;Char D
	DB	NOT 01111001B	;Char E
	DB	NOT 01110001B	;Char F


;Interrupt rutina za osvezevanje displaya

REFRESH:				;Interrupt REFRESH()
	MOV	TL0,#T0_REL_LO		;1C Nastavi Timer_0
	MOV	TH0,#T0_REL_HI		;1C se high vrednost

	PUSH	PSW		     	;2C
	PUSH	ACC			;2C
	PUSH	DPL			;2C
	PUSH	DPH			;2C
	
	MOV	A,KEYC			;kontroliramo ali je stevec za tipko
	INC	A			;dosegel stevilko 255
	JZ	RFSH_NI			;ce jo je potem ne povecujemo vec
	INC	KEYC	  		;Povecamo casovni stevec za tipko

RFSH_NI:MOV	A,WENS 			;1C Brisemo kolone
	ANL	A,#11000000B		;1C
	MOV	DPTR,#MUX		;2C
	MOVX	@DPTR,A			;2C
	MOV	A,RFSHC	     		;1C Povecamo RFSHC za 1 in
	MOV	DPTR,#JMPTBL 		;2C izracunamo skok
	MOVC	A,@A+DPTR		;2C
	JMP	@A+DPTR			;2C
	
JMPTBL:	DB	DISPLAY_0 - JMPTBL   	;Tabela skokov
	DB	DISPLAY_1 - JMPTBL
	DB	DISPLAY_2 - JMPTBL	
	DB	DISPLAY_3 - JMPTBL
	DB	DISPLAY_4 - JMPTBL
	DB	DISPLAY_5 - JMPTBL

DISPLAY_0:

	MOV	A,COL_0	  		;1C Osvezimo posamezne
	MOV	DPTR,#LAT		;2C vrstice
	MOVX	@DPTR,A			;2C
	MOV	A,COL_0 + 1		;1C
	MOV	DPTR,#LON		;2C
	MOVX	@DPTR,A			;2C
	MOV	A,COL_0 + 2		;1C
	MOV	DPTR,#HDG		;2C
	MOVX	@DPTR,A			;2C
	MOV	A,COL_0 + 3		;1C
	MOV	DPTR,#SPD		;2C
	MOVX	@DPTR,A			;2C
      
	CLR	A		      	;1C prizgemo ustrezne
	ORL	A,WENS			;1C kolone
	ORL	A,#00000001B		;1C
	MOV	DPTR,#MUX		;2C
	MOVX	@DPTR,A	  		;2C

	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH			;2C
	POP	DPL			;2C
	POP	ACC			;2C
	POP	PSW			;2C
	RETI				;2C in se vrnemo iz interupta
	      				;sum = 65Cycles == 65 microseconds
DISPLAY_1:
	
	MOV	A,COL_1	  		;Osvezimo posamezne
	MOV	DPTR,#LAT		;vrstice
	MOVX	@DPTR,A
	MOV	A,COL_1 + 1
	MOV	DPTR,#LON
	MOVX	@DPTR,A
	MOV	A,COL_1 + 2
	MOV	DPTR,#HDG
	MOVX	@DPTR,A
	MOV	A,COL_1 + 3
	MOV	DPTR,#SPD
	MOVX	@DPTR,A
      
	CLR	A		      	;prizgemo ustrezno
	ORL	A,WENS			;kolono
	ORL	A,#00000010B
	MOV	DPTR,#MUX
	MOVX	@DPTR,A
     
	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH
	POP	DPL
	POP	ACC
	POP	PSW
	RETI				;in se vrnemo iz interupta
	      
DISPLAY_2:
	
	MOV	A,COL_2	  		;Osvezimo posamezne
	MOV	DPTR,#LAT		;vrstice
	MOVX	@DPTR,A
	MOV	A,COL_2 + 1
	MOV	DPTR,#LON
	MOVX	@DPTR,A
	MOV	A,COL_2 + 2
	MOV	DPTR,#HDG
	MOVX	@DPTR,A
	MOV	A,COL_2 + 3
	MOV	DPTR,#SPD
	MOVX	@DPTR,A
      
	CLR	A		      	;prizgemo ustrezno
	ORL	A,WENS			;kolono
	ORL	A,#00000100B
	MOV	DPTR,#MUX
	MOVX	@DPTR,A
     
	INC	RFSHC			;1C Izberemo naslednjo 
      
	POP	DPH
	POP	DPL
	POP	ACC
	POP	PSW
	RETI				;in se vrnemo iz interupta
	      
DISPLAY_3:
	
	MOV	A,COL_3	  		;Osvezimo posamezne
	MOV	DPTR,#LAT		;vrstice
	MOVX	@DPTR,A
	MOV	A,COL_3 + 1
	MOV	DPTR,#LON
	MOVX	@DPTR,A
	MOV	A,COL_3 + 2
	MOV	DPTR,#HDG
	MOVX	@DPTR,A
	MOV	A,COL_3 + 3
	MOV	DPTR,#SPD
	MOVX	@DPTR,A
      
	CLR	A		      	;prizgemo ustrezno
	ORL	A,WENS			;kolono
	ORL	A,#00001000B
	MOV	DPTR,#MUX
	MOVX	@DPTR,A
     
	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH
	POP	DPL
	POP	ACC
	POP	PSW
	RETI				;in se vrnemo iz interupta
	      
DISPLAY_4:
	
	MOV	A,COL_4	  		;Osvezimo posamezne
	MOV	DPTR,#LAT		;vrstice
	MOVX	@DPTR,A
	MOV	A,COL_4 + 1
	MOV	DPTR,#LON
	MOVX	@DPTR,A
	MOV	A,COL_4 + 2
	MOV	DPTR,#HDG
	MOVX	@DPTR,A
	MOV	A,COL_4 + 3
	MOV	DPTR,#SPD
	MOVX	@DPTR,A
      
	CLR	A		      	;prizgemo ustrezno
	ORL	A,WENS			;kolono
	ORL	A,#00010000B
	MOV	DPTR,#MUX
	MOVX	@DPTR,A
     
	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH
	POP	DPL
	POP	ACC
	POP	PSW
	RETI				;in se vrnemo iz interupta

	      
DISPLAY_5:
	
	MOV	A,COL_5	  		;Osvezimo posamezne
	MOV	DPTR,#LAT		;vrstice
	MOVX	@DPTR,A
	MOV	A,COL_5 + 1
	MOV	DPTR,#LON
	MOVX	@DPTR,A
	MOV	A,COL_5 + 2
	MOV	DPTR,#HDG
	MOVX	@DPTR,A
	MOV	A,COL_5 + 3
	MOV	DPTR,#SPD
	MOVX	@DPTR,A
      
	CLR	A		      	;prizgemo ustrezno
	ORL	A,WENS			;kolono
	ORL	A,#00100000B
	MOV	DPTR,#MUX
	MOVX	@DPTR,A

	MOV	RFSHC,#0		;Brisi stevec na nulo

	POP	DPH
	POP	DPL
	POP	ACC
	POP	PSW
	RETI				;in se vrnemo iz interupta

	
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  


;Interrupt rutina serijskega porta za polnjenje cirkularnega bufferja
;Poveca se kazalec na konec bufferja in na mesto kamor kaze buffer se
;vpise vrednost SBUF registra

SERIAL_SERVER:				;Interrupt SERIAL_SERVER()
	CLR	RI			;omogoci sprejem sledecega byta

	PUSH	PSW			;shrani pomembne
	PUSH	ACC			;registre

	MOV	PSW,#00001000B		;2C Izberi REGISTER BANK 1
       
	MOV	R0,BUF_END		;R0 kaze na mesto
	MOV	@R0,SBUF		;ki ga je potrebno zapolniti

	INC	BUF_END			;Povecamo kazalec 
	MOV	A,BUF_END		;na konec bufferja
					;Kontroliramo ali je kazalec na konec 
					;prekoracil vrh bufferja

	CJNE	A, #BUFFER+BUF_LEN, SS_NOT_TOP   ; ce ni vrh skoci
     
	MOV	BUF_END,#BUFFER		;vrh je dosezen -> kazalec na dno
	MOV	A,BUF_END

SS_NOT_TOP:
	CJNE	A,BUF_BEG,SS_BUF_OK 	;Kontroliramo polnost bufferja
	MOV	A,#0
	JMP	ERROR			;Buffer je prepolnjen->izpisi napako 0

SS_BUF_OK:		 
	POP	ACC
	POP 	PSW
	
	RETI
	

;Izpise "error" na display in stevilko napake
;V Akumulatorju mora biti stevilka napake 0..0FH
; 0 -> Serial buffer prepolnjen

ERROR:					; ERROR(A)
	CLR	TR1			;ustavi timer_1 in serial port
	CALL	CLR_TAB			;Brisi tabelo

	PUSH	ACC			;Vrednost v A
	CALL	HEX_TO_7		;pretvori v 7 segment
	POP	ACC
	MOV	COL_5+2,A		;vstavi stevilko v tabelo

	MOV	COL_0,#NOT 01111011B	;'e'
	MOV	COL_1,#NOT 00110001B	;'r'
	MOV	COL_2,#NOT 00110001B	;'r'
	MOV	COL_3,#NOT 00111111B	;'o'
	MOV	COL_4,#NOT 00110001B	;'r'

	MOV	R0,#200			;Nastavi cakanje 20.0 s		
	CALL	DELAY		     	;in klici rutino za delay
	JMP	RESET			;nato resetiraj sistem
	RET				;RET je kar tako

;Zakasnitev oziroma tratenje casa v desetinkah sekunde
;Parameter za delay R0
;Uporablja R0, R1, R2
DELAY:					;Cakaj nekaj casa
DEL_L0:	MOV	R1,#200			;0.1s  delay
DEL_L1:	MOV	R2,#248			;0.5ms delay
	DJNZ	R2, $
	DJNZ	R1,DEL_L1
	DJNZ	R0,DEL_L0

	RET



;Interrupt rutina za osvezevanje displaya >> SAMO ZA  testiranje

DISPLAY_SERVER:				;Interrupt DISPLAY_SERVER ()
	MOV	TL0,#T0_REL_LO		;1C Nastavi Timer_0
	MOV	TH0,#T0_REL_HI		;1C se high vrednost

;	MOV	P1,#0FFH

	PUSH	PSW		     	;2C
	PUSH	ACC			;2C
	PUSH	DPL			;2C
	PUSH	DPH			;2C
	MOV	A,RFSHC	     		;1C Povecamo RFSHC za 1 in
	MOV	DPTR,#DS_JMPTBL 		;2C izracunamo skok
	MOVC	A,@A+DPTR		;2C
	JMP	@A+DPTR			;2C
	
DS_JMPTBL:
	DB	D_0 - DS_JMPTBL   	;Tabela skokov
	DB	D_1 - DS_JMPTBL
	DB	D_2 - DS_JMPTBL	
	DB	D_3 - DS_JMPTBL
	DB	D_4 - DS_JMPTBL

D_0:
	MOV	A,COL_0	  		;1C Osvezimo posamezne
	MOVX	@DPTR,A			;2C
      
	MOV	P1,# NOT 10000000B		;Izberi ustrezno kolono

	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH			;2C
	POP	DPL			;2C
	POP	ACC			;2C
	POP	PSW			;2C
	RETI				;2C in se vrnemo iz interupta
	      				;sum = 65Cycles == 65 microseconds
D_1:
	MOV	A,COL_1  		;1C Osvezimo posamezne
	MOVX	@DPTR,A			;2C
      
	MOV	P1,# NOT 01000000B		;Izberi ustrezno kolono

	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH			;2C
	POP	DPL			;2C
	POP	ACC			;2C
	POP	PSW			;2C
	RETI				;2C in se vrnemo iz interupta
	      				;sum = 65Cycles == 65 microseconds
D_2:
	MOV	A,COL_2		;1C Osvezimo posamezne
	MOVX	@DPTR,A			;2C
      					      
	MOV	P1,# NOT 00100000B		;Izberi ustrezno kolono

	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH			;2C
	POP	DPL			;2C
	POP	ACC			;2C
	POP	PSW			;2C
	RETI				;2C in se vrnemo iz interupta
	      				;sum = 65Cycles == 65 microseconds
D_3:
	MOV	A,COL_3  		;1C Osvezimo posamezne
	MOVX	@DPTR,A			;2C
      
	MOV	P1,# NOT 00010000B		;Izberi ustrezno kolono

	INC	RFSHC			;1C Izberemo naslednjo 

	POP	DPH			;2C
	POP	DPL			;2C
	POP	ACC			;2C
	POP	PSW			;2C
	RETI				;2C in se vrnemo iz interupta
	      				;sum = 65Cycles == 65 microseconds
D_4:
	MOV	A,COL_4	  		;1C Osvezimo posamezne
	MOVX	@DPTR,A			;2C
      
	MOV	P1,# NOT 00001000B		;Izberi ustrezno kolono

	MOV	RFSHC,#0		;1C Izberemo naslednjo 

	POP	DPH			;2C
	POP	DPL			;2C
	POP	ACC			;2C
	POP	PSW			;2C
	RETI				;2C in se vrnemo iz interupta
	      				;sum = 65Cycles == 65 microseconds


;Rutina izpise decimalna vrednost akumulatorja na display

OUTA_DEC:			       	; OUTA_DEC (A)
	MOV	B,#100
	DIV 	AB
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_0
	MOV	A,#10
	XCH	A,B
	DIV	AB
	PUSH	ACC
	CALL	HEX_TO_7
	POP	COL_1
	PUSH	B
	CALL	HEX_TO_7
	POP	COL_2
	MOV	COL_3,#0
	RET

;Rutina izpise heksadecimalna vrednost akumulatorja na display
;Uporablja A, R0, COL_0..2,
OUTA_HEX:			    	; OUTA_HEX (A)
       	PUSH	ACC
       	CALL	HEX_TO_7
       	POP	COL_2
       	SWAP	A
       	PUSH	ACC
       	CALL	HEX_TO_7
       	POP	COL_1
       	RET


;Izpisovanje vhodnih podatkov iz serijskega bufferja v hex na display
;Zanka je neskoncna -> ni izhoda iz nje
;Uporablja A, R0
DUMP_HEX:				; DUMP_HEX ()
	CALL 	CLR_TAB			;Brisi tabelo
DU_WA:	MOV	A,BUF_BEG		;A<- kazalec na zacetek tabele
	CJNE	A,BUF_END,DU_OK		;ali je buffer prazen
	JMP	DU_WA			;zacetek je enak koncu
DU_OK:	CALL	SHIFT_TABEL		;Napravi prostor za eno HEX[00..FF]mesto
	MOV	R0,BUF_BEG		
	MOV	A, @R0
	CALL	OUTA_HEX		;Izpisi Hex

	INC	BUF_BEG			;povecaj BUF_BEG
	MOV	A,BUF_BEG
	CJNE	A,#BUFFER+BUF_LEN,DU_POK ;ali je zacetek na vrhu
	MOV	BUF_BEG,#BUFFER		 ;BUF_BEG kaze na zacetek bufferja
DU_POK:					;kazalec na zacetek je OK {ni na vrhu}
	JMP	DU_WA			;ponovi isto se za naslednji znak
	RET				;RET kar tako

SHIFT_TABEL:				;napravi prostor za eno stevilko
	PUSH	COL_1 + 3	      
	POP	COL_3 + 3

	PUSH	COL_2 + 3
	POP	COL_3 + 3
     
	PUSH	COL_4 + 2
	POP	COL_2 + 3
       
	PUSH	COL_3 + 2
	POP	COL_1 + 3

	PUSH	COL_2 + 2
	POP	COL_4 + 2

	PUSH	COL_1 + 2
	POP	COL_3 + 2

	PUSH	COL_5 + 3
	POP	COL_2 + 2

	PUSH	COL_5 + 1
	POP	COL_1 + 2

	PUSH	COL_4 + 1
	POP	COL_5 + 3

	PUSH	COL_3 + 1
	POP	COL_5 + 1

	PUSH	COL_2 + 1
	POP	COL_4 + 1

	PUSH	COL_1 + 1
	POP	COL_3 + 1

	PUSH 	COL_5 + 2
	POP	COL_2 + 1

	PUSH	COL_5 + 0
	POP	COL_1 + 1

	PUSH	COL_4 + 0
	POP	COL_5 + 2

	PUSH	COL_3
	POP	COL_5

	PUSH	COL_2
	POP	COL_4

	PUSH	COL_1
	POP	COL_3

	RET


;Izpise na display zascitni znak "OLEO"
OUT_OLEO:
	MOV	COL_1+2,#NOT 00111111B		;O
	MOV	COL_2+2,#NOT 00111000B		;L
	MOV	COL_3+2,#NOT 01111001B		;E
	MOV	COL_4+2,#NOT 00111111B		;O
	MOV	COL_1+3,#NOT 00111111B		;O obrnjen
	MOV	COL_2+3,#NOT 01001111B		;E obrnjen
	MOV	COL_3+3,#NOT 00000111B		;L obrnjen
	MOV	COL_4+3,#NOT 00111111B		;O obrnjen
	RET



DB '       The program is provided ''as is'' without waranty of any kind, '
DB 'either expressed or implied, including, but not limited to the '
DB '(implied warranties of merchantability and fittness for a particular '
DB 'purpose. The entire risk as to the quality and to the performance '
DB 'of the program is with you. Should the program prove defective, '
DB 'YOU and NOT AUTOR assume the entire cost of all necessary servicing, '
DB 'repair and correction. '

END