.DEVICE AT90S1200

;***************************************************************************
;* a few, very useful macros
;***************************************************************************

.LISTMAC
;* definisce il nome passato come il registro r20
.MACRO ARGUMENT1
.def 	@0 = r16
.ENDMACRO
.MACRO ARGUMENT2
.def 	@0 = r17
.ENDMACRO
.MACRO ARGUMENT3
.def 	@0 = r18
.ENDMACRO
.MACRO ARGUMENT4
.def 	@0 = r19
.ENDMACRO
.MACRO ARGUMENT5
.def 	@0 = r20
.ENDMACRO
.MACRO MAINVARIABLE1
.def 	@0 = r21
.ENDMACRO
.MACRO MAINVARIABLE2
.def 	@0 = r22
.ENDMACRO
.MACRO MAINVARIABLE3
.def 	@0 = r23
.ENDMACRO
.MACRO MAINVARIABLE4
.def 	@0 = r24
.ENDMACRO


.MACRO  ADDI    
	subi @0, -@1
.ENDMACRO

;skip next instruction if not equal to zero
.MACRO skipne                   
.SET    _skipne = PC+2
	brne    _skipne
.ENDMACRO

;skip next instruction if carry set
.MACRO skipcs                   
.SET    _skipcs = PC+2
	brcs    _skipcs
.ENDMACRO

;skip next instruction if carry clear
.MACRO skipcc
.SET    _skipcc = PC+2
	brcc    _skipcc
.ENDMACRO

;skip next instruction if equal to zero
.MACRO  skipeq
.SET    _skipeq = PC+2
	breq    _skipeq
.ENDMACRO

;skip next instruction if lower
.MACRO skiplo                   
.SET    _skiplo = PC+2
	brlo    _skiplo
.ENDMACRO

;skip next instruction if half carry set
.MACRO skiphs                   
.SET    _skiphs = PC+2
	brhs    _skiphs
.ENDMACRO

;skip next instruction if half carry clear
.MACRO skiphc
.SET    _skiphc= PC+2
	brhc   _skiphc
.ENDMACRO

;skip next instruction if T set
.MACRO skipts                  
.SET    _skipts = PC+2
	brts    _skipts
.ENDMACRO

;skip next instruction if T clear
.MACRO skiptc                  
.SET    _skiptc = PC+2
	brtc    _skiptc
.ENDMACRO

;skip next instruction if minus
.MACRO skipmi
.SET    _skipmi = PC+2
	brmi    _skipmi
.ENDMACRO

;wait two cycles but waste only one instruction
.MACRO  doublenop
.SET    _doublenop = PC+1
	rjmp    _doublenop
.ENDMACRO

;include AT90S1200 registers definitions
.include "1200def.inc"
.include "fonts.inc"

;***************************************************************************
;* VARIABLE ASSIGNEMENTS
;***************************************************************************
.CSEG

	.def    SaveStatus =    r0      ;status buffer during interrupts
	.def	NumeriDaEstrarre=r1	;quanti numeri da estrarre per generatore casuale
	.def    Random =    	r2      ;generatore casuale da 1 a NumeriDaEstrarre
	.def    RunningNumber = r3      ;numero corrente sul tabellone
	.def    AltezzaPixel =  r4
	.def    EstrattiLow=r5      ; bitmap di una decina di numeri estratti
	.def    EstrattiHigh=r6     ; per accensione/spegnimento cifra
	.def    CopiaEstrattiLow=r7	;copia di lavoro di quanto sopra
	.def    CopiaEstrattiHigh=r8
	.def    x5		=r9
	.def    Delay =   	r10
	.def    CopiaPatternDecine =          r11 
	.def    X4 =    	r12
	.def    EEDriverRegister=r13
	.def    NumeriDaSaltare=r14
	.def    X6   =r15

	.def    Arg1 =          r16     ;Temp variable used by interrupt
	.def    Arg2 =          r17     ; "      "      "          "
	.def    Arg3 =          r18     ; "      "      "          "
	.def    Arg4 =          r19     ; "      "      "          "
	.def	Arg5 = 		r20	; "      "      "          "
	.def    Main1 =         r21     ;Temp variable used by main program
	.def    Main2 =         r22     ; "      "      "       "      "
	.def    Main3 =         r23     ; "      "      "       "      "
	.def    Main4 =         r24     ; "      "      "       "      "
	.def    Decine = 		r25
	.def    Unita =       	r26    ;  "       "      "     " 
	.def    RowsModFour =   r27	;raster rows counter, split in two for
	.def    RowsDivFour =   r28     ;convenience of use. Counts up to 312
	.def    RowOffset =    	r29
	.def    NumeroScansione =r30     
	.def    MiscFlags =     r31     ;Assorted flags
					;bit 0,1: position (0-3) of interrupt
					;identifies wich of the four line position
					;we are on (3=end of line, 0=sync pulse) when
					;an interrupt occurs
					;used by timer interrupt routine
	;flags bit definition
	.equ	Position1Bit = 	0
	.equ	Position2Bit =  1
	.equ    SerialReqBit =  2

	.equ	EEReadReqBit = 	3
	.equ	EEWriteReqBit = 4
	.equ	EEWritePendingBit = 5
	.equ	EEDataBit = 	6
	.equ	BlankScreenBit = 7

	.equ	POSITIONMASK =  3




;***************************************************************************
;* Constants
;***************************************************************************

	.equ    DisplayRow =    150/4   ;counter value for display start 
	.equ    StartRetrace = (312/4)-1;counter value at wich retrace starts
	.equ    StopRetrace = (312/4)   ;maximum counter value


	.equ	STARTBLOCKED = 255	;time value signalling indefinite
					;delay due to jump start


	.equ	LARGHEZZABIGNUMBERS = 1
	.equ	ALTEZZABIGNUMBERS = 11
	.equ	ALTEZZANUMERITABELLA = 3	

;***************************************************************************
;* Port Pin Assignements
;***************************************************************************

	;port D bit definitions (OUTPUTS)
	.equ    CSyncBit =      0       ;set video output to composite sync level when low

	.equ    VideoBit =      1       ;set video level to white when high, black when low
	.equ    FastBlank =     2      
	.equ    GreenBit =      3       ;
	.equ    RedBit =        4       ;
	.equ    AudioBit =      5       ;board led
	.equ    RS232Bit =      6       ;1200 baud TTL level serial data

	;port B bit definitions (INPUTS)
	.equ    KeyStop    =    1       ;Button: forced end
	.equ	KeyLastLap =    2	;Button: allow automatic stop
	.equ	KeyGo =      	3	;Button: automatic start sequence
	.equ	KeyClear =	4	;Button: clear counters
	.equ    Photo1 =     	5       ;photocell car 1...3
	.equ    Photo2 =     	6       ;
	.equ    Photo3 =     	7       ;	
	

;***************************************************************************
;* VECTORS
;***************************************************************************

	rjmp    RESET           ;Reset Handle
	rjmp    RESET           ;Ext. interrupt request 0
	rjmp    TIMER           ;Timer




;***************************************************************************
;*
;* MAIN PROGRAM
;*
;***************************************************************************
;* INITAILIZATION
;***************************************************************************


RESET:  
		clt     ;clear T bit flag       ;VERY important: 
						;clear T flag, here used to 
						;verify if we were sleeping
		ldi     Arg1, 0b01111111        ;set port D bits to outputs
		out     DDRD, Arg1
		ldi     Arg1, 0b00000001        ;preset  output state
		out     PortD, Arg1
		ldi     Arg1, 0b00000000        ;set port B to inputs
		out     DDRB, Arg1
		ldi     Arg1,  0b11111111       ;turn on pullups on inputs
		out     PortB, Arg1

		ldi	Arg1, 1
		out     TCCR0, Arg1             ;dont'use timer prescaler             
		ldi     Arg1, 32
		out     MCUCR, Arg1             ;enable sleep idle mode
		ldi     Arg1, 2
		out     TIMSK, Arg1             ;enable timer interrupt 


		ldi 	Arg1, 3	
		mov	AltezzaPixel, Arg1
	
		
		ldi	MiscFlags, 1
		clr     Arg1			;and clear interrupt variables
		clr     Arg2
		clr     Arg3
		clr     Arg4

		sei                     	;at last, allow interrupts


	;;;	numeridaestrarre = 0
	;;;	for numeroscansione = 89 to 0
	;;;		if numeroscansione is not estratto
	;;;			numeridaestrarre++

	clr	NumeriDaEstrarre
	ldi	NumeroScansione, 89+1
FOR1:	dec	NumeroScansione
	brmi	ENDFOR1	
	mov	EEDriverRegister, NumeroScansione	;set number to read
	rcall	READ_EEPROM
	sbrs	MiscFlags, EEDataBit
	inc	NumeriDaEstrarre
	rjmp	FOR1
ENDFOR1:
	ldi	NumeroScansione,90

		

;***************************************************************************
;* MAIN LOOP
;***************************************************************************

FOREVER:                
MAINVARIABLE2   Ripristino
TESTKEYGO:		
	sbic	PinB, KeyGo			;if GO! pressed, restart time
	rjmp	TESTKEYCLEAR
	tst	NumeriDaEstrarre
	breq	TESTKEYCLEAR

	;;;	numeridasaltare = random
	;;;	for numeroscansione = 89 to 0
	;;;		if numeroscansione IS NOT estratto
	;;;			if numeridasaltare == 0
	;;;				estrai numeroscansione
	;;;				exit for
	;;;			else
	;;;				numeridasaltare--
	;;;			endif
	;;;		endif

	
	mov	NumeriDaSaltare, Random
	ldi	NumeroScansione, 89+1
FOR:	dec	NumeroScansione
	brmi	ENDFOR	
	mov	EEDriverRegister, NumeroScansione	;set number to read
	rcall	READ_EEPROM
	sbrc	MiscFlags, EEDataBit
	rjmp	FOR
	dec	NumeriDaSaltare
	brpl	FOR
	;estrazione!
	dec	NumeriDaEstrarre
	sbr	MiscFlags, EXP2(EEDataBit)		;set data to write
	mov	EEDriverRegister, NumeroScansione	;set number to write
	rcall	WRITE_EEPROM
ENDFOR:
	rcall	Delay
WAITRELEASE:
	sbis	PinB, KeyGo				;aspettiamo il rilascio
	rjmp 	WAITRELEASE
	rcall	Delay					;debounce

TESTKEYCLEAR:
	sbic	PinB, KeyClear
	rjmp 	ENDKEYS
	ldi 	NumeroScansione,90			;90 = clear
	ldi 	Ripristino, 90
	mov	NumeriDaEstrarre, Ripristino
	ldi	Ripristino, 89
_L30:	cbr	MiscFlags, EXP2(EEDataBit)		;set data to write
	mov	EEDriverRegister, Ripristino		;set number to write
	rcall	WRITE_EEPROM
	dec	Ripristino
	brpl	_L30
	
ENDKEYS:
	rjmp	FOREVER



;****************************************************************************
;*  MAIN ROUTINES
;****************************************************************************


DELAY:					;ritardo dopo pressione tasti
	ldi	Ripristino, 50		;a me piaceva 5....
	mov	Delay, Ripristino
_L40:	tst	Delay
	skipeq
	rjmp	_L40
	ret
	
	

READ_EEPROM:
	sbr	MiscFlags, EXP2(EEReadReqBit)		;send request
_L10:	sbrc    MiscFlags, EEReadReqBit			;read done?
	rjmp	_L10					;no, wait
	ret						;yes, return

WRITE_EEPROM:
	sbr	MiscFlags, EXP2(EEWriteReqBit)		;send request
_L20:	sbrc    MiscFlags, EEWriteReqBit		;write done?
	rjmp	_L20					;no, wait
	ret						;yes, return

		

;****************************************************************************
;*
;* Timer Interrupt: occurs four times in each video line.
;*      The Position records which of four interrupt stages we are on.
;*      At the third stage, we go in sleep mode, in order to have constant
;*      servicing time for the fourth, crucial interrupt were we will output
;*      the sync waveform.
;*      This is the very heart of sync generation.
;*
;****************************************************************************


TIMER:
	;if we were sleeping, then this is a synchronizing cycle: just return
	brtc    TIMER_NOSLEEP   ;if T cleared, do timer routine
	reti                    ;otherwise return (sync sleep)

TIMER_NOSLEEP:        
	in      SaveStatus, SREG
	;if not at line start,simply decrement position counter and return
	;otherwise do the real thing...
	dec     MiscFlags                ;Position(bits 0 and 1) range from 3 down to 0
	mov	Arg1, MiscFlags
	andi	Arg1, POSITIONMASK
	breq    WAITNEWLINE             ;if Position = 0 then wait (sleeping) for new line
TIMER_EXIT:        
	out     SREG, SaveStatus        ;otherwise do nothing
	reti
WAITNEWLINE:
	set                             ;set T flag to tell we are sleeping
	sei                             ;re-enable interrupts, otherwise we sleep forever!
	sleep                           ;wait sleeping the next timer interrupt
	                                ;(during sleep we have constant interrupt recovery time)
	cli                             ;disable further interrupts

NEWLINE:                                ;when awaken, we will restart here
	ori     MiscFlags, 3 		;reset position index
	in      Arg1, PortD             ;read previous CSync level
	ldi     Arg2, 0b00000001        ;load mask for toggle csync bit

TOGGLESYNC:
	eor     Arg1, Arg2              ;toggle CSync output
	out     PortD, Arg1             ;now we are in the horizontal sync pulse
HOUSEKEEPING:        
	;once in horizontal sync pulse space, we have 
	;enough time to do some housekeeping routines...
	inc     RowsModFour             ;increment row counters
	cpi     RowsModFour, 4          ;if RowsModFour == 4
	skipne           
	inc     RowsDivFour             ;then increment RowsDivFour
	andi    RowsModFour, 0b00000011 ;clear anyway bit 2

CHECKLASTLINE:        
	;when at last line, the sync pulse is stretched to half line
       	cpi     RowsDivFour, StopRetrace        ;if at last line 
       	skiplo
	rjmp	LASTLINE			;do a long pulse

WAITSYNCEND:                            ;else wait sync pulse end
	in      Arg1, TCNT0             ;note that now we are perfectly in
	cpi     Arg1, 64                ;sync with timer.        64 = 4 uS
	brlo    WAITSYNCEND

	ldi     Arg2, 0b00000001         ;prepare mask for csync toggle

VERTICALRETRACE:        
	ldi     Arg1, StartRetrace
	cpi     RowsModFour, 0          ;if at start of vertical retrace pulse
	cpc     RowsDivFour, Arg1                   
	brne    HSYNCEND                ;then leave CSync low
	ldi     Arg2, 0

HSYNCEND:        
	in      Arg1, PortD             ;
	eor     Arg1, Arg2              ;toggle CSync output
	out     PortD, Arg1             ;now we are in the color burst space

RANDOMNUMBER:
	inc	Random			;increase random counter
	cp	NumeriDaEstrarre, Random 	;modulo (numbers to extract)
	skipne
	clr	Random

EEPROM:	rcall 	EEDRIVER

WAITVISIBLEPORTION:        
	in      Arg1, TCNT0           ;wait for start of visible area
	cpi     Arg1, 150	      ;increasing this moves display right
	brlo    WAITVISIBLEPORTION

	rjmp	BUILDSCREEN		;go to display building table

LASTLINE:
	;this is a good time to make slow (1/50 sec.) housekeepings,
	;or to do things that are made once every screen picture
	clr 	Decine
	clr     RowsDivFour             ;reset row counters
	clr     RowsModFour             
	tst 	Delay
	skipeq
	dec	Delay


WAITHALFLINE:
	in      Arg1, TIFR              ;wait for two timer overflows
	sbrs    Arg1, TOV0              ;(each overflow is a quarter line)
	rjmp    WAITHALFLINE
	ldi     Arg1, EXP2(TOV0)        ;reset timer overflow bit
	out     TIFR, Arg1
SECONDQUARTER:
	in      Arg1, TIFR              ;wait second overflow
	sbrs    Arg1, TOV0              ;
	rjmp    SECONDQUARTER
	ldi     Arg1, EXP2(TOV0)        ;reset timer overflow bit
	out     TIFR, Arg1
	andi	MiscFlags, 0b11111101
	ori	MiscFlags, 0b00000001	;and align position counter (1)
	sbi     PortD, CSyncBit         ;and end composite sync
	rjmp    TIMER_EXIT


;****************************************************************************
;* SCREEN MAKEUP JUMP STRUCTURE
;* This compare and jump table determines the appearence of the display
;* at each step, the current line number is examinated to decide
;* which display routine to use
;****************************************************************************

BUILDSCREEN:
	;it's time to decide what to display, depending on current line
	ldi	Arg1, ALTEZZABIGNUMBERS
	cpi	RowsDivFour, 220/4
	skipne
	mov	AltezzaPixel, Arg1

	cpi	RowsDivFour, 288/4
	skiplo
	rjmp	VOIDLINE
	mov	Arg1, NumeroScansione
	inc	Arg1
	cpi	RowsDivFour, 224/4
	skiplo
	rjmp	DISPLAYBIGNUMBERS	
	cpi     RowsDivFour, 220/4	;blank display
	skiplo
	rjmp    VOIDLINE        
        cpi     RowsDivFour, 35/4
	skiplo
	rjmp    DISPLAYTABLE

	clr 	Unita
	clr	RunningNumber
	ldi	Arg1, ALTEZZANUMERITABELLA
	mov	AltezzaPixel, Arg1
        rjmp    VOIDLINE        






VOIDLINE:     
     	clr	RowOffset
	rjmp    TIMER_EXIT



				     
;****************************************************************************
;* ON SCREEN DISPLAY ROUTINES
;****************************************************************************
ARGUMENT1 Counter
WHITELINE:
	sbi	PortD, VideoBit
	ldi	Counter, 200
_wh1:
	dec 	Counter
	nop
	brne	_wh1
	cbi	PortD,VideoBit
	rjmp	DISPLAYLINERESTART
	

;****************************************************************************
;* DISPLAYTABLE
;****************************************************************************



ARGUMENT1 Output
ARGUMENT2 Temp
ARGUMENT2 PatternUnita

ARGUMENT3 PatternDecine
ARGUMENT4 PatternUltimaDecina
ARGUMENT5 Counter

DISPLAYTABLE:
	sbic	EECR, EEWE	;IF WRITE IN PROGRESS, SKIP
	rjmp	VOIDLINE
	
	sbi	PortD, GreenBit
	in 	Output, PortD

	clt			;separazioni orizzontali
	cpi	Decine, 3
	skipne
	set
	cpi 	Decine, 6
	skipne
	set
	ldi	Temp, 3
	cp	AltezzaPixel, Temp
	skipeq
	clt
	cpi	RowOffset, 0
	skipeq
	clt
	bld	Output, VideoBit
	out	PortD, Output


	
	mov	RunningNumber,Decine
	lsl	RunningNumber
	lsl	RunningNumber
	lsl	RunningNumber
	add	RunningNumber,Decine
	add	RunningNumber,Decine	;runningnumber=decine*10

	mov	EstrattiLow, CopiaEstrattiLow
	mov	EstrattiHigh, CopiaEstrattiHigh

	rol 	EstrattiLow
	rol	EstrattiHigh
	rol 	EstrattiLow
	rol	EstrattiHigh
	rol 	EstrattiLow
	rol	EstrattiHigh
	rol 	EstrattiLow
	rol	EstrattiHigh
	rol 	EstrattiLow
	rol	EstrattiHigh

	inc	Unita
	in 	Output, PortD		;read PortB status
	ldi	Counter,8

	mov 	Temp, RowOffset
	add	Temp, Decine	
	out     EEAR,  Temp             ;set eeprom address register
	sbi     EECR, 0                 ;send read command
	in      CopiaPatternDecine,EEDR ;read font table in EEPROM
	tst	Decine			;suppress leading zero
	skipne
	clr	CopiaPatternDecine

	inc	Temp			;load pattern for last column
	out     EEAR,  Temp             ;set eeprom address register
	sbi     EECR, 0                 ;send read command
	in      PatternUltimaDecina,EEDR      ;read font table in EEPROM

DISPLAYNUMBER:


	mov 	Temp, RowOffset		;get pattern for the units
	add	Temp, Unita
	out     EEAR, Temp           	;set eeprom address register
	sbi     EECR, 0                 ;send read command
	in      PatternUnita, EEDR      ;read font table in EEPROM
	mov	PatternDecine, CopiaPatternDecine  ;get the pattern for tens

	
	cpi	Unita, 6
	brne	NOSEPARATORE
	in	Output, PortD
	sbi	PortD, VideoBit
	nop
	out	PortD, Output

NOSEPARATORE:
	cpi	RowOffset, 60		;from row 6 on, blank display
	skiplo
	clr	PatternDecine
	skiplo
	clr	PatternUnita
	cpi	RowOffset, 0
	brne 	BITBANG

TESTESTRATTO:
	mov	Temp, RunningNumber	;temp=number to examine
	andi	Temp, 0b00111111	;temp=temp mod 64 to get real address
	out	EEAR, Temp
	sbi	EECR, 0
	cp	Temp, RunningNumber
	in	Temp, EEDR
	skipne
	bst	Temp, 0
	skipeq	
	bst	Temp, 1
	bld	CopiaEstrattiLow,0
	rol	CopiaEstrattiLow
	rol	CopiaEstrattiHigh
	inc	RunningNumber		
	inc	Unita
	nop
	doublenop
	doublenop
	doublenop
	doublenop
	doublenop
	nop
	clt
	cpi	Decine, 3
	skipne
	set
	cpi 	Decine, 6
	skipne
	set
	ldi	Temp, 3
	cp	AltezzaPixel, Temp
	skipeq
	clt
	bld	Output, VideoBit
	out	PortD, Output

	rjmp	ENDBITBANG



BITBANG:					;pixel bitbanging
	rol	EstrattiLow
	rol	EstrattiHigh
	skipcc
	rjmp	BANGBIANCO
	nop

;	skipcs
;	ldi	PatternDecine, 0
;	skipcs
;	ldi	PatternUnita, 0

BANGVERDE:
	bst	PatternDecine, 7	
	bld	Output, FastBlank	
	out	PortD, Output		
	bst	PatternDecine, 6	
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternDecine, 5
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternDecine, 4
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternDecine, 3
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternDecine, 2
	bld	Output, FastBlank
	out	PortD, Output
	inc 	Unita			;increase now to make black space
	bst	PatternUnita, 7
	bld	Output, FastBlank
	out	PortD, Output		
	bst	PatternUnita, 6
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternUnita, 5
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternUnita, 4
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternUnita, 3
	bld	Output, FastBlank
	out	PortD, Output
	bst	PatternUnita, 2
	bld	Output, FastBlank
	out	PortD, Output
	rjmp	ENDBITBANG


BANGBIANCO:
	bst	PatternDecine, 7		;read bit 7 into T
	bld	Output, VideoBit	;and copy it in PortB buffer
	out	PortD, Output		;set PortB accordingly
	bst	PatternDecine, 6		;repeat for the next 4 bits
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternDecine, 5
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternDecine, 4
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternDecine, 3
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternDecine, 2
	bld	Output, VideoBit
	out	PortD, Output

	;units digit

	inc 	Unita			;increase now to make black space
		
	bst	PatternUnita, 7		;read bit 7 into T
	bld	Output, VideoBit	;and copy it in output
	out	PortD, Output		;set hardware
	bst	PatternUnita, 6
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternUnita, 5
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternUnita, 4
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternUnita, 3
	bld	Output, VideoBit
	out	PortD, Output
	bst	PatternUnita, 2
	bld	Output, VideoBit
	out	PortD, Output
	rjmp	ENDBITBANG	

ENDBITBANG:
	subi 	Counter, 1
	skipmi
	rjmp	DISPLAYNUMBER	
	clr	Unita
	mov	CopiaPatternDecine, PatternUltimaDecina
	cpi	Counter, 255
	skipne
	rjmp	DISPLAYNUMBER

	dec 	AltezzaPixel
	brne	fine

	ldi	Temp, ALTEZZANUMERITABELLA
	mov	AltezzaPixel, Temp
	addi 	RowOffset, 10		;increment offset
	cpi 	RowOffset, 70
	brne	fine
	ldi	RowOffset, 0
	inc	Decine
fine:
	cbi	PortD, VideoBit
	cbi	PortD, GreenBit
	rjmp    DISPLAYLINERESTART      ;end line

	






;****************************************************************************
;* DISPLAY BIG NUMBER
;****************************************************************************


ARGUMENT1 Number
ARGUMENT2 Decine
ARGUMENT3 Counter
ARGUMENT4 ShiftPattern
ARGUMENT5 TimeDelay

DISPLAYBIGNUMBERS:
	sbic	EECR, EEWE	;IF WRITE IN PROGRESS, SKIP
_SKIP:	rjmp	VOIDLINE
	cpi	Number, 90+1
	breq	_SKIP
	cpi	Number, 0
	breq	_SKIP

	clr	Decine
	clr	TimeDelay
BIN2BCD:
	cpi	Number, 10
	brlo	READPATTERNS
	subi	Number, 10
	inc	Decine
	rjmp	BIN2BCD			;ora Number contiene le unit e decine le decine

READPATTERNS:
	cpi	Decine, 0		;skip leading zero
	breq	_LZ1


	add	Decine, RowOffset
	out     EEAR, Decine           	;set eeprom address register
	sbi     EECR, 0                 ;send read command
	in      Decine, EEDR      	;read font table in EEPROM

_LZ1:
	add	Number, RowOffset
	out     EEAR, Number           	;set eeprom address register
	sbi     EECR, 0                 ;send read command
	in      Number, EEDR      	;read font table in EEPROM
	
	ldi Counter, 161	
	rcall ZEBRA

	mov	ShiftPattern, Decine
	ldi	Counter, 6
	rcall	SHIFTER
	
	mov	ShiftPattern, Number
	ldi	Counter, 6
	rcall	SHIFTER

	dec	AltezzaPixel
	brne	END_DISPBIGNUM
	addi	RowOffset, 10
	ldi	Number, ALTEZZABIGNUMBERS
	mov	AltezzaPixel, Number
END_DISPBIGNUM:
	rjmp    DISPLAYLINERESTART      ;end line

SHIFTER:
	rol	ShiftPattern
	skipcc
	sbi	PortD, VideoBit
	skipcs
	cbi	PortD, VideoBit
_L1:	inc	TimeDelay
	cpi	TimeDelay, LARGHEZZABIGNUMBERS
	brlo	_L1
	clr	TimeDelay
	dec	Counter	
	brne	SHIFTER
	cbi	PortD, VideoBit
	ret


ZEBRA:
	dec 	Counter
	brne 	ZEBRA
	ret


;****************************************************************************
;* Official line exit point for all display routines
;****************************************************************************

DISPLAYLINERESTART:
	ldi     Arg1, EXP2(TOV0)        ;clear timer overflow bit
	out     TIFR, Arg1              ;
	rjmp	WAITNEWLINE
	
					
	




;****************************************************************************************
;* EEDRIVER:
;* driver per la lettura e scrittura dell'EEprom da parte del main
;* la lettura e scrittura  sempre di un singolo BIT mappato nello spazio virtuale da 1 a 90
;* usa i flag seguenti di MiscFlags:
;* EEDataBit -> di da leggere o scrivere
;* EEReadRequestBit -> legge all'indirizzo EEDriverRegister
;* EEWriteRequestBit -> scrive il bit EEDataBit all'indirizzo EEDriverRegister
;* il completamento dell'operazione  segnalato dall'azzeramento del flag relativo


ARGUMENT1 EEAddress
ARGUMENT2 Temp

EEDRIVER:
	
	sbrs	MiscFlags, EEReadReqBit		;is read requested?
	rjmp	_EE1				;no, go check write request

	;*******READ*****
	cbr	MiscFlags, EXP2(EEReadReqBit)	;yes, clear service request
	mov	EEAddress, EEDriverRegister	;copy address
	andi	EEAddress, 0b00111111		;map into memory
	bst	EEDriverRegister, 6		;check bit 6 address
	out     EEAR,  EEAddress                ;set eeprom address register
	
	ldi	TEMP, 1<<0
	out	EECR, TEMP
	out	EECR, TEMP			;send read command
	in      EEDriverRegister,EEDR      	;read EEPROM contents
	brts    _EE2				;if number > 63, go read bit 1
	bst	EEDriverRegister, 0		;else read bit 0
	bld	MiscFlags, EEDataBit
	ret

_EE2:	bst	EEDriverRegister, 1		;read bit 1 (number greater than 63)
	bld	MiscFlags, EEDataBit
	ret

	;*******WRITE******
	
_EE1:	cpi	RowsDivFour, 288/4		;are we near vertical retrace?
	skipne					;no, go return
	sbrs	MiscFlags, EEWriteReqBit	;is write requested?
	ret					;no, return
	
	sbrs	MiscFlags, EEWritePendingBit	;is write pending?
	rjmp	_EE3				;no, go write byte
						;else check for write completion
	sbis	EECR, 1				;is write completed?
	cbr	MiscFlags, EXP2(EEWriteReqBit)+EXP2(EEWritePendingBit)+EXP2(BlankScreenBit);yes, clear
	ret	

_EE3:	
	mov	EEAddress, EEDriverRegister	;copy address
	andi	EEAddress, 0b00111111		;map into memory
	out     EEAR,  EEAddress                ;set eeprom address register
	
	ldi	TEMP, 1<<0
	out	EECR, TEMP
	out	EECR, TEMP

	in      Temp,EEDR  		  	;read EEPROM contents
	bst	MiscFlags, EEDataBit		;store data to write
	cp	EEDriverRegister, EEAddress	;if lower 63 bits
	skipne	
	bld	Temp, 0				;then use bit 0
	skipeq
	bld	Temp, 1				;else use bit 1
	out	EEDR, Temp			
	sbi     EECR, 1                 	;send write command to store data
	sbr	MiscFlags, EXP2(BlankScreenBit)+EXP2(EEWritePendingBit)	;blank screen....
	ret
