		.INCLUDE "m16def.inc"

.LIST

;definitions for registers

.DEF CLR_REG=R5
.DEF SET_REG=R6
.DEF UART_TEMP=R8
.DEF UB_RD=R9
.DEF UB_LENGTH=R10
.DEF KB_BUF=R11
.DEF A=R16				
.DEF B=R17
.DEF C=R18
.DEF D=R19
.DEF E=R20
.DEF F=R21
.DEF UART_REG3=R22

;**************************************************************

.DSEG
		.ORG $60

EEPROM_HIGH:	.BYTE 1
EEPROM_LOW:	.BYTE 1
UART_DELAY:	.BYTE 1
BUFFER_DDR:	.BYTE 1
MULTI1:		.BYTE 1
MULTI2:		.BYTE 1
MULRES_HIGH:	.BYTE 1
MULRES_LOW:	.BYTE 1
ROM_H:		.BYTE 1
ROM_L:		.BYTE 1
PAGE_H:		.BYTE 1
PAGE_L:		.BYTE 1
KEY_PRESSED:	.BYTE 1
VERSION_HI:	.BYTE 1
VERSION_LO:	.BYTE 1

		.ORG $100
PAGE_BUFFER:	.BYTE $80		;128 BYTES FOR UPDATE
		.ORG $200
KEY_BUFFER:	.BYTE 10		;10 BYTES FOR KEYBOARD BUFFER
		.ORG $300
UART_BUFFER:	.BYTE 255		;255 UART BUFFER

;**************************************************************

.CSEG
		.ORG $0
 		JMP RESET

;EXTERNAL INTERRUPT 1
		SBI DDRD,7		;OUT COMMAND
		RJMP WRITE_REG

;EXTERNAL INTERRUPT 2
		SBI DDRD,7		;IN COMMAND
		RJMP READ_REG

;**************************************************************
;ADDRESS REDIRECTION

READ_REG:	IN ZL,PINB
		LDI ZH,1
		IJMP

WRITE_REG:	IN ZL,PINB
		LDI ZH,2
		IJMP

;**************************************************************
;RETURNING FROM THE INTERRUPT

RD_END:		CBI DDRD,7		;WAIT SIGNAL OFF
RD_END_L:	SBIS PIND,3
		RJMP RD_END_L
		OUT DDRC,CLR_REG	;PORTC=INPUT
		RETI

WR_END:		CBI DDRD,7		;WAIT SIGNAL OFF
WR_END_L:	SBIS PIND,2
		RJMP WR_END_L
		RETI

;************************************************************
MAIN:		RJMP MAIN_L


VERSION_DATA:	.DB "CPC BOOSTER+",$0D,$0A
		.DB "DEVELOPED BY",$0D,$0A
		.DB "AGRAFIOTIS PETROS ",$0D,$0A
		.DB "VERSION 1.0 ",$0D,$0A
		.DB "10/11/2004 ",0
;************************************************************
.ORG $100				;IN &FFXX
		RJMP TEST_B1		;00
		RJMP TEST_B2		;01
		RJMP RD_END		;02
		RJMP RD_END		;03
		RJMP RD_BAUD		;04
		RJMP RD_UDR		;05
		RJMP RD_UART_REG1	;06
		RJMP RD_UART_REG2	;07
		RJMP RD_END		;08
		RJMP UART_RX_AP		;09
		RJMP RD_RX_TIME		;0A
		RJMP RD_UART_REG3	;0B
		RJMP RD_EEDDR_HI	;0C
		RJMP RD_EEDDR_LO	;0D
		RJMP RD_EEPROM		;0E
		RJMP RD_ADMUX		;0F
		RJMP RD_ADFREQ		;10
		RJMP RD_ADVALUE		;11
		RJMP RD_KEYBOARD	;12
		RJMP RD_END		;13
		RJMP RD_END		;14
		RJMP RD_BIOS_BUFFER	;15
		RJMP RD_PAGE_H		;16
		RJMP RD_PAGE_L		;17
		RJMP RD_PAGE_D		;18
		RJMP RD_ROM_H		;19
		RJMP RD_ROM_L		;1A
		RJMP RD_ROM_D		;1B
		RJMP RD_UARTLENGTH	;1C
		RJMP RD_UARTBUFFER	;1D
		RJMP RD_DDRA		;1E
		RJMP RD_PORTA		;1F
		RJMP RD_PINA		;20
		RJMP RD_MULTI1		;21
		RJMP RD_MULTI2		;22
		RJMP RD_MRES_H		;23
		RJMP RD_MRES_L		;24
		RJMP RD_VERSION		;25						
;************************************************************
.ORG $200				;OUT &FFXX
		RJMP RESET		;00
		RJMP RESET		;01
		RJMP PWM_1		;02
		RJMP PWM_2		;03
		RJMP WR_BAUD		;04
		RJMP WR_UDR		;05
		RJMP WR_UART_REG1	;06
		RJMP WR_UART_REG2	;07
		RJMP UART_TX_AUTO	;08
		RJMP WR_END		;09
		RJMP WR_RX_TIME		;0A
		RJMP WR_UART_REG3	;0B
		RJMP WR_EEDDR_HI	;0C
		RJMP WR_EEDDR_LO	;0D
		RJMP WR_EEPROM		;0E
		RJMP WR_ADMUX		;0F
		RJMP WR_ADFREQ		;10
		RJMP WR_END		;11
		RJMP WR_KEYBOARD	;12
		RJMP BIOS_UPDATE	;13
		RJMP BIOS_BUFFER	;14
		RJMP WR_BIOS_ADDR	;15
		RJMP WR_PAGE_H		;16
		RJMP WR_PAGE_L		;17
		RJMP WR_END		;18
		RJMP WR_ROM_H		;19
		RJMP WR_ROM_L		;1A
		RJMP WR_END		;1B
		RJMP WR_UARTLENGTH	;1C
		RJMP WR_END		;1D
		RJMP WR_DDRA		;1E
		RJMP WR_PORTA		;1F
		RJMP WR_END		;20
		RJMP WR_MULTI1		;21
		RJMP WR_MULTI2		;22
		RJMP WR_END		;23
		RJMP WR_END		;24
		RJMP WR_END		;25
;********************************************************
;COMMANDS
		.ORG $300

;****************************************************************

;WRITING PROGRAM CODE PAGE FOR UPDATING THE MICROCONTROLLER

BIOS_UPDATE:	JMP SMALLBOOTSTART

;****************************************************************
;ROUTINE TO FILL THE 128 BYTES BUFFER AND READ THE BUFFER CURRENT ADDRESS

BIOS_BUFFER:	IN A,PINC		;STORE DATA TO BUFFER
		LDI YH,1
		LDS YL,BUFFER_DDR
		ST Y+,A
		ANDI YL,0B1111111
		STS BUFFER_DDR,YL
		RJMP WR_END
		
RD_BIOS_BUFFER:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,BUFFER_DDR
		OUT PORTC,A
		RJMP RD_END
		
WR_BIOS_ADDR:	IN A,PINC		;STORE DATA TO BUFFER
		ANDI A,127
		STS BUFFER_DDR,A
		ST Y+,A
		RJMP WR_END


;****************************************************************
;READING VERSION

RD_VERSION:	OUT DDRC,SET_REG
		LDS ZH,VERSION_HI
		LDS ZL,VERSION_LO
		LPM A,Z+
		OR A,A
		BRNE RD_VERSION_A
		LDI ZH,HIGH(VERSION_DATA*2)
		LDI ZL,LOW(VERSION_DATA*2)
RD_VERSION_A:	STS VERSION_HI,ZH
		STS VERSION_LO,ZL
		OUT PORTC,A
		RJMP RD_END
		

;****************************************************************
;READING VALUES TO CHECK CORRECT COMMUNICATION
;$FF00

TEST_B1:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDI A,0B10101010
		OUT PORTC,A
		RJMP RD_END
;$FF01
TEST_B2:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDI A,0B1010101
		OUT PORTC,A
		RJMP RD_END

;****************************************************************
;VALUES FOR THE TWO PWM CHANNELS
;$FF03-$FF04

PWM_1:		IN A,PINC
		OUT OCR1AL,A
		RJMP WR_END

PWM_2:		IN A,PINC
		OUT OCR1BL,A
		RJMP WR_END

;****************************************************************
;SETTING THE UART BAUD RATE
;$FF04

RD_BAUD:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,UBRRL
		OUT PORTC,A
		RJMP RD_END

WR_BAUD:	IN A,PINC
		OUT UBRRL,A
		RJMP WR_END

;****************************************************************
;READING/WRITING UDR
;$FF05

RD_UDR:		OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,UDR
		OUT PORTC,A
		RJMP RD_END

WR_UDR:		IN A,PINC
		OUT UDR,A
		RJMP WR_END

;****************************************************************
;UART REGISTER 1

RD_UART_REG1:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,UCSRA
		ANDI A,0B11111100
		IN B,UCSRB
		ANDI B,0B11
		OR A,B
		OUT PORTC,A
		RJMP RD_END

WR_UART_REG1:	IN A,PINC
		BST A,0
		ANDI A,0B11111100
		IN B,UCSRA
		ANDI B,0B11
		OR A,B
		OUT UCSRA,A
		IN A,UCSRB
		BLD A,0
		OUT UCSRB,A
		RJMP WR_END

;****************************************************************
;UART REGISTER 2

RD_UART_REG2:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN B,UBRRH
		IN B,UCSRC
		
		IN A,UCSRB
		BST A,2
		MOV A,B
		LSL A
		ANDI A,0B11110000
		ANDI B,0B00000111
		BLD B,3
		OR A,B
		OUT PORTC,A
		RJMP RD_END
		
WR_UART_REG2:	IN A,PINC
		BST A,3
		IN B,UCSRB
		BLD B,2
		OUT UCSRB,B
		MOV B,A
		LSR A
		ANDI A,0B01111000
		ORI A,0B10000000	;SELECT UCSRC
		ANDI B,0B111
		OR A,B
		OUT UCSRC,A
		RJMP WR_END

;****************************************************************
;UART REGISTER 3

WR_UART_REG3:	IN UART_REG3,PINC
		ANDI UART_REG3,0B11111

		SBRC UART_REG3,3		;CHECK DOUBLE SPEED
		RJMP PC+3
		CBI UCSRA,U2X
		RJMP PC+2
		SBI UCSRA,U2X
		
		SBRC UART_REG3,0		;CHECK 485 PIN
		RJMP PC+3
		CBI PORTD,6
		RJMP PC+2
		SBI PORTD,6
		RJMP WR_END
		

RD_UART_REG3:	OUT DDRC,SET_REG		;PORTC=OUTPUT
		OUT PORTC,UART_REG3
		RJMP RD_END

;****************************************************************
;AUTO POLLING ROUTINES

;TX FULL DUPLEX / HALF DUPLEX

UART_TX_AUTO:	SBRC UART_REG3,1		;CHECK BIT HALF/FULL DUPLEX
		RJMP UART_TX_HD

UART_TX_AP:	IN A,PINC			;TX CHAR AUTO-POLLING
READY_TX:	SBIS UCSRA,UDRE			;FOR FULL DUPLEX COM.
		RJMP READY_TX
		OUT UDR,A
		RJMP WR_END

UART_TX_HD:	SBRC UART_REG3,2		;CHECK AUTO 485 HALF DUPLEX
		SBI PORTD,6
		IN A,PINC			;TX CHAR AUTO-POLLING
		OUT UDR,A
READY_TX_HD:	SBIS UCSRA,TXC			;FOR HALF DUPLEX COM.
		RJMP READY_TX_HD
		SBI UCSRA,TXC			;CLEAR TXC
		SBRS UART_REG3,2		;CHECK AUTO 485 HALF DUPLEX
		RJMP WR_END

		CBI PORTD,6
		ANDI UART_REG3,0B11111110	;CLEAR 485 BIT ON REGISTER
		RJMP WR_END
		
;****************************************************************
;AUTO POLLING FOR RX

UART_RX_AP:	OUT DDRC,SET_REG
		LDI A,255
		LDI YH,$F0
		LDI YL,$00
		LDS B,UART_DELAY	;PARAMETERS FOR DELAY
		
READ_RX_LOOP:	SBIC USR,RXC
		RJMP UART_RX_CHAR
		OR B,B
		BREQ UART_NO_CHAR
		NOP
		SBIW YL,1
		BRNE READ_RX_LOOP
		DEC B
		LDI YH,$F0
		LDI YL,$00
		RJMP READ_RX_LOOP
UART_NO_CHAR:	CLR A
UART_RX_CHAR:	OUT PORTC,A
		RJMP RD_END

;****************************************************************
;READING/WRITING THE UART TIME OUT DELAY VALUE

RD_RX_TIME:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,UART_DELAY
		OUT PORTC,A
		RJMP RD_END

WR_RX_TIME:	IN A,PINC
		STS UART_DELAY,A
		RJMP WR_END

;****************************************************************
;EEPROM ADDRESS

RD_EEDDR_HI:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,EEPROM_HIGH
		OUT PORTC,A
		RJMP RD_END

WR_EEDDR_HI:	IN A,PINC
		ANDI A,0B1
		STS EEPROM_HIGH,A
		RJMP WR_END
		
RD_EEDDR_LO:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,EEPROM_LOW
		OUT PORTC,A
		RJMP RD_END
		

WR_EEDDR_LO:	IN A,PINC
		STS EEPROM_LOW,A
		RJMP WR_END

;****************************************************************
;EEPROM BYTE READ/WRITE

WR_EEPROM:	LDS A,EEPROM_HIGH
		OUT EEARH,A
		LDS A,EEPROM_LOW
		OUT EEARL,A
		IN A,PINC
		OUT EEDR,A
		SBI EECR,EEMWE
		SBI EECR,EEWE
EEWRITE_END:	SBIC EECR,EEWE
		RJMP EEWRITE_END
		OUT EEARH,CLR_REG
		OUT EEARL,CLR_REG
		RJMP WR_END
		
RD_EEPROM:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,EEPROM_HIGH
		OUT EEARH,A
		LDS A,EEPROM_LOW
		OUT EEARL,A
		SBI EECR,EERE
		IN A,EEDR
		OUT PORTC,A
		OUT EEARH,CLR_REG
		OUT EEARL,CLR_REG
		RJMP RD_END

;****************************************************************
 ;ADC CONVERTER
		;LDI A,0B10000Y
		;Y=CHANNEL SELECTOR
RD_ADMUX:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,ADMUX
		ANDI A,0B1
		OUT PORTC,A
		RJMP RD_END

WR_ADMUX:	IN A,PINC
		ORI A,0B100000
		ANDI A,0B100001
		OUT ADMUX,A
		RJMP WR_END

;****************************************************************
;READING VALUE FROM THE A/D CONVERTER

RD_ADVALUE:	OUT DDRC,SET_REG
		SBI ADCSR,ADIF
		SBI ADCSR,ADSC
		SBIS ADCSR,ADIF		;CHECK IF THE CONVERSION IS COMPLETED
		RJMP PC-1
		IN A,ADCH		;READ HIGH BYTE OF A/D VALUE
		OUT PORTC,A
		RJMP RD_END

;****************************************************************
;SETTING THE FREQUENCY OF THE SAMPLER

RD_ADFREQ:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,ADCSR
		ANDI A,0B111
		OUT PORTC,A
		RJMP RD_END

WR_ADFREQ:	IN A,PINC
		ANDI A,0B111
		ORI A,0B10000000
		OUT ADCSR,A
		RJMP WR_END

;****************************************************************
;PORTA 5 BITS INPUT/OUTPUT


RD_PORTA:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,PORTA
		ANDI A,0B11111000
		LSR A
		LSR A
		LSR A
		OUT PORTC,A
		RJMP RD_END

WR_PORTA:	IN A,PINC
		ANDI A,0B11111
		LSL A
		LSL A
		LSL A
		OUT PORTA,A
		RJMP WR_END


RD_DDRA:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,DDRA
		ANDI A,0B11111000
		LSR A
		LSR A
		LSR A
		OUT PORTC,A
		RJMP RD_END

WR_DDRA:	IN A,PINC
		ANDI A,0B11111
		LSL A
		LSL A
		LSL A
		ORI A,4
		OUT DDRA,A
		RJMP WR_END

RD_PINA:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		IN A,PINA
		ANDI A,0B11111000
		LSR A
		LSR A
		LSR A
		OUT PORTC,A
		RJMP RD_END

WR_PINA:	IN A,PINC
		ANDI A,0B11111
		LSL A
		LSL A
		LSL A
		OUT PINA,A
		RJMP WR_END

;***************************************************
;MULTIPLICATION

RD_MULTI1:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,MULTI1
		OUT PORTC,A
		RJMP RD_END

RD_MULTI2:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,MULTI2
		OUT PORTC,A
		RJMP RD_END

RD_MRES_H:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,MULRES_HIGH
		OUT PORTC,A
		RJMP RD_END

RD_MRES_L:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,MULRES_LOW
		OUT PORTC,A
		RJMP RD_END

WR_MULTI1:	IN A,PINC
		STS MULTI1,A
		RJMP WR_END

WR_MULTI2:	IN A,PINC
		STS MULTI2,A
		LDS B,MULTI1
		MUL A,B
		STS MULRES_HIGH,R1
		STS MULRES_LOW,R0
		RJMP WR_END

;***************************************************************
;ROUTINE TO READ DATA FROM ROM USING PAGE MODE

RD_PAGE_H:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,PAGE_H
		OUT PORTC,A
		RJMP RD_END

RD_PAGE_L:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,PAGE_L
		OUT PORTC,A
		RJMP RD_END

WR_PAGE_H:	IN A,PINC
		ANDI A,127
		STS PAGE_H,A
		RJMP WR_END

WR_PAGE_L:	IN A,PINC
		ANDI A,127
		STS PAGE_L,A
		RJMP WR_END

RD_PAGE_D:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS ZL,PAGE_L
		LDS ZH,PAGE_H
		BST ZH,0
		LSR ZH
		BLD ZL,7
		LPM A,Z
		OUT PORTC,A
		LDS A,PAGE_L
		LDS B,PAGE_H
		INC A
		ANDI A,0B1111111
		BRNE RD_PAGE_D1
		INC B
RD_PAGE_D1:	STS PAGE_L,A
		ANDI B,0B1111111
		STS PAGE_H,B
		RJMP RD_END
	
		
;***************************************************************
;ROUTINE TO READ DATA FROM ROM USING NORMAL MODE


RD_ROM_H:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,ROM_H
		OUT PORTC,A
		RJMP RD_END
		
RD_ROM_L:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,ROM_L
		OUT PORTC,A
		RJMP RD_END

WR_ROM_H:	IN A,PINC
		ANDI A,63
		STS ROM_H,A
		RJMP WR_END

WR_ROM_L:	IN A,PINC
		STS ROM_L,A
		RJMP WR_END



RD_ROM_D:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS ZH,ROM_H
		LDS ZL,ROM_L
		LPM A,Z+
		ANDI ZH,0B111111
		STS ROM_H,ZH
		STS ROM_L,ZL
		OUT PORTC,A
		RJMP RD_END

;****************************************************************
;ROUTINE TO TURN ON/OFF PWM CHANNELS

RD_PWMONOFF:	OUT DDRC,SET_REG
		IN A,TCCR1A
		CLR B
		SBRC A,7
		LDI B,255
		OUT PORTC,B
		RJMP RD_END

WR_PWMONOFF:	IN A,PINC
		OR A,A
		BRNE WR_PWMON
WR_PWMOFF:	OUT TCCR1A,A
		LDI A,1
		OUT TCCR1B,A
		RJMP WR_END

WR_PWMON:	LDI A,0B10101101
		OUT TCCR1A,A
		LDI A,0B1001
		OUT TCCR1B,A
		RJMP WR_END
		
;****************************************************************
;KEYBOARD ROUTINE

RD_KEYBOARD:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		LDS A,KEY_PRESSED	;READ LAST KEY PRESSED
		OUT PORTC,A
		CLR KB_BUF		;RESET KEYBOARD BUFFER
		STS KEY_PRESSED,KB_BUF
		RJMP RD_END

WR_KEYBOARD:	IN A,PINC
		LDI YH,2
		MOV YL,KB_BUF
		ST Y+,A
		MOV KB_BUF,YL
		CPI YL,10
		BREQ FIND_KEY
		RJMP WR_END

.INCLUDE "KEYS.ASM"

;****************************************************************
;UART BUFFER

RD_UARTLENGTH:	OUT DDRC,SET_REG	;PORTC=OUTPUT
		OUT PORTC,UB_LENGTH
		RJMP RD_END

WR_UARTLENGTH:	CLR XL
		CLR UB_LENGTH
		CLR UB_RD
		RJMP WR_END

RD_UARTBUFFER:	OUT DDRC,SET_REG
		OR UB_LENGTH,UB_LENGTH
		BRNE RD_UARTBUFFER1
		OUT PORTC,CLR_REG
		RJMP RD_END
RD_UARTBUFFER1:	LDI YH,3
		MOV YL,UB_RD
		LD A,Y
		INC YL
		MOV UB_RD,YL
		DEC UB_LENGTH
		OUT PORTC,A
		RJMP RD_END

;****************************************************************


;ADDRESS LIST

;00		IN/OUT	10101010	TEST BYTE #1 / RESET
;01		IN/OUT	01010101	TEST BYTE #2 / RESET

;02		OUT	00-$FF		PWM CHANNEL 1
;03		OUT	00-$FF		PWM CHANNEL 2

;04		IN/OUT	00-$FF		UBRR/BAUD RATE
;05		IN/OUT	00-$FF		UDR READ/WRITE
;06		IN/OUT	00-$FF		UART REG 1
;07		IN/OUT	00-$FF		UART REG 2
;08		OUT	00-$FF		UART TX/AUTO POLLING
;09		IN	00/$FF		UART WAIT UDR CHARACTER
;0A		IN/OUT	00-$FF		UART READ TIME OUT*50ms
;0B		IN/OUT	00-$01		UART REG 3

;0C		IN/OUT	00-$01		EEPROM ADDRESS HIGH
;0D		IN/OUT	00-$FF		EEPROM ADDRESS LOW
;0E		IN/OUT	00-$FF		EEPROM READ/WRITE

;0F		IN/OUT	00-$01		ADC CHANNEL SELECTION
;10		IN/OUT	00000XXX	ADC SAMPLING FREQUENCY
;11		IN	00-$FF		READ ADC VALUE

;12		IN/OUT	00-$FF		KEYBOARD READ

;13		OUT	00-$7F		PAGE WRITE FOR UPDATE
;14		OUT	00-$FF		DATA FOR UPDATE BUFFER
;15		IN/OUT	00-$7F		ADDRESS OF BUFFER FOR BIOS UPDATE

;16		IN/OUT  00-$7F		ROM PAGE NUMBER
;17		IN/OUT	00-$7F		ADDRESS OF PAGE
;18		IN	00-$FF		READ ROM DATA (PAGE MODE)

;19		IN/OUT  00-$3F		ROM ADDRESS HIGH
;1A		IN/OUT  00-$FF		ROM ADRESS LOW
;1B		IN	00-$FF		READ ROM DATA (ADDRESSING MODE)

;1C		IN/OUT	00-$FF		AVAILABLE CHARACTER IN UART BUFFER / RESET UART BUFFER
;1D		IN	00-$FF		READ CHARACTER FROM BUFFER

;1E		IN/OUT	00-$1F		5 BITS PORT DIRECTION SETTING
;1F		IN/OUT	00-$1F		5 BITS PORT LATCH (OUTPUT)
;20		IN	00-$1F		5 BITS PORT INPUT

;21		OUT	00-$FF		MULTIPLIER 1
;22		OUT	00-$FF		MULTIPLIER 2
;23		IN	00-$FF		RESULT HIGH BYTE
;24		IN	00-$FF		RESULT LOW BYTE

;**************************************************************		

.INCLUDE "INITIALIZE.ASM"

;**************************************************************		
;ROUTINE FOR AUTO-UPDATE
		
		.ORG SMALLBOOTSTART
		
		IN A,PINC		;GET NUMBER OF PAGE (0-127)
		ANDI A,0B1111111
		MOV ZH,A
		LSR ZH
		CLR ZL
		BST A,0
		BLD ZL,7

		LDI B,0B11
		CALL DO_SPM		;ERASE PAGE

		LDI B,0B10001
		CALL DO_SPM		;RE-ENABLE APPLICATION SECTION

;TRANSFER DATA FROM SRAM TO FLASH PAGE BUFFER
		MOV ZH,A		;RESTORE Z
		LSR ZH
		CLR ZL
		BST A,0
		BLD ZL,7

		CBI PORTA,2
		LDI C,64		;WORDS/PAGE
		LDI YH,1
		LDS YL,BUFFER_DDR
WRLOOP:		LD R0,Y+
		LD R1,Y+
		LDI B,1
		CALL DO_SPM
		ADIW ZL,2
		DEC C
		BRNE WRLOOP

		MOV ZH,A		;RESTORE Z
		LSR ZH
		CLR ZL
		BST A,0
		BLD ZL,7
		
		LDI B,0B101
		CALL DO_SPM		;WRITE PAGE
		
		LDI B,0B10001
		CALL DO_SPM		;RE-ENABLE APPLICATION SECTION
		
APL_READY:	IN A,SPMCR
		SBRS A,ASB
		RJMP BOOT_EXIT	
		LDI A,0B10001
		CALL DO_SPM
		RJMP APL_READY

BOOT_EXIT:	CLR YL
		STS BUFFER_DDR,YL
		
		LDI YL,LOW(PAGE_BUFFER)
		LDI YH,HIGH(PAGE_BUFFER)
		LDI C,128
		CLR A
CLR_BUFFER:	ST Y+,A
		DEC C
		BRNE CLR_BUFFER


		SBI PORTA,2
		;JMP WR_END

		CBI DDRD,7		;WAIT SIGNAL OFF
		SBIS PIND,2
		RJMP PC-1

		POP A
		POP A			;SIMULATE RETI COMMAND
		SEI
		JMP MAIN		
		
		
DO_SPM:		OUT SPMCR,B
		SPM
		.DW $FFFF
		NOP
		NOP
WAIT_SPM:	IN B,SPMCR
		SBRC B,SPMEN
		RJMP WAIT_SPM
		RET
		
