
AVRASM ver. 1.11  SKLOK.ASM Wed Dec 13 09:52:40 2000


         ;*************************************************************************** 
         ;* P R O G R A M   F O R   T H E   A V R   F A M I L Y 
         ;*  
         ;* File Name		:"sklok.asm" 
         ;* Title		: Schakelklok
         ;* Date	 		: 24-04-2000
         ;* Version 		: 1.00 
         ;* By			: Hugo Vos 
         ;* Target MCU		: AT90S8515 
         ;*
         ;* E-mail		: hugo@hvos.myweb.nl
         ;* 
         ;*************************************************************************** 
         
          .device	AT90S8515	;Prohibits use of non-implemented instructions
          .include "8515def.inc"
         ;***************************************************************************
         ;* A P P L I C A T I O N   N O T E   F O R   T H E   A V R   F A M I L Y
         ;* 
         ;* Number		:AVR000
         ;* File Name            :"8515def.inc"
         ;* Title                :Register/Bit Definitions for the AT90S8515
         ;* Date                 :97.01.28
         ;* Version              :1.11
         ;* Support telephone    :+47 72 88 87 20 (ATMEL Norway)
         ;* Support fax          :+47 72 88 87 18 (ATMEL Norway)
         ;* Support email        :avr@atmel.com
         ;* Target MCU           :AT90S8515
         ;*
         ;* DESCRIPTION
         ;* When including this file in the assembly program file, all I/O register 
         ;* names and I/O register bit names appearing in the data book can be used.
         ;* In addition, the six registers forming the three data pointers X, Y and
         ;* Z have been assigned names XL - ZH. Highest RAM address for Internal 
         ;* SRAM is also defined
         ;*
         ;* The Register names are represented by their hexadecimal address.
         ;* 
         ;* The Register Bit names are represented by their bit number (0-7).
         ;* 
         ;* Please observe the difference in using the bit names with instructions
         ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" 
         ;* (skip if bit in register set/cleared). The following example illustrates
         ;* this:
         ;* 
         ;* in	r16,PORTB		;read PORTB latch
         ;* sbr	r16,(1<<PB6)+(1<<PB5)	;set PB6 and PB5 (use masks, not bit#)
         ;* out  PORTB,r16		;output to PORTB
         ;*
         ;* in	r16,TIFR		;read the Timer Interrupt Flag Register
         ;* sbrc	r16,TOV0		;test the overflow flag (use bit#)
         ;* rjmp	TOV0_is_set		;jump if set
         ;* ...				;otherwise do something else
         ;***************************************************************************
         
         
         ;***** I/O Register Definitions
          .equ	SREG	=$3f
          .equ	SPH	=$3e
          .equ	SPL	=$3d
          .equ	GIMSK	=$3b
          .equ	TIMSK	=$39
          .equ	TIFR	=$38
          .equ	MCUCR	=$35
          .equ	TCCR0	=$33
          .equ	TCNT0	=$32
          .equ	TCCR1A	=$2f
          .equ	TCCR1B	=$2e
          .equ	TCNT1H	=$2d
          .equ	TCNT1L	=$2c
          .equ	OCR1AH	=$2b
          .equ	OCR1AL	=$2a
          .equ	OCR1BH	=$29
          .equ	OCR1BL	=$28
          .equ	ICR1H	=$25
          .equ	ICR1L	=$24
          .equ	WDTCR	=$21
          .equ	EEARH	=$1f
          .equ	EEARL	=$1e
          .equ	EEDR	=$1d
          .equ	EECR	=$1c
          .equ	PORTA	=$1b
          .equ	DDRA	=$1a
          .equ	PINA	=$19
          .equ	PORTB	=$18
          .equ	DDRB	=$17
          .equ	PINB	=$16
          .equ	PORTC	=$15
          .equ	DDRC	=$14
          .equ	PINC	=$13
          .equ	PORTD	=$12
          .equ	DDRD	=$11
          .equ	PIND	=$10
          .equ	SPDR	=$0f
          .equ	SPSR	=$0e
          .equ	SPCR	=$0d
          .equ	UDR	=$0c
          .equ	USR	=$0b
          .equ	UCR	=$0a
          .equ	UBRR	=$09
          .equ	ACSR	=$08
         
         
         ;***** Bit Definitions
          .equ	INT1	=7
          .equ	INT0	=6
         
          .equ	TOIE1	=7
          .equ	OCIE1A	=6
          .equ	OCIE1B	=5
          .equ	TICIE	=3
          .equ	TOIE0	=1
         
          .equ	TOV1	=7
          .equ	OCF1A	=6
          .equ	OCF1B	=5
          .equ	ICF1	=3
          .equ	TOV0	=1
         
          .equ	SRE	=7
          .equ	SRW	=6
          .equ	SE	=5
          .equ	SM	=4
          .equ	ISC11	=3
          .equ	ISC10	=2
          .equ	ISC01	=1
          .equ	ISC00	=0
         
          .equ	CS02	=2
          .equ	CS01	=1
          .equ	CS00	=0
         
          .equ	COM1A1	=7
          .equ	COM1A0	=6
          .equ	COM1B1	=5
          .equ	COM1B0	=4
          .equ	PWM11	=1
          .equ	PWM10	=0
         
          .equ	ICNC1	=7
          .equ	ICES1	=6
          .equ	CTC1	=3
          .equ	CS12	=2
          .equ	CS11	=1
          .equ	CS10	=0
         
          .equ	WDE	=3
          .equ	WDP2	=2
          .equ	WDP1	=1
          .equ	WDP0	=0
         
          .equ	EEAR8	=0
         
          .equ	EEWE	=1
          .equ	EERE	=0
         
          .equ	PA7	=7
          .equ	PA6	=6
          .equ	PA5	=5
          .equ	PA4	=4
          .equ	PA3	=3
          .equ	PA2	=2
          .equ	PA1	=1
          .equ	PA0	=0
         
          .equ	DDA7	=7
          .equ	DDA6	=6
          .equ	DDA5	=5
          .equ	DDA4	=4
          .equ	DDA3	=3
          .equ	DDA2	=2
          .equ	DDA1	=1
          .equ	DDA0	=0
         
          .equ	PINA7	=7
          .equ	PINA6	=6
          .equ	PINA5	=5
          .equ	PINA4	=4
          .equ	PINA3	=3
          .equ	PINA2	=2
          .equ	PINA1	=1
          .equ	PINA0	=0
         
          .equ	PB7	=7
          .equ	PB6	=6
          .equ	PB5	=5
          .equ	PB4	=4
          .equ	PB3	=3
          .equ	PB2	=2
          .equ	PB1	=1
          .equ	PB0	=0
         
          .equ	DDB7	=7
          .equ	DDB6	=6
          .equ	DDB5	=5
          .equ	DDB4	=4
          .equ	DDB3	=3
          .equ	DDB2	=2
          .equ	DDB1	=1
          .equ	DDB0	=0
         
          .equ	PINB7	=7
          .equ	PINB6	=6
          .equ	PINB5	=5
          .equ	PINB4	=4
          .equ	PINB3	=3
          .equ	PINB2	=2
          .equ	PINB1	=1
          .equ	PINB0	=0
         
          .equ	PC7	=7
          .equ	PC6	=6
          .equ	PC5	=5
          .equ	PC4	=4
          .equ	PC3	=3
          .equ	PC2	=2
          .equ	PC1	=1
          .equ	PC0	=0
         
          .equ	DDC7	=7
          .equ	DDC6	=6
          .equ	DDC5	=5
          .equ	DDC4	=4
          .equ	DDC3	=3
          .equ	DDC2	=2
          .equ	DDC1	=1
          .equ	DDC0	=0
         
          .equ	PINC7	=7
          .equ	PINC6	=6
          .equ	PINC5	=5
          .equ	PINC4	=4
          .equ	PINC3	=3
          .equ	PINC2	=2
          .equ	PINC1	=1
          .equ	PINC0	=0
         
          .equ	PD6	=6
          .equ	PD5	=5
          .equ	PD4	=4
          .equ	PD3	=3
          .equ	PD2	=2
          .equ	PD1	=1
          .equ	PD0	=0
         
          .equ	DDD6	=6
          .equ	DDD5	=5
          .equ	DDD4	=4
          .equ	DDD3	=3
          .equ	DDD2	=2
          .equ	DDD1	=1
          .equ	DDD0	=0
         
          .equ	PIND6	=6
          .equ	PIND5	=5
          .equ	PIND4	=4
          .equ	PIND3	=3
          .equ	PIND2	=2
          .equ	PIND1	=1
          .equ	PIND0	=0
         
          .equ	SPIF	=7
          .equ	WCOL	=6
         
          .equ	SPIE	=7
          .equ	SPE	=6
          .equ	DORD	=5
          .equ	MSTR	=4
          .equ	CPOL	=3
          .equ	CPHA	=2
          .equ	SPR1	=1
          .equ	SPR0	=0
         
          .equ	RXC	=7
          .equ	TXC	=6
          .equ	UDRE	=5
          .equ	FE	=4
          .equ	OR	=3
         
          .equ	RXCIE	=7
          .equ	TXCIE	=6
          .equ	UDRIE	=5
          .equ	RXEN	=4
          .equ	TXEN	=3
          .equ	CHR9	=2
          .equ	RXB8	=1
          .equ	TXB8	=0
         
          .equ	ACD	=7
          .equ	ACO	=5
          .equ	ACI	=4
          .equ	ACIE	=3
          .equ	ACIC	=2
          .equ	ACIS1	=1
          .equ	ACIS0	=0
         
          .def	XL	=r26
          .def	XH	=r27
          .def	YL	=r28
          .def	YH	=r29
          .def	ZL	=r30
          .def	ZH	=r31
         
          .equ    RAMEND =$20+$40+$1ff    ;Adjust for registers and I/O
         
          .equ	INT0addr=$001	;External Interrupt0 Vector Address
          .equ	INT1addr=$002	;External Interrupt1 Vector Address
          .equ	ICP1addr=$003	;Input Capture1 Interrupt Vector Address
          .equ	OC1Aaddr=$004	;Output Compare1A Interrupt Vector Address
          .equ	OC1Baddr=$005	;Output Compare1B Interrupt Vector Address
          .equ	OVF1addr=$006	;Overflow1 Interrupt Vector Address
          .equ	OC0addr =$007	;Output Compare0 Interrupt Vector Address
          .equ	OVF0addr=$008	;Overflow0 Interrupt Vector Address
          .equ	SPIaddr =$009	;SPI Interrupt Vector Address
          .equ	URXCaddr=$00a	;UART Receive Complete Interrupt Vector Address
          .equ	UDREaddr=$00b	;UART Data Register Empty Interrupt Vector Address
          .equ	UTXCaddr=$00c	;UART Transmit Complete Interrupt Vector Address
          .equ	ACIaddr =$00d	;Analog Comparator Interrupt Vector Address
         
         ;***** Code
         
000000 c62b      	rjmp	RESET		; Reset Handle
000001 c00b      	rjmp	NOFUNC		; IRQ0
000002 c00a      	rjmp	NOFUNC		; IRQ1
000003 c009      	rjmp	NOFUNC		; Timer1 cap
000004 c008      	rjmp	NOFUNC		; Timer1 compA
000005 c007      	rjmp	NOFUNC		; Timer1 compB
000006 c61b      	rjmp	TIM1_OVF	; Timer1 overflow
000007 c615      	rjmp	TIM0_OVF	; Timer 0 overflow int.
000008 c004      	rjmp	NOFUNC		; SPI
000009 c003      	rjmp	NOFUNC		; UART RX
00000a c002      	rjmp	NOFUNC		; UART EMPTY
00000b c001      	rjmp	NOFUNC		; UART TX
00000c c000      	rjmp	NOFUNC		; ANA_COMP
         
         ;****************************************************************************
         ;
         ; Routine if a unexpected interrupt occurs
         ; 
         ;****************************************************************************
         
          nofunc:
         
00000d 0000      	nop
         
00000e 9518      	reti
         	
         ;****************************************************************************
         ;*
         ;* Main Program MCU pin definition :
         ;*
         ;* PortA = PA0 = Display DB0
         ;*         PA1 = Display DB1
         ;*	   PA2 = Display DB2
         ;*         PA3 = Display DB3
         ;*         PA4 = Display DB4
         ;*         PA5 = Display DB5
         ;*         PA6 = Display DB6
         ;*         PA7 = Display DB7
         ;* PortB = PB0 = Return key 
         ;*         PB1 = Select key 
         ;*         PB2 = + key
         ;*	   PB3 = - key
         ;*	   PB4 =
         ;*         PB5 = 
         ;*         PB6 =
         ;*         PB7 = 
         ;* PortC = PC0 = 
         ;*	   PC1 = 
         ;*	   PC2 = 
         ;*	   PC3 =
         ;*         PC4 = Display RS 
         ;*	   PC5 = Display R/W
         ;*	   PC6 = Display E
         ;*         PC7 =
         ;* PortD = control signals
         ;*	   PD0 = 
         ;*	   PD1 = 	
         ;*	   PD2 = 
         ;*	   PD3 = 	
         ;*	   PD4 = SCL ( klok line I2C )
         ;*	   PD5 = SDLO ( data line out I2C )
         ;*	   PD6 = SDLI ( data line in I2C )
         ;*	   PD7 =
         ;*
         ;***************************************************************************
         
         ;***** Main Program Register Variables
         
          .def	SWmod_L		=R14
          .def	SWmod_H		=R15
          .def	Ax		=R16
          .def	Bx		=R17
          .def	Cx		=R18
          .def	Dx		=R19
          .def	dispfunc	=R20
          .def	Tempvar		=R21
          .def	TcountL		=R22
          .def	I2Cstatreg	=R24
          .def	TcountH		=R25
          .def	disp_refresh	=R23
          .def	X_low		=R26
          .def	X_high		=R27
          .def	Y_low		=R28
          .def	Y_high		=R29
          .def	Z_low		=R30
          .def	Z_high		=R31
         
         
         ;***** Main Programm Constant declaration
         
          .equ	Def_menuitem	=$03		; startoption is default menuitem
          .equ	Stack_high	=$02		; High byte of stack pointer.
          .equ	Stack_low	=$57		; Low byte of stack pointer.
          .equ	Tot_daypatrn	=$0B		; total number of switch day paterns defined in DATADEF.ASM
          .equ	Max_menuitem	=$04		; vallue of total number of menuitems + 1.
          .equ	Highwait	=$01
          .equ	Lowwait		=$04
          .equ	PCF8583		=0b10100000	; RTC address
          .equ	PCF8583_CTRL	=0b00000000	; RTC control register
          .equ	X24C02		=0b10100010	; EEPROM address
          .equ	Dispclear	=$01
          .equ	Dispinit	=$0C	
          .equ	Eightbitinit	=$38
          .equ	disp_CTRL	=0b00000000	
          .equ	disp_write	=0b00000001
          .equ	disp_busy	=0b00000010
          .equ	disp_read	=0b00000011
          .equ	disp_kontr	=$34
          .equ	max_swclktimes	=$14		; Max SW times = 20
          .equ	max_swchannels	=$0F		; Max channel = 16
          .equ	TcountH		=$00
          .equ	TcountL		=$00
          .equ	Timer0		=$80
          .equ	Timer1H		=$34
          .equ	Timer1L		=$D3
          .equ	Disp_refresh	=$FF
          .equ	Temp_comp	=$04
          .equ	maxday_select	=$0A
          .equ	SW_arrayH_SRAM	=$00
          .equ	SW_arrayL_SRAM	=$B0
          .equ	SW_E2_I2C	=$80
         
          .equ	plus_key	=$08
          .equ	min_key		=$04
          .equ	Select_key	=$02
          .equ	return_key	=$01
         
          .equ	PCF8574_SWL	=0b01000000	; Base address for PCF8574
          .equ	PCF8574_SWH	=0b01110000	; Base address for PCF8574A
         
         
          .include	"I2Cfunc.asm"
          .def	Ax	=R16
          .def	Bx	=R17
          .def	Cx	=R18
         
         
         
         ;**************************************************************************
         ;
         ; Hugo Vos, Rotterdam. 16-1-98
         ;
         ; E-mail		: hugo@hvos.myweb.nl
         ;
         ; I2C assembler code including the next function's :
         ;
         ;	I2Cstop		= send I2C stop command
         ;	initI2Cbus	= init I2C bus
         ;	I2Cstart	= send I2C start command
         ;	I2Csend		= send byte on the I2C bus
         ;	I2Cread		= read byte from I2C bus
         ;	master_ack	= send master acknowledge to I2C device
         ;	master_noack	= send No master acknowledge to I2C device
         ;	Acknowledge	= read acknowledge bit fron I2C slave
         ;	I2C_regread	= Read data from I2C register
         ;	I2C_regstore	= Write's data into I2C register
         ;	Devicecheck	= Check if I2C device(ses) exist on the bus
         ;	no_I2Cresponce	= displays a messa on the display and stops the programm.
         ;
         ;	Used port pins	= PortD, 5 ( I2C data line out)
         ;			= PortD, 4 ( I2C clock line )
         ;			= PortD, 6 ( I2C data line in )
         ;
         ;***************************************************************************
         ;
         ; Initialize I2C stop function.
         ;
         ;	Used registers : None
         ;
         ;***************************************************************************
         	
          I2Cstop:
00000f 9a95      	sbi	PortD, 5			; Set SDL to low level
000010 d6e3      	rcall	delayfunc	
         
000011 9894      	cbi	PortD, 4			; Set SCL to high level
000012 d6e1      	rcall	delayfunc
         
000013 9895      	cbi	PortD, 5			; Set SDL to high level
         
000014 0000      	nop
000015 0000      	nop
         
000016 9508      	ret
         ;***************************************************************************
         ;
         ; Initialize I2C-bus function.
         ;
         ;	Used registers : None
         ;
         ;***************************************************************************
         
          initI2Cbus:
         
000017 9894      	cbi	PortD, 4			; Set SCL line in high level
000018 9895      	cbi	PortD, 5			; Set SDL line in high level
         
000019 0000      	nop
00001a 0000      	nop
         	
00001b 9508      	ret
         
         ;***************************************************************************
         ;
         ; Initialize I2C start function.
         ;
         ;	Used registers : None
         ;
         ;***************************************************************************
         
          I2Cstart:
         
00001c 9894      	cbi	PortD, 4			; Set SCL line in high level
00001d 9895      	cbi	PortD, 5			; Set SDL line in high level
00001e d6d5      	rcall	delayfunc
00001f 9a95      	sbi	PortD, 5			; Set SDL line in low level
000020 d6d3      	rcall	delayfunc
         
000021 0000      	nop
000022 0000      	nop
         	
000023 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform an I2C send function.
         ;
         ;	Used registers : Ax = Data to send on the I2C bus
         ;			 Bx = temp variabele 
         ;			 Cx = temp variabele
         ;
         ;***************************************************************************
         
          I2Csend:
         
000024 931f      	push	Bx
000025 932f      	push	Cx
         
000026 9a94      	sbi	PortD, 4			; Set SCL line in low level
000027 e810      	ldi	Bx, $80
         
          testbit:
000028 2f21      	mov	Cx, Bx				; Load Counter with new bit vallue
000029 2320      	and	Cx, Ax				; logical AND function to check bit to send	
00002a 3020      	cpi	Cx, $00
00002b f451      	brne	Highbit 			; skip next instuction is bit is set
         
00002c 9a95      	sbi	PortD, 5			; set SDL line to low level
00002d d6c6      	rcall	delayfunc
00002e 9894      	cbi	PortD, 4			; create clock puls on the SCL line
00002f d6c4      	rcall	delayfunc
000030 9a94      	sbi	PortD, 4
000031 d6c2      	rcall	delayfunc
         
          end_byte:	
000032 9516      	lsr	Bx				; rol Tempvar 1 bit right
000033 3010      	cpi	Bx, $00				; check if vallue = $ff ( if all 8 bits
000034 f799      	brne	testbit				; are send. If so jump to end of routine
000035 c007      	rjmp	end_send			; if not, jump to testbit to send next bit 
         
          Highbit:
000036 9895      	cbi	PortD, 5			; set SDL line in high level
000037 d6bc      	rcall	delayfunc
000038 9894      	cbi	PortD, 4			; create clock puls on the SCL line
000039 d6ba      	rcall	delayfunc
00003a 9a94      	sbi	PortD,4
00003b d6b8      	rcall	delayfunc
00003c cff5      	rjmp	end_byte
         
          end_send:
         
00003d d6b6      	rcall	delayfunc
00003e 9a94      	sbi	PortD, 4			; set SCL line in low level
00003f 9895      	cbi	PortD, 5			; release SDL line allow acknowledge from slave
         
000040 912f      	pop	Cx
000041 911f      	pop	Bx
         
000042 d030      	rcall	Acknowledge
         		
000043 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform a I2C Read function.
         ;
         ;	Used registers : Ax = Temp register
         ;			 Bx = Temp register
         ;			 Cx = Temp register
         ;	Return : Ax = Read data
         ;
         ;***************************************************************************
         
          I2Cread:
         
000044 931f      	Push	Bx
000045 932f      	Push	Cx
         
000046 9a94      	sbi	PortD, 4			; Set SCL line to low level
000047 e018      	ldi	Bx, $08
000048 e000      	ldi	Ax, $00				; Set read_data to $00
000049 0000      	nop
00004a 0000      	nop
00004b 0000      	nop
         
          beginread:
00004c 9894      	cbi	PortD, 4			; set SCL line to high level ( begin off clock )
00004d 0000      	nop					; wait for stable clock signal
00004e 0000      	nop
00004f 0000      	nop
000050 b320      	in	Cx, PinD			; Read vallue of SDL line
000051 ff26      	sbrs	Cx, 6				; skip next instuvtion if high level.
000052 c002      	rjmp	Bitlow
         
000053 6001      	sbr	Ax, 1				; Set bit in Read_data register
000054 c001      	rjmp	testRbyte
         
          Bitlow:
000055 7f0e      	cbr	Ax, 1				; reset bit in Read_data register
         
          testRbyte:
         
000056 9a94      	sbi	PortD, 4			; Set SCL line to low level ( end off clock )
000057 951a      	dec	Bx 
000058 3010      	cpi	Bx, 0
000059 f019      	breq	endRead				; check for 8 bits received
00005a 9488      	clc					; clear carry bit before rol left function
00005b 1f00      	rol	Ax
00005c cfef      	rjmp	beginread
         
          endread:		
         
00005d 0000      	nop
00005e 912f      	pop	Cx
00005f 911f      	pop	Bx
         
000060 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform a master Acknowledge function.
         ;
         ;	Used registers : none
         ;
         ;***************************************************************************
         
          master_ack:
         
000061 9a95      	sbi	PortD, 5			; set SDL line to low level
000062 d691      	rcall	delayfunc
000063 9894      	cbi	PortD, 4			; porform a SCL clock signal
000064 d68f      	rcall	delayfunc
000065 9a94      	sbi	PortD, 4
000066 d68d      	rcall	delayfunc
000067 9895      	cbi	PortD, 5			; releace SDL line 
         
000068 0000      	nop					; wait for stable SDL line
000069 0000      	nop
         	
00006a 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform a master No_Acknowledge function.
         ;
         ;	Used registers : none
         ;
         ;***************************************************************************
         
          master_noack:
         
00006b 9895      	cbi	PortD, 5			; release SDL line 
00006c d687      	rcall	delayfunc
00006d 9894      	cbi	PortD, 4			; porform a SCL clock signal
00006e d685      	rcall	delayfunc
00006f 9a94      	sbi	PortD, 4
         
000070 0000      	nop					; wait for stable SCL line
000071 0000      	nop
         	
000072 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform a read Acknowledge function.
         ;
         ;	Used registers : Ax = Acknowledge register
         ;			 Bx = temp register, only vallid in this function
         ;
         ;	Return : Ax ( Bit 1 is set when acknowledge )
         ;
         ;***************************************************************************
         
          Acknowledge:
         
000073 931f      	push	Bx
         
000074 e000      	ldi	Ax,$00				; clear acknowledgement register
000075 9894      	cbi	PortD, 4			; set SCL line in high level
000076 d67d      	rcall	delayfunc			; wait for stable SCL line
         
000077 b310      	in	Bx, PinD			; load PortD pin levels
000078 7410      	andi	Bx, 0b01000000
000079 3410      	cpi	Bx, 0b01000000
00007a f009      	breq	resetSCL			; Goto resetSCL is SDL is high (No ack.)
         	
00007b e001      	ldi	Ax, $01				; PortD, 6 line is low when acknow. )
         
          resetSCL:
00007c 9a94      	sbi	PortD, 4
         
00007d 0000      	nop					; wait for stable SCL line
00007e 0000      	nop
00007f 911f      	pop	Bx
         	
000080 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform a I2C register Read function
         ;
         ;	Used registers : Ax = I2C drives adres
         ;			 Bx = I2C device register nummer to read
         ;			 Cx = temp register, only vallid in this function
         ;
         ;	Return 	       : Ax = Read data 
         ;
         ;***************************************************************************
         
          I2C_regread:
         
000081 932f      	push	Cx
         
000082 2f20      	mov	Cx, Ax			; save Ax contens into Cx
         
000083 df98      	rcall	I2Cstart
000084 df9f      	rcall	I2Csend			; Select device with adres named
         
000085 ff00      	sbrs	Ax, 0
000086 c00f      	rjmp	set_I2Cstatreg
         
000087 2f01      	mov	Ax, Bx			; Send register number to device
000088 df9b      	rcall	I2Csend
         
000089 ff00      	sbrs	Ax,0
00008a c00b      	rjmp	set_I2Cstatreg
         
00008b df90      	rcall	I2Cstart
         
00008c 2f02      	mov	Ax, Cx			; REstore I2C address in Ax from Cx
00008d 6001      	ori	Ax, $01			; set device to read 
00008e df95      	rcall	I2Csend
         
00008f ff00      	sbrs	Ax,0
000090 c005      	rjmp	set_I2Cstatreg
         
000091 dfb2      	rcall	I2Cread			; Read data from selected device
000092 dfd8      	rcall	master_noack
         
000093 df7b      	rcall	I2Cstop
000094 e080      	ldi	I2Cstatreg, $00
000095 c001      	rjmp	No_regread
         
          set_I2Cstatreg:
000096 ef8f      	ldi	I2Cstatreg, $FF
         
          No_regread:
         	
000097 912f      	pop	Cx
         
000098 9508      	ret
         
         ;***************************************************************************
         ;
         ; perform a I2C register write function
         ;
         ;	Used registers : Ax = I2C drives adres
         ;			 Bx = I2C device register nummer write in
         ;			 Cx = Data to store in register
         ;
         ;***************************************************************************
         
          I2C_regstore:
         
000099 df82      	rcall	I2Cstart		; Start I2C sequence
         
00009a df89      	rcall	I2Csend			; send device adres to bus
         
00009b ff00      	sbrs	Ax, 0
00009c d00a      	rcall	no_I2Cresponce	
         
00009d 2f01      	mov	Ax, Bx			; send registernummer to device
00009e df85      	rcall	I2Csend
         
00009f ff00      	sbrs	Ax, 0
0000a0 d006      	rcall	no_I2Cresponce
         
0000a1 2f02      	mov	Ax, Cx			; send data to device
0000a2 df81      	rcall	I2Csend
         
0000a3 ff00      	sbrs	Ax, 0
0000a4 d002      	rcall	no_I2Cresponce
         
0000a5 df69      	rcall	I2Cstop			; stop I2C sequence
         
0000a6 9508      	ret
         
         ;**************************************************************************
         ;
         ; Display's an error on the display and the program stay's in an deadlock
         ;
         ;**************************************************************************
         
          no_I2Cresponce:
         
0000a7 e001      	ldi	Ax, Dispclear			; Set display cursor function
0000a8 e010      	ldi	Bx, disp_CTRL
0000a9 d69b      	rcall	disp_lcd
         
0000aa ec01      	ldi	Ax, low(errortxt1)		; write "I2C error" to te display
0000ab e010      	ldi	Bx, high(errortxt1)
0000ac e020      	ldi	Cx, $00				; starting at position 00
0000ad d67b      	rcall	STr2disp
         
0000ae ed02      	ldi	Ax, low(errortxt2)		; write "I2C error" to te display
0000af e010      	ldi	Bx, high(errortxt2)
0000b0 e420      	ldi	Cx, $40				; starting at first position 2e line
0000b1 d677      	rcall	Str2disp
         
          no_I2Clus:
0000b2 9a90      	sbi	PortD,0
0000b3 0000      	nop
0000b4 9890      	cbi	PortD,0
0000b5 cffc      	rjmp	no_I2Clus
         
0000b6 9508      	ret
         
         ;***************************************************************************
         ;
         ; Check if I2C device(s) exist on the bus
         ;
         ;	Used registers : Ax = I2C device start address
         ;			 Bx = addresses to check with Ax as start address
         ;			
         ;	Return	       : Ax = Bit0 is set if device with address Ax exist
         ;			      Bit1 is set if device Ax+2 exist
         ;			      ......
         ;			      Bit7 is set if device Ax + 14 exist
         ; 
         ;***************************************************************************
         
          devicecheck:
         	
0000b7 932f      	push	Cx		; Save Cx to stack
0000b8 e020      	ldi	Cx, $00		; Set all device available bit's to zero
0000b9 931f      	push	Bx		; Calculate the highest I2C address
0000ba 951a      	dec	Bx		; to check and store the new address
0000bb 0f11      	lsl	Bx		; in Ax
0000bc 0f01      	add	Ax, Bx
0000bd 911f      	pop	Bx		; store device to check number back in Bx
         
          addres_I2C:
         
0000be 951a      	dec	Bx		; decrease loop counter with one
0000bf 3f1f      	cpi	Bx, $FF
0000c0 f079      	breq	end_check	; and check for end of loop
         	
0000c1 df5a      	rcall	I2Cstart	; send I2C addres on the bus
0000c2 930f      	push	Ax		; save I2C address on stack
0000c3 df60      	rcall	I2Csend		; and check for I2C slave responce
0000c4 df4a      	rcall	I2Cstop		; end I2C sequence
0000c5 931f      	push	Bx		; save loop counter
         
          bit_shift:
         
0000c6 951a      	dec	Bx		; rotate Ax left to shift it to the proper bit	
0000c7 3010      	cpi	Bx, $00		; corresponding with the check I2C device
0000c8 f011      	breq	end_bitshift
0000c9 0f00      	lsl	Ax
0000ca cffb      	rjmp	bit_shift
         
          end_bitshift:
         
0000cb 2b20      	or	Cx, Ax		; Set proper Acknowleds bit in Cx
0000cc 911f      	pop	Bx		; restore loop counter and
0000cd 910f      	pop	Ax		; currend I2C address from stack
0000ce 5002      	subi	Ax, $02		; reduce I2C address with two to check the next I2C
0000cf cfee      	rjmp	addres_I2C	; device
         
          end_check:
         
0000d0 2f02      	mov	Ax, Cx		; load Ax with the available Sw module information
0000d1 912f      	pop	Cx		; restore Cx vallue
         
0000d2 9508      	ret          .include	"menu.asm"
         ;***************************************************************************
         ;
         ; File	: "Menu.asm"
         ; By	: Hugo Vos
         ; E-mail: hugo@hvos.myweb.nl
         ;	
         ; Menu routine
         ;
         ;***************************************************************************
         
          menu:
0000d3 e043      	ldi	dispfunc, Def_menuitem		; Variable defines active menu option
0000d4 e050      	ldi	Tempvar, $00			; Temp. value
         
         
          start_menu:
         
0000d5 e001      	ldi	Ax, Dispclear			; Load display clear command in Ax reg.
0000d6 e010      	ldi	Bx, disp_CTRL			; Select display control mode
0000d7 d66d      	rcall	disp_lcd
         
0000d8 e109      	ldi	Ax, low(menutxt)		; write "menu" to te display
0000d9 e010      	ldi	Bx, high(menutxt)
0000da e026      	ldi	Cx, $06				; starting at position 06
0000db d64d      	rcall	Str2disp
         
         ;***************************************************************************
         ;
         ; check for menu item "RTC klok" settings
         ;
         ;***************************************************************************
         
0000dc 3040      	cpi	dispfunc, $00			; check if RTC clock setting menu is selected
0000dd f441      	brne	timer_menu			
         	
0000de e202      	ldi	Ax, low(rtc)			; write "RTC instellen" to the display
0000df e010      	ldi	Bx, high(rtc)
0000e0 e420      	ldi	Cx, $40				; starting at the 2snd line
0000e1 d647      	rcall	Str2disp	
         
0000e2 934f      	push	dispfunc
         	
0000e3 fd50      	sbrc	Tempvar, 0			; check for select key pressed
0000e4 d1b1      	rcall	set_hour
         	
0000e5 914f      	pop	dispfunc			; if pressed then start set RTC clock.
         
          timer_menu:
         ;***************************************************************************
         ;
         ; check for menu item "Schakelklok"
         ;
         ;***************************************************************************
         
0000e6 3041      	cpi	dispfunc, $01			; check for menu item "timer klok"
0000e7 f441      	brne	module_menu
         	
0000e8 e302      	ldi	Ax, low(klok)			; write "Schakelklok" to te display
0000e9 e010      	ldi	Bx, high(klok)
0000ea e420      	ldi	Cx, $40				; starting at the second displ line
0000eb d63d      	rcall	Str2disp	
         
0000ec 934f      	push	dispfunc
         
0000ed fd50      	sbrc	Tempvar, 0			; check for select key pressed
0000ee d2c8      	rcall	set_SWklok			; if pressed then start set RTC clock.
         	
0000ef 914f      	pop	dispfunc
         
          module_menu:
         ;***************************************************************************
         ;
         ; check for menu item "mudule lijst"
         ;
         ;***************************************************************************
         
0000f0 3042      	cpi	dispfunc, $02			; check for menu item "timer klok"
0000f1 f441      	brne	manual_menu
         	
0000f2 ee02      	ldi	Ax, low(module)			; write "Schakelklok" to te display
0000f3 e010      	ldi	Bx, high(module)
0000f4 e420      	ldi	Cx, $40				; starting at the second displ line
0000f5 d633      	rcall	Str2disp	
         
0000f6 934f      	push	dispfunc
         
0000f7 fd50      	sbrc	Tempvar, 0			; check for select key pressed
0000f8 d436      	rcall	module_list			; if pressed then start set RTC clock.
         	
0000f9 914f      	pop	dispfunc
         
         
          manual_menu:
         ;**************************************************************************
         ;
         ; Check for munu item "handmatig"
         ;
         ;**************************************************************************
         
0000fa 3043      	cpi	dispfunc, $03
0000fb f441      	brne	input_key
         	
0000fc ef06      	ldi	Ax, low(manual)
0000fd e010      	ldi	Bx, high(manual)
0000fe e420      	ldi	Cx, $40
0000ff d629      	rcall	Str2disp
         	
000100 934f      	push	dispfunc
         	
000101 fd50      	sbrc	Tempvar, 0
000102 d496      	rcall	manual_set
         	
000103 914f      	pop	dispfunc		
         	
         ;***************************************************************************
         ;
         ; check for witch key is pressed and take action on it.
         ;
         ;***************************************************************************
         
          input_key:
         
000104 d614      	rcall	Key_released			; Check for all key's released
         
000105 fd50      	sbrc	Tempvar, 0
000106 cfcc      	rjmp	menu
         
000107 2755      	clr	Tempvar
000108 d65b      	rcall	input_keyread
         
000109 3008      	cpi	Ax, plus_key			; check for + key pressed
00010a f429      	brne	no_pluskey
00010b 9543      	inc	dispfunc
00010c 3044      	cpi	dispfunc, max_menuitem
00010d f409      	brne	no_clear
00010e 2744      	clr	dispfunc
          no_clear:	
00010f cfc5      	rjmp	start_menu
         
          no_pluskey:
         
000110 3004      	cpi	Ax, min_key			; check for - key pressed
000111 f431      	brne	no_minkey
000112 954a      	dec	dispfunc
000113 3f4f      	cpi	dispfunc, $FF
000114 f601      	brne	start_menu
000115 e044      	ldi	dispfunc, max_menuitem
000116 954a      	dec	dispfunc
000117 cfbd      	rjmp	start_menu
         
          no_minkey:
         
000118 3002      	cpi	Ax, select_key			; check for select key pressed
000119 f411      	brne	no_selkey
00011a ef5f      	ldi	Tempvar, $FF
00011b cfb9      	rjmp	start_menu
         	
          no_selkey:
         
00011c 3001      	cpi	Ax, return_key
         ;	cpi	Ax, $01
00011d f731      	brne	input_key
00011e c54e      	rjmp	start_loop          .include	"divfunc.asm
         ;***************************************************************************
         ;
         ; function assembles source by	: Hugo Vos
         ;				: 15-4-98
         ;
         ; E-mail			: hugo@hvos.myweb.nl
         ;
         ;
         ; Functions:	HEX2DEC      , converts a HEX vallue into a DEC vallue ( $0F = $15 )
         ;		DEC2HEX      , converts a DEC vallue into a HEX vallue ( $15 = $0F )
         ;		modDECval    , inc or dec a DEC vallue between specified min. and max. vallue
         ;		modHEXval    , inc or dec a HEX vallue between specified min. and max. vallue
         ;		Beep         , creates a tone on the speaker
         ;		Sendtime     , Send current time/date to RS-232 port.
         ;		disp_RTCtime , displays time on display: Ax disp pos, Bx hour
         ;		createArray  , Create vallid time's array in SRAM
         ;		dispDECval   , display a DEC number on the display
         ;		SendDECval   , Send DEC value define in AX to the UART
         ;		Send_chanstat, Send channel number and statas on the RS-232 port
         ;
         ;***************************************************************************
         ;
         ; Routine convert a HEX vallue to a DEC vallue
         ;
         ; Parameters : Ax = HEX vallue
         ; Return     : Ax = DEC vallue
         ;
         ;***************************************************************************
         
          HEX2DEC:
         
00011f 931f      	push	Bx
000120 932f      	push	Cx
         
000121 2f10      	mov	Bx, Ax				; Load Bx with HEX vallue
000122 e000      	ldi	Ax, $00				
         
          HEXdec:
000123 301a      	cpi	Bx, $0A
000124 f01c      	brlt	end10inc			; end loop if Bx < 10 dec
000125 5f00      	subi	Ax, $F0				; increase Ax with 10 dec
000126 501a      	subi	Bx, $0A
000127 cffb      	rjmp	HEXdec
         
          end10inc:
000128 0f01      	add	Ax, Bx
000129 912f      	pop	Cx
00012a 911f      	pop	Bx
         
00012b 9508      	ret
         
         ;***************************************************************************
         ;
         ; Routine to converte a DEC vallue to a HEX vallue
         ;
         ; Parameters : Ax = DEC vallue
         ; Return     : Ax = HEX vallue
         ;
         ;***************************************************************************
         
          DEC2HEX:
         
00012c 931f      	push	Bx
00012d 932f      	push	Cx
         
00012e 930f      	push	Ax				; save Ax onto stack
00012f 2f10      	mov	Bx, Ax				; Load Bx with DEC vallue
000130 9512      	swap	Bx
000131 701f      	andi	Bx, $0F				; Bx contains DEC 10's vallue
000132 e020      	ldi	Cx, $00
000133 e00a      	ldi	Ax, $0A
         
          inclus:
000134 3010      	cpi	Bx, $00				 
000135 f019      	breq	endinclus
000136 0f20      	add	Cx, Ax
000137 951a      	dec	Bx
000138 cffb      	rjmp	inclus
         
          endinclus:	
000139 910f      	pop	Ax				; load Ax with org vallue
00013a 700f      	andi	Ax, $0F				; Remove 10's from DEC  vallue
00013b 0f02      	add	Ax, Cx				; add them to Bx
         						; Ax contains HEX vallue 
00013c 912f      	pop	Cx
00013d 911f      	pop	Bx
         	
00013e 9508      	ret
         
         ;***************************************************************************
         ;
         ; modify DEC vallue specified :
         ;	  Ax = DEC vallue
         ;	  Bx = min. DEC vallue
         ;	  Cx = Max. vallue + 1
         ;
         ; Return: Ax, new DEC vallue.
         ;	  Bx, last pressed key vallue 
         ;
         ;***************************************************************************
         
          moddecval:
         
00013f 930f      	push	Ax			; Save DEC vallue
         
          Read_key:
         
000140 b306      	in	Ax, PinB		; Read input key's
000141 700f      	andi	Ax, $0F
         	
000142 3001      	cpi	Ax, return_key		; Check if return key is pressed
000143 f169      	breq	end_moddecval		
         
000144 3002      	cpi	Ax, select_key		; check if select key is pressed
000145 f159      	breq	end_moddecval
         
000146 3008      	cpi	Ax, plus_key		; Check if "+" key is pressed
000147 f019      	breq	inc_DECVAL
         
000148 3004      	cpi	Ax, min_key		; Check if "-" key is pressed
000149 f091      	breq	dec_DECVAL	
         
00014a cff5      	rjmp	Read_key		; read key's again if no key is pressed
         
         ; **********************************
         ; Start of increase DEC-val routine
         ; **********************************
         
          inc_DECVAL:
         
00014b d04b      	rcall	Beep
00014c 910f      	pop	Ax			; Get Vallue
00014d 9503      	inc	Ax			; Increase vallue by 1
         
00014e 930f      	push	Ax			; Save DECval on stack
00014f 700f      	andi	Ax, $0f			
000150 300a      	cpi	Ax, $0a			; check of "0A" = 10 in low nibble Ax
000151 f011      	breq	add_10h			; if so, then jump to add_10h
000152 910f      	pop	Ax			; if not, pull Decval from stack
000153 c003      	rjmp	stop_moddecvalinc	; Jump to end of subroutine
         
          add_10h:
000154 910f      	pop	Ax			; pull DECval from stack
000155 5f00      	subi	Ax, $F0			; Inc Ax with 10
000156 7f00      	andi	Ax, $F0			; make DECval low nibble "0"
         
          stop_moddecvalinc:
         
000157 1702      	cp	Ax, Cx			; check DECval for max. vallue specified in Cx register
000158 f409      	brne	end_maxcheck		; Jump is not equel to max vallue
000159 2f01      	mov	Ax, Bx			; load DECval with min. vallue specified in Bx register.
         
          end_maxcheck:
00015a e010      	ldi	Bx, $00			; load Bx with "00" to specify + or - key function
00015b c018      	rjmp	end_DECsub
         
         ; **********************************
         ; Start of decrease DEC-val routine
         ; **********************************
         
          dec_DECVAL:
00015c d03a      	rcall	Beep
00015d 910f      	pop	Ax			; Get Vallue
00015e 1710      	cp	Bx, Ax			; check if Ax if Min vallue
00015f f441      	brne	dec_val			; is not then decrease AX, or else
000160 2f02      	mov	Ax, Cx			; load Ax with Max. val - 1
000161 950a      	dec	Ax			; decrease Ax by 1
000162 2f20      	mov	Cx, Ax			; load Cx with new valleu
000163 702f      	andi	Cx, $0F
000164 302f      	cpi	Cx, $0F			; check for low nibble is "F"
000165 f449      	brne	end_mincheck		; if low nibble is "F" then
000166 5006      	subi	Ax, $06			; subtrak 6 from Ax to get "9" in low nibble
000167 c007      	rjmp	end_mincheck
         
          dec_val:
000168 950a      	dec	Ax			; decrease Ax with 1
000169 930f      	push	Ax
00016a 700f      	andi	Ax, $0F
00016b 300f      	cpi	Ax, $0F
00016c 910f      	pop	Ax
00016d f409      	brne	end_mincheck
00016e 5006      	subi	Ax, $06			; Decrease Ax with 6 to make Ax low nibbel "9"
         
          end_mincheck:
00016f e010      	ldi	Bx, $00			; load Bx with "00" to specify + or - key function
000170 c003      	rjmp	end_DECsub
         
          end_moddecval:
000171 d025      	rcall	Beep
000172 2f10      	mov	Bx, Ax			; save last key vallue into Bx
000173 910f      	pop	Ax			; pull DECval from stack
         	
          end_DECsub:
         
000174 9508      	ret				; return from subroutine
         
         ;***************************************************************************
         ;
         ; modify HEX vallue specified :
         ;	  Ax = DEC vallue
         ;	  Bx = min. HEX vallue
         ;	  Cx = Max. HEX vallue + 1
         ;
         ; Return: Ax, new HEX vallue.
         ;	  Bx, last pressed key vallue 
         ;
         ;***************************************************************************
         
          modHEXval:
         
000175 930f      	push	Ax			; Save DEC vallue
         
          hex_read_key:
         
000176 b306      	in	Ax, PinB		; Read input key's
000177 700f      	andi	Ax, $0F
         	
000178 3001      	cpi	Ax, return_key		; Check if return key is pressed
000179 f0c9      	breq	end_modhexval		
         
00017a 3002      	cpi	Ax, select_key		; check if select key is pressed
00017b f0b9      	breq	end_modhexval
         
00017c 3008      	cpi	Ax, plus_key		; Check if "+" key is pressed
00017d f019      	breq	inc_HEXVAL
         
00017e 3004      	cpi	Ax, min_key		; Check if "-" key is pressed
00017f f049      	breq	dec_HEXVAL	
         
000180 cff5      	rjmp	hex_Read_key		; read key's again if no key is pressed
         
         ; **********************************
         ; Start of increase HEX-val routine
         ; **********************************
         
          inc_HEXVAL:
000181 d015      	rcall	Beep
000182 910f      	pop	Ax			; Get Vallue
000183 9503      	inc	Ax			; Increase vallue by 1
         		
000184 1702      	cp	Ax, Cx			; check HEXval for max. vallue specified in Cx register
000185 f409      	brne	end_maxHEXcheck		; Jump is not equel to max vallue
000186 2f01      	mov	Ax, Bx			; load HEXval with min. vallue specified in Bx register.
         
          end_maxHEXcheck:
000187 e010      	ldi	Bx, $00			; load Bx with "00" to specify + or - key function
000188 c00d      	rjmp	end_HEXsub
         
         ; **********************************
         ; Start of decrease HEX-val routine
         ; **********************************
         
          dec_HEXVAL:
000189 d00d      	rcall	Beep
00018a 910f      	pop	Ax			; Get Vallue
00018b 1710      	cp	Bx, Ax			; check if Ax if Min vallue
00018c f419      	brne	dec_HEX			; is not then decrease AX, or else
00018d 2f02      	mov	Ax, Cx			; load Ax with Max. val - 1
00018e 950a      	dec	Ax			; decrease Ax by 1
00018f c001      	rjmp	end_minHEXcheck
         
          dec_HEX:
000190 950a      	dec	Ax			; decrease Ax with 1
         
          end_minHEXcheck:
000191 e010      	ldi	Bx, $00			; load Bx with "00" to specify + or - key function
000192 cfe1      	rjmp	end_DECsub
         
          end_modHEXval:
         
000193 d003      	rcall	Beep
000194 2f10      	mov	Bx, Ax			; save last key vallue into Bx
000195 910f      	pop	Ax			; pull DECval from stack
         	
          end_HEXsub:
         
000196 9508      	ret				; return from subroutine
         
         ;***************************************************************************
         ;
         ; Creates a tone on the speaker
         ;
         ;***************************************************************************
         
          Beep:
000197 930f      	push	Ax
000198 b709      	in	Ax, TIMSK
000199 6002      	ori	Ax, 0b00000010		; Enable Timer 0 overflow INT
00019a bf09      	out	TIMSK, Ax
00019b d565      	rcall	delay_5ms		; Enable 5mS tone output onto speaker
00019c b709      	in	Ax, TIMSK
00019d 7f0d      	andi	Ax, 0b11111101		; Disable Timer 0 overflow INT
00019e bf09      	out	TIMSK, Ax
00019f 910f      	pop	Ax
         
0001a0 98aa      	cbi	PORTC, 2
         
0001a1 9508      	ret
         
         ;***************************************************************************
         ;
         ; converts vallue to ASC code and send it to the RS-232 port
         ;
         ;***************************************************************************
         
          SendTime:
         
0001a2 930f      	push	Ax			; Save namen registers on stack
0001a3 931f      	push	Bx
0001a4 932f      	push	Cx
0001a5 93ef      	push	Z_low
0001a6 93ff      	push	Z_high
         
         ;********* START OF SENDEN THE TIME ON THE RS-232 PORT **********
         
         	
0001a7 e023      	ldi	Cx, $03			; Load Cx as cycle counter
0001a8 e014      	ldi	Bx, $04			; load Bx with RTC clock start register value
         	
          Start_timesend:
         	
0001a9 ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
         					; Bx is loaded with Reg. number
0001aa ded6      	rcall	I2C_regread		; Load register vallue from RTC into Ax register	
         
0001ab 930f      	push	Ax			; Save read value on stack
0001ac 7f00      	andi	Ax, $F0			; clear low nibble
0001ad 9502      	swap	Ax			; and move high nibble to low nibble
0001ae 5d00      	subi	Ax, $D0			; and convert DEC val into ASCII val.
0001af d04d      	rcall	sendCHR			; an send it to RS-232 port
         
0001b0 910f      	pop	Ax			; Reload Ax with read value
0001b1 700f      	andi	Ax, $0F			; clear high nibble
0001b2 5d00      	subi	Ax, $D0			; and convert it into ASCII val
0001b3 d049      	rcall	sendCHR			; and send it to RS-232 port
         
0001b4 952a      	dec	Cx			; decrease cycle counter and
0001b5 3020      	cpi	Cx, $00			; check for end of cycle
0001b6 f021      	breq	end_timesend		; if not, jump to begin of loop
         	
0001b7 e30a      	ldi	Ax, $3A			; send ":" CHR to RS-232 port
0001b8 d044      	rcall	sendCHR	
0001b9 951a      	dec	Bx			; Decrease reg. number by one
0001ba cfee      	rjmp	Start_timesend
         	
          end_timesend:	
0001bb e200      	ldi	Ax, $20			; load Ax with " " CHR	
0001bc d040      	rcall	sendCHR
         
         
         ;********* START SENDING CURRENT DAY BY NAME TO RS-232 PORT ********
         
0001bd ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
0001be e016      	ldi	Bx, $06			; Bx is loaded with Reg. number
0001bf dec1      	rcall	I2C_regread		; Load register vallue from RTC into Ax register	
         
0001c0 930f      	push	Ax			; Save read value on stack ( day/month info )
         					; THIS VALUE WIL BE LOADED IN 2 BLOCKS !!!
0001c1 7e00      	andi	Ax, 0b11100000		; remove month information
0001c2 9502      	swap 	Ax
         	
0001c3 2f20      	mov	Cx, Ax			; Load AX, Bx and CX register with proper
0001c4 e402      	ldi	Ax, low(dagen)		; values to locate the string of the
0001c5 e018      	ldi	Bx, high(dagen)		; current day to send on the RS-232 port
0001c6 d32e      	rcall	calcpointer
0001c7 2fe0      	mov	Z_low, Ax		; and load it into Z_reg.
0001c8 2ff1      	mov	Z_high, Bx
         	
0001c9 95c8      	lpm				; load 1st CHR into Ax end send it
0001ca 2d00      	mov	Ax, R0
0001cb d031      	rcall	sendCHR
0001cc 9631      	adiw	Z_low, $01		; increase 16-bit pointer by one
0001cd 95c8      	lpm				; and load 2nd CHR
0001ce 2d00      	mov	Ax, R0
0001cf d02d      	rcall	sendCHR			; and send it to the RS-232 port
         	
0001d0 e200      	ldi	Ax, $20			; send space to RS-232 port
0001d1 d02b      	rcall	sendCHR
         	
         ;********* START OF SENDING CURRENT DATE TO THE RS-232 PORT *********
         	
         	
0001d2 ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
0001d3 e015      	ldi	Bx, $05			; Bx is loaded with day Reg. number
0001d4 deac      	rcall	I2C_regread		; Load register vallue from RTC into Ax register	
0001d5 730f      	andi	Ax, 0b00111111		; remove year info from Ax reg. 
         
0001d6 930f      	push	Ax			; Save read value on stack
0001d7 7f00      	andi	Ax, $F0			; clear low nibble
0001d8 9502      	swap	Ax			; and move high nibble to low nibble
0001d9 5d00      	subi	Ax, $D0			; and convert DEC val into ASCII val.
0001da d022      	rcall	sendCHR			; an send it to RS-232 port
         
0001db 910f      	pop	Ax			; Reload Ax with read value
0001dc 700f      	andi	Ax, $0F			; clear high nibble
0001dd 5d00      	subi	Ax, $D0			; and convert it into ASCII val
0001de d01e      	rcall	sendCHR			; and send it to RS-232 port
         
0001df e200      	ldi	Ax, $20			; Send space to RS-232 port
0001e0 d01c      	rcall	sendCHR
         	
         ;*********** SEND CURRENT MONTH NAME TO RS-232 PORT
         
0001e1 910f      	pop	Ax			; reload month info from stack again
0001e2 710f      	andi	Ax, 0b00011111		; and remove day info
0001e3 df48      	rcall	DEC2HEX			; and convert DEC val into HEX value
0001e4 950a      	dec	Ax			; decrease by one ( Jan is offset 0 )
0001e5 0f00      	lsl	Ax			; and multiply val by four ( monthname is 4 byte's)
0001e6 0f00      	lsl	Ax
0001e7 2f20      	mov	Cx, Ax			; load Ax, Bx and Cx to calculate proper
0001e8 e409      	ldi	Ax, low(maanden)	; pointer of the month string in memory
0001e9 e018      	ldi	Bx, high(maanden)
0001ea d30a      	rcall	calcpointer
0001eb 2fe0      	mov	Z_low, Ax		; and load it into Z-register
0001ec 2ff1      	mov	Z_high, Bx
         	
0001ed e014      	ldi	Bx, $04			; load Bx as cycle counter
         	
          monthagain:
         
0001ee 95c8      	lpm				; load CHR from memory
0001ef 2d00      	mov	Ax, R0			; into Ax register
0001f0 d00c      	rcall	sendCHR			; and send it to the RS-232 port
0001f1 9631      	adiw	Z_low, $01		; increase Z-register by one
         			
0001f2 951a      	dec	Bx			; decrease cycle counter
0001f3 3010      	cpi	Bx, $00			; and check for end of string
0001f4 f7c9      	brne	monthagain
         
0001f5 e200      	ldi	Ax, $20			; Load "space" info Ax
0001f6 d006      	rcall	SendCHR
         	
0001f7 91ff      	pop	Z_high
0001f8 91ef      	pop	Z_low	
0001f9 912f      	pop	Cx
0001fa 911f      	pop	Bx
0001fb 910f      	pop	Ax
         
         
0001fc 9508      	ret
         
         ;**********************************************************************
         ;
         ; Waits until the UART is ready, and put's Ax reg. into UDR.
         ;
         ;	Ax = ASCII val. to send to RS-232 port.
         ;
         ;**********************************************************************
         
          SendCHR:
         
         		
          UART_ready:
0001fd 9b5d      	sbis	USR,5			; Check for UART is ready
0001fe cffe      	rjmp	UART_ready
         	
0001ff b90c      	out	UDR, Ax			; Send charakter definex in Ax to RS-232 port
         	
000200 9508      	ret
         	
         
         
         ;***********************************************************************
         ;
         ;	Display time on the display
         ;	
         ;	Ax	= contains start position on display
         ;	Bx	= contains hour vallue.
         ;
         ;***********************************************************************
         
          disp_RTCtime:
         
000201 931f      	push	Bx			; save vallue to display on stack
         
000202 9503      	inc	Ax
000203 701f      	andi	Bx, $0F			; 
000204 5d10      	subi	Bx, $D0
000205 930f      	push	Ax			; save display position
000206 d507      	rcall	dispCHR			; and display tihs vallue.
000207 910f      	pop	Ax
000208 950a      	dec	Ax
         
000209 911f      	pop	Bx
00020a 9512      	swap	Bx			; calculate the ASCII vallue of the  10 hour's setting
00020b 701f      	andi	Bx, $0F			; off the SW clock
00020c 5d10      	subi	Bx, $D0			; and load this ASCII vallue in Bx
00020d d500      	rcall	dispCHR			; display ASCII vallue
         	
00020e 9508      	ret
         
         
         ;**************************************************************************
         ;
         ; Routine to display the selected day informataion
         ;
         ;	Ax	= selected day information
         ;	Bx	= startposition on LCD
         ;
         ;**************************************************************************
         
          disp_days:
         
00020f 93ef      	push	Z_low			; Save Z register SRAM pointer
000210 93ff      	push	Z_high
000211 930f      	push	Ax			; Save selected day info on stack
000212 931f      	push	Bx			; save display position on stack
         
000213 2f20      	mov	Cx, Ax			; Move selected day info into Cx reg.
000214 e30c      	ldi	Ax, low(dayinfo)	; load Z-register with switchday data start
000215 e018      	ldi	Bx, high(dayinfo)	; position
000216 d2de      	rcall	Calcpointer
000217 2fe0      	mov	Z_low,Ax
000218 2ff1      	mov	Z_high,Bx
000219 911f      	pop	Bx			; Reload Bx with display position
00021a 910f      	pop	Ax			; Load Ax with day select info
         
00021b 95c8      	lpm				; Load R0 with the proper day settings
00021c 2d20      	mov	Cx, R0			; and move it to Cx reg.
         
         
00021d 2f01      	mov	Ax, Bx			; Load Ax with display start position 
00021e e018      	ldi	Bx, $08			; for printing selected SW time day's
         
          SWnext_day:
00021f 9503      	inc	Ax			; move cursor one place right
000220 951a      	dec	Bx			; decrease bit test counter.
000221 3010      	cpi	Bx, $00			; check for all non-selected day's
000222 f081      	breq	SWend_next_day
000223 9526      	lsr	Cx			; shift Cx register right
000224 f038      	brcs	SWdisp_ster		; if carry is set ( LSB = 1 ) then display
000225 931f      	push	Bx			; an "*" or else
000226 e51f      	ldi	Bx, $5F			; Load "_" character in Bx register
000227 930f      	push	Ax
000228 d4e5      	rcall	dispCHR			; to display indicating selected day
000229 910f      	pop	Ax
00022a 911f      	pop	Bx
00022b cff3      	rjmp	SWnext_day
         
          SWdisp_ster:
00022c 931f      	push	Bx
00022d e21a      	ldi	Bx, $2a			; Load "*" character in Bx register 
00022e 930f      	push	Ax
00022f d4de      	rcall	dispCHR			; to display indicating non-selected day
000230 910f      	pop	Ax
000231 911f      	pop	Bx
000232 cfec      	rjmp	SWnext_day		; and go to check the next bit.
         
          SWend_next_day:
         
000233 91ff      	pop	Z_high			; and restore Z-register
000234 91ef      	pop	Z_low
         
000235 9508      	ret
         	
         ;**************************************************************************
         ;
         ; Routine to display a DEC value on the display
         ;
         ;	Ax	= display position to start printing at
         ;	Bx	= DEC value to display
         ;
         ;**************************************************************************
         
          dispDECval:
         
000236 932f      	push	Cx
         
000237 930f      	push	Ax		; Save current display position on stack
000238 2f21      	mov	Cx, Bx		; Save DEC val in Cx reg
         	
000239 7f10      	andi	Bx, 0b11110000	; Clear lower four bit's
00023a 9512      	swap	Bx		; and swap the nibles
00023b 5d10      	subi	Bx, $D0		; Add $30 to get ASCII value if DEC number
         	
00023c d4d1      	rcall	DispCHR		; and goto display this ASCII value
         	
00023d 910f      	pop	Ax		; reload Ax with display position
00023e 9503      	inc	Ax		; and increase this number by one
         		
00023f 2f12      	mov	Bx, Cx		; Reload Bx with org. DEC value
000240 701f      	andi	Bx, 0b00001111	; and clear the high nibble
000241 5d10      	subi	Bx, $D0		; Add $30 to get ASCII value of DECnumber
         	
000242 d4cb      	rcall	dispCHR		; and goto display this DEC number
         	
000243 912f      	pop	Cx		; Restore Cx from stack
         
         
000244 9508      	ret
         	
         ;**************************************************************************
         ;
         ; Routine to display a DEC value on the display
         ;
         ;	Ax	= DEC value to send to RS-232 port
         ;
         ;**************************************************************************
         
          SendDECval:
         
000245 932f      	push	Cx
         
000246 930f      	push	Ax		; Save DEC value on stack.
         	
000247 7f00      	andi	Ax, 0b11110000	; Clear lower four bit's
000248 9502      	swap	Ax		; and swap the nibles
000249 5d00      	subi	Ax, $D0		; Add $30 to get ASCII value if DEC number
         	
00024a dfb2      	rcall	SendCHR		; and Send it to the RS-232 port
         	
00024b 910f      	pop	Ax		; reload Ax with DEC value
00024c 700f      	andi	Ax, 0b00001111	; and clear the high nibble
00024d 5d00      	subi	Ax, $D0		; Add $30 to get ASCII value of DECnumber
         	
00024e dfae      	rcall	SendCHR		; and goto display this DEC number
         	
00024f 912f      	pop	Cx		; Restore Cx from stack
         
000250 9508      	ret		
         	
         ;*********************************************************************
         ;
         ; Send channel nummer and channel status information to the RS-232 port
         ;
         ; Registers : 	Ax = Channel status info
         ;
         ; Return    :   None
         ;
         ;***********************************************************************
         
          Send_chanstat:
         
000251 932f      	push	Cx			; Save used register vulue's 
000252 931f      	push	Bx			; to stack
000253 93ef      	push	Z_low
000254 93ff      	push	Z_high
         		
000255 930f      	push	Ax			; Save channel/stat into to stack
         
000256 e601      	ldi	Ax, low(channel)	; Load "channel" pointer into Ax
000257 e018      	ldi	Bx, high(channel)	; and Bx register
000258 e020      	ldi	Cx, $00			; Set offset to zero
000259 d29b      	rcall	calcpointer		; calculate memory pointer
00025a 2fe0      	mov	Z_low, Ax		; and move it into Z register
00025b 2ff1      	mov	Z_high, Bx
         	
          send_CHnum:
         
00025c 95c8      	lpm				; Load CHR from memory
00025d 2d00      	mov	Ax, R0			; and move it to Ax
00025e 3000      	cpi	Ax, $00			; check if CHR is "00"
00025f f019      	breq	end_CHnum		; if so, then jump out
000260 df9c      	rcall	SendCHR			; Send CHR  on RS-232 port
000261 9631      	adiw	Z_low, $01		; increase momory pointer by one
000262 cff9      	rjmp	send_CHnum		; and read CHR again
         		
          end_CHnum:
         
000263 910f      	pop	Ax			; Reload Ax with channel state into
000264 930f      	push	Ax			; and save it back on stack again
         
000265 7f00      	andi	Ax, $F0			; remove channel state info 
000266 9502      	swap	Ax
000267 deb7      	rcall	HEX2DEC
000268 2f10      	mov	Bx, Ax			; save DEC val into Bx reg.
000269 7f00      	andi	Ax, $F0			; clear low nibble
00026a 9502      	swap	Ax			; and move high nibble to low nibble
00026b 5d00      	subi	Ax, $D0			; and convert DEC val into ASCII val.
00026c df90      	rcall	sendCHR			; an send it to RS-232 port
         
00026d 2f01      	mov	Ax, Bx			; reload Ax with read value
00026e 700f      	andi	Ax, $0F			; clear high nibble
00026f 5d00      	subi	Ax, $D0			; and convert it into ASCII val
000270 df8c      	rcall	sendCHR			; and send it to RS-232 port
         
000271 e200      	ldi	Ax, $20			; load ASCII val for "space"
000272 df8a      	rcall	SendCHR			; and send it ro RS-232 port
         	
000273 e30a      	ldi	Ax, $3A			; Send ":" to the RS-232 port
000274 df88      	rcall	SendCHR
         	
000275 e200      	ldi	Ax, $20			; Send "SPACE" on the RS-232 port
000276 df86      	rcall	SendCHR
         	
000277 910f      	pop	Ax			; reload Ax with channel/state info
         	
000278 7001      	andi	Ax, $01			; remove channel number from data
000279 fd00      	sbrc	Ax, 0			; skip if state bit is clear
00027a c003      	rjmp	state_onn		
         	
00027b e000      	ldi	Ax, low(off)		; load "Off" string pointer into Ax
00027c e010      	ldi	Bx, high(off)
00027d c002      	rjmp	read_EEPROM	
         	
          state_onn:
00027e e10e      	ldi	Ax, low(on)		; Load "On "string pointer into Ax
00027f e010      	ldi	Bx, high(on)
         
          read_EEPROM:
         
000280 bb0e      	out	EEARL, Ax		; write EEPROM addres to read in EEPROM addres 
000281 bb1f      	out	EEARH, Bx
000282 9ae0      	sbi	EECR, EERE		; Set EEPROM Read start bit	
         	
          check_EEPROMready:
000283 b30c      	in 	Ax, EECR		; load EECR status in Ax reg.
000284 fd00      	sbrc	Ax, 0			; check if EEPROM read bit is cleared by hardware
000285 cffd      	rjmp	check_EEPROMready	; if not, then wait until reset
         	
000286 b30d      	in	Ax, EEDR 		; Load read EEPROM data into Ax reg.
000287 3000      	cpi	Ax, $00
000288 f041      	breq	end_Statesend
000289 df73      	rcall	SendCHR
00028a b30e      	in	Ax, EEARL
00028b 9503      	inc	Ax
00028c 3000      	cpi	Ax, $00
00028d f791      	brne	read_EEPROM
00028e b31f      	in	Bx, EEARH
00028f 9513      	inc	Bx
000290 cfef      	rjmp	read_EEPROM
         	
          end_Statesend:
         
000291 91ff      	pop	Z_high
000292 91ef      	pop	Z_low
000293 911f      	pop	Bx
000294 912f      	pop	Cx
         
         
000295 9508      	ret          .include	"8583set.asm"
         ;***************************************************************************
         ;* Routines to set all the time registers of the 8583 I2C RTC klok
         ;*
         ;* Autor	: H. Vos
         ;* Date	: 04-02-98
         ;*
         ;* E-mail		: hugo@hvos.myweb.nl
         ;* 
         ;*
         ;***************************************************************************
         ;
         ; Routine for setting the proper hour vallue to the 8583 clock chip
         ;
         ;***************************************************************************
         
          set_hour:
         
000296 e001      	ldi	Ax, Dispclear		; Set display cursor function
000297 e010      	ldi	Bx, disp_CTRL
000298 d4ac      	rcall	disp_lcd
         
000299 e202      	ldi	Ax, low(rtc)		; write tekst to te display
00029a e010      	ldi	Bx, high(rtc)
00029b e020      	ldi	Cx, $00
00029c d48c      	rcall	Str2disp	
         
00029d e70c      	ldi	Ax, low(uren)
00029e e010      	ldi	Bx, high(uren)
00029f e420      	ldi	Cx, $40
0002a0 d488      	rcall	Str2disp
         
0002a1 e406      	ldi	Ax, $46
0002a2 e01a      	ldi	Bx, $0A	
0002a3 d25a      	rcall	disp_space
         
0002a4 ea00      	ldi	Ax, PCF8583
0002a5 e014      	ldi	Bx, $04
0002a6 ddda      	rcall	I2C_regread		; read register Bx from device Ax
         
0002a7 2f20      	mov	Cx, Ax			; store read data into Cx
         
          start_hourset:
         
0002a8 d470      	rcall	Key_released
         
0002a9 e408      	ldi	Ax, $48
0002aa 2f12      	mov	Bx, Cx
0002ab d0fd      	rcall	Disp_DECval
         
0002ac 2f02      	mov	Ax, Cx				; Load DEC clock vallue into Ax
0002ad e010      	ldi	Bx, $00				; Load Bx with min DEC vallue
0002ae e224      	ldi	Cx, $24				; Load Cx with max DEC vallue
         
0002af de8f      	rcall	moddecval			 
0002b0 2f20      	mov	Cx, Ax				; Save new vallue into Cx
         
0002b1 3010      	cpi	Bx, $00
0002b2 f3a9      	breq	start_hourset
         
0002b3 931f      	push	Bx				; save lastkey pressed vallue
         
0002b4 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
0002b5 e014      	ldi	Bx, $04				; load Bx with I2C device reg. nummer
         						; Cx already loaded with hour vallue
0002b6 dde2      	rcall	I2C_regstore
         
0002b7 911f      	pop	Bx
0002b8 3012      	cpi	Bx, select_key			; check if lastkey was select
0002b9 f009      	breq	set_min				; if so, start set min vallue
         
0002ba c0fb      	rjmp	endtimeset			; otherwise jump back to display time and temp
         		
         ;***************************************************************************
         ;
         ; Routine for setting the proper minute vallue to the 8583 clock chip
         ;
         ;***************************************************************************
         
          set_min:
         
0002bb ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
0002bc e014      	ldi	Bx, $04				; load Bx with I2C device reg. nummer
         						; Cx already loaded with hour vallue
0002bd dddb      	rcall	I2C_regstore			; save hour vallue
         
0002be d45a      	rcall	Key_released
         
0002bf e802      	ldi	Ax, low(min)
0002c0 e010      	ldi	Bx, high(min)
0002c1 e420      	ldi	Cx, $40
0002c2 d466      	rcall	Str2disp
         
0002c3 e408      	ldi	Ax, $48
0002c4 e018      	ldi	Bx, $08
0002c5 d238      	rcall	disp_space
         	
0002c6 ea00      	ldi	Ax, PCF8583
0002c7 e013      	ldi	Bx, $03				;
0002c8 ddb8      	rcall	I2C_regread			; read register Bx from device Ax
         
0002c9 2f20      	mov	Cx, Ax				; store read data into Cx
         
          start_minset:
         
0002ca d44e      	rcall	Key_released
         
0002cb e409      	ldi	Ax, $49
0002cc 2f12      	mov	Bx, Cx
0002cd d0db      	rcall	Disp_DECval
         
0002ce 2f02      	mov	Ax, Cx				; Load DEC clock vallue into Ax
0002cf e010      	ldi	Bx, $00				; load Bx with min DEC vallue
0002d0 e620      	ldi	Cx, $60				; load Cx with max DEC vallue
         
0002d1 de6d      	rcall	moddecval
0002d2 2f20      	mov	Cx, Ax				; Save new vallue into Cx
         
0002d3 3010      	cpi	Bx, $00
0002d4 f3a9      	breq	start_minset
         
0002d5 931f      	push	Bx				; save lastkey pressed vallue
         
0002d6 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
0002d7 e013      	ldi	Bx, $03				; load Bx with I2C device reg. nummer
         						; Cx already loaded with hour vallue
0002d8 ddc0      	rcall	I2C_regstore
         
0002d9 911f      	pop	Bx
0002da 3012      	cpi	Bx, select_key			; check if lastkey was select
0002db f009      	breq	set_month			; if so, start set min vallue
         
0002dc c0d9      	rjmp	endtimeset			; otherwise jump back to display time
         
         ;***************************************************************************
         ;
         ; Routine for setting the proper month vallue to the 8583 clock chip
         ;
         ;***************************************************************************
         
          set_month:
0002dd ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
0002de e013      	ldi	Bx, $03				; load Bx with I2C device reg. nummer
         						; Cx already loaded with hour vallue
0002df ddb9      	rcall	I2C_regstore			; save hour vallue
         	
0002e0 d438      	rcall	Key_released
         
0002e1 e80b      	ldi	Ax, low(maand)
0002e2 e010      	ldi	Bx, high(maand)
0002e3 e420      	ldi	Cx, $40
0002e4 d444      	rcall	Str2disp
         
0002e5 e406      	ldi	Ax, $46
0002e6 e01a      	ldi	Bx, $0A
0002e7 d216      	rcall	disp_space
         
0002e8 ea00      	ldi	Ax, PCF8583
0002e9 e016      	ldi	Bx, $06				; read month
0002ea dd96      	rcall	I2C_regread			; read register Bx from device Ax
0002eb 710f      	andi	Ax, 0b00011111			; Remove weekday information
         
0002ec 2f20      	mov	Cx, Ax				; store read data into Cx
         
          start_monthset:
         
0002ed d42b      	rcall	Key_released
         
0002ee 2f12      	mov	Bx, Cx				; display low nibble of vallue
0002ef e407      	ldi	Ax, $47
0002f0 d0b8      	rcall	disp_DECval
         
0002f1 2f02      	mov	Ax, Cx				; Load DEC clock vallue into Ax
0002f2 e011      	ldi	Bx, $01				; load Bx with min DEC vallue
0002f3 e123      	ldi	Cx, $13				; load Cx with max DEC vallue
         
0002f4 de4a      	rcall	moddecval
0002f5 2f20      	mov	Cx, Ax				; Save new vallue into Cx
         
0002f6 3010      	cpi	Bx, $00
0002f7 f3a9      	breq	start_monthset
         
0002f8 931f      	push	Bx				; save lastkey pressed vallue
         	
0002f9 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
0002fa e016      	ldi	Bx, $06				; Read I2C device register
0002fb dd85      	rcall	I2C_regread
         
0002fc 7e00      	andi	Ax, 0b11100000			; Clear lower 6 bits
0002fd 2b20      	or	Cx, Ax				; Load Cx with new register vallue
0002fe ea00      	ldi	Ax, PCF8583			; Load Ax with I2C device address
0002ff e016      	ldi	Bx, $06				; load Bx with I2C device reg. nummer
         						
000300 dd98      	rcall	I2C_regstore
         
000301 911f      	pop	Bx
000302 3012      	cpi	Bx, select_key			; check if lastkey was select
000303 f009      	breq	set_day				; if so, start set day vallue
         
000304 c0b1      	rjmp	endtimeset			; otherwise jump back to display time
         
         
         ;***************************************************************************
         ;
         ; Routine for setting the proper day vallue to the 8583 clock chip
         ;
         ;***************************************************************************
         
          set_day:
         
000305 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000306 e016      	ldi	Bx, $06				; Read I2C device register
000307 dd79      	rcall	I2C_regread
         
000308 7e00      	andi	Ax, 0b11100000			; Clear lower 6 bits
000309 2b20      	or	Cx, Ax				; Load Cx with new register vallue
         
00030a ea00      	ldi	Ax, PCF8583			; Load Ax with I2C device address
00030b e016      	ldi	Bx, $06				; load Bx with I2C device reg. nummer
00030c dd8c      	rcall	I2C_regstore
         
00030d d40b      	rcall	Key_released
         
00030e e902      	ldi	Ax, low(dag)
00030f e010      	ldi	Bx, high(dag)
000310 e420      	ldi	Cx, $40
000311 d417      	rcall	Str2disp
         
000312 ea00      	ldi	Ax, PCF8583
000313 e015      	ldi	Bx, $05				; read date/year register
000314 dd6c      	rcall	I2C_regread			; read register Bx from device Ax
         
000315 730f      	andi	Ax, 0b00111111			; remove year information from data
000316 2f20      	mov	Cx, Ax				; store read data into Cx
         
          start_dayset:
         
000317 d401      	rcall	Key_released
         
000318 2f12      	mov	Bx, Cx			; display low nibble of vallue
000319 e40e      	ldi	Ax, $4E
00031a d08e      	rcall	disp_DECval
         
00031b 2f02      	mov	Ax, Cx
00031c e011      	ldi	Bx, $01
00031d e322      	ldi	Cx, $32
         
00031e de20      	rcall	moddecval
00031f 2f20      	mov	Cx, Ax				; Save new vallue into Cx
         
000320 3010      	cpi	Bx, $00
000321 f3a9      	breq	start_dayset
         
000322 931f      	push	Bx				; save lastkey pressed vallue
         	
000323 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000324 e015      	ldi	Bx, $05				; Read I2C device register
000325 dd5b      	rcall	I2C_regread
         
000326 7c00      	andi	Ax, 0b11000000			; Clear lower 6 bits
000327 932f      	push	Cx				; Save Cx to stack
000328 2b20      	or	Cx, Ax				; Load Cx with new register vallue
000329 ea00      	ldi	Ax, PCF8583			; Load Ax with I2C device address
00032a e015      	ldi	Bx, $05				; load Bx with I2C device reg. nummer
00032b dd6d      	rcall	I2C_regstore
00032c 912f      	pop	Cx				; Get old Cx vallue from stack
         
00032d 911f      	pop	Bx
00032e 3012      	cpi	Bx, select_key			; check if lastkey was select
00032f f009      	breq	set_dayweek			; if so, start set dayweek vallue
         
000330 c085      	rjmp	endtimeset			; otherwise jump back to display time
         
         ;***************************************************************************
         ;
         ; Routine for setting the proper day vallue to the 8583 clock chip
         ;
         ;***************************************************************************
         
          set_dayweek:
         
000331 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000332 e015      	ldi	Bx, $05				; Read I2C device register
000333 dd4d      	rcall	I2C_regread
         
000334 7c00      	andi	Ax, 0b11000000			; Clear lower 6 bits
000335 2b20      	or	Cx, Ax
         
000336 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000337 e015      	ldi	Bx, $05				; load Bx with I2C device reg. nummer
         						; Cx already loaded with hour vallue
000338 dd60      	rcall	I2C_regstore
         
000339 d3df      	rcall	Key_released
         	
00033a e90f      	ldi	Ax, low(dag_w)
00033b e010      	ldi	Bx, high(dag_w)
00033c e420      	ldi	Cx, $40
00033d d3eb      	rcall	Str2disp
         
00033e ea00      	ldi	Ax, PCF8583
00033f e016      	ldi	Bx, $06				; read month/Weekday
000340 dd40      	rcall	I2C_regread			; read register Bx from device Ax
000341 7e00      	andi	Ax, 0b11100000			; remove month information from data
000342 9502      	swap	Ax				; swap high nibble to low nibble
000343 9506      	lsr	Ax				; and rotate one bt right
         	
000344 2f20      	mov	Cx, Ax				; store read data into Cx
         
          start_dayweekset:
         
000345 d3d3      	rcall	Key_released			; check for no key pressed
         
000346 932f      	push	Cx				; save "day of week" to stack
         ;	mov	Ax, Cx				; load reg contens into Ax
         ;	lsl	Ax				; multiply vallue by two
         ;	mov	Cx, Ax
000347 0f22      	lsl	Cx
000348 e402      	ldi	Ax, low(dagen)
000349 e018      	ldi	Bx, high(dagen)
00034a d1aa      	rcall	calcpointer
00034b 2fe0      	mov	Z_low, Ax
00034c 2ff1      	mov	Z_high, Bx
         
00034d 95c8      	lpm	
00034e 9631      	adiw	Z_low, $01
         			
00034f 2d10      	mov	Bx, R0				; load 1st CHR to display
000350 e40d      	ldi	Ax, $4d
000351 d3bc      	rcall	dispCHR
         
000352 95c8      	lpm				
000353 2d10      	mov	Bx, R0				; load 2nd CHR to display
000354 e40e      	ldi	Ax, $4e
000355 d3b8      	rcall	dispCHR
         
000356 912f      	pop	Cx				; restore "day of week" value into Cx reg	mov	Ax, Cx
000357 2f02      	mov	Ax, Cx				; and move it to Ax reg.
000358 e010      	ldi	Bx, $00				; load min value into Bx and
000359 e027      	ldi	Cx, $07				; max value +1 into Cx reg
         
00035a dde4      	rcall	moddecval
00035b 2f20      	mov	Cx, Ax				; Save new vallue into Cx
         
00035c 3010      	cpi	Bx, $00
00035d f339      	breq	start_dayweekset
         
00035e 931f      	push	Bx				; save lastkey pressed vallue
         	
00035f ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000360 e016      	ldi	Bx, $06				; Read I2C device register
000361 dd1f      	rcall	I2C_regread
         
000362 710f      	andi	Ax, 0b00011111			; Clear lower 6 bits
         
000363 932f      	push	Cx				; Save Cx on stack
000364 9522      	swap	Cx
000365 0f22      	lsl	Cx
000366 2b20      	or	Cx, Ax				; Load Cx with new register vallue
000367 ea00      	ldi	Ax, PCF8583			; Load Ax with I2C device address
000368 e016      	ldi	Bx, $06				; load Bx with I2C device reg. nummer
000369 dd2f      	rcall	I2C_regstore
00036a 912f      	pop	Cx
         
00036b 911f      	pop	Bx
00036c 3012      	cpi	Bx, select_key			; check if lastkey was select
00036d f009      	breq	set_year			; if so, start set dayweek vallue
         
00036e c047      	rjmp	endtimeset			; otherwise jump back to display time
         
         
         ;***************************************************************************
         ;
         ; Routine for setting the proper year vallue to the 8583 clock chip
         ;
         ;***************************************************************************
         
          set_year:
         
00036f ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000370 e016      	ldi	Bx, $06				; Read I2C device register
000371 dd0f      	rcall	I2C_regread
         
000372 710f      	andi	Ax, 0b00011111			; Clear lower 6 bits
000373 9522      	swap	Cx
000374 0f22      	lsl	Cx
000375 2b20      	or	Cx, Ax				; Load Cx with new register vallue
000376 ea00      	ldi	Ax, PCF8583			; Load Ax with I2C device address
000377 e016      	ldi	Bx, $06				; load Bx with I2C device reg. nummer
000378 dd20      	rcall	I2C_regstore
         	
000379 d39f      	rcall	Key_released
         
00037a eb00      	ldi	Ax, low(Jaar)
00037b e010      	ldi	Bx, high(Jaar)
00037c e420      	ldi	Cx, $40
00037d d3ab      	rcall	Str2disp
         
00037e e407      	ldi	Ax, $47				; Load Ax with display position
00037f e312      	ldi	Bx, $32				; Load Bx with "2"
000380 d38d      	rcall	DispCHR
         	
000381 9503      	inc	Ax				; go to next display position
000382 e310      	ldi	Bx, $30				; Load Bx with "0"
000383 d38a      	rcall	DispCHR
         
000384 ea00      	ldi	Ax, PCF8583
000385 ef1f      	ldi	Bx, $FF				; read year information from RTC SRAM location
000386 dcfa      	rcall	I2C_regread			; read register Bx from device Ax
000387 dd97      	rcall	HEX2DEC				; convert value to DEC value
000388 2f20      	mov	Cx, Ax				; store read data into Cx
         
          start_yearset:
         
000389 d38f      	rcall	Key_released			; Check for no key's pressed anymore
         
00038a e409      	ldi	Ax, $49
00038b 2f12      	mov	Bx, Cx
00038c d01c      	rcall	disp_DECval
         	
00038d 2f02      	mov	Ax, Cx				; Load current DEC val into Ax
00038e e010      	ldi	Bx, $00				; Load min. DEC val into Bx reg
00038f e929      	ldi	Cx, $99				; Load max. DEC val into Cx
000390 ddae      	rcall	moddecval
000391 2f20      	mov	Cx, Ax				; Save new vallue into Cx
         
000392 3010      	cpi	Bx, $00				; check for end of modification
000393 f3a9      	breq	start_yearset			; if not, then loop again
         
000394 2f02      	mov	Ax, Cx				; mov new value to Ax
000395 dd96      	rcall	DEC2HEX				; and convert it into HEX val
000396 2f20      	mov	Cx, Ax				; and move back to Cx reg.
000397 932f      	push	Cx				; and save on stack
         	
000398 ea00      	ldi	Ax, PCF8583			; load Ax with I2C device adres
000399 ef1f      	ldi	Bx, $FF				; Read I2C device register
00039a dcfe      	rcall	I2C_regstore			; save new year into in SRAM
         	
00039b ea00      	ldi	Ax, PCF8583
00039c e015      	ldi	Bx, $05
00039d dce3      	rcall	I2C_regread
         	
         	
00039e 730f      	andi	Ax, 0b00111111			; Clear bit[6:7]
00039f 912f      	pop	Cx
0003a0 7023      	andi	Cx, 0b00000011			; Remove Bit[2:7]
0003a1 9522      	swap	Cx
0003a2 0f22      	lsl	Cx
0003a3 0f22      	lsl	Cx
0003a4 2b20      	or	Cx, Ax				; Load Cx with new register vallue
0003a5 ea00      	ldi	Ax, PCF8583			; Load Ax with I2C device address
0003a6 e015      	ldi	Bx, $05				; load Bx with I2C device reg. nummer
0003a7 dcf1      	rcall	I2C_regstore
0003a8 c00d      	rjmp	endtimeset
         
         ;***************************************************************************
         ;
         ; Routine to converd a DEC vallue in ADCII vallue and display it
         ;
         ;	Ax = start display position
         ;	Bx = Dec vallue to display	
         ;
         ; Return:
         ;	
         ;	none
         ;
         ;***************************************************************************
         
          disp_DECval:
         
0003a9 931f      	push	Bx
         
0003aa 7f10      	andi	Bx, $F0		; select 10th number of DEC vallue
0003ab 9512      	swap	Bx
0003ac 5d10      	subi	Bx, $D0		; calculate ASCII vallue
0003ad 930f      	push	Ax
0003ae d35f      	rcall	dispCHR		; and display it on the LCD.
         
0003af 910f      	pop	Ax
0003b0 911f      	pop	Bx
0003b1 701f      	andi	Bx, $0F		; select 1th number of DEC vallue
0003b2 5d10      	subi	Bx, $D0		; and calculate ASCII vallue
0003b3 9503      	inc	Ax
0003b4 d359      	rcall	dispCHR		; and dislpay it on the LCD.
         
0003b5 9508      	ret
         
          endtimeset:
         
0003b6 9508      	ret
          .include	"SWklok.asm"
         
         ;***************************************************************************
         ;
         ; Routine to set the Switchclock time 
         ; by Hugo Vos
         ;
         ; E-mail		: hugo@hvos.myweb.nl
         ;
         ;***************************************************************************
         
          set_SWklok:
         
         
0003b7 e030      	ldi	Dx ,$00			; clear time counter
         
0003b8 2d0e      	mov	Ax, SWmod_L		; Load available 8574 bit stream into Ax reg.
0003b9 3000      	cpi	Ax, $00			; and check for modules available
0003ba f4a1      	brne	start_SWtime_set
         	
0003bb 2d0f      	mov	Ax, SWmod_H		; Load available 8574A bit stream into Ax Reg.	
0003bc 3000      	cpi	Ax, $00			; and check if modules are available
0003bd f489      	brne	start_SWtime_set	; If so , then jump.
         					; if NOT then :
0003be e001      	ldi	Ax, Dispclear		; Clear display.
0003bf e010      	ldi	Bx, disp_CTRL
0003c0 d384      	rcall	disp_lcd
         
0003c1 e401      	ldi	Ax, low(noSWmod1)	; print "no SW modules found on the I2C bus"
0003c2 e010      	ldi	Bx, high(noSWmod1)
0003c3 e020      	ldi	Cx, $00			; message on the LC- display.
0003c4 d364      	rcall	str2disp		; print first line
         
0003c5 e501      	ldi	Ax, low(noSWmod2)
0003c6 e010      	ldi	Bx, high(noSWmod2)		
0003c7 e420      	ldi	Cx, $40
0003c8 d360      	rcall	str2disp		; print second line.
         
0003c9 d34f      	rcall	Key_released		; check for no key's pressed
         
          readSWkey:
0003ca d399      	rcall	input_keyread
0003cb 3001      	cpi	Ax, return_key		; check for return key read
0003cc f7e9      	brne    readSWkey
         
0003cd d34b      	rcall	Key_released
         
0003ce 9508      	ret				; return to menu programm
         
          start_SWtime_set:
         
         
0003cf e000      	ldi	Ax, $00			; Load Ax reg. with display location
0003d0 e01f      	ldi	Bx, $0F			; Load Bx with number of spaces to print
0003d1 d12c      	rcall	disp_space		; Go print spaces
         
0003d2 e50d      	ldi	Ax, low(cvklok)		; Set "Tijd   MDWDVZZ" on the display
0003d3 e010      	ldi	Bx, high(cvklok)
0003d4 e020      	ldi	Cx, $00			; starting at position zero
0003d5 d353      	rcall	str2disp
         
          SW_klokset:
         
0003d6 d342      	rcall	Key_released		; Check for no key pressed
         
0003d7 3134      	cpi	Dx, max_SWclktimes	; Check for max. SW timesetting.
0003d8 f2f1      	breq	set_SWklok		; if last setting then start at setting one
0003d9 3f3f      	cpi	Dx, $ff
0003da f411      	brne	Nomaxtime
0003db e134      	ldi	Dx, max_SWclktimes
0003dc 953a      	dec	Dx
         
          Nomaxtime:
         	
0003dd 2f03      	mov	Ax, Dx			; Load Ax with Set-time counter
0003de dd40      	rcall	HEX2DEC			; convert HEX number to DEC number
0003df 2f10      	mov	Bx, Ax			; move it to Bx reg and
0003e0 e00e      	ldi	Ax, $0E			; load display location in Ax reg.
0003e1 de54      	rcall	dispDECval		; and display the number
         
0003e2 e72b      	ldi	Cx, $7B			; EEPROM start address for SW time setting
0003e3 2f03      	mov	Ax, Dx			; is $80
         
         ;********************************************************************
         ;
         ; Routine to calculate the EEPROM data start address
         ;
         ;********************************************************************
         
          add_SWadres:
0003e4 5f2b      	subi	Cx, $FB			; calculate klok data start address
0003e5 950a      	dec	Ax			; in EEPROM with respect to the time
0003e6 3f0f      	cpi	Ax, $FF			; set counter in Dx
0003e7 f7e1      	brne	add_SWadres	
         	
0003e8 9320 0100 	sts	$0100, Cx		; Save EEPROM start address on SRAM location $0100 
         	
         ;********************************************************************
         ;
         ; Routine to load the EEPROM data into SRAM starting at address $0060
         ;
         ;********************************************************************
         
0003ea e0f0      	ldi	Z_high,$00		; Load Z register with $0060 ( SRAM address )
0003eb e6e0      	ldi	Z_low,$60		; SRAM Location to store EERPOM data to.
0003ec 2f12      	mov	Bx, Cx			; Load Bx with calculated EEPROM start address		
0003ed e025      	ldi	Cx, $05			; Load total byte read counter.
         
          SWread_data:
0003ee ea02      	ldi	Ax, X24C02		; copy DATA from EEPROM to SRAM
0003ef 3020      	cpi	Cx, $00			; check for end SRAM load loop	
0003f0 f029      	breq	end_SWdataread
0003f1 dc8f      	rcall	I2C_regread		; Load EEPROM data at address location given in Bx
0003f2 9301      	st	Z+, Ax			; Store data in to SRAM
         
0003f3 9513      	inc	Bx			; increase EEPROM address
0003f4 952a      	dec	Cx			; decrease loop counter
0003f5 cff8      	rjmp	SWread_data
         
         ;********************************************************************
         ;
         ; Routine to check for vallid data read from the EEPROM. Byte 5 is
         ; 2-comp from byte 1 to 4
         ;
         ;********************************************************************
         
          end_SWdataread:
0003f6 e0f0      	ldi	Z_high,$00		; Load Z-register with $0060 ( SRAM address )
0003f7 e6e0      	ldi	Z_low,$60
0003f8 e024      	ldi	Cx, $04
0003f9 e000      	ldi	Ax, $00
         	
          chk_SW2comp:
0003fa 9111      	ld	Bx, Z+			; check readed data for real settings
         
0003fb 0f01      	add	Ax, Bx			; fifth byte is 2COMP from four pref.
0003fc 952a      	dec	Cx			; bytes
0003fd 3020      	cpi	Cx, $00
0003fe f7d9      	brne	chk_SW2comp		
         
0003ff 9500      	com	Ax			; create 2comp of value in Ax reg.
000400 5f0f      	subi	Ax, $FF
000401 8110      	ld	Bx, Z			; Read 2-comp value stored in EEPROM
000402 1701      	cp	Ax, Bx			; check for C-comp
000403 f031      	breq	SWcomp2_ok
         
000404 e20b      	ldi	Ax, $2B			; if not the load SRAM with default vallues
000405 9302      	st	-Z, Ax			; defuald vallue  defined in Ax register
000406 e000      	ldi	Ax, $00
000407 9302      	st	-Z, Ax
000408 9302      	st	-Z, Ax
000409 9302      	st	-Z, Ax
         
          SWcomp2_ok:
         ;********************************************************************
         ;
         ; Display SW switch time onto display
         ;
         ;********************************************************************
         
00040a e6e0      	ldi	Z_low,$60		; reload Z register with address $0060
         	
00040b 9111      	ld	Bx, Z+			; Load hour vallue for SRAM $0060 and inc Z-pointer
00040c e400      	ldi	Ax, $40			; Load Ax with proper display position and
00040d de28      	rcall	DispDECval
         
         
00040e e31a      	ldi	Bx, $3a			; set ":" in LCD	
00040f e402      	ldi	Ax, $42			;
000410 d2fd      	rcall	dispCHR
         
000411 e403      	ldi	Ax, $43			; Load Ax with new display position
000412 9111      	ld	Bx, Z+			; and load RTC minute vallue for SRAM address
000413 de22      	rcall	DispDECval		; $0061 and increase Z -pointer to $0062
         
000414 e405      	ldi	Ax, $45
000415 e210      	ldi	Bx, $20			; display a " " on the LCD
000416 d2f7      	rcall	dispCHR
         	
000417 8120      	ld	Cx, Z			; load Cx with day switch day vallue located on SRAM address
000418 502b      	subi	Cx, Tot_daypatrn
         
000419 f008      	brcs	goodSWval		; check for vallid vallue
00041a ef25      	ldi	Cx, $F5			; set to zero if vallue is not vallid
          goodSWval:
00041b 5f25      	subi	Cx, $F5			; else restore org vallue
00041c 9321      	st	Z+, Cx			; store day vallue to SRAM addres $0062 and ic Z-pointer  
         					; to $0063
         ;********************************************************************
         ;
         ; display selected switch days onto display
         ;
         ;********************************************************************
         
00041d 930f      	push	Ax
00041e 931f      	push	Bx
         
00041f 2f02      	mov	Ax, Cx			; load Ax with selected day information
000420 e415      	ldi	Bx, $45			; load Bx with start position on LCD
         
000421 dded      	rcall	disp_days
         
000422 911f      	pop	Bx
000423 910f      	pop	Ax
         
         ;********************************************************************
         ;
         ; Display three spaces on the display spacting at position 4D
         ;
         ;********************************************************************
         
000424 e40d      	ldi	Ax, $4D
000425 e013      	ldi	Bx, $03
000426 d0d7      	rcall	disp_space
         
          SW_readkey:
         ;********************************************************************
         ;
         ; Routine to check the pressed key command
         ;
         ;********************************************************************
         
000427 d33c      	rcall	input_keyread
         	
000428 3008      	cpi	Ax, plus_key		; check for "+" key pressed
000429 f411      	brne	SW_min_key
00042a 9533      	inc	Dx
00042b cfaa      	rjmp	SW_klokset
         
          SW_min_key:
00042c 3004      	cpi	Ax, min_key		; check for "-" key pressed
00042d f411      	brne	SW_retkey
00042e 953a      	dec	Dx
00042f cfa6      	rjmp	SW_klokset
         
          SW_retkey:
000430 3001      	cpi	Ax, return_key		; check for "Return" key pressed
000431 f409      	brne	SW_selectkey
000432 c0a0      	rjmp	SW_endset
         
          SW_selectkey:
000433 3002      	cpi	Ax, select_key		; check for "Select" key pressed
000434 f791      	brne	SW_readkey
         
000435 d2e3      	rcall	Key_released
         
000436 e00c      	ldi	Ax, Dispinit		; Set cursor on and Char at cursor
000437 6003      	ori	Ax, $03			; position to blink
000438 e010      	ldi	Bx, disp_CTRL
000439 d30b      	rcall	Disp_lcd
         	
00043a e6e0      	ldi	Z_low, $60		; Set Z register in start position 
00043b e0f0      	ldi	Z_high, $00		; data pointer in SRAM to manipulate
         
00043c 8120      	ld	Cx, Z			; Load Cx with SRAM data form Address $0060
         
         ;********************************************************************
         ;
         ; Start SW hour switch setting
         ;
         ;********************************************************************
         
          SW_start_hourset:
         
00043d d2db      	rcall	Key_released		; Check for no key's pressed.
         	
00043e 2f12      	mov	Bx, Cx			; display low nibble of vallue
00043f e400      	ldi	Ax, $40
000440 ddf5      	rcall	DispDECval
         
000441 2f02      	mov	Ax, Cx			; Load DEC clock vallue into Ax
000442 e010      	ldi	Bx, $00			; Load Bx with min DEC vallue ( decimal )
000443 e224      	ldi	Cx, $24			; Load Cx with max DEC vallue ( decimal )
         
000444 dcfa      	rcall	moddecval			 
000445 2f20      	mov	Cx, Ax			; Save new vallue into Cx
         
000446 3010      	cpi	Bx, $00
000447 f3a9      	breq	SW_start_hourset
         
000448 9321      	st	Z+, Cx			; Store the new hour vallue in SRAM position $0060
000449 8120      	ld	Cx, Z			; and inc Z-pointer to $0061
         					; load Cx with minute vallue
         
         ;********************************************************************
         ;
         ; Start SW minutes switch setting
         ;
         ;********************************************************************
         
          SW_start_minset:
         
00044a d2ce      	rcall	Key_released		; check for no key's pressed
         	
00044b 2f12      	mov	Bx, Cx			; display low nibble of vallue
00044c e403      	ldi	Ax, $43
00044d dde8      	rcall	DispDECval
         
00044e 2f02      	mov	Ax, Cx			; Load DEC clock vallue into Ax
00044f e010      	ldi	Bx, $00			; Load Bx with min DEC vallue
000450 e620      	ldi	Cx, $60			; Load Cx with max DEC vallue
         
000451 dced      	rcall	moddecval			 
000452 2f20      	mov	Cx, Ax			; Save new vallue into Cx
         
000453 3010      	cpi	Bx, $00
000454 f3a9      	breq	SW_start_minset
         
000455 9321      	st	Z+, Cx			; Save new Min. vallue into SRAM location $0061
000456 8120      	ld	Cx, Z			; and inc Z-pointer to location $0062
         					; load Cx with selected day vallue
         
         ;********************************************************************
         ;
         ; Start SW day switch setting
         ;
         ;********************************************************************
         
          SW_switchday:
         
000457 d2c1      	rcall	Key_released		; check for no key's pressed
         
000458 2f02      	mov	Ax, Cx			; Load Ax with selected day info
000459 e415      	ldi	Bx, $45			; Load Bx with display location
00045a ddb4      	rcall	disp_days
         
00045b 8100      	ld	Ax, Z			; Load Ax with SRAM value ( address  $0062 )
00045c e010      	ldi	Bx, $00			; Load Bx with min vallue
00045d e02b      	ldi	Cx, Tot_daypatrn	; Load Cx with number of day bit steams
         					; defined in DEFDATA.ASM pointer dayinfo
00045e dd16      	rcall	modHEXval		; modify dec val
00045f 8300      	st	Z, Ax			; sav new value to SRAM location $0062
000460 2f20      	mov	Cx, Ax					
000461 3010      	cpi	Bx, $00
000462 f3a1      	breq	SW_switchday
         
         ;*****************************************************************************
         ;
         ; START OFF SCREEN TWO MODIFICATION
         ;
         ;*****************************************************************************
         ;
         ; Routine to display current Channel and status information.
         ;
         ;***************************************************************************** 
         
000463 e001      	ldi	Ax, Dispclear		; Set display cursor function
000464 e010      	ldi	Bx, disp_CTRL
000465 d2df      	rcall	disp_lcd
         	
000466 e00a      	ldi	Ax, low(chanstate)	; Print the defined message on the LCD
000467 e010      	ldi	Bx, high(chanstate)
000468 e020      	ldi	Cx, $00			; screen
000469 d2bf      	rcall	Str2disp
         
00046a 9101      	ld	Ax, Z+			; load Ax with SRAM address $0062 ( day information ) and
00046b 8100      	ld	Ax, Z			; inc Z-pointer to $0063. Load Ax with channel information
00046c 7f00      	andi	Ax, $F0			; delete channel state information
00046d 9502      	swap 	Ax
00046e dcb0      	rcall	HEX2DEC
         	
00046f 2f10      	mov	Bx, Ax
000470 e40b      	ldi	Ax, $4B
000471 ddc4      	rcall	DispDECval
         	
         ;*****************************************************************************
         ;
         ; Start for channel status information.
         ;
         ;	located in the LSB : "1" is channel on, "0" is channel off
         ;
         ;*****************************************************************************
         
          Start_channelstat:
         
000472 d2a6      	rcall	Key_released		; Check for no key's pressed
         
000473 e422      	ldi	Cx, $42			; Load display position into Cx reg.
         
000474 8100      	ld	Ax, Z			; Load Ax with SRAM position $0063 containing
         					; channel and channelstatus information.
000475 ff00      	sbrs	Ax, 0			; check if bit 0 is set or clear indication
000476 c004      	rjmp	channeloff
         
000477 e10e      	ldi	Ax, low(on)
000478 e010      	ldi	Bx, high(on)
000479 d2af      	rcall	Str2disp
00047a c003      	rjmp	end_statecheck
         
          channeloff:
         
00047b e000      	ldi	Ax, low(off)
00047c e010      	ldi	Bx, high(off)
00047d d2ab      	rcall	Str2disp
         
          end_statecheck:
         
         
00047e d2e5      	rcall	input_keyread		; Read key's.
         
00047f 3008      	cpi	Ax, plus_key		; check for "+" key.
000480 f421      	brne	minkeycheck
         
000481 8100      	ld	Ax, Z			; If "+" key is selected then
000482 6001      	sbr	Ax, 1			; Set LSB in SRAM location
000483 8300      	st	Z, Ax
000484 cfed      	rjmp	Start_channelstat	; loop again
         
          minkeycheck:
000485 3004      	cpi	Ax, min_key		; check for "-" key pressed.
000486 f421      	brne	nextkeycheck
         	
000487 8100      	ld	Ax, Z			; If "-" key is selected then
000488 7f0e      	cbr	Ax, 1			; Reset LSB in SRAM location
000489 8300      	st	Z, Ax
00048a cfe7      	rjmp	Start_channelstat	; loop agian
         
          nextkeycheck:
00048b 3002      	cpi	Ax, select_key		; Check for "Select" key.
00048c f729      	brne	Start_channelstat	; if not pressed then loop again
         
         ;********************************************************************
         ;
         ; Start for channel select routine
         ;
         ;	located in the high nibble
         ;
         ;********************************************************************
         
          start_channelsel:
         
00048d d28b      	rcall	Key_released		; Check for no key pressed
         
00048e 8100      	ld	Ax, Z			; Load Ax with Channel selected information
00048f 7f00      	andi	Ax, $F0			; delete channel state information
000490 9502      	swap 	Ax			; move info to low nibble
000491 2f20      	mov	Cx, Ax			; and save it into Reg. Cx
         	
000492 dc8c      	rcall	HEX2DEC			; convert HEX channel nr. info DEC value
000493 2f10      	mov	Bx, Ax			; and move it into Bx
000494 e40b      	ldi	Ax, $4B			; Load display location into Ax reg.
000495 dda0      	rcall	DispDECval
         
         ;******** CHECK FOR PRINTING SPACE OF STAR **********
         
000496 2f02      	mov	Ax, Cx			; Load selected channel number into Ax
000497 d16d      	rcall	checkIOmod
         
000498 3000      	cpi	Ax, $00			; Ax = "00" is device is NOT available
000499 f421      	brne	Nodev
         	
00049a e40e      	ldi	Ax, $4E
00049b e210      	ldi	Bx, $20			; display " " to indicate channel not available
00049c d271      	rcall	dispCHR	
00049d c003      	rjmp	enddevcheck
         	
          Nodev:
00049e e40e      	ldi	Ax, $4E
00049f e21a      	ldi	Bx, $2A			; display "*" to indicate channel not available
0004a0 d26d      	rcall	dispCHR		
         
          enddevcheck:
         
0004a1 2f02      	mov	Ax, Cx			; Load Ax with current selected channel
0004a2 e010      	ldi	Bx, $00			; Load Bx with lowest channel number
0004a3 e02f      	ldi	Cx, max_SWchannels	; Load max channel number
0004a4 9523      	inc	Cx			; increase Cx by one the get 16 channels 
0004a5 dccf      	rcall	modHEXval
         
0004a6 931f      	push	Bx			; save last pressed key information on stack
         					; restore channel inforamtion
0004a7 9502      	swap	Ax
0004a8 8110      	ld	Bx, Z			; load old data from RAM
0004a9 701f      	andi	Bx, $0F
0004aa 2b10      	or	Bx, Ax			; replace old inforamtion
0004ab 8310      	st	Z, Bx			; store new data in SRAM
         
0004ac 911f      	pop	Bx			; restore last pressed key information
0004ad 3010      	cpi	Bx, $00			; check for end of modification
0004ae f2f1      	breq	start_channelsel
         
         ;********************************************************************
         ;
         ; Start of new setting save routine
         ;
         ;********************************************************************
         
0004af d269      	rcall	Key_released
         
0004b0 e00c      	ldi	Ax, Dispinit		; Set cursor on and Char at cursor
0004b1 e010      	ldi	Bx, disp_CTRL
0004b2 d292      	rcall	Disp_lcd
         
0004b3 e60b      	ldi	Ax, low(cvsave)		; Set the save message on the display
0004b4 e010      	ldi	Bx, high(cvsave)
0004b5 e420      	ldi	Cx, $40			; ( defined in Cx )
0004b6 d272      	rcall	Str2disp
         
          SWsavekey:
0004b7 d2ac      	rcall	input_keyread		; Check for no key's pressed.
         
0004b8 3008      	cpi	Ax, plus_key		; check for "+" key
0004b9 f4b1      	brne	SW_saveminkey
         
0004ba e6e0      	ldi	Z_low, $60		; Set Z register in start position SRAM data
0004bb e0f0      	ldi	Z_high, $00
         
0004bc 9110 0100 	lds	Bx, $0100		; Load EEPROM start adres for SRAM location $0100
0004be e020      	ldi	Cx, $00			; load Cx with "00" for starting 2-comp calcutation
         
          SW_save_lus:
         
0004bf 9101      	ld	Ax, Z+			; Store Hour, Min, Days and Temp
0004c0 0f20      	add	Cx, Ax			; value into EEPROM
0004c1 932f      	push	Cx
0004c2 2f20      	mov	Cx, Ax
0004c3 ea02      	ldi	Ax, X24C02
         
0004c4 dbd4      	rcall	I2C_regstore		; Store vallue (Ax) into EEPROM at address Bx
0004c5 d23b      	rcall	delay_5mS		; 5mS delay to let the EEPROM save the value
0004c6 912f      	pop	Cx
0004c7 9513      	inc	Bx
         
0004c8 36e4      	cpi	Z_low, $64		; check for end of Save 
0004c9 f7a9      	brne	SW_save_lus
         
0004ca 9520      	com	Cx			; Calculate 2 Comp of new data
0004cb 5f2f      	subi	Cx, $FF
0004cc ea02      	ldi	Ax, X24C02
0004cd dbcb      	rcall	I2C_regstore		; Store into EEPROM	
0004ce d232      	rcall	delay_5mS		; 5 mS delay to let the EEPROM save the value
0004cf ceff      	rjmp	start_SWtime_set
         
          SW_saveminkey:
0004d0 3004      	cpi	Ax, min_key		; Check for "-" key
0004d1 f729      	brne	SWsavekey
0004d2 cefc      	rjmp	start_SWtime_set
         
          SW_endset:
         
0004d3 d30e      	rcall	SWswitchtime		; create switch time array
         
0004d4 9508      	ret
         
         
         
         ;***************************************************************************
         ;
         ; Scans for all PCF8574 and PCF8574A chips on the I2C bus and set all output's to "0"
         ; if I2C device is pressent ont the bus.
         ;
         ;***************************************************************************
         
          ResetSWports:
         
0004d5 930f      	push	Ax			; Save registers to stack
0004d6 931f      	push	Bx
0004d7 932f      	push	Cx
         
0004d8 e010      	ldi	Bx, $00			; set counter to scan eight 8574 device's
0004d9 e400      	ldi	Ax, PCF8574_SWL		; load startaddres first 8574 in Ax register
0004da 2f20      	mov	Cx, Ax
         
          Startresetport:
         
0004db 930f      	push	Ax			; Save current I2C address on stack
0004dc 9513      	inc	Bx
0004dd db3e      	rcall	I2Cstart		; send I2C start command on I2C bus
0004de db45      	rcall	I2Csend			; send I2C device address on the bus
         
0004df ff00      	sbrs	Ax, 0			; check for aknowledge from device
0004e0 c004      	rjmp	SWnext8574		; if not, check next I2C device address
         
0004e1 e000      	ldi	Ax, $00			; if acknowledge then reset all eight pin's
0004e2 db41      	rcall	I2Csend
         	
0004e3 ff00      	sbrs	Ax, 0
0004e4 dbc2      	rcall	no_I2Cresponce		; if no responce the I2C error on display
         
          SWnext8574:
         
0004e5 db29      	rcall	I2Cstop			; Send I2c stop sequence on the bus
0004e6 910f      	pop	Ax			; Restore I2C address from stack
0004e7 3018      	cpi	Bx, $08			; check for last device address
0004e8 f011      	breq	HighReset
         	
0004e9 5f0e      	subi	Ax, $FE			; add two to I2C address to get next
0004ea cff0      	rjmp	Startresetport		; device address
         	
          HighReset:	
         
0004eb 3720      	cpi	Cx, PCF8574_SWH
0004ec f021      	breq	endreset
         	
0004ed e700      	ldi	Ax, PCF8574_SWH		; load Ax with I2C start address
0004ee e010      	ldi	Bx, $00
0004ef 2f20      	mov	Cx, Ax
0004f0 cfea      	rjmp	StartResetport
         	
          endreset:	
         	
0004f1 912f      	pop	Cx
0004f2 911f      	pop	Bx
0004f3 910f      	pop	Ax
         
0004f4 9508      	ret
         
         ;*********************************************************************
         ;
         ; Calculate programm memory address vallue for the address defined
         ; in Ax ( lowbyte ) and Bx ( highbyte ) and increase address with
         ; vallue defined in Cx
         ;
         ;	Return	: Ax = lowbyte
         ;		  Bx = Highbyte
         ;		  Cx = offset variable
         ;
         ;*********************************************************************
         
          calcpointer:
         
0004f5 0f11      	lsl	Bx			; Shift high byte one bit to the left
0004f6 9488      	clc				; to dubble vallue and clear the carry bit
0004f7 1f00      	rol	Ax			; rotate Ax to the left to doubble the vallue
0004f8 f408      	brcc	no_bitoverflow		; Check for overflow and set LSB in Bx 
0004f9 9513      	inc	Bx			; if there is an overflow
         
          no_bitoverflow:
0004fa 0f02      	add	Ax, Cx			; add Cx to the calculated address and add one
0004fb f408      	brcc	no_addoverflow		; to high byte address is caary is set.
0004fc 9513      	inc	Bx
         
          no_addoverflow:	
         	
0004fd 9508      	ret
         
         ;*********************************************************************
         ;
         ; Display a serie of spaces on the display from location Ax with a
         ; total of Bx.
         ;
         ;*********************************************************************
         
          disp_space:
         
0004fe 932f      	push	Cx
0004ff 2f21      	mov	Cx, Bx
         
          next_space:
         
000500 e210      	ldi	Bx, $20			; load [space] ASCII vallue into Bx
000501 930f      	push	Ax
000502 d20b      	rcall	dispCHR			; and display it at location defined in Ax
000503 910f      	pop	Ax
         
000504 9503      	inc	Ax
000505 952a      	dec	Cx
000506 3020      	cpi	Cx, $00
000507 f7c1      	brne	next_space
         
000508 912f      	pop	Cx
         
000509 9508      	ret	
         	
         	
         ;*******************************************************************
         ;
         ; Routine to check witch 8574(A) modules are available on I2C bus
         ;
         ;*******************************************************************
         	
          SWmod_press :
         
00050a 930f      	push	Ax			; Save Reg. Ax, Bx and Cx on stack
00050b 931f      	push	Bx
00050c 932f      	push	Cx
         
00050d e010      	ldi	Bx, $00			; Init total unit counter
00050e e020      	ldi	Cx, $00			; Init available module bit's to "0"
         	
00050f e400      	ldi	Ax, PCF8574_SWL		; Load I2C address to check
         
          Checkifthere:
         
000510 930f      	push	Ax			; Save current I2C address on stack
000511 931f      	push	Bx
         
000512 db09      	rcall	I2Cstart		; send I2C start command on I2C bus
000513 db10      	rcall	I2Csend			; send I2C device address on the bus
         
000514 ff00      	sbrs	Ax, 0			; check for aknowledge from device
000515 c004      	rjmp	no_8574there		; if not, check next I2C device address
         
000516 9408      	sec
000517 9527      	ror	Cx			; Shift "1" in to indicate module available.
000518 daf6      	rcall	I2Cstop
000519 c002      	rjmp	Nextmodule
         	
          no_8574there:
         
00051a 9488      	clc				; Shift "0" in to indicate module NOT available
00051b 9527      	ror	Cx
         
          Nextmodule:
         
00051c 911f      	pop	Bx			; Reload Bx with device counter val
00051d 910f      	pop	Ax			; Reload current I2C address in Ax reg.	
00051e 5f0e      	subi	Ax, $FE			; Increase Ax by 2 to get next I2C address	
         	
00051f 9513      	inc	Bx			; Increase module check counter
000520 3018      	cpi	Bx, $08			; Check for last module
000521 f009      	breq	high_module	
         	
000522 cfed      	rjmp	Checkifthere
         
          high_module:
         
000523 3800      	cpi	Ax, 0b10000000		; Check for end of test
000524 f029      	breq	end_IOtest		; Jump out if last address
         	
000525 e700      	ldi	Ax, PCF8574_SWH		; Load Ax witn PCF8574A base address
000526 e010      	ldi	Bx, $00			; Clear mod counter
000527 2ee2      	mov	SWmod_L, Cx		; Save found modules in Reg.
000528 e020      	ldi	Cx, $00
         	
000529 cfe6      	rjmp	checkifthere
         	
         	
          end_IOtest:	
         
00052a 2ef2      	mov	SWmod_H, Cx
         	
00052b 912f      	pop	Cx
00052c 911f      	pop	Bx
00052d 910f      	pop	Ax
         
00052e 9508      	ret
         ;*******************************************************************
         ;
         ; Routine to display the available modules on I2C bus
         ;
         ;*******************************************************************
         	
          module_list:
         
00052f e001      	ldi	Ax, Dispclear		; Load display clear command in Ax reg.
000530 e010      	ldi	Bx, disp_CTRL		; Select display control mode
000531 d213      	rcall	disp_lcd
         
000532 ef01      	ldi	Ax, low(PCF8574)	; write "PCF8574" to the display
000533 e010      	ldi	Bx, high(PCF8574)
000534 e020      	ldi	Cx, $00			; starting at the 1st line
000535 d1f3      	rcall	Str2disp
         	
000536 ef01      	ldi	Ax, low(PCF8574)	; write "PCF8574" to the display
000537 e010      	ldi	Bx, high(PCF8574)
000538 e420      	ldi	Cx, $40
000539 d1ef      	rcall	Str2disp
         	
00053a e404      	ldi	Ax, $44			; Load new display position into Ax rig.
00053b e411      	ldi	Bx, $41			; and load ASCII "A" info Bx
00053c d1d1      	rcall	dispCHR			; and go display the CHR.
         	
         
00053d e008      	ldi	Ax, $08			; Load Ax with display position
00053e e028      	ldi	Cx, $08			; Load Cx as cycle counter
00053f 2d1e      	mov	Bx, SWmod_L		; Load Bx with available PCF8574 bitstream
         
          loop2nextmod:
         
000540 9488      	clc				; clear carry flag
000541 9517      	ror	Bx			; rotate Bx reg. 
000542 931f      	push	Bx
000543 f418      	brcc	nomod			; Branch if carry is clear
         	
000544 e21a      	ldi	Bx, $2A			; load ASCII "*"
000545 d1c8      	rcall	dispCHR
000546 c002      	rjmp	outnow
         	
          nomod:
         
000547 e21d      	ldi	Bx, $2D			; Load ASCII "-"
000548 d1c5      	rcall	dispCHR
         	
          outnow:
000549 911f      	pop	Bx
00054a 9503      	inc	Ax
00054b 952a      	dec	Cx
00054c 3020      	cpi	Cx, $00
00054d f791      	brne	loop2nextmod
00054e 3500      	cpi	Ax, $50	
00054f f021      	breq	readnextkey
         	
000550 e408      	ldi	Ax, $48
000551 e028      	ldi	Cx, $08
000552 2d1f      	mov	Bx, SWmod_H
000553 cfec      	rjmp	loop2nextmod
         
         	
          readnextkey:	
000554 d20f      	rcall	input_keyread
000555 3001      	cpi	Ax, return_key		; Check for reset key pressed
000556 f7e9      	brne	readnextkey	
         
         	
000557 d1c1      	rcall	key_released
         	
000558 9508      	ret
         	
         ;*********************************************************************
         ;
         ; Send time list to RS-232 port.
         ;	Ax = Low byte array address
         ;	Bx = High byte array address
         ; Return : -
         ;
         ;*********************************************************************	
         		
          SendSWlist:
         
000559 93ff      	push	Z_high		; Save registers on stack
00055a 93ef      	push	Z_low
00055b 932f      	push	Cx
00055c 931f      	push	Bx
00055d 930f      	push	Ax
         	
00055e 2fe0      	mov	Z_low, Ax	; load memory address into Z register
00055f 2ff1      	mov	Z_high, Bx
000560 9121      	ld	Cx, Z+
         
          Start_sendlist:	
000561 3020      	cpi	Cx, $00		; Check for last timer setting send
000562 f181      	breq	end_sendlist
000563 952a      	dec	Cx		; Decrease loop counter by one
000564 932f      	push	Cx
         	
000565 9101      	ld	Ax, Z+		; Load Ax with SW hour setting
000566 dcde      	rcall	SendDECval	; Send it to the RS-232 port.
         	
000567 e30a      	ldi	Ax, $3A		; Load ":" ASCII value
000568 dc94      	rcall	SendCHR		; and send it to RS-232 port
         	
000569 9101      	ld	Ax, Z+		; Load Ax with Sw minute setting
00056a dcda      	rcall	SendDECval	; send to the RS-232 port
         	
00056b e200      	ldi	Ax, $20
00056c dc90      	rcall	SendCHR
         	
00056d 9101      	ld	Ax, Z+		; load Ax with switch day information
00056e 93ef      	push	Z_low
00056f 93ff      	push	Z_high
000570 2f20      	mov	Cx, Ax
000571 e30c      	ldi	Ax, low(dayinfo)
000572 e018      	ldi	Bx, high(dayinfo)
000573 df81      	rcall	calcpointer
000574 2fe0      	mov	Z_low, Ax
000575 2ff1      	mov	Z_high, Bx
         	
000576 95c8      	lpm
000577 2d00      	mov	Ax, R0
         	
000578 91ff      	pop	Z_high
000579 91ef      	pop	Z_low
         	
00057a e018      	ldi	Bx, $08		; Load Bx as cycle counter
         
          Nextdaybit:	
00057b 951a      	dec	Bx		; decrease loop counter
00057c 3010      	cpi	Bx, $00		; Check if loop is complete
00057d f059      	breq	Enddaysend
         	
00057e 9506      	lsr	Ax		; shift Ax one bit right
00057f 930f      	push	Ax
000580 f020      	brcs	dayvalid
         	
000581 e20d      	ldi	Ax, $2D		; Load Ax with ASCII "-"
000582 dc7a      	rcall	SendCHR
000583 910f      	pop	Ax
000584 cff6      	rjmp	Nextdaybit
          Dayvalid:
         
000585 e20a      	ldi	Ax, $2A		; Load Ax with ASCII "*"
000586 dc76      	rcall	SendCHR		; and send CHR to RS-232 port
000587 910f      	pop	Ax
000588 cff2      	rjmp	Nextdaybit
         		 
          Enddaysend:
         	
000589 e200      	ldi	Ax, $20		; Send "space" to the RS-232 port
00058a dc72      	rcall	SendCHR
         	
00058b 9101      	ld	Ax, Z+
00058c dcc4      	rcall	send_chanstat
         		
00058d e00a      	ldi	Ax, $0A
00058e dc6e      	rcall	SendCHR
00058f e00d      	ldi	Ax, $0D
000590 dc6c      	rcall	SendCHR
         
000591 912f      	pop	Cx
000592 cfce      	rjmp	Start_sendlist
         			
         			
          end_sendlist:			
         
000593 910f      	pop	Ax
000594 911f      	pop	Bx
000595 912f      	pop	Cx
000596 91ef      	pop	Z_low
000597 91ff      	pop	Z_high
         
         
000598 9508      	ret		
         	
         ;************************************************************************
         ;
         ; Routine to set or reset I/O module connected to SW klok bus 
         ;
         ;************************************************************************
         
          manual_set:
         
000599 930f      	push	Ax
00059a 931f      	push	Bx
00059b 932f      	push	Cx
         
00059c e001      	ldi	Ax, Dispclear		; Set display cursor function
00059d e010      	ldi	Bx, disp_CTRL
00059e d1a6      	rcall	disp_lcd
         	
00059f e00a      	ldi	Ax, low(chanstate)	; Print the defined message on the LCD
0005a0 e010      	ldi	Bx, high(chanstate)
0005a1 e020      	ldi	Cx, $00			; screen
0005a2 d186      	rcall	Str2disp
         	
0005a3 e010      	ldi	Bx, $00			; display channel number on display.
0005a4 e40b      	ldi	Ax, $4B
0005a5 dc90      	rcall	dispDECval
         
0005a6 e00c      	ldi	Ax, Dispinit		; Set cursor on and Char at cursor
0005a7 6003      	ori	Ax, $03			; position to blink
0005a8 e010      	ldi	Bx, disp_CTRL
0005a9 d19b      	rcall	Disp_lcd
         	
0005aa e000      	ldi	Ax, 0b00000000		; Load Ax with channel "off" state.
         	
          disp_statagain:
         
0005ab 930f      	push	Ax			; save channel status on stack
         	
0005ac e422      	ldi	Cx, $42			; Load display position into Cx reg.
         
0005ad ff00      	sbrs	Ax, 0			; check if bit 0 is set or clear indication
0005ae c004      	rjmp	disp_channeloff
         
0005af e10e      	ldi	Ax, low(on)
0005b0 e010      	ldi	Bx, high(on)
0005b1 d177      	rcall	Str2disp
0005b2 c003      	rjmp	end_statedisp
         
          disp_channeloff:
         
0005b3 e000      	ldi	Ax, low(off)
0005b4 e010      	ldi	Bx, high(off)
0005b5 d173      	rcall	Str2disp
         
          end_statedisp:
         
0005b6 d162      	rcall	Key_released		; Check for no key's pressed
         
0005b7 d1ac      	rcall	input_keyread		; Read key's.
         
0005b8 3008      	cpi	Ax, plus_key		; check for "+" key.
0005b9 f419      	brne	stat_minkeycheck
         
0005ba 910f      	pop	Ax
0005bb 6f0f      	ori	Ax, 0b11111111
         
0005bc cfee      	rjmp	disp_statagain		; loop again
         
          stat_minkeycheck:
0005bd 3004      	cpi	Ax, min_key		; check for "-" key pressed.
0005be f419      	brne	stat_defkeycheck
         
0005bf 910f      	pop	Ax
0005c0 2700      	clr	Ax
         	
0005c1 cfe9      	rjmp	disp_statagain		; loop again
         	
          stat_defkeycheck:
         
0005c2 3002      	cpi	Ax, select_key		; check for select key is pressed
0005c3 f791      	brne	end_statedisp
         
         ; current stack address contains channal status !!!!!!!
         	
0005c4 e020      	ldi	Cx, $00			; load cx with first module number
0005c5 932f      	push	Cx
         
          select_chan:
         
0005c6 d152      	rcall	Key_released		; Check for no key's pressed.
         	
0005c7 912f      	pop	Cx
0005c8 2f12      	mov	Bx, Cx			; move current mod number into Bx
0005c9 e40b      	ldi	Ax, $4B			; Load disp position into Ax
0005ca dc6b      	rcall	DispDECval		; and display vallue
         	
0005cb 932f      	push	Cx			; save current channel number to stack
0005cc 2f02      	mov	Ax, Cx
         
         
         ; check for printing channel available or not
         	
0005cd db5e      	rcall	DEC2HEX			; convert DEC vallue into HEX vallue
0005ce d036      	rcall	checkIOmod
0005cf 2f10      	mov	Bx, Ax
         	
0005d0 e40e      	ldi	Ax, $4E			; Load display pos. into Ax reg.
0005d1 3010      	cpi	Bx, $00
0005d2 f419      	brne	man_dispstar	
         	
0005d3 e210      	ldi	Bx, $20			; load ASCII " "
0005d4 d139      	rcall	dispCHR
0005d5 c002      	rjmp	check_manend
         	
          man_dispstar:
         
0005d6 e21a      	ldi	Bx, $2A			; Load ASCII "*"
0005d7 d136      	rcall	dispCHR
         	
          check_manend:
         	
0005d8 912f      	pop	Cx	
0005d9 2f02      	mov	Ax, Cx			; Load DEC channel vallue into Ax
0005da e010      	ldi	Bx, $00			; Load Bx with min DEC vallue ( decimal )
0005db e126      	ldi	Cx, $16			; Load Cx with max DEC vallue ( decimal )
         
0005dc db62      	rcall	moddecval			 
0005dd 2f20      	mov	Cx, Ax			; Save new vallue into Cx
0005de 932f      	push	Cx			; ans store on stack again
         
0005df 3010      	cpi	Bx, $00
0005e0 f329      	breq	select_chan
         	
0005e1 e008      	ldi	Ax, low(schakel)	; display text on display at pos. 40
0005e2 e011      	ldi	Bx, high(schakel)	; defined in DATADEF.ASM
0005e3 e420      	ldi	Cx, $40
0005e4 d144      	rcall	Str2disp
         	
0005e5 d133      	rcall	Key_released
0005e6 d17d      	rcall	input_keyread		; Read key's.
         
0005e7 3008      	cpi	Ax, plus_key		; check for "+" key.
0005e8 f491      	brne	no_modchannel
         	
0005e9 910f      	pop	Ax			; load channel number from stack
0005ea 2f20      	mov	Cx, Ax
0005eb 9522      	swap	Cx			; Cx contains channel nr. in high nibble
0005ec db3f      	rcall	DEC2HEX			; and convert it into HEX vallue
0005ed 911f      	pop	Bx			; load wanted channel state from stack
0005ee 7011      	andi	Bx, 0b00000001
0005ef 2b21      	or	Cx, Bx			; LSB Cx contains channel stat
0005f0 dbb1      	rcall	sendtime		; Send current time/date to RS-232 port
         	
0005f1 930f      	push	Ax
0005f2 2f02      	mov	Ax, Cx
0005f3 dc5d      	rcall	send_chanstat
         	
0005f4 e00d      	ldi	Ax, $0D			; send linefeed to RS-232 port
0005f5 dc07      	rcall	sendCHR
0005f6 e00a      	ldi	Ax, $0A			; send CR to RS-232 port
0005f7 dc05      	rcall	sendCHR
         	
0005f8 910f      	pop	Ax
0005f9 d226      	rcall	activate_channel	
         		
0005fa c002      	rjmp	end_manualset
         	
          no_modchannel:
         
0005fb 910f      	pop	Ax			; pop two byte from stack to remove
0005fc 910f      	pop	Ax			; two unused byte from stack.
         
         
          end_manualset:
         
0005fd e00c      	ldi	Ax, Dispinit		; Set cursor off
0005fe e010      	ldi	Bx, disp_CTRL
0005ff d145      	rcall	Disp_lcd
         	
000600 d118      	rcall	Key_released
         	
000601 912f      	pop	Cx
000602 911f      	pop	Bx
000603 910f      	pop	Ax
         	
000604 9508      	ret
         	
         ;*****************************************************************
         ;
         ; Routine to check if selected channel is available
         ;
         ;	Ax = HEX number of selected channel
         ; Return :
         ;	Ax= 1 if available
         ;	Ax =0 if NOT available
         ;
         ;****************************************************************
         
          checkIOmod:
         
000605 931f      	push	Bx
000606 932f      	push	Cx
         
000607 fd03      	sbrc	Ax, 3			; check for 8474/8474AA
000608 c007      	rjmp	man_high
         	
000609 2d1e      	mov	Bx, SWmod_L		; Load Bx with 8474 available bit stream
         			
00060a e021      	ldi	Cx, $01			; Set LSB of Cx register	
          check_manlow:	
00060b 3000      	cpi	Ax, $00			; Check Ax for 0 vallue
00060c f059      	breq	end_manbitsetH		; if so, jump out
00060d 950a      	dec	Ax			; decrease Ax
00060e 0f22      	lsl	Cx			; Rotale Cx one bit to the left
00060f cffb      	rjmp	check_manlow
         	
          man_high:
000610 2d1f      	mov	Bx, SWmod_H
000611 7007      	andi	Ax, 0b00000111
000612 e021      	ldi	Cx, $01			; Set LSB of Cx register	
         	
          check_manhigh:	
000613 3000      	cpi	Ax, $00			; Check Ax for 0 vallue
000614 f019      	breq	end_manbitsetH		; if so, jump out
000615 950a      	dec	Ax			; decrease Ax
000616 0f22      	lsl	Cx			; Rotale Cx one bit to the left
000617 cffb      	rjmp	check_manhigh
         
          end_manbitsetH:	
000618 2312      	and	Bx, Cx
000619 2f01      	mov	Ax, Bx
         	
00061a 912f      	pop	Cx
00061b 911f      	pop	Bx
         
         
00061c 9508      	ret         
         ;***************************************************************************
         ;
         ; Interrupt routine when TIMER 0 Overflow occurs
         ;
         ;***************************************************************************
         
          TIM0_OVF:
         
00061d 930f      	push	Ax				; Save Ax and Bx register to stack
         
00061e e800      	ldi	Ax, Timer0			; load TCNT0 reg. of timer 0 with init value
00061f bf02      	out	TCNT0, Ax
         
000620 910f      	pop	Ax				; Restore Ax register value
         
000621 9518      	reti
         
         ;***************************************************************************
         ;
         ; Interrupt routine when TIMER 1 Overflow occurs
         ;
         ;***************************************************************************
         
          TIM1_OVF:
         
000622 ef7f      	ldi	Disp_refresh, $FF		; Load disp_refresh register with $FF to jump
         						; out of 0.9 Sec delay lus.
000623 930f      	push	Ax				; and save Ax and Bx register to stack.
000624 931f      	push	Bx
         
000625 e304      	ldi	Ax, Timer1H			; load timer counter register with $CA80
000626 ed13      	ldi	Bx, Timer1L			; for 0.9 sec INT generation
000627 bd0d      	out	TCNT1H, Ax
000628 bd1c      	out	TCNT1L, Bx
         
000629 911f      	pop	Bx				; restore org. value's Ax and Bx from stack
00062a 910f      	pop	Ax
         
00062b 9518      	reti
         
          RESET:
         ;***************************************************************************
         ;
         ; Set all I/O ports of the microcontroller to the proper vallue's
         ;
         ;***************************************************************************
         
00062c e507      	ldi	Ax, Stack_low		; Init Stack pointer. Set to highest
00062d bf0d      	out	spl, Ax			; SRAM location ( 025F ) for 8515 without ext. SRAM
00062e e002      	ldi	Ax, Stack_high
00062f bf0e      	out	sph, Ax
         
000630 ef00      	ldi	Ax ,0b11110000		; Set PortB[7:4] to output and PortB
000631 bb07      	out	DDRB, Ax		; [3:0] to input
         					
000632 eb0f      	ldi	Ax, 0b10111111		; Set PortD to output except for bit 6. Wil be used
000633 bb01      	out	DDRD, Ax		; as I2C data input line
         
000634 ef0f      	ldi	Ax, 0b11111111		; Set Port A and PortC to output.
000635 bb0a      	out	DDRA, Ax		; Used are display data bus
000636 bb04      	out	DDRC, Ax		; used as display control signal bus.
         
000637 e000      	ldi	Ax, $00			; set all output Port's to "0" level
000638 bb0b      	out	PortA, Ax
000639 bb08      	out	PortB, Ax 
00063a bb05      	out	PortC, Ax
00063b bb02      	out	PortD, Ax
         
00063c e107      	ldi	Ax, 23			; Set UBRR to 9600 Baud using 3.6864 MHz clock
00063d b909      	out	UBRR, Ax		; Serial port used to send switch off/on data
00063e e008      	ldi	Ax, 0b00001000		; to terminal
00063f b90a      	out	UCR, Ax			; Enable transmitter
         
         ;*********************************************************************
         ;	
         ; Init Timer 0 
         ;
         ;*********************************************************************
         
000640 e002      	ldi	Ax, $02			; Set timer0 prescaler to CK/8
000641 bf03      	out	TCCR0, Ax
         
000642 e800      	ldi	Ax, Timer0		; and set timer0 value to initvalue
000643 bf02      	out	TCNT0, Ax 
         
         ;*********************************************************************	
         ;
         ; Init Timer 1 
         ; 
         ;*********************************************************************
         
000644 e003      	ldi	Ax, $03
000645 bd0e      	out	TCCR1B, Ax		; Set timer 1 prescaler to CK/64
000646 e000      	ldi	Ax, $00
000647 bd0f      	out	TCCR1A, Ax		; Disable PWM mode and I/O Pin connections
         
000648 e304      	ldi	Ax, Timer1H		; load timer counter register with $CA80
000649 ed13      	ldi	Bx, Timer1L		; for 0.9 sec INT generation
00064a bd0d      	out	TCNT1H, Ax
00064b bd1c      	out	TCNT1L, Bx
         
00064c e800      	ldi	Ax, 0b10000000		; Enable timer 1 overflow int. and	
00064d bf09      	out	TIMSK, Ax		; disable timer 0 overflow int
         
00064e 9478      	sei				; Enable global INT.
         
00064f e080      	ldi	I2Cstatreg, $00		; load I2C status register with zero
         
000650 d9be      	rcall	I2Cstop			; generate I2C stop function
000651 d0a2      	rcall	delayfunc		; delay
000652 d9c4      	rcall	initI2Cbus		; initializa I2C init function
000653 d0a0      	rcall	delayfunc		; delay
         
         ;***************************************************************************
         ;
         ;* Initialise LCD display
         ;
         ;***************************************************************************
         
000654 e00c      	ldi	Ax, Dispinit		; Set display cursor function
000655 e010      	ldi	Bx, disp_CTRL		; and load dipslay control mode.
000656 d0ee      	rcall	disp_lcd		; init display via I/O port.
         
000657 e308      	ldi	Ax, Eightbitinit	; Set display in 8-Bit data mode
000658 d0ec      	rcall	disp_lcd		; init display via I/O port'
         
         ;***************************************************************************
         ;
         ;* Init PCF8583 RTC clock chip
         ;
         ;***************************************************************************
         
000659 d9c2      	rcall	I2Cstart		; I2C start function
00065a ea00      	ldi	Ax, PCF8583		; select I2C device clock device
00065b d9c8      	rcall	I2Csend			; send adres to bus
         	
00065c ff00      	sbrs	Ax, 0			; check next adres is there is no acknowledge
00065d da49      	rcall	no_I2Cresponce
         
00065e e000      	ldi	Ax, $00			; Goto register 0
00065f d9c4      	rcall	I2Csend
         
000660 ff00      	sbrs	Ax, 0
000661 da45      	rcall	no_I2Cresponce
         	
000662 e000      	ldi	Ax, PCF8583_CTRL	; initialize clock chip
000663 d9c0      	rcall	I2Csend
         
000664 ff00      	sbrs	Ax, 0
000665 da41      	rcall	no_I2Cresponce
         
000666 d9a8      	rcall	I2Cstop
         
         ;***************************************************************************
         ;
         ; Create array with vallid SW switch times starting at SRAM address $00B0
         ;
         ; Definition : $00B0 = Number of vallid switch times
         ;              $00B1 = Hour (time 1)
         ;	       $00B2 = minutes ( time 1 )
         ;	       $00B3 = days ( times 1 )
         ;	       $00B4 = temp ( time 1 )
         ;	       $00B5 = Hour ( time 2 )
         ;              cont ..........
         ;
         ;***************************************************************************
         
000667 d17a      	rcall	SWswitchtime		; Create array with vallid schalekklok switch times
         					; read from I2C EEPROM
000668 eb00      	ldi	Ax, SW_arrayL_SRAM
000669 e010      	ldi	Bx, SW_arrayH_SRAM				
00066a deee      	rcall	SendSWlist		; Send SW time list to RS-232 port.					
00066b de9e      	rcall	SWmod_press 		; Set bit's of all modules available
         					; on I2C bus				
00066c de68      	rcall	ResetSWports		; set alle available Switch ports to off.
         					
          start_loop:
         
00066d e001      	ldi	Ax, Dispclear		; Set display cursor function
00066e e010      	ldi	Bx, disp_CTRL
00066f d0d5      	rcall	disp_lcd
         
         ;***************************************************************************
         ;
         ; check for any keyboard activity.....
         ;
         ;***************************************************************************
         
          display_check:
         
000670 b306      	in	Ax, PinB		; Read input key's
000671 0000      	nop
000672 0000      	nop
000673 700f      	andi	Ax, $0F			; clear bit 4 to 7
         
000674 3002      	cpi	Ax, select_key		; check if "select" key is pressed
000675 f411      	brne	nokeypressed		; skip jump is Z-bit is clear
000676 db20      	rcall	Beep			; generate beep on speaker
000677 ca5b      	rjmp	menu			; Jump to start menu-routine
         
          nokeypressed:
000678 3070      	cpi	Disp_refresh, $00	; Check for end of 0,9 sec delay created by timer 0
000679 f3b1      	breq	display_check		; if exp. then check for switch time reached
         
         ;***************************************************************************
         ;
         ; Check for channel status changes 
         ;
         ;***************************************************************************
         
00067a ea00      	ldi	Ax, PCF8583		; Load I2C RTC address into Ax reg.
00067b e012      	ldi	Bx, $02			; Load "second" register number into Bx
00067c da04      	rcall	I2C_Regread		; and read in from the RTC chip
         	
00067d 3000      	cpi	Ax, $00			; check for zero second's
00067e f431      	brne	no_checkSWstat		; if not so, than then no channel check
         					; TO PREVENT CHANNEL CHANGE FOR THE WHOLE MINUTE.
00067f d0f1      	rcall	check_SWstat		; check if any timer setting is set to
         					; current RTC time for channel status chenge.
         
          readsec_again:
000680 ea00      	ldi	Ax, PCF8583		; Load I2C RTC address into Ax reg.
000681 e012      	ldi	Bx, $02			; Load "second" register number into Bx
000682 d9fe      	rcall	I2C_Regread		; and read in from the RTC chip
         	
000683 3000      	cpi	Ax, $00			; check for zero second's
000684 f3d9      	breq	readsec_again		; if so, than wait for no zero sec
         					; WAITS FOR SECOND "00" IS OVER
          no_checkSWstat:
         					
         ;***************************************************************************
         ;
         ; Start display time from the 8583 RTC device
         ;
         ;***************************************************************************
         
          Readtime:
         
000685 e004      	ldi	Ax, low(Time)
000686 e010      	ldi	Bx, high(time)		
000687 e020      	ldi	Cx, $00			; Load display position "Tijd" string into Cx register
000688 d0a0      	rcall	Str2disp		; Print it via I/O
         
000689 e022      	ldi	Cx, $02			; load 8583 time hour register number into Cx
         ;	ldi	Bx, $0F			; Load display position for printing in Bx
00068a e01e      	ldi	Bx, $0E
          startread:
         
00068b ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
         
00068c 931f      	push	Bx			; save display position number onto stack
00068d 2f12      	mov	Bx, Cx			; load register select into Bx
         
00068e d9f2      	rcall	I2C_regread		; Load register vallue from RTC into Ax register
00068f 911f      	pop	Bx			; restore display position from stack
000690 9523      	inc	Cx			; increase RTC register pointer to next time register
         					; NOTE :	if Cx = 02 > seconds will be read
         					; 		if Cx = 03 > minutes will be read
         					; 		if Cx = 04 > hours will be read.
         
         ;*************************************
         ; start to display the found vallue
         ;*************************************
         
000691 932f      	push	Cx			; Save register address to stack
         
000692 2f21      	mov	Cx, Bx			; Load display position into Cx reg
000693 2f10      	mov	Bx, Ax			; move read register value into Bx reg
000694 2f02      	mov	Ax, Cx			; move display position into Ax
000695 dd13      	rcall	disp_DECval
         
         
000696 912f      	pop	Cx
000697 3025      	cpi	Cx, $05			; check Cx value for end of time read from RTC 
000698 f031      	breq	No_time			; register $05 contains no time information anymore !
         
000699 5002      	subi	Ax, $02
00069a e31a      	ldi	Bx, 0b00111010		; load ":" charakter on display databus
00069b d072      	rcall	dispCHR			; and display it.
         	
00069c 2f10      	mov	Bx, Ax
00069d 5012      	subi	Bx, $02
         
00069e cfec      	rjmp	Startread		; read next time tegister from RTC.
         
          No_time:
         
         ;**************************************************
         ;
         ; Display Day of week text on the LC-Display
         ;
         ;**************************************************
         
00069f ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
0006a0 e016      	ldi	Bx, $06			; load Day of Week reg. vallue
         
0006a1 d9df      	rcall	I2C_regread		; Load register vallue from RTC into Ax register
         
0006a2 7e00      	andi	Ax, 0b11100000		; Remove month information from Ax
0006a3 9502      	swap	Ax			; swap byte's and multiply value by two
         					; for calculating day of week address pointer
0006a4 2f20       	mov	Cx, Ax			; Save day information in Cx as offset
         	
0006a5 e402      	ldi	Ax, low(dagen)		; load data pointer of day "string"
0006a6 e018      	ldi	Bx, high(dagen)		; into Ax and Bx reg. and
0006a7 de4d      	rcall	calcpointer		; calculate proper memory pointer
         	
0006a8 2fe0      	mov	Z_low, Ax		;and move address location in Z-register
0006a9 2ff1      	mov	Z_high, Bx
         	
0006aa e400      	ldi	Ax, $40			; Load Ax with new display location
0006ab 95c8      	lpm				; load 1st CHR into Bx register	
0006ac 2d10      	mov	Bx, R0			; via R0
0006ad d060      	rcall	dispCHR			; and display it
         	
0006ae 9631      	adiw	Z_low, $01		; increase memory pointer by one
0006af 95c8      	lpm				; and load 2nd CHR into Bx
0006b0 2d10      	mov	Bx, R0			; via R0
0006b1 9503      	inc	Ax			; increase display location by one
0006b2 d05b      	rcall	DispCHR			; and display CHR
         
         ;***************************************************
         ;
         ; Display Day off month number on the display
         ;
         ;***************************************************
         	
0006b3 ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
0006b4 e015      	ldi	Bx, $05			; load Day off Month reg. vallue
0006b5 d9cb      	rcall	I2C_regread		; Load register vallue from RTC into Ax register
         
0006b6 730f      	andi	Ax, 0b00111111		; clear bit [7:6]
0006b7 2f10      	mov	Bx, Ax			; and move it to Bx reg.
0006b8 e403      	ldi	Ax, $43			; load display position into Ax reg
0006b9 dcef      	rcall	Disp_DECval		; and display the day of month
         	
         ;**************************************************
         ;
         ; Set  Month Text on the display
         ;
         ;**************************************************
         
0006ba ea00      	ldi	Ax, PCF8583		; load I2C adres into Ax
0006bb e016      	ldi	Bx, $06			; load Day of Week reg. vallue
         
0006bc d9c4      	rcall	I2C_regread		; Load register vallue from RTC into Ax register
0006bd 710f      	andi	Ax, 0b00011111		; Extract month information from Ax
0006be da6d      	rcall	DEC2HEX			; convert DEC value to HEX value
0006bf 950a      	dec	Ax			; 
0006c0 0f00      	lsl	Ax			; and multiply by four
0006c1 0f00      	lsl	Ax
0006c2 2f20      	mov	Cx, Ax			; and load it into Cx as address offset
0006c3 e409      	ldi	Ax, low(Maanden)	; Load month txt pointer into Ax and Bx
0006c4 e018      	ldi	Bx, high(Maanden)
0006c5 de2f      	rcall	calcpointer
         	
0006c6 2fe0      	mov	Z_low, Ax
0006c7 2ff1      	mov	Z_high, Bx
         	
0006c8 e024      	ldi	Cx, $04			; Load Cx with Txt length
0006c9 e406      	ldi	Ax, $46			; Load display position into Ax
         	
          Next_MonthCHR:	
0006ca 95c8      	lpm				; Get CHR to display
0006cb 2d10      	mov	Bx, R0			; and move it into Bx reg
0006cc d041      	rcall	DispCHR			; and display it
0006cd 9631      	adiw	Z_low, $01		; increase Text pointer by one
0006ce 9503      	inc	Ax			; increase display position by one
0006cf 952a      	dec	Cx			; decrease CHR counter by one
0006d0 3020      	cpi	Cx, $00			; check for ned of string
0006d1 f7c1      	brne	Next_MonthCHR
         
         ;*************************************************
         ;
         ; Set "20" on the display 
         ;
         ;*************************************************
         	
0006d2 e40b      	ldi	Ax, $4B			; Load Ax with display position
0006d3 e312      	ldi	Bx, $32			; Load Bx with "2"
0006d4 d039      	rcall	DispCHR
         	
0006d5 9503      	inc	Ax			; go to next display position
0006d6 e310      	ldi	Bx, $30			; Load Bx with "0"
0006d7 d036      	rcall	DispCHR	
         
         ;*************************************************
         ;
         ; Display Number of Year on the screen.
         ;
         ;**************************************************
         	
0006d8 ea00      	ldi	Ax, PCF8583
0006d9 ef1f      	ldi	Bx, $FF			; read year information from RTC SRAM location
0006da d9a6      	rcall	I2C_regread		; read register Bx from device Ax
0006db 930f      	push	Ax			; Save HEX year value onto stack
0006dc da42      	rcall	HEX2DEC	
         
0006dd 2f10      	mov	Bx, Ax
0006de e40d      	ldi	Ax, $4D
0006df dcc9      	rcall	disp_DECval
         	
         ;***********************************************************
         ;
         ; Check for Year increase in SRAM RTC clock
         ;
         ;***********************************************************
         
0006e0 ea00      	ldi	Ax, PCF8583
0006e1 e015      	ldi	Bx, $05			; read year information from RTC SRAM location
0006e2 d99e      	rcall	I2C_regread		; read register Bx from device Ax
         	
0006e3 9502      	swap	Ax			; Move Year information to Bit[0:1]
0006e4 9506      	lsr	Ax
0006e5 9506      	lsr	Ax
0006e6 7003      	andi	Ax, 0b00000011		; Clear Bit[2:7]
         	
0006e7 912f      	pop	Cx			; Remove HEX year info from stack
0006e8 2f12      	mov	Bx, Cx			; Save HEX year value in Bx reg.
0006e9 7023      	andi	Cx, 0b00000011		; clear bit[2:7]
0006ea 1702      	cp	Ax, Cx			; check if year is stil the same
0006eb f039      	breq	no_yearinc
         	
0006ec 9513      	inc	Bx			; Increase HEX year info by one
0006ed fd16      	sbrc	Bx, 6
0006ee 2711      	clr	Bx
         	
0006ef 2f21      	mov	Cx, Bx			; Save new year number into Cx reg
0006f0 ea00      	ldi	Ax, PCF8583		; Loead Ax with RTC I2C address
0006f1 ef1f      	ldi	Bx, $FF			; Load Bx reg. with RTC SRAM location
0006f2 d9a6      	rcall	I2C_regstore		; Store new year value into RTC SRAM location
         
          no_yearinc:
0006f3 cf7c      	rjmp	display_check		; jump back to start of loop
         
         
         ;***************************************************************************
         ;
         ; Delayfunction to set the I2C speed. Adjustable for different CPU speed.
         ;	Used registers : Ax = temp var, only vallid in this function
         ;			 Bx = temp var, only vallid in this function
         ;
         ;	Return : None
         ;
         ;***************************************************************************
         	
          delayfunc :
         
0006f4 930f      	push	Ax
0006f5 931f      	push	Bx
         
0006f6 e011      	ldi	Bx, Highwait			; Set registers for proper delay
0006f7 e004      	ldi	Ax, Lowwait
         
          No_zero:
0006f8 950a      	dec	Ax				; decrease low byte and check for zero
0006f9 f7f1      	brne	No_zero				; if not zero then subtrack again
         
0006fa 951a      	dec	Bx				; decrease high byte and check for zero
0006fb f011      	breq	End_delay			; return from subroutine is highbyte is zero
         
0006fc e004      	ldi	Ax, Lowwait			; reload lowbyte nd jump to No_zero
0006fd cffa      	rjmp	No_zero
         
          End_delay:
         
0006fe 911f      	pop	Bx
0006ff 910f      	pop	Ax
         
000700 9508      	ret					; return from subroutine
         
         ;***************************************************************************
         ;
         ; Delayfunction to set the I2C speed. Adjustable for different CPU speed.
         ;	Used registers : Ax = temp var, only vallid in this function
         ;			 Bx = temp var, only vallid in this function
         ;
         ;	Return : None
         ;
         ;***************************************************************************
         	
          delay_5mS :
         
000701 930f      	push	Ax
000702 931f      	push	Bx
         
000703 e810      	ldi	Bx, $80				; Set registers for proper delay
000704 e000      	ldi	Ax, $00
         
          No_zero_5mS:
000705 950a      	dec	Ax				; decrease low byte and check for zero
000706 f7f1      	brne	No_zero_5mS				; if not zero then subtrack again
         
000707 951a      	dec	Bx				; decrease high byte and check for zero
000708 f011      	breq	End_delay_5mS			; return from subroutine is highbyte is zero
         
000709 e000      	ldi	Ax, $00				; reload lowbyte nd jump to No_zero
00070a cffa      	rjmp	No_zero_5mS
         
          End_delay_5mS:
         
00070b 911f      	pop	Bx
00070c 910f      	pop	Ax
         
00070d 9508      	ret					; return from subroutine
         
         
         ;***************************************************************************
         ;
         ; Display a character to LCD display
         ;
         ;	Used registers : accureg
         ;			 Ax = display position register
         ;			 Bx = Character to display
         ;
         ;	Return : None
         ;
         ;***************************************************************************
         
          dispCHR:
         
00070e 930f      	push	Ax
00070f 931f      	push	Bx
         	
000710 6800      	ori	Ax, $80
000711 e010      	ldi	Bx, disp_CTRL
000712 d032      	rcall	disp_LCD
         
000713 911f      	pop	Bx
000714 2f01      	mov	Ax, Bx
000715 e011      	ldi	Bx, disp_write
000716 d02e      	rcall	disp_LCD
         	
000717 910f      	pop	Ax
         
000718 9508      	ret	
         
         ;***************************************************************************
         ;
         ; check for no key pressed
         ;
         ;***************************************************************************
         
          key_released:
         
000719 930f      	push	Ax			; Save Reg. Ax and Bx to stack
00071a 931f      	push	Bx
         	
00071b e004      	ldi	Ax, $04			; Load ax with cycle counter value
         	
          check_key_again:
00071c 950a      	dec	Ax
00071d 3000      	cpi	Ax, $00			; check for 3 times no key pressed
00071e f039      	breq	end_key_released	; Jump out if so.
         
         
00071f dfe1      	rcall	delay_5ms	
000720 b316      	in	Bx, PinB		; Read key's
000721 701f      	andi	Bx, $0F			; Clear high nibble from data
         
000722 3010      	cpi	Bx, $00			; check for no key pressed
000723 f3c1      	breq	check_key_again		; jump if no key pressed
         	
000724 e004      	ldi	Ax, $04
000725 cff6      	rjmp	check_key_again
         
          end_key_released:
         
000726 911f      	pop	Bx
000727 910f      	pop	Ax
         
000728 9508      	ret
         
         ;***************************************************************************
         ;
         ; Display a string to the display until the data-byte read is $00 using data
         ; defenition id EEPROM.
         ;
         ;	Used registers : Ax = low byte address data pointer
         ;			 Bx = high byte of address data pointer
         ;			 Cx = startposition display
         ;
         ;***************************************************************************
         
          str2disp:
         
000729 bb0e      	out	EEARL, Ax		; write EEPROM addres to read in EEPROM addres 
00072a bb1f      	out	EEARH, Bx
         
          start_displaySTR:
         
00072b 2f02      	mov	Ax, Cx			; load display position into Ax reg.
00072c 6800      	ori	Ax, $80			; Set MSB in Ax reg. ( See display data sheet )
00072d e010      	ldi	Bx, disp_CTRL		; load display control reg. prot. into Bx
00072e d016      	rcall	disp_LCD		; go display it.
00072f d020      	rcall	disp_ready		; Wait until display's busy flag is clear
         			
000730 e011      	ldi	Bx, disp_write		; Load display data write prot. in Bx
         
          Str_loop:
         
000731 9ae0      	sbi	EECR, EERE		; Set EEPROM Read start bit	
         	
          check_EERE:
000732 b30c      	in 	Ax, EECR		; load EECR status in Ax reg.
000733 fd00      	sbrc	Ax, 0			; check if EEPROM read bit is cleared by hardware
000734 cffd      	rjmp	check_EERE		; if not, then wait until reset
         	
000735 b30d      	in	Ax, EEDR 		; Load read EEPROM data into Ax reg.
000736 3000      	cpi	Ax, $00			; and check for "$00" end of data
000737 f061      	breq	end_str2disp		; jump to end of routine if so.
         	
000738 d00c      	rcall	disp_LCD		; display read ASCII value onto display
000739 d016      	rcall	disp_ready
         	
00073a b30e      	in	Ax, EEARL		; load Ax with current EERPOM address
00073b 9503      	inc	Ax			; Inc Address by one
00073c bb0e      	out	EEARL, Ax		; Store new address into EEPROM reg.
         
00073d 3000      	cpi	Ax, $00
00073e f419      	brne	no_pageinc
         	
00073f b30f      	in	Ax, EEARH
000740 9503      	inc	Ax
000741 bb0f      	out	EEARH, Ax
         
         	
          no_pageinc:	
000742 9523      	inc	Cx			; inc. display position by one
         
000743 cfe7      	rjmp	Start_displaySTR	; Jump to start of routine.
         
          end_str2disp:
         
000744 9508      	ret
         	
         ;***************************************************************************
         ;
         ; Routine to control the LCD display
         ;	Ax = Data to display
         ;	Bx = 0b00000000	= Display control register mode
         ;	     0b00000001 = CG RAM/DD RAM data write
         ;	     0b00000010 = Busy flag / address counter read
         ;	     0b00000011 = CG RAM/DD RAM data read
         ;
         ;***************************************************************************
         
          Disp_LCD:
         
         
         
000745 bb0b      	out	PortA, Ax		; Put data on displays data bus
         	
000746 9512      	swap	Bx			; swap high and low nibble to get proper	
000747 bb15      	out	PortC, Bx		; value of RS and R/W bit and output it
         					; to port C.
000748 6410      	ori	Bx, 0b01000000		; Set E bit of display and set new value on
000749 bb15      	out	PortC, Bx		; port C
00074a 7b1f      	andi	Bx, 0b10111111		; Reset E bit of display and set new value on
00074b bb15      	out	PortC, Bx
         	
00074c 2711      	clr	Bx
00074d bb15      	out	PortC, Bx		; Set all display control line's low.					
         	
00074e d001      	rcall	Disp_ready
         				
00074f 9508      	ret
         	
         ;***************************************************************************
         ;
         ; Routine that wait's until the display is ready.
         ; ( To avoid inpropper display information )	
         ;
         ;***************************************************************************	
         
          disp_ready:
         
000750 930f      	push	Ax			; Save registers Ax and Bx to stack
000751 931f      	push	Bx
         
000752 e000      	ldi	Ax, 0b00000000		; Set port A to input
000753 bb0a      	out	DDRA, Ax
         
          not_ready:
         	
000754 e002      	ldi	Ax, disp_busy		; Load Read Busy sequence into Ax
000755 9502      	swap	Ax			; Swap Byte to get proper bit mask
000756 bb05      	out	PortC, Ax		; Output to display control lines
         	
000757 6400      	ori	Ax, 0b01000000		; Set E bit high
000758 bb05      	out	PortC, Ax		; And output new bit mask to port C
000759 0000      	nop				; wait one clock cycle
00075a b319      	in	Bx, PinA		; Read display busy flag
00075b 7b0f      	andi	Ax, 0b10111111		; Reset E bit
00075c bb05      	out	PortC, Ax		; and output new bit mask to PortC
         	
00075d fd17      	sbrc	Bx, 7			; Check it display is ready ( Bit 7 = 0 )
00075e cff5      	rjmp	not_ready
         	
         
00075f ef0f      	ldi	Ax, 0b11111111		; Set port A to output
000760 bb0a      	out	DDRA, Ax
         
000761 911f      	pop	Bx
000762 910f      	pop	Ax
         	
000763 9508      	ret
         
         ;***************************************************************************
         ;
         ; Routine voor het uitlezen van de toetsen aangesloten op PORTB[0:3]
         ;	
         ;	Ax = return waarde van de ingedrukte toets
         ;
         ;***************************************************************************
         
         
          Input_keyread:
         
000764 b306      	in	Ax, PinB		; Read input key's
000765 700f      	andi	Ax, $0F
         	
000766 3001      	cpi	Ax, return_key		; Check for Return key pressen
000767 f039      	breq	end_keyreadsub		
         
000768 3002      	cpi	Ax, select_key		; check if Select key is pressed
000769 f029      	breq	end_keyreadsub
         
00076a 3008      	cpi	Ax, plus_key		; Check if "+" key is pressed
00076b f019      	breq	end_keyreadsub
         
00076c 3004      	cpi	Ax, min_key			; Check if "-" key is pressed
00076d f009      	breq	end_keyreadsub
         
00076e cff5      	rjmp	Input_keyread		; read key's again if no key is pressed
         
          end_keyreadsub:
         
00076f da27      	rcall	Beep
         
000770 9508      	ret
         
         ;***************************************************************************
         ;
         ; Check for changes in SW-switch modules.
         ;
         ;***************************************************************************
         
          Check_SWstat:
         
000771 930f      	push	Ax			; Save register Ax, Bx and Cx to stack
000772 931f      	push	Bx
000773 932f      	push	Cx
000774 93ef      	push	Z_low
000775 93ff      	push	Z_high
         
000776 2722      	clr	Cx			; Clear Cx register.
         
          checkagain:
         
000777 eb00      	ldi	Ax, SW_arrayL_SRAM	; Load Ax end Bx with start address of
000778 e010      	ldi	Bx, SW_arrayH_SRAM	; array in SRAM defined is variables
         
000779 d01e      	rcall	check_change		; check for wanted channel change time in array.
         
00077a 3000      	cpi	Ax, $00			; If return value is NOT equel to zero, there is
00077b f409      	brne	SWchange		; an channel status change. If not then jump out.
00077c c015      	rjmp	noSWchange
         
          SWchange:
00077d 931f      	push	Bx			; save timer loop number
00077e 930f      	push	Ax			; save channel number/stat information on stack
         
00077f da22      	rcall	SendTime		; Send current time on the RS-232 port
000780 910f      	pop	Ax			; reload Ax with number/stat info
000781 930f      	push	Ax
000782 dace      	rcall	Send_chanstat		; Send channel number and stata info
         					; to the RS-232 port.
000783 e00d      	ldi	Ax, $0D			; send linefeed to RS-232 port
000784 da78      	rcall	sendCHR
000785 e00a      	ldi	Ax, $0A			; send CR to RS-232 port
000786 da76      	rcall	sendCHR
         	
000787 910f      	pop	Ax			; reload channel/state info from stack
000788 2f10      	mov	Bx, Ax
         	
000789 7f00      	andi	Ax, $F0			; remove channel stat. information
00078a 9502      	swap	Ax
00078b 701f      	andi	Bx, $0F
00078c d093      	rcall	activate_channel
         
00078d 911f      	pop	Bx			; reload timer vallue
00078e 3010      	cpi	Bx, $00			; check for end of array check reached.
00078f 2f21      	mov	Cx, Bx			; if not, move vallue to Cx to become preset val
000790 f009      	breq	noSWchange
000791 cfe5      	rjmp	checkagain		; and go to check again
         
          noSWchange:
         
000792 91ff      	pop	Z_high
000793 91ef      	pop	Z_low
000794 912f      	pop	Cx
000795 911f      	pop	Bx
000796 910f      	pop	Ax
         
000797 9508      	ret
         	
         ;**************************************************************************
         ;
         ; Routine to check for new SW clock settings
         ;
         ;	Ax	= Low byte start addres in SRAM of array
         ;	Bx	= High byte start address in SRAM of array
         ;	Cx	= Preset for vallid time counter
         ;
         ;	Return:
         ;	Ax	= new vallue of settings (SW channel stat/numb.)
         ;	Bx	= number of time setting vallid for changecheck
         ;
         ;**************************************************************************
         
          check_change:
         
000798 2fe0      	mov	Z_low, Ax		; Load Z_register with start array in SRAM. 
000799 2ff1      	mov	Z_high, Bx		; as defined in Ax (low byte) and Bx (high byte)
00079a 930f      	push	Ax			; Save org SRAM start addres to stack
00079b 931f      	push	Bx
         
00079c 2f12      	mov	Bx, Cx			; Move counter preset to Bx register
         
00079d 9121      	ld	Cx, Z+			; Load number of vallid clock settings into Cx
         					; and set SRAM pointer to next location.
00079e 1b21      	sub	Cx, Bx			; Adjust counter with Preset
00079f 0f11      	lsl	Bx			;
0007a0 0f11      	lsl	Bx			; Multiply Bx contens by 4 for calculating SRAM offset
0007a1 0fe1      	add	Z_low,Bx		; compensate Z_register pointer start address.
         
          chk_nexttime:
0007a2 3020      	cpi	Cx, $00			; check for last timer setting.
0007a3 f409      	brne	Notimeend			 
0007a4 c036      	rjmp	end_switchchk		; jump to end of subroutine if last time is checked
         
          Notimeend:
         
0007a5 ea00      	ldi	Ax, PCF8583		; Load I2C RTCclock address in Ax register.
0007a6 e014      	ldi	Bx, $04			; Load Hour reg. number into Bc register.
0007a7 d8d9      	rcall	I2C_regread		; Load RTC current hour vallue into Ax
         
0007a8 9111      	ld	Bx, Z+			; Load Bx with Clock hour setting from SRAM
0007a9 1701      	cp	Ax, Bx			; and set increase SRAM pointer. compare hour settings
0007aa f019      	breq	chk_switchmin		; if equal then check for minute setting
0007ab 5fed      	subi	Z_low, $FD		; Set Z-register to next Hour SRAM address ( by adding 2 )
0007ac 952a      	dec	Cx			; decrease total timesetting counter. 
0007ad cff4      	rjmp	chk_nexttime		; Jump to check next timer setting.
         
          chk_switchmin:
0007ae ea00      	ldi	Ax, PCF8583		; Load I2C RTCclock address in Ax register.
0007af e013      	ldi	Bx, $03			; Load minute reg. number in Bx register
0007b0 d8d0      	rcall	I2C_regread		; Load RTC current minutes vallue into Ax.
         
0007b1 9111      	ld	Bx, Z+			; Load Bx with CV-clock minute setting from SRAM and inc SRAM pointer
0007b2 1701      	cp	Ax, Bx			; if equel then check for switch day setting
0007b3 f019      	breq	chk_switchday
0007b4 5fee      	subi	Z_low, $FE		; Set Z_register to next hour SRAM address
0007b5 952a      	dec	Cx			; decrease total timesetting counter.
0007b6 cfeb      	rjmp	chk_nexttime		; Jump to check next times setting
         
         
          chk_switchday:
         
0007b7 ea00      	ldi	Ax, PCF8583		; Load I2C device number
0007b8 e016      	ldi	Bx, $06			; Load RTC Weekday/Month register number
0007b9 d8c7      	rcall	I2C_regread		; Load Ax with RTC current day
0007ba 7e00      	andi	Ax, $E0			; Remove month information
0007bb 9502      	swap	Ax			; and swap byte to get a number from 0 to 6
0007bc 9506      	lsr	Ax			; Ax contains RTC day of week information
0007bd e011      	ldi	Bx, $01			; Set Bx LSB
         
          calc_day:
0007be 3000      	cpi	Ax, $00			; shift Bx to set proper day bit to check
0007bf f019      	breq	end_calc_day		; with SRAM day setting
0007c0 0f11      	lsl	Bx			; if Ax is NOT 0 then shift Bx to left without carry
0007c1 950a      	dec	Ax			
0007c2 cffb      	rjmp	calc_day		; Bx contains bitset for current day
         
          end_calc_day:
         ;	mov	Ax, Bx			; move proper day bit patern into Ax
         ;	mov	Bx, Ax
0007c3 9101      	ld	Ax, Z+			; Load wanted day information from SRAM
0007c4 93ef      	push	Z_low
0007c5 93ff      	push	Z_high
0007c6 932f      	push	Cx			; Save register Cx and Bx to stack
0007c7 931f      	push	Bx
0007c8 2f20      	mov	Cx, Ax			; mov	dayinfo to Cx as address offset
0007c9 e30c      	ldi	Ax, low(dayinfo)	; Load pointer into Ax and Bx
0007ca e018      	ldi	Bx, high(dayinfo)
0007cb dd29      	rcall	calcpointer		; calculate data memory position
0007cc 2fe0      	mov	Z_low, Ax		; and move pointer into Z-reg.
0007cd 2ff1      	mov	Z_high, Bx
0007ce 911f      	pop	Bx			; reload wanted day-bitstream into Bx 
0007cf 912f      	pop	Cx
         	
0007d0 95c8      	lpm				; load day-bit pattern from Programm memory
0007d1 2d00      	mov	Ax, R0			; into Ax through R0
0007d2 91ff      	pop	Z_high			; restore Z vallue
0007d3 91ef      	pop	Z_low
0007d4 2301      	and	Ax, Bx			; logical AND to check if proper day bit is selected
         
0007d5 f011      	breq	no_day_select		; jump is proper day bit is NOT set
         
0007d6 8100      	ld	Ax, Z			; load wanted channel number/state infomation into Ax again
0007d7 c004      	rjmp	time_vallid
         
          no_day_select:
0007d8 5fef      	subi	Z_low, $FF		; set SRAM pointer to next Hour vallue
0007d9 952a      	dec	Cx			; decrease total timer check counter
0007da cfc7      	rjmp	chk_nexttime		; goto start check next setting
         
          end_switchchk:
         
0007db 2700      	clr	Ax			; Clear AX to indicate no vallid time found.
         
          time_vallid:
         
         
0007dc 91ff      	pop	Z_high			; Load Z-register with startaddress SRAM and load
0007dd 91ef      	pop	Z_low			; Bx with total vallid time vallue
0007de 8110      	ld	Bx, Z
0007df 952a      	dec	Cx
0007e0 1b12      	sub	Bx, Cx			; subtrack current loop vallue of timer check
         	
0007e1 9508      	ret
         	
         ;***************************************************************************
         ;
         ; Create SW time array in SRAM starting at address defined in SW_arrayH_SRAM
         ; and SW_arrayL_SRAM.
         ;
         ;***************************************************************************
         ;
         ; Startaddres in EEPROM is : $80 = hour setting
         ;			     $81 = minute setting
         ; 			     $82 = Day pattern
         ;			     $83 = on off state / channel
         ;			     $84 = 2-comp from above vallue's
         ; Array is taking space up to addres $A7
         ;
         ;***************************************************************************
         
          SWswitchtime:
         
0007e2 930f      	push	Ax			; Save Ax, Bx and Cx register to stack.
0007e3 931f      	push	Bx
0007e4 932f      	push	Cx
         
         
0007e5 e800      	ldi	Ax, SW_E2_I2C		; load I2C EEPROM start address of time table in Ax
0007e6 e010      	ldi	Bx, SW_arrayH_SRAM	; load SRAM address in Bx ( high byte ) and Cx 
0007e7 eb20      	ldi	Cx, SW_arrayL_SRAM	; ( low byte )
         
0007e8 d004      	rcall	createArray		; Go create Array in SRAM
         
0007e9 912f      	pop	Cx			; Restore org vallue's of Cx, Bx and Ax register
0007ea 911f      	pop	Bx
0007eb 910f      	pop	Ax
         
0007ec 9508      	ret
         
         ;********************************************************************
         ;
         ; Routine to create an Array in SRAM as :
         ;
         ;	Ax	= I2C EEPROM startaddres for time information
         ;	Bx	= High byte start addres in SRAM of array
         ;	Cx	= Low byte start address in SRAM of array
         ;
         ;********************************************************************
         
          createArray:
         
0007ed 93ef      	push	Z_low			; Save current Z-pointer to Stack
0007ee 93ff      	push	Z_high
0007ef 932f      	push	Cx			; save Cx to stack.
         
0007f0 2fc2      	mov	Y_low, Cx		; and load it into Y-reg(low)
0007f1 2fd1      	mov	Y_high, Bx		; and load it into Y-reg (high)
0007f2 9621      	adiw	Y_low, $01		; Increase Y pointer by one.
0007f3 2f10      	mov	Bx, Ax			; and move I2C EEPROM address to
         					; read from into Bx reg.
         
0007f4 e124      	ldi	Cx, max_SWclktimes	; Load Cx with max SW timer setting
         
          SWnext_time:
         
0007f5 932f      	push	Cx			; save Cx to stack and load it with the
0007f6 e024      	ldi	Cx, $04			; number of registers to read from I2C devie
         
          SWload_lus:
0007f7 952a      	dec	Cx
0007f8 ea02      	ldi	Ax, X24C02		; load I2C device from location dev. in Bx
0007f9 d887      	rcall	I2C_regread		; Read from I2C device
0007fa 9309      	st	Y+, Ax			; Save in SRAM in increase SRAM pointer by one. 	
          
0007fb 9513      	inc	Bx			; Increase I2C reg number 1.
0007fc 3020      	cpi	Cx, $00			; check for read of last register.
0007fd f7c9      	brne	SWLoad_lus		; goto read next register.
         
0007fe 2700      	clr	Ax			; clear Ax register.
0007ff 931f      	push	Bx			; save I2C device Reg. nr. on stack.
000800 e014      	ldi	Bx, $04			; load Bx with total byte's to read from SRAM.
         
          SW2comp_lus:
000801 951a      	dec	Bx			; Calculate the 2 complement from the byte's
000802 912a      	ld	Cx, -Y			; Load Cx with SRAM location and dec. SRAM pointer by 1
000803 0f02      	add	Ax, Cx			; add result to Ax
000804 3010      	cpi	Bx, $00
000805 f7d9      	brne	SW2comp_lus		; check for all byte readed
000806 9500      	com	Ax
000807 5f0f      	subi	Ax, $ff			; calculate 2-comp from Ax
         					; Ax reg. contains 2comp value of previous read four
000808 911f      	pop	Bx			; bytes. Reload Bx with I2C reg. number
000809 2f20      	mov	Cx, Ax			; Move calculated 2COMP val. into Cx reg.
00080a ea02      	ldi	Ax, X24C02
00080b d875      	rcall	I2C_regread		; Load 2-comp val location in I2C device
00080c 9513      	inc	Bx			; increase Bx to set proper EERPOM read addres
00080d 1720      	cp	Cx, Ax			; check if vallue in I2C device is the 
00080e f409      	brne	SWnotvallid_2comp	; calculated 2comp.
         
00080f 5fcc      	subi	Y_low, $FC		; Set Y-pointer to new SRAM start addres
         					; if calculate and read vallue are equal.
         
          SWnotvallid_2comp:
000810 912f      	pop	Cx
000811 952a      	dec	Cx
000812 3020      	cpi	Cx, $00			; check for for all posible SW-timer setting ( 10 ).
000813 f709      	brne	SWnext_time
         
000814 2f0c      	mov	Ax, Y_low		; Load Ax with low byte Y-pointer and
000815 950a      	dec	Ax
000816 eb10      	ldi	Bx, SW_arrayL_SRAM
000817 1b01      	sub	Ax, Bx
         ;	subi	Ax, $7F			; subtrakt $7F and devide in by two by
000818 9506      	lsr	Ax			; shift vallue right 2 bits without carry.
000819 9506      	lsr	Ax			; Ax contains total found vallid SW times
00081a 912f      	pop	Cx			; restore low byte SRAM vallue 
00081b 2fc2      	mov	Y_low,Cx		; load Y-low org. vallue
00081c 8308      	st	Y, Ax			; Store total Sw-times number into SRAM location 
         
00081d 91ff      	pop	Z_high			; Retore org Z-register vallues
00081e 91ef      	pop	Z_low
         
00081f 9508      	ret
         
         ;************************************************************************
         ;
         ; Routine to set I/O module in the wanted state:
         ;
         ;	Ax = channel number
         ;	Bx = wanted state of channel ( LSB = 0 > off )
         ;				     ( LSB = 1 > onn )
         ;***********************************************************************
         
          activate_channel:
         
000820 932f      	push	Cx			; save Cx reg. on stack
000821 931f      	push	Bx			; save channel status on stack
         
000822 ff03      	sbrs	Ax, 3			; check for 74A module to change
000823 c005      	rjmp	change_lowSW
         	
000824 7007      	andi	Ax, 0b00000111		; Remove bit[3]
000825 0f00      	lsl	Ax			; multiply SW number by two
000826 e710      	ldi	Bx, PCF8574_SWH		; Load Bx with basic I2C 8574A address
000827 0f01      	add	Ax, Bx			; add number of SW to I2C address
000828 c003      	rjmp	changestate
         	
          change_lowSW:
         
000829 0f00      	lsl	Ax
00082a e410      	ldi	Bx, PCF8574_SWL
00082b 0f01      	add	Ax, Bx
         		
          changestate:	
         	
00082c 911f      	pop	Bx			; reload channel number/stat information
00082d ef2f      	ldi	Cx, $FF			; Load Cx with all bits high
00082e ff10      	sbrs	Bx, 0			; check if LSB Bx id "0", if so
00082f 2722      	clr	Cx			; then clear Cx register
000830 2f12      	mov	Bx, Cx			; load stat information from Cx into Bx
         
000831       	rcall	I2Cstart		; send I2C start command on I2C bus
error : Relative branch out of reach
000832       	rcall	I2Csend			; send I2C device address on the bus
error : Relative branch out of reach
         
000833 ff00      	sbrs	Ax, 0			; check for aknowledge from device
000834 c005      	rjmp	norespI2C
         
000835 2f01      	mov	Ax, Bx
000836       	rcall	I2Csend
error : Relative branch out of reach
         	
000837 ff00      	sbrs	Ax, 0
000838 d86e      	rcall	no_I2Cresponce		; if no responce the I2C error on display
         
000839       	rcall	I2Cstop	
error : Relative branch out of reach
         
          norespI2C:
         
00083a 912f      	pop	Cx
         	
00083b 9508      	ret
         
          .include	"data_ned.asm"
         ;***************************************************************************
         ;*
         ;* Data definition Nederlands
         ;* By hugo Vos
         ;*
         ;* E-mail		: hugo@hvos.myweb.nl
         ;* 
         ;***************************************************************************
          dayinfo:
         
          .db	$00, $01, $02, $04, $08, $10, $20, $40, $1F, $60, $7F
00083c 0100
00083d 0402
00083e 1008
00083f 4020
000840 601f
000841 007f
         
         
          Dagen:
         
          .db	$6d, $61, $64, $69, $77, $6f, $64, $6f, $76, $72, $7a, $61, $7a ,$6f
000842 616d
000843 6964
000844 6f77
000845 6f64
000846 7276
000847 617a
000848 6f7a
         ;	 m    a    d    i    w    o    d    o    v    r    z    a    z    o
         
         
          maanden:
         
          .db	$6A, $61, $6E, $20, $66, $65, $62, $20, $6D, $72, $74, $20, $61, $70, $72, $20
000849 616a
00084a 206e
00084b 6566
00084c 2062
00084d 726d
00084e 2074
00084f 7061
000850 2072
         ;        j    a    n         f    e    b         m    r    t         a    p    r
          .db	$6D, $65, $69, $20, $6A, $75, $6E, $69, $6A, $75, $6C, $69, $61, $75, $67, $20
000851 656d
000852 2069
000853 756a
000854 696e
000855 756a
000856 696c
000857 7561
000858 2067
         ;	 m    e    i         j    u    n    i    j    u    l    i    a    u    g       
          .db	$73, $65, $70, $20, $6F, $6B, $74, $20, $6E, $6F, $76, $20, $64, $65, $63, $20
000859 6573
00085a 2070
00085b 6b6f
00085c 2074
00085d 6f6e
00085e 2076
00085f 6564
000860 2063
         ;	 s    e    p         o    k    t         n    o    v         d    e    c    
         
          channel:
         
          .db	$4B, $61, $6E, $61, $61, $6C, $20, $00
000861 614b
000862 616e
000863 6c61
000864 0020
         ;	 K    a    n    a    a    l
         
         
         ;***************************************************************************
         ;
         ; EEPROM Data definition
         ;
         ;***************************************************************************
         
          .ESEG
          .ORG 0x0000
         
          Off:
          .db	$55, $69, $74, $00
000000 55
000001 69
000002 74
000003 00
         ;	 U    i    t
         
          .ORG 0x0004
          Time:
         
          .db	$54, $69, $6a, $64, $3a, $00
000004 54
000005 69
000006 6a
000007 64
000008 3a
000009 00
         ;	 T    i    j    d    :
         
          .ORG 0x000A
          Chanstate:
         
          .db	$53, $74, $61, $74, $75, $73, $20, $20, $4B, $61, $6E, $61, $61, $6C, $00
00000a 53
00000b 74
00000c 61
00000d 74
00000e 75
00000f 73
000010 20
000011 20
000012 4b
000013 61
000014 6e
000015 61
000016 61
000017 6c
000018 00
         ;	 S    t    a    t    u    s              K    a    n    a    a    l
         
          .ORG 0x0019
          Menutxt:
         
          .db	$4D, $65, $6E, $75, $00
000019 4d
00001a 65
00001b 6e
00001c 75
00001d 00
         ;	 m    e    n    u
         
          .ORG 0x001E
          On:
         
          .db	$41, $61, $6E, $00
00001e 41
00001f 61
000020 6e
000021 00
         ;	 A    a   n
         
          .ORG 0x0022
          rtc:
         
          .db	$20, $20, $52, $54, $43, $20, $69, $6E, $73, $74, $65, $6C, $6C, $65, $6E, $00
000022 20
000023 20
000024 52
000025 54
000026 43
000027 20
000028 69
000029 6e
00002a 73
00002b 74
00002c 65
00002d 6c
00002e 6c
00002f 65
000030 6e
000031 00
         ;	           r    t    c         i    n    s    t    e    l    l    e    n
         
          .ORG 0x0032
          klok:
         
          .db	$20, $20, $20, $53, $63, $68, $61, $6b, $65, $6c, $6b, $6c, $6f, $6b, $00
000032 20
000033 20
000034 20
000035 53
000036 63
000037 68
000038 61
000039 6b
00003a 65
00003b 6c
00003c 6b
00003d 6c
00003e 6f
00003f 6b
000040 00
         ;	                s    c    h    a    k    e    l    k    l    o    k
         
          .ORG 0x0041
         
         
          noSWmod1:
         
          .db	$47, $65, $65, $6E, $20, $53, $57, $2D, $6D, $6F, $64, $75, $6C, $65, $73, $00
000041 47
000042 65
000043 65
000044 6e
000045 20
000046 53
000047 57
000048 2d
000049 6d
00004a 6f
00004b 64
00004c 75
00004d 6c
00004e 65
00004f 73
000050 00
         ;	 G    e    e    n         S    W    -    m    o    d    u    l    e    s
         
          .ORG 0x0051
         
          noSWmod2:
         
          .db     $6F, $70, $20, $49, $32, $43, $20, $62, $75, $73, $21, $00
000051 6f
000052 70
000053 20
000054 49
000055 32
000056 43
000057 20
000058 62
000059 75
00005a 73
00005b 21
00005c 00
         ;	 o    p         I    2    C         b    u    s    !
          .ORG 0x005D
         
          cvklok:
         
          .db	$54, $69, $6A, $64, $3A, $20, $4D, $44, $57, $44, $56, $5A, $5A, $00
00005d 54
00005e 69
00005f 6a
000060 64
000061 3a
000062 20
000063 4d
000064 44
000065 57
000066 44
000067 56
000068 5a
000069 5a
00006a 00
         ;	 T    i    j    d    :         M    D    W    D    V    Z    Z
         
          .ORG 0x006B
         
          cvsave:
         
          .db	$42, $65, $77, $61, $61, $72, $20, $4E, $28, $2D, $29, $20, $4A, $28, $2B, $29, $00 
00006b 42
00006c 65
00006d 77
00006e 61
00006f 61
000070 72
000071 20
000072 4e
000073 28
000074 2d
000075 29
000076 20
000077 4a
000078 28
000079 2b
00007a 29
00007b 00
         ;	 B    e    w    a    a    r         N    (    -    )         J    (    +    )
         
          .ORG 0x007C
         
          Uren:
         
          .db	$55, $72, $65, $6e, $3a, $00
00007c 55
00007d 72
00007e 65
00007f 6e
000080 3a
000081 00
         ;	 u    r    e    n    :
         
          .ORG 0x0082
         
          Min:
         
          .db	$4d, $69, $6e, $75, $74, $65, $6e, $3a, $00
000082 4d
000083 69
000084 6e
000085 75
000086 74
000087 65
000088 6e
000089 3a
00008a 00
         ;	  m   i    n    u    t    e    n    :
         
          .ORG 0x008B
         
          Maand:
         
          .db	$4d, $61, $61, $6e, $64, $3a, $00
00008b 4d
00008c 61
00008d 61
00008e 6e
00008f 64
000090 3a
000091 00
         ;	  m   a    a    n    d    :
         
          .ORG 0x0092
         
          Dag:
         
          .db	$44, $61, $67, $20, $76, $20, $6d, $61, $61, $6e, $64, $3a, $00
000092 44
000093 61
000094 67
000095 20
000096 76
000097 20
000098 6d
000099 61
00009a 61
00009b 6e
00009c 64
00009d 3a
00009e 00
         ;	 d    a    g         v         m    a    a    n    d    :
         
          .ORG 0x009F
          Dag_w:
         
          .db	$44, $61, $67, $20, $76, $20, $77, $65, $65, $6b, $3a, $20, $20, $20, $20, $20,$00
00009f 44
0000a0 61
0000a1 67
0000a2 20
0000a3 76
0000a4 20
0000a5 77
0000a6 65
0000a7 65
0000a8 6b
0000a9 3a
0000aa 20
0000ab 20
0000ac 20
0000ad 20
0000ae 20
0000af 00
         ;	 d    a    g         v         w    e    e    k    :
         
          .ORG 0x00B0
          Jaar:
         
          .db	$4a, $61, $61, $72, $3a, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20,$00
0000b0 4a
0000b1 61
0000b2 61
0000b3 72
0000b4 3a
0000b5 20
0000b6 20
0000b7 20
0000b8 20
0000b9 20
0000ba 20
0000bb 20
0000bc 20
0000bd 20
0000be 20
0000bf 20
0000c0 00
         ;	 j    a    a    r    :
         
          .ORG 0x00C1
         
          errortxt1:
         
          .db	$49, $32, $43, $20, $43, $68, $69, $70, $20, $6E, $69, $65, $74, $20, $20, $20, $00      
0000c1 49
0000c2 32
0000c3 43
0000c4 20
0000c5 43
0000c6 68
0000c7 69
0000c8 70
0000c9 20
0000ca 6e
0000cb 69
0000cc 65
0000cd 74
0000ce 20
0000cf 20
0000d0 20
0000d1 00
         ;	 I    2    C         C    h    i    p         n    i    e    t
         
          .ORG 0x00D2
          errortxt2:
         
          .db     $67, $65, $76, $6F, $6E, $64, $65, $6E, $21, $20, $20, $20, $20, $20, $20, $00
0000d2 67
0000d3 65
0000d4 76
0000d5 6f
0000d6 6e
0000d7 64
0000d8 65
0000d9 6e
0000da 21
0000db 20
0000dc 20
0000dd 20
0000de 20
0000df 20
0000e0 20
0000e1 00
         ;        g    e    v    o    n    d    e    n    !
         
          .ORG 0x00E2
          module:
         
          .db	$20, $20, $6D, $6F, $64, $75, $6c, $65, $20, $6c, $69, $6A, $73, $74, $00
0000e2 20
0000e3 20
0000e4 6d
0000e5 6f
0000e6 64
0000e7 75
0000e8 6c
0000e9 65
0000ea 20
0000eb 6c
0000ec 69
0000ed 6a
0000ee 73
0000ef 74
0000f0 00
         ;	           m    o    d    u    l    e         l    i    j    s    t
         
         
          .ORG 0x00F1
          PCF8574:
         
          .db	$38, $35, $37, $34, $00 
0000f1 38
0000f2 35
0000f3 37
0000f4 34
0000f5 00
         ;	 8    5    7    4
         
          .ORG 0x00F6
          manual:
         
          .db	$20, $20, $20, $20, $48, $61, $6E, $64, $6D, $61, $74, $69, $67, $20, $20, $20, $00
0000f6 20
0000f7 20
0000f8 20
0000f9 20
0000fa 48
0000fb 61
0000fc 6e
0000fd 64
0000fe 6d
0000ff 61
000100 74
000101 69
000102 67
000103 20
000104 20
000105 20
000106 00
         ;                            H   a    n    d    m    a    t    i    g
         
          .ORG 0x0108
          schakel:
         
          .db	$53, $63, $68, $61, $6b, $65, $6C, $20, $4E, $28, $2D, $29, $4A, $28, $2B, $29, $00 
000108 53
000109 63
00010a 68
00010b 61
00010c 6b
00010d 65
00010e 6c
00010f 20
000110 4e
000111 28
000112 2d
000113 29
000114 4a
000115 28
000116 2b
000117 29
000118 00
         ;	 S    c    h    a    k    e    l         N    (    -    )    J    (    +    )
         
         
         
         ;.include	"data_eng.asm"
Assembly complete with 4 errors
