;LATEST CHANGES 13/06/2005 17:30
;BOOSTER_MAIN.ASM

		.INCLUDE "m16def.inc"

.LIST

;definitions for registers
.DEF UART_TEMP	=R10
.DEF UB_RD	=R11
.DEF UB_LENGTH	=R12
.DEF CLR_REG	=R13
.DEF SET_REG	=R14
.DEF TEMP_SREG	=R15
.DEF A		=R16				
.DEF B		=R17
.DEF C		=R18
.DEF D		=R19
.DEF E		=R20
.DEF F		=R21
.DEF UART_REG3	=R22

.EQU STARTUP_DELAY=50
;**************************************************************

.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
PWM_BUF:	.BYTE 1
PWM_BUF_VALUE:	.BYTE 1
RAM_ADDRESS:	.BYTE 1
KB_BUFFER:	.BYTE 1
BIOS_PROTECT:	.BYTE 1

		.ORG $100
PAGE_BUFFER:	.BYTE $80		;128 BYTES FOR UPDATE
		.ORG $200
RAM_BUFFER:	.BYTE $FF
		.ORG $300
UART_BUFFER:	.BYTE 255		;255 UART BUFFER
		.ORG $400
KEY_BUFFER:	.BYTE 10		;10 BYTES FOR KEYBOARD 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:	LDI ZH,1
		IN ZL,PINB
		IN TEMP_SREG,SREG
		OUT DDRC,SET_REG		;PORTC=OUTPUT
		IJMP

WRITE_REG:	LDI ZH,2
		IN ZL,PINB
		IN TEMP_SREG,SREG
		IJMP

;**************************************************************
;RETURNING FROM THE INTERRUPT

RD_END:		JMP RD_END_NEW
		.ORG $11
WR_END:		JMP WR_END_NEW

;**************************************************************
		.ORG $15

MAIN:		SBRS UART_REG3,4		;CHECK IF BUFFERED UART=ON
		RJMP PC-1
		SBIS UCSRA,RXC			;CHECK FOR AVAILABLE CHARACTER
		RJMP MAIN
		IN UART_TEMP,UDR		;GET NEW CHARACTER
		ST X,UART_TEMP			;STORE NEW CHARACTER
		INC XL				;INCREASE BUFFER POINTER
		INC UB_LENGTH			;INCREASE BUFFER LENGTH
		OR UB_LENGTH,UB_LENGTH		;CHECK IF BUFFER IS FULL
		BREQ PC+2
		RJMP MAIN
		DEC UB_LENGTH			;INCASE OF BUFFER OVERFLOW
		INC UB_RD			;INCREASE UB_READ
		RJMP MAIN
;**************************************************************

		.ORG $25

RD_END_NEW:	CBI DDRD,7		;WAIT SIGNAL OFF
		SBIS PIND,3
		RJMP PC-1
		OUT DDRC,CLR_REG	;PORTC=INPUT
		OUT SREG,TEMP_SREG
		RETI


		.ORG $30		
WR_END_NEW:	CBI DDRD,7		;WAIT SIGNAL OFF
		SBIS PIND,2
		RJMP PC-1
		OUT SREG,TEMP_SREG
		RETI



		.ORG $70
BIOS_WRITE:	LDS A,BIOS_PROTECT
		CPI A,$CC
		BRNE PC+3
		JMP SMALLBOOTSTART
		RJMP WR_END
		
		.ORG $80		
;************************************************************
VERSION_DATA:	.DB "CPC BOOSTER+",$0D,$0A
		.DB "DEVELOPED BY",$0D,$0A
		.DB "AGRAFIOTIS PETROS ",$0D,$0A
		.DB "VERSION 1.5 ",$0D,$0A
		.DB "July, 6, 2005 ",$0D,$0A,$0D,$0A
		.DB "antitec@hotmail.com",0
;************************************************************
.ORG $100				;IN &FFXX
		RJMP TEST_B1		;00
		RJMP TEST_B2		;01
		RJMP RD_PWM_1		;02
		RJMP RD_PWM_2		;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_ADFREQ		;0F
		RJMP RD_ADMUX		;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
		RJMP CLR_PWM_BUF	;26
		RJMP RD_PWM_1		;27
		RJMP RD_RAM_ADDR	;28
		RJMP RD_RAM_DATA	;29
		RJMP RD_RAM_DATAP	;2A
		RJMP RD_PROTECT		;2B
								
;************************************************************
.ORG $200				;OUT &FFXX
		RJMP RESET		;00
		RJMP RESET		;01
		RJMP WR_PWM_1		;02
		RJMP WR_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_ADFREQ		;0F
		RJMP WR_ADMUX		;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_VERSION		;25
		RJMP WR_PWM_BUF		;26
		RJMP WR_PWM_MONO	;27
		RJMP WR_RAM_ADDR	;28
		RJMP WR_RAM_DATA	;29
		RJMP WR_RAM_DATAP	;2A
		RJMP WR_PROTECT		;2B
;********************************************************
;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:	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/WRITING SRAM

RD_RAM_ADDR:	LDS A,RAM_ADDRESS
		OUT PORTC,A
		RJMP RD_END
WR_RAM_ADDR:	IN A,PINC
		STS RAM_ADDRESS,A
		RJMP WR_END

RD_RAM_DATA:	LDI YH,$2
		LDS YL,RAM_ADDRESS
		LD A,Y
		OUT PORTC,A
		RJMP RD_END

WR_RAM_DATA:	IN A,PINC
		LDI YH,$2
		LDS YL,RAM_ADDRESS
		ST Y,A
		RJMP WR_END

RD_RAM_DATAP:	LDI YH,$2
		LDS YL,RAM_ADDRESS
		LD A,Y+
		STS RAM_ADDRESS,YL
		OUT PORTC,A
		RJMP RD_END

WR_RAM_DATAP:	IN A,PINC
		LDI YH,$2
		LDS YL,RAM_ADDRESS
		ST Y+,A
		STS RAM_ADDRESS,YL
		RJMP WR_END


;****************************************************************
;WRITE PROTECT FOR BIOS

RD_PROTECT:	LDS A,BIOS_PROTECT
		OUT PORTC,A
		RJMP RD_END

WR_PROTECT:	IN A,PINC
		STS BIOS_PROTECT,A
		RJMP WR_END



;****************************************************************
;READING VERSION

RD_VERSION:	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
		

WR_VERSION:	LDI ZH,HIGH(VERSION_DATA*2)
		LDI ZL,LOW(VERSION_DATA*2)
		STS VERSION_HI,ZH
		STS VERSION_LO,ZL
		RJMP WR_END
;****************************************************************
;READING VALUES TO CHECK CORRECT COMMUNICATION
;$FF00

TEST_B1:	LDI A,0B10101010
		OUT PORTC,A
		RJMP RD_END
;$FF01
TEST_B2:	LDI A,0B1010101
		OUT PORTC,A
		RJMP RD_END

;****************************************************************
;VALUES FOR THE TWO PWM CHANNELS
;$FF03-$FF04

WR_PWM_1:	IN A,PINC
		OUT OCR1AL,A
		RJMP WR_END

WR_PWM_2:	IN A,PINC
		OUT OCR1BL,A
		RJMP WR_END

RD_PWM_1:	IN A,OCR1AL
		OUT PORTC,A
		RJMP RD_END

RD_PWM_2:	IN A,OCR1BL
		OUT PORTC,A
		RJMP RD_END

;*************************************
CLR_PWM_BUF:	STS PWM_BUF,CLR_REG
		STS PWM_BUF_VALUE,CLR_REG
		OUT PORTC,CLR_REG
		RJMP RD_END

WR_PWM_BUF:	IN A,PINC
		LDS B,PWM_BUF
		OR B,B
		BREQ WR_PWM_BUF_1
		LDS B,PWM_BUF_VALUE
		OUT OCR1AL,B
		OUT OCR1BL,A
		STS PWM_BUF,CLR_REG
		RJMP WR_END

WR_PWM_BUF_1:	LDI B,$FF
		STS PWM_BUF,B
		STS PWM_BUF_VALUE,A
		RJMP WR_END

;*************************************		
WR_PWM_MONO:	IN A,PINC
		OUT OCR1AL,A
		OUT OCR1BL,A
		RJMP WR_END

;****************************************************************
;SETTING THE UART BAUD RATE
;$FF04

RD_BAUD:	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:		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:	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:	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 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:	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:	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:	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:	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:	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:	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:	SBI ADCSRA,ADIF
		SBI ADCSRA,ADSC
		SBIS ADCSRA,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:	IN A,ADCSRA
		ANDI A,0B111
		OUT PORTC,A
		RJMP RD_END

WR_ADFREQ:	IN A,PINC
		ANDI A,0B111
		ORI A,0B10000000
		OUT ADCSRA,A
		RJMP WR_END

;****************************************************************
;PORTA 5 BITS INPUT/OUTPUT


RD_PORTA:	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:	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:	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:	LDS A,MULTI1
		OUT PORTC,A
		RJMP RD_END

RD_MULTI2:	LDS A,MULTI2
		OUT PORTC,A
		RJMP RD_END

RD_MRES_H:	LDS A,MULRES_HIGH
		OUT PORTC,A
		RJMP RD_END

RD_MRES_L:	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:	LDS A,PAGE_H
		OUT PORTC,A
		RJMP RD_END

RD_PAGE_L:	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:	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:	LDS A,ROM_H
		OUT PORTC,A
		RJMP RD_END
		
RD_ROM_L:	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:	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

;********************************************
;KEYBOARD ROUTINE

RD_KEYBOARD:	LDS A,KEY_PRESSED	;READ LAST KEY PRESSED
		OUT PORTC,A
		STS KB_BUFFER,CLR_REG	;RESET KEYBOARD BUFFER
		STS KEY_PRESSED,CLR_REG
		RJMP RD_END

WR_KEYBOARD:	IN A,PINC
		LDI YH,4
		LDS YL,KB_BUFFER
		ST Y+,A
		STS KB_BUFFER,YL
		CPI YL,10
		BREQ FIND_KEY
		RJMP WR_END

.INCLUDE "KEYS.ASM"

;****************************************************************
;UART BUFFER

RD_UARTLENGTH:	OUT PORTC,UB_LENGTH
		RJMP RD_END

WR_UARTLENGTH:	CLR XL
		CLR UB_LENGTH
		CLR UB_RD
		RJMP WR_END

RD_UARTBUFFER:	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	00000XXX	ADC SAMPLING FREQUENCY
;10		IN/OUT	00-$01		ADC CHANNEL SELECTION
;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

;25		IN/OUT	00-$FF		READ VERSION

;26		OUT	00-$FF		PWM BUFFERED STEREO
;27		OUT	00-$FF		PWM MONO TO BOTH CHANNELS

;28		IN/OUT	00-$FF		RAM ADDRESS
;29		IN/OUT	00-$FF		RAM DATA
;2A		IN/OUT	00-$FF		RAM DATA POST INCREMENT

;**************************************************************		

.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
		
