
AVRASM ver. 1.30  hcs01mon.asm Sun Mar 11 20:57:29 2001


          .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                 :98.05.22
         ;* Version              :1.22
         ;* Support telephone	:+47 72 88 43 88 (ATMEL Norway)
         ;* Support fax		:+47 72 88 43 99 (ATMEL Norway)
         ;* Support E-mail	: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
         ;***************************************************************************
         
         ;***** Specify Device
          .device AT90S8515
         
         ;***** I/O Register Definitions
          .equ	SREG	=$3f
          .equ	SPH	=$3e
          .equ	SPL	=$3d
          .equ	GIMSK	=$3b
          .equ	GIFR	=$3a
          .equ	TIMSK	=$39
          .equ	TIFR	=$38
          .equ	MCUCR	=$35
         
          .equ	TCCR0	=$33
          .equ	TCNT0	=$32
          .equ	OCR0	=$31
         
          .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	INTF1	=7
          .equ	INTF0	=6
         
          .equ	TOIE1	=7
          .equ	OCIE1A	=6
          .equ	OCIE1B	=5
          .equ	TICIE1	=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	WDDE	=4
          .equ	WDE	=3
          .equ	WDP2	=2
          .equ	WDP1	=1
          .equ	WDP0	=0
         
          .equ	EEMWE	=2
          .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	PD7	=7
          .equ	PD6	=6
          .equ	PD5	=5
          .equ	PD4	=4
          .equ	PD3	=3
          .equ	PD2	=2
          .equ	PD1	=1
          .equ	PD0	=0
         
          .equ	DDD7	=7
          .equ	DDD6	=6
          .equ	DDD5	=5
          .equ	DDD4	=4
          .equ	DDD3	=3
          .equ	DDD2	=2
          .equ	DDD1	=1
          .equ	DDD0	=0
         
          .equ	PIND7	=7
          .equ	PIND6	=6
          .equ	PIND5	=5
          .equ	PIND4	=4
          .equ	PIND3	=3
          .equ	PIND2	=2
          .equ	PIND1	=1
          .equ	PIND0	=0
         
          .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	SPIF	=7
          .equ	WCOL	=6
         
          .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  =$25F	;Last On-Chip SRAM Location
          .equ	XRAMEND =$FFFF
          .equ	E2END	=$1FF
          .equ	FLASHEND=$FFF
         
         
          .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	OVF0addr=$007	;Overflow0 Interrupt Vector Address
          .equ	SPIaddr =$008	;SPI Interrupt Vector Address
          .equ	URXCaddr=$009	;UART Receive Complete Interrupt Vector Address
          .equ	UDREaddr=$00a	;UART Data Register Empty Interrupt Vector Address
          .equ	UTXCaddr=$00b	;UART Transmit Complete Interrupt Vector Address
          .equ	ACIaddr =$00c	;Analog Comparator Interrupt Vector Address
         ;
         ;
         ; -------------------------------------------------------------------
         ;
         ; H C S 0 1   -   M O N I T O R
         ;
         ; -------------------------------------------------------------------
         ;
         ; Abstract:
         ;
         ; DESCRIPTION:	This is the operating software for the HCS01 
         ;               Home-Controller-Small board
         ;
         ; Board Environment:
         ; ------------------
         ;
         ; The HCS01 Board is equipped with drivers for the On-Chip
         ; UART Interface enhanced by RS232 control lines.
         ;
         ;   Port A all bits ... multiplexed Address/Data bus
         ;
         ;   Port B bit 0 ... activity LED green active low
         ;   Port B bit 1 ...
         ;   Port B bit 2 ...
         ;   Port B bit 3 ... RS232 Data Terminal Ready MAX T3 DB9 pin 4
         ;   Port B bit 4 ...
         ;   Port B bit 5 ... SPI MOSI
         ;   Port B bit 6 ... SPI MISO
         ;   Port B bit 7 ... SPI SCK  serial data clock
         ;
         ;   Port C all bits ... Address bus bits 15..8
         ;
         ;   Port D bit 0 ... RS232 Receive Data        MAX R1 DB9 pin 2
         ;   Port D bit 1 ... RS232 Transmit Data       MAX T1 DB9 pin 3
         ;   Port D bit 2 ... RS232 Data Carrier Detect MAX R4 DB9 pin 1
         ;   Port D bit 3 ... RS232 Data Set Ready      MAX R3 DB9 pin 6
         ;   Port D bit 4 ... RS232 Ring Indicator      MAX R2 DB9 pin 9
         ;   Port D bit 5 ... RS232 Request to Send     MAX T2 DB9 pin 7
         ;   Port D bit 6 ... memory write negative strobe
         ;   Port D bit 7 ... memory read negative enable
         ;
         ;
         ; Functinal Description:
         ; ----------------------
         ;
         ; The TASKER function checks for events having happened and performs 
         ; the actions defined for specific events defined in the TASK TABLE
         ;
         ; events have EVENT CLASSES and EVENT IDs
         ;
         ; EVENT CLASS   01 ... key action       EVENT ID is KEY ACTION CODE
         ;
         ; actions have ACTION CLASSES and ACTION IDs
         ;
         ; ACTION CLASS  
         ;               01 ... ON_BI_RELAY
         ;               02 ... OFF_BI_RELAY
         ;               03 ... TOGGLE_BI_RELAY 
         ;		04 ... ON_MO_RELAY
         ;		05 ... OFF_MO_RELAY
         ;		06 ... TOGGLE_MO_RELAY
         ;
         ; a BI_RELAY is assumed to be controlled by 2 I/O LINEs, #0 for OFF-pulse, #1 for ON-PULSE
         ;   BI_RELAYs count from 00..15,
         ;             00 controlled by I/O LINE 00,01
         ;             01 controlled by I/O LINE 02,03
         ;                       ....
         ;             15 controlled by I/O LINE 30,31
         ;
         ; a MO_RELAY is assumed to be controlled by 1 I/O LINE, ON for ON, OFF for OFF
         ;   MO_RELAYs count from 00..31,
         ;             00 controlled by I/O LINE 00
         ;                       ....
         ;             31 controlled by I/O LINE 31
         ;
         ; I/O lines are counted from 0 to 31,
         ;     00..07 controlled by writing to address 8000
         ;     08..15 controlled by writing to address 8001
         ;     16..23 controlled by writing to address 8002
         ;     24..31 controlled by writing to address 8003
         ;
         ;
         ; -------------------------------------------------------------------
         ;
         ; Register allocation
         ;
         ;				reg	1st	2nd
         ;					use	use
         ;
         ; R0				R16	P1	ROWNUM	parameter 1
         ; R1				R17	P2	COLNUM	parameter 2
         ; R2				R18	P3	ROW	parameter 3
         ; R3				R19	TEMP	LAST	temporary
         ; R4				R20	INDEX	CHG	array index temporary
         ; R5				R21	OP2	I	operand 2 for operations
         ; R6				R22	OP3	J	operand 3 for operations
         ; R7				R23	OP4	K	operand 4 for operations
         ; R8				R24	MASK		bit mask for operations
         ; R9				R25	MASK2		2nd bit mask
         ; R10				R26	Xlow
         ; R11				R27	Xhigh
         ; R12				R28	Ylow
         ; R13				R29	Yhigh
         ; R14				R30	Zlow
         ; R15				R31	Zhigh
         ;
         ;
          .DEF	p1	=	r16
          .DEF	p2	=	r17
          .DEF	p3	=	r18
          .DEF	temp	=	r19
          .DEF	index	=	r20
          .DEF	op2	=	r21
          .DEF	op3	=	r22
          .DEF	op4	=	r23
          .DEF	mask	=	r24
          .DEF	mask2	=	r25
         ;
          .DEF	rownum	=	R16
          .DEF	colnum	=	R17
          .DEF	row	=	R18
          .DEF	last	=	R19
          .DEF	chg	=	R20
         ;
          .DEF	i	=	R21
          .DEF	j	=	R22
          .DEF	k	=	R23
         ; 
         ; -------------------------------------------------------------------
         ;
         ; ----- Constants definitions ----------
         ;
          .SET	t1div	= (4000000/8)/50	; 20 msec. interval time
         ;
          .SET	numofrelays	=	32	; there are 32 relays
         ;
         ; pulser time definitions
         ;
          .set	pulsoncnt	=	15	; 15 cycles = 300 ms ON delay
          .set	pulsoffcnt	=	15	; 15 cycles = 300 ms OFF delay
         ;
         ;
         ; -------------------------------------------------------------------
         ;
         ; HCS01 board definitions
         ;
         ; Memory range
         ;
          .equ	XRAMBEGIN=$0260
          .equ	XRAMTOP  =$7FFF
         ;
         ; Memory mapped I/O
         ;
          .dseg
          .org	0x8000
008000      xport0:	.byte	1	; external I/O port 0
008001      xport1:	.byte	1	; external I/O port 1
008002      xport2:	.byte	1	; external I/O port 2
008003      xport3:	.byte	1	; external I/O port 3
008004      xport4:	.byte	1	; external I/O port 4
008005      xport5:	.byte	1	; external I/O port 5
008006      xport6:	.byte	1	; external I/O port 6
008007      xport7:	.byte	1	; external I/O port 7
         ;
          .equ	keyscan=xport7	; keyboard scan lines on external port 7
          .equ	keysens=xport7  ; keyboard return lines on external port 7
          .equ	reldrv1=xport0	; relay driver for relay 0..3   on external port 0
          .equ	reldrv2=xport1	; relay driver for relay 4..7   on external port 1
          .equ	reldrv3=xport2	; relay driver for relay 8..15  on external port 0
          .equ	reldrv4=xport3	; relay driver for relay 16..23 on external port 1
         ;
         ; I/O Port definitions
         ;
          .equ	actled	=0		; activity LED is bit 0 of Port B
          .equ	serDTR  =3		; DTR of serial interface is bit 3
         
          .equ	serDCD	=2 		; DCD is bit 2 of Port D
          .equ	serDSR	=3		; DSR is bit 3 of Port D
          .equ	serRI	=4		; RI  is bit 4 of Port D
          .equ	serRTS	=5		; RTS is bit 5 of Port D
         ;
         ;  cell structure definition
         ;
          .equ	cflag	=0		; offset to usage flag 
          .equ	cnext	=1		; offset to next pointer
          .equ	csize	=3		; offset to cell data size
          .equ	cdata	=4		; offset to cell data
          .equ	CELLSIZE=11
         
         ;
         ; -------------------------------------------------------------------
         ;
         ; DATA STORAGE
         ;
          .dseg
          .org	0x60
000060      tcnt:	.byte	1	; timer counter, divides Timer1 cycle further
000061      kcnt:	.byte	1	; timer counter for keyscan timer1 division
000062      pbbuf:	.byte   1       ; buffer for Port B output bits
000063      pdbuf:	.byte	1	; buffer for Port D output bits
         ;
000064      repmod:	.byte	1	; repeat mode, 0=none, 1=repeat, 2=repeat with HOME
         ;
000065      keyrow:	.byte	1	; counts current key row number
000066      keyscn:	.byte	1	; current key scan buffer
000067      keycmd:	.byte	1	; command from key matrix, bit 7 is BUSY flag
         ;
         ; relay pulser control
         ;
000068      pulscmd:	.byte	1	; command byte to pulser
         				; bit 8 is BUSY flag
000069      pulsstat:	.byte	1	; current state of pulser:
         				; 0 .. idle, wait for command
00006a      pulsrnum:	.byte	1	; relay number to control
00006b      pulsdcnt:	.byte	1	; counter for delay cycles
00006c      pulsmask:	.byte	1	; bit mask for controlling output line
         ;
         ; output switcher control
         ;
00006d      swicmd:		.byte	1	; command byte to switcher
         ;
         ; tasker control
         ;
00006e      taskstat:	.byte	1	; tasker state
00006f      taskp1:		.byte	1	; tasker parameter 1
000070      taskp2:		.byte	1	; tasker parameter 2
000071      tasktabptr:	.byte	2
000073      taskdis:	.byte	1	;  <>0 to disable TASKER
         ;
         ; debug control
         ;
000074      debugctl:	.byte	1	; 8 debug classes
000075      timdis:		.byte	1	; <>0 to disable timer treatment
         ;
000076      moncmd:		.byte	1	; monitor command character
000077      monpcnt:	.byte	1	; number of monitor command parameters
000078      monp1:		.byte	2	; parameter 1 for monitor commands
00007a      monp2:		.byte	2	; parameter 2 for monitor commands
00007c      monp3:		.byte	2	; parameter 3 for monitor commands
00007e      monp4:		.byte	2	; parameter 4 for monitor commands
000080      monp5:		.byte	2	; parameter 5 for monitor commands
000082      monp6:		.byte	2	; parameter 6 for monitor commands
000084      monp7:		.byte	2	; parameter 7 for monitor commands
000086      monp8:		.byte	2	; parameter 8 for monitor commands
         ;
          .org	XRAMBEGIN
         ;
         ; ------ KEY scan storage ---------
         ;
          .set	numofkeyrows=8
          .set	numofkeycols=8
          .set	numofkeybufs=2
         ;
          keybuf:
000260      keysbuf:	.byte	numofkeyrows	; key scan states
000268      keydbuf:	.byte	numofkeyrows	; debounced key states
         ;
000270      evtquehead:	.byte	2	; pointer to event queue head
000272      evtquetail:	.byte	2	; pointer to event queue
         ;
000274      cellpool:	.byte	(100*CELLSIZE)	; 100 cells 32 bytes each
          .set	cellpoolend=PC
          .set	cellpoolsize=cellpoolend-cellpool
         ;
         ; driver buffer
         ;
0006c0      reldrvbuf:	.byte	4
         ;
         ; ------- RELAY control storage --------------------
         ;
0006c4      birelaybuffer:	.byte	16	; 1 byte state memory for each BI-relay
0006d4      morelaybuffer:	.byte	31	; 1 byte state memory for each MO-relay
         ;
         ; ------- TASKER control table storage -------------
         ;
          .set	tasktabentsiz=4		; task table entry has 4 bytes:
         				; event class:	00 ... end of task table
         				;		01 ... KEY state change
         				; event ID
         				; action class:	01 ... relay ON
         				;		02 ... relay OFF
         				;		03 ... relay toggle
         				; action ID
         ;
0006f3      tasktab:	.byte	(200*tasktabentsiz)	; 200 task control entries
         ;
         ; ------- UART transmit buffer ---------------------
         ;
         ; +CFG+
         ;
          .SET	txbufsize	=	2000	; size in bytes for UART transmit buffer
         ;
         ; -CFG-
         ;
000a13      txbuf:		.byte	txbufsize		; UART transmit buffer
         ;
         ; -------------------------------------------------------------------
         ; 
         ; MACROS
         ;
          .MACRO chkdbg
                 push	temp
                 ldi	temp,@0
                 rcall	chk_debug
                 pop	temp
          .ENDMACRO
         ;
          .MACRO DBGOUT
                 push	zl
                 push	zh
                 push	p1
                 push	p2
                 ldi	zl,low(@0*2)
                 ldi	zh,high(@0*2)
                 mov	p1,@1
                 mov	p2,@2
                 rcall	debug_out
                 pop	p2
                 pop	p1
                 pop	zh
                 pop	zl
          .ENDMACRO
         ;
          .MACRO DBGOUTSS
                 push	zl
                 push	zh
                 push	p1
                 push	p2
                 ldi	zl,low(@0*2)
                 ldi	zh,high(@0*2)
                 lds	p1,@1
                 lds	p2,@2
                 rcall	debug_out
                 pop	p2
                 pop	p1
                 pop	zh
                 pop	zl
          .ENDMACRO
         ;
         ; -------------------------------------------------------------------
         ;
         ; RESET and INTERRUPT vectors
         ;
          .cseg
          .org	0
000000 c581      	rjmp	RESET	; main hardware reset vector
         
          .org	OC1Aaddr
000004 c093      	rjmp	T1OVER	; Timer 1 overflow handler
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:     INITKEYS
         ; ACTION:       initialize key state buffer
         ;
          initkeys:
000005 e170              ldi     op4,(numofkeybufs*numofkeyrows)
000006 e6a0              ldi     xl,LOW(keybuf)
000007 e0b2              ldi     xh,HIGH(keybuf)
          inikey1:
000008 e030              ldi     temp,0
000009 933d              st      X+,temp
00000a 957a              dec     op4
00000b f7e1              brne    inikey1
00000c 9508              ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	INITCELLS
         ; ACTION:	initialize cell pool by marking all cells as free
         ;		(flag byte set to value 0)
         ;
          initcells:
00000d e7a4      	ldi	xl,low(cellpool)
00000e e0b2      	ldi	xh,high(cellpool)
00000f e8cc      	ldi	yl,low(cellpoolsize)
000010 efdd      	ldi	yh,high(cellpoolsize)
          initcellloop:
000011 e030      	ldi	temp,0
000012 933d      	st	X+,temp
000013 9721      	sbiw	yl,1
000014 2f3c      	mov	temp,yl
000015 2b3d      	or	temp,yh
000016 f7d1      	brne	initcellloop
000017 9508      	ret
         	
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	INITEVTQUE
         ; ACTION:	initialize event que by zeroing head and tail pointer
         ;
          initevtque:
000018 e030      	ldi	temp,0
000019 9330 0270 	sts	evtquehead,temp
00001b 9330 0271 	sts	evtquehead+1,temp
00001d 9330 0272 	sts	evtquetail,temp
00001f 9330 0273 	sts	evtquetail+1,temp
000021 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          initpulser:
000022 e030      	ldi	temp,0
000023 9330 0069 	sts	pulsstat,temp
000025 9330 006a 	sts	pulsrnum,temp
000027 9330 006b 	sts	pulsdcnt,temp
000029 9330 8000 	sts	reldrv1,temp
00002b 9330 8001 	sts	reldrv2,temp
00002d 9330 8002 	sts	reldrv3,temp
00002f 9330 8003 	sts	reldrv4,temp
000031 9330 0068 	sts	pulscmd,temp
000033 ecc4      	ldi	yl,low(birelaybuffer)
000034 e0d6      	ldi	yh,high(birelaybuffer)
000035 e340      	ldi	index,16+32		; initialize relay buffers
          ipl1:
000036 9339      	st	Y+,temp			; ... to 00
000037 954a      	dec	index
000038 f7e9      	brne	ipl1
          ipl1end:
000039 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          initswitcher:
00003a e030      	ldi	temp,0
00003b 9330 006d 	sts	swicmd,temp
00003d 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          initscanner:
00003e ef3e      	ldi	temp,0xFE
00003f 9330 0066 	sts	keyscn,temp		; drive keyrow 0
000041 9330 8007 	sts	keyscan,temp	
000043 e030      	ldi	temp,0x00
000044 9330 0065 	sts	keyrow,temp		; current keyrow is 0
000046 9330 0061 	sts	kcnt,temp		; initialize key divider
000048 9330 0067 	sts	keycmd,temp
00004a 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          inittasker:
00004b e030      	ldi	temp,0
00004c 9330 0073 	sts	taskdis,temp		;  init to enabled
00004e 9330 006e 	sts	taskstat,temp
000050 e6e4      	ldi	zl,low(initasktab*2)
000051 e0fb      	ldi	zh,high(initasktab*2)
000052 efc3      	ldi	yl,low(tasktab)
000053 e0d6      	ldi	yh,high(tasktab)
000054 93c0 0071 	sts	tasktabptr,yl
000056 93d0 0072 	sts	tasktabptr+1,yh
          itl:
000058 95c8      	lpm
000059 9631      	adiw	zl,1
00005a 2d00      	mov	p1,r0
00005b 9209      	st	Y+,r0
00005c 95c8      	lpm
00005d 9631      	adiw	zl,1
00005e 9209      	st	Y+,r0
00005f 95c8      	lpm
000060 9631      	adiw	zl,1
000061 9209      	st	Y+,r0
000062 95c8      	lpm
000063 9631      	adiw	zl,1
000064 9209      	st	Y+,r0
000065 3000      	cpi	p1,0		; end of initial table ?
000066 f789      	brne	itl
000067 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	INIT
         ; ACTION:	Initializes storage and i/o for STK200MON
         ;
          INIT:
000068 e030      	ldi	temp,0			; set timer counter to 0
000069 9330 0060 	sts	tcnt,temp
00006b 9330 0064         sts     repmod,temp             ; initialize command repeat mode
00006d 9330 0074 	sts	debugctl,temp		; reset debug mode
00006f 9330 0075 	sts	timdis,temp		; reset timer disabler
         
000071 d383      	rcall	setupsram
         
000072 e139      	ldi	temp,25
000073 b939      	out	UBRR,temp		; set baudrate to 9600 (0.2% error) 
         	                                ; ... at 4MHz XTAL frequency
000074 e138      	ldi	temp,0b00011000		; set UART control:
000075 b93a      	out	UCR,temp		; RXC interrupt disabled
         					; TXC interrupt disabled
         					; UDR empty interrupt disabled
         					; RX enable
         					; TX enable
         					; no 9-bit characters
         					; RX8/TX8 set to 0
         	
000076 e03f      	ldi	temp,0x0F		; set port B low nibble to output
000077 bb37      	OUT	DDRB,temp
000078 ef3f      	ldi	temp,0xb00001101	; initialize Port B data
000079 9330 0062 	sts	pbbuf,temp
00007b bb38      	out	PORTB,temp 		; Write initial value to PORTB
         
00007c e232      	ldi	temp,0b00100010		; set port D data direction
00007d bb31      	out	DDRD,temp
00007e ef3f      	ldi	temp,0xFF
00007f 9330 0063 	sts	pdbuf,temp
000081 bb32      	out 	PORTD,temp
         
000082 dfbb      	rcall	initscanner
000083 dfb6      	rcall	initswitcher
000084 df9d      	rcall	initpulser
000085 df87      	rcall	initcells
000086 df91      	rcall	initevtque
000087 df7d              rcall   initkeys
000088 dfc2      	rcall	inittasker
         
000089 e237      	ldi temp,high(t1div) 		; Load compare high value
00008a bd3b      	out OCR1AH,temp
00008b e130      	ldi temp,low(t1div) 		; Load compare low value
00008c bd3a      	out OCR1AL,temp
00008d e030      	ldi temp,0x00
00008e bd3d      	out TCNT1H,temp 		; Clear timer high byte
00008f bd3c      	out TCNT1L,temp 		; Clear timer low byte
000090 bd3f      	out TCCR1A,temp 		; Clear timer control reg A
000091 e430      	ldi temp,0x40
000092 bf38      	out TIFR,temp 			; Clear pending timer interrupt
000093 bf39      	out TIMSK,temp 			; Enable Timer compare interrupt	
000094 e03a      	ldi temp,0xA
000095 bd3e      	out TCCR1B,temp 		; Clear timer on compare match,CK/8
         
000096 9478      	sei 				; Enable global interrupt
         		
000097 9508      	RET	
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	T1OVER
         ; ACTION:	timer 1 overflow interrupt routine
         ;
          T1OVER:
000098 933f      	push	temp
000099 b73f      	in	temp,SREG
00009a 933f      	push	temp
00009b 931f      	push	r17
00009c 9130 0075 	lds	temp,timdis
00009e 2333      	tst	temp
00009f f009      	breq	t1nodis
0000a0 c01e      	rjmp	t1overe
          t1nodis:
0000a1 9130 0060 	lds	temp,tcnt
0000a3 9533      	inc	temp
0000a4 9330 0060 	sts	tcnt,temp
0000a6 303a      	cpi	temp,10			; divide down to 5 Hz (20ms*10 )
0000a7 f050      	brlo	t1over1
0000a8 e030      	ldi	temp,0
0000a9 9330 0060 	sts	tcnt,temp
         ;
         ; let activity LED blink
         ;
0000ab 9130 0062 	lds	temp,pbbuf
0000ad e011      	ldi	r17,0b00000001
0000ae 2731      	eor	temp,r17
0000af 9330 0062 	sts	pbbuf,temp
0000b1 bb38      	out	PORTB,temp
         ;
          t1over1:
0000b2 9130 0061 	lds	temp,kcnt
0000b4 9533      	inc	temp
0000b5 9330 0061 	sts	kcnt,temp
0000b7 3031      	cpi	temp,1			; divide down
0000b8 f020      	brlo	t1over2
0000b9 e030      	ldi	temp,0
0000ba 9330 0061 	sts	kcnt,temp
         ;
         ; perform next key scan
         ;
0000bc d007      	rcall	scankey
         ;
         ; perform next pulsing action
         ;
          t1over2:
0000bd d0a6      	rcall	pulser
         ;
         ; perform next switching action
         ;
0000be d06c      	rcall	switcher
         ;
          t1overe:
0000bf 911f      	pop	r17
0000c0 913f      	pop	temp
0000c1 bf3f      	out	SREG,temp
0000c2 913f      	pop	temp
0000c3 9518      	reti
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	SCANKEY
         ; ACTION:	analyzes the current scanned key row,
         ;               generates key change messages and
         ;               moves scan hardware to next row
         ;
         ;
          scankey:
0000c4 93af      	push	XL
0000c5 93bf      	push	XH
0000c6 93cf      	push	YL
0000c7 93df      	push	YH
0000c8 930f      	push	rownum
0000c9 931f      	push	colnum
0000ca 932f      	push	row
0000cb 933f      	push	last
0000cc 934f      	push	chg
0000cd 935f      	push	i
0000ce 2744      	clr	chg
0000cf 9100 0065 	lds	rownum,keyrow
0000d1 e650      	ldi	i,low(keysbuf)
0000d2 0f50      	add	i,rownum
0000d3 2fa5      	mov	xl,i
0000d4 e052      	ldi	i,high(keysbuf)
0000d5 1f54      	adc	i,chg
0000d6 2fb5      	mov	xh,i		; let X point to this row's scan buffer
0000d7 e658      	ldi	i,low(keydbuf)
0000d8 0f50      	add	i,rownum
0000d9 2fc5      	mov	yl,i
0000da e052      	ldi	i,high(keydbuf)
0000db 1f54      	adc	i,chg
0000dc 2fd5      	mov	yh,i		; let Y point to this row's debounced buffer
         
0000dd 9120 8007 	lds	row,keysens	; get column return lines to ROW
0000df ef4f      	ldi	chg,0xFF
0000e0 2724      	eor	row,chg		; convert to positive logic
0000e1 913c      	ld	last,X
0000e2 2f52      	mov	i,row
0000e3 2353      	and	i,last		; AND with last sample to debounce
0000e4 932c      	st	X,row		; memorize this sample as last sample
0000e5 8138      	ld	last,Y		; get last debounced state
0000e6 8358      	st	Y,i		; memorize new debounced state
0000e7 2f25      	mov	row,i
0000e8 2f45      	mov	chg,i
0000e9 2743      	eor	chg,last	; check for a change
0000ea f0c9      	breq	scannext	; = no change, all done
0000eb e010      	ldi	colnum,0	; scan thru all 8 keys in this row
          scnonecol:
0000ec 9546      	lsr	chg		; "changed" flag for column <colnum> to C
0000ed f490      	brcc	scnnxtnoc	; = no change
0000ee 9526      	lsr	row		; get new key state to C
0000ef 2755      	clr	i
0000f0 9557      	ror	i
0000f1 9557      	ror	i		; new key state to bit 6
0000f2 2f40      	mov	chg,rownum
0000f3 0f44      	lsl	chg
0000f4 0f44      	lsl	chg
0000f5 0f44      	lsl	chg
0000f6 2b54      	or	i,chg		; row number to bits 5,4,3
0000f7 2b51      	or	i,colnum	; column number to bits 2,1,0
         
0000f8 9140 0067 	lds	chg,keycmd	; check key command
0000fa 7840      	andi	chg,0x80
0000fb f421      	brne	scnnxtnoc	; = busy cannot place command
0000fc 6850      	ori	i,0x80		; mark command busy
0000fd 9350 0067 	sts	keycmd,i	; place key command
0000ff c001      	rjmp	scnnxtcol
          scnnxtnoc:
000100 9526      	lsr	row
          scnnxtcol:
000101 9513      	inc	colnum
000102 3018      	cpi	colnum,numofkeycols
000103 f741      	brne	scnonecol
          scannext:
000104 9150 0066 	lds	i,keyscn
000106 9503      	inc	rownum		; next key row
000107 9408      	sec
000108 1f55      	rol	i
000109 3008      	cpi	rownum,numofkeyrows	; have to wrap around ?
00010a f411      	brne	scannowrap
00010b e000      	ldi	rownum,0	; jump back to row 0
00010c ef5e      	ldi	i,0xFE		; scan pattern for row 0
          scannowrap:
00010d 9350 0066 	sts	keyscn,i	; memorize scanmask
00010f 9350 8007 	sts	keyscan,i	; set scan output port
000111 9300 0065 	sts	keyrow,rownum	; memorize row number
         
000113 915f      	pop	i
000114 914f      	pop	chg
000115 913f      	pop	last
000116 912f      	pop	row
000117 911f      	pop	colnum
000118 910f      	pop	rownum
000119 91df      	pop	YH
00011a 91cf      	pop	YL
00011b 91bf      	pop	XH
00011c 91af      	pop	XL
00011d 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	makemask
         ; INPUT:	TEMP - number 0..7
         ; OUTPUT:	TEMP - bit number 0..7 set
         ;
          makemask:
00011e 935f      	push	i
00011f 2f53      	mov	i,temp
000120 7057      	andi	i,0x07
000121 e030      	ldi	temp,0		; initialize mask to 0
000122 9408      	sec			; preset bit to be rotated into from LSB
          makmsk0:
000123 1f33      	rol	temp		; move bit to next position
000124 2355      	tst	i
000125 f019      	breq	makmsk1
000126 955a      	dec	i		
000127 9488      	clc
000128 cffa      	rjmp	makmsk0
          makmsk1:
000129 915f      	pop	i
00012a 9508      	ret	
         ;
         ; LoaDImmediateWordwithOFfSetfromRegister
         ;
         ; @0 ... register name holding low byte
         ; @1 ... register name holding high byte
         ; @2 ... value to be loaded to register
         ; @3 ... register name holding offset
         ;
          .MACRO	LDIWOFSR
          	push	@3
          	ldi	@0,low(@2)
          	add	@0,@3
          	ldi	@1,high(@2)
          	ldi	@3,0
          	adc	@1,@3
          	pop	@3
          .ENDMACRO
         
          .LISTMAC
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	switcher
         ; ACTION:	process witcher command if any present
         ;
          switcher:
00012b 933f      	push	temp
00012c 935f      	push	i
00012d 936f      	push	j
00012e 937f      	push	k
00012f 93af      	push	xl
000130 93bf      	push	xh
000131 93cf      	push	yl
000132 93df      	push	yh
         
000133 9130 006d 	lds	temp,swicmd
000135 2333      	tst	temp
000136 f121      	breq	swiend		; = no command, nothing to do
         
         	; got command, bit 0 is ON(1)/OFF(0)
         	;              bit 1..5 is MO-RELAY number
         	;			1,2,3 ... bit number
         	;			4,5 ..... output port number
         
         
000137 fb30      	bst	temp,0		; ON/OFF flag to T-flag
000138 2f53      	mov	i,temp		; memorize command 
000139 7051      	andi	i,0x01		; new state to I
00013a 9536      	lsr	temp
00013b 2f73      	mov	k,temp
00013c dfe1      	rcall	makemask	; bit mask to TEMP
00013d 9576      	lsr 	k
00013e 9576      	lsr	k
00013f 9576      	lsr	k		
000140 7073      	andi	k,0x03		; byte number to K
000141   +  	LDIWOFSR	xl,xh,reldrvbuf,k	; X points to driver buffer byte
000141 937f      	push	k
000142 eca0      	ldi	xl,low(reldrvbuf)
000143 0fa7      	add	xl,k
000144 e0b6      	ldi	xh,high(reldrvbuf)
000145 e070      	ldi	k,0
000146 1fb7      	adc	xh,k
000147 917f      	pop	k
          .ENDMACRO
000148   +  	LDIWOFSR	yl,yh,reldrv1,k		; Y points to relay driver port
000148 937f      	push	k
000149 e0c0      	ldi	yl,low(reldrv1)
00014a 0fc7      	add	yl,k
00014b e8d0      	ldi	yh,high(reldrv1)
00014c e070      	ldi	k,0
00014d 1fd7      	adc	yh,k
00014e 917f      	pop	k
          .ENDMACRO
00014f 916c      	ld	j,X		; get current state to J
000150 f026      	brts	swion
         	;
         	; switch selected port OFF
         	;
000151 ef7f      	ldi	k,0xFF
000152 2737      	eor	temp,k
000153 2363      	and	j,temp		; switch bit OFF
000154 c001      	rjmp	swiout
          swion:
000155 2b63      	or	j,temp		; switch bit to ON
          swiout:
000156 936c      	st	X,j		; memorize output line state
000157 8368      	st	Y,j		; set output lines
000158 e030      	ldi	temp,0
000159 9330 006d 	sts	swicmd,temp
          swiend:
00015b 91df      	pop	yh
00015c 91cf      	pop	yl
00015d 91bf      	pop	xh
00015e 91af      	pop	xl
00015f 917f      	pop	k
000160 916f      	pop	j
000161 915f      	pop	i
000162 913f      	pop	temp
000163 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	pulser
         ; ACTION:	proceed with next pulser step
         ;
         ;
          pulser:
000164 933f      	push	temp
000165 935f      	push	i
000166 936f      	push	j
000167 93af      	push	xl
000168 93bf      	push	xh
000169 93cf      	push	yl
00016a 93df      	push	yh
00016b 9130 0069 	lds	temp,pulsstat
00016d 3030      	cpi	temp,0
00016e f541      	brne	pulsnot0
         ;
         ; pulser state 0: wait for command
         ;
00016f 9130 0068 	lds	temp,pulscmd
000171 2333      	tst	temp
000172 f119      	breq	pulsend0	; = no command, nothing to do
         ;
         ; got command: bit 0   ..... ON=1 OFF=0
         ;              bit 1,2 ..... BI-relay number in group
         ;              bit 3,4 ..... BI-relay group number
         ;
000173 2f53      	mov	i,temp
000174 9556      	lsr	i
000175 9556      	lsr	i
000176 9556      	lsr	i
000177 7053      	andi	i,0b00000011	; relay group number
000178 9350 006a 	sts	pulsrnum,i
00017a   +  	LDIWOFSR	xl,xh,reldrv1,i
00017a 935f      	push	i
00017b e0a0      	ldi	xl,low(reldrv1)
00017c 0fa5      	add	xl,i
00017d e8b0      	ldi	xh,high(reldrv1)
00017e e050      	ldi	i,0
00017f 1fb5      	adc	xh,i
000180 915f      	pop	i
          .ENDMACRO
000181   +  	LDIWOFSR	yl,yh,reldrvbuf,i
000181 935f      	push	i
000182 ecc0      	ldi	yl,low(reldrvbuf)
000183 0fc5      	add	yl,i
000184 e0d6      	ldi	yh,high(reldrvbuf)
000185 e050      	ldi	i,0
000186 1fd5      	adc	yh,i
000187 915f      	pop	i
          .ENDMACRO
000188 7037      	andi	temp,0b00000111	; relay+onoff number
000189 df94      	rcall	makemask
00018a 9330 006c 	sts	pulsmask,temp	; memorize mask for turning off afterwards
00018c 8158      	ld	i,Y
00018d 2b35      	or	temp,i
00018e 933c      	st	X,temp		; apply pulse bit
00018f 8338      	st	Y,temp		; memorize driver states
000190 e03f      	ldi	temp,pulsoncnt
000191 9330 006b 	sts	pulsdcnt,temp
000193 e031      	ldi	temp,1
000194 9330 0069 	sts	pulsstat,temp	; change to state 1
          pulsend0:
000196 c034      	rjmp	pulsend
          pulsnot0:
000197 3031      	cpi	temp,1
000198 f529      	brne	pulsnot1
         ;
         ; pulser state 1: pulse applied to relay, wait ON time
         ;
000199 9130 006b 	lds	temp,pulsdcnt
00019b 953a      	dec	temp
00019c 9330 006b 	sts	pulsdcnt,temp
00019e f561      	brne	pulsend		; = not yet delayed enough
         ;
         ; ON delay expired, turn pulse off
         ;
00019f 9160 006a 	lds	j,pulsrnum
0001a1   +  	LDIWOFSR	xl,xh,reldrv1,j
0001a1 936f      	push	j
0001a2 e0a0      	ldi	xl,low(reldrv1)
0001a3 0fa6      	add	xl,j
0001a4 e8b0      	ldi	xh,high(reldrv1)
0001a5 e060      	ldi	j,0
0001a6 1fb6      	adc	xh,j
0001a7 916f      	pop	j
          .ENDMACRO
0001a8   +  	LDIWOFSR	yl,yh,reldrvbuf,j
0001a8 936f      	push	j
0001a9 ecc0      	ldi	yl,low(reldrvbuf)
0001aa 0fc6      	add	yl,j
0001ab e0d6      	ldi	yh,high(reldrvbuf)
0001ac e060      	ldi	j,0
0001ad 1fd6      	adc	yh,j
0001ae 916f      	pop	j
          .ENDMACRO
0001af 9130 006c 	lds	temp,pulsmask
0001b1 ef5f      	ldi	i,0xFF
0001b2 2735      	eor	temp,i
0001b3 8158      	ld	i,Y
0001b4 2353      	and	i,temp		; turn off bit
0001b5 8358      	st	Y,i		; memorize new output line state
0001b6 935c      	st	X,i		; set output lines
0001b7 e03f      	ldi	temp,pulsoffcnt
0001b8 9330 006b 	sts	pulsdcnt,temp
0001ba e032      	ldi	temp,2
0001bb 9330 0069 	sts	pulsstat,temp
0001bd c00d      	rjmp	pulsend
          pulsnot1:
0001be 3032      	cpi	temp,2
0001bf f459      	brne	pulsnot2
         ;
         ; pulser state 2: pulse removed from relay, wait OFF time
         ;
0001c0 9130 006b 	lds	temp,pulsdcnt
0001c2 953a      	dec	temp
0001c3 9330 006b 	sts	pulsdcnt,temp
0001c5 f429      	brne	pulsend		; = not yet delayed enough
         ;
         ; OFF delay expired, command completed
         ;
0001c6 e030      	ldi	temp,0
0001c7 9330 0068 	sts	pulscmd,temp
0001c9 9330 0069 	sts	pulsstat,temp
          pulsnot2:
          pulsend:
0001cb 91df      	pop	yh
0001cc 91cf      	pop	yl
0001cd 91bf      	pop	xh
0001ce 91af      	pop	xl
0001cf 916f      	pop	j
0001d0 915f      	pop	i
0001d1 913f      	pop	temp
0001d2 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	CALCMOPARAM
         ; INPUT:	<TASKP2>-	relay number
         ; OUTPUT:	X	-	points to relay buffer
         ;		Y	-	points to relay drive port
         ;		Z	-	point to relay state port
         ;		MASK	-	contains byte mask with relay bit set
         ;
          calcmoparam:
0001d3 9130 0070 	lds	temp,taskp2	; relay number
0001d5 713f      	andi	temp,0b00011111 ; limit to 0..31
0001d6   +  	LDIWOFSR zl,zh,morelaybuffer,temp  ; point to relay state byte
0001d6 933f      	push	temp
0001d7 ede4      	ldi	zl,low(morelaybuffer)
0001d8 0fe3      	add	zl,temp
0001d9 e0f6      	ldi	zh,high(morelaybuffer)
0001da e030      	ldi	temp,0
0001db 1ff3      	adc	zh,temp
0001dc 913f      	pop	temp
          .ENDMACRO
0001dd 9536      	lsr	temp
0001de 9536      	lsr	temp
0001df 9536      	lsr	temp
0001e0 7037      	andi	temp,0x07	; relay byte number
0001e1   +  	LDIWOFSR  xl,xh,reldrvbuf,temp	; point to buffer port
0001e1 933f      	push	temp
0001e2 eca0      	ldi	xl,low(reldrvbuf)
0001e3 0fa3      	add	xl,temp
0001e4 e0b6      	ldi	xh,high(reldrvbuf)
0001e5 e030      	ldi	temp,0
0001e6 1fb3      	adc	xh,temp
0001e7 913f      	pop	temp
          .ENDMACRO
0001e8   +  	LDIWOFSR  yl,yh,reldrv1,temp	; point to driver port
0001e8 933f      	push	temp
0001e9 e0c0      	ldi	yl,low(reldrv1)
0001ea 0fc3      	add	yl,temp
0001eb e8d0      	ldi	yh,high(reldrv1)
0001ec e030      	ldi	temp,0
0001ed 1fd3      	adc	yh,temp
0001ee 913f      	pop	temp
          .ENDMACRO
0001ef 9130 0070 	lds	  temp,taskp2		; relay number
0001f1 df2c      	rcall	  makemask
0001f2 2f83      	mov	  mask,temp
0001f3 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          .SET	tskevtdbg	=	0b00000001
          .SET	tskactdbg	=	0b00000010
          .SET	tsknstdbg	=	0b00000100
         ;
0001f4      tskevtmsg:	.db	'T','A','S','K','E','R','/','E','V','T','/',0
0001f4 4154
0001f5 4b53
0001f6 5245
0001f7 452f
0001f8 5456
0001f9 002f
0001fa      tskactmsg:	.db	'T','A','S','K','E','R','/','A','C','T','/',0
0001fa 4154
0001fb 4b53
0001fc 5245
0001fd 412f
0001fe 5443
0001ff 002f
000200      tsknstmsg:	.db	'T','A','S','K','E','R','/','N','S','T','/',0
000200 4154
000201 4b53
000202 5245
000203 4e2f
000204 5453
000205 002f
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	tasker
         ;
          tasker:
000206 933f      	push	temp
000207 9130 0073 	lds	temp,taskdis		; check if disabled
000209 2333      	tst	temp
00020a f009      	breq	taskernodis
00020b c0b6      	rjmp	taskerexit
          taskernodis:	
00020c 93af      	push	xl
00020d 93bf      	push	xh
00020e 935f      	push	i
00020f 936f      	push	j
000210 9130 006e 	lds	temp,taskstat
000212 3030      	cpi	temp,0
000213 f009      	breq	task0
000214 c056      	rjmp	tasknot0
          task0:	
         ;
         ; tasker state 0: waiting for event
         ;
000215 d0ae      	rcall	getevent
000216 3000      	cpi	p1,0
000217 f409      	brne	task0evt
000218 c051      	rjmp	task0end
          task0evt:	
         ;
         ; got event
         ;
000219   +  	CHKDBG	tskevtdbg
000219 933f             push	temp
00021a e031             ldi	temp,tskevtdbg
00021b d10b             rcall	chk_debug
00021c 913f             pop	temp
          .ENDMACRO
00021d f069      	breq	taskendbg
00021e   +  	DBGOUT	tskevtmsg,p1,p2
00021e 93ef             push	zl
00021f 93ff             push	zh
000220 930f             push	p1
000221 931f             push	p2
000222 eee8             ldi	zl,low(tskevtmsg*2)
000223 e0f3             ldi	zh,high(tskevtmsg*2)
000224 2f00             mov	p1,p1
000225 2f11             mov	p2,p2
000226 d106             rcall	debug_out
000227 911f             pop	p2
000228 910f             pop	p1
000229 91ff             pop	zh
00022a 91ef             pop	zl
          .ENDMACRO
          taskendbg:
00022b d0a7      	rcall	findevtact	; is there an action for this event
00022c 9130 006f 	lds	temp,taskp1
00022e 3030      	cpi	temp,0
00022f f1d1      	breq	task0end
         ;
         ; found action to be performed
         ;
000230   +  	CHKDBG	tskactdbg
000230 933f             push	temp
000231 e032             ldi	temp,tskactdbg
000232 d0f4             rcall	chk_debug
000233 913f             pop	temp
          .ENDMACRO
000234 f079      	breq	taskandbg
000235   +  	DBGOUTSS	tskactmsg,taskp1,taskp2
000235 93ef             push	zl
000236 93ff             push	zh
000237 930f             push	p1
000238 931f             push	p2
000239 efe4             ldi	zl,low(tskactmsg*2)
00023a e0f3             ldi	zh,high(tskactmsg*2)
00023b 9100 006f        lds	p1,taskp1
00023d 9110 0070        lds	p2,taskp2
00023f d0ed             rcall	debug_out
000240 911f             pop	p2
000241 910f             pop	p1
000242 91ff             pop	zh
000243 91ef             pop	zl
          .ENDMACRO
          taskandbg:
000244 3031      	cpi	temp,1		; BI-RELAY ON ?
000245 f021      	breq	task0wait
000246 3032      	cpi	temp,2		; BI-RELAY OFF
000247 f011      	breq	task0wait
000248 3033      	cpi	temp,3		; BI-RELAY toggle
000249 f421      	brne	task0not3
          task0wait:
00024a e031      	ldi	temp,1		; wait for relay command ready
00024b 9330 006e 	sts	taskstat,temp
00024d c01c      	rjmp	task0end
          task0not3:
00024e 3034      	cpi	temp,4		; MO-RELAY ON ?
00024f f441      	brne	task0not4
000250 df82      	rcall	calcmoparam
          task04do:
000251 e031      	ldi	temp,1
000252 8330      	st	Z,temp		; relay state to ON
000253 913c      	ld	temp,X
000254 2b38      	or	temp,mask
          task045com:
000255 933c      	st	X,temp
000256 8338      	st	Y,temp
000257 c012      	rjmp	task0end
          task0not4:
000258 3035      	cpi	temp,5		; MO-RELAY OFF ?
000259 f441      	brne	task0not5
00025a df78      	rcall	calcmoparam
          task05do:
00025b e030      	ldi	temp,0
00025c 8330      	st	Z,temp		; relay state to OFF
00025d ef3f      	ldi	temp,0xFF
00025e 2783      	eor	mask,temp	; invert mask to turn off
00025f 913c      	ld	temp,X
000260 2338      	and	temp,mask	; mask OFF relay bit
000261 cff3      	rjmp	task045com
          task0not5:
000262 3036      	cpi	temp,6		; MO-RELAY TOGGLE ?
000263 f429      	brne	task0not6
000264 df6e      	rcall	calcmoparam
000265 8130      	ld	temp,Z		; get current state
000266 2333      	tst	temp		; on or off ?
000267 f799      	brne	task05do	; on => turn OFF
000268 cfe8      	rjmp	task04do	; off => turn ON
          task0not6:
000269 c000      	rjmp	task0end
          task0end:
00026a c053      	rjmp	taskend
          tasknot0:
00026b 3031      	cpi	temp,1
00026c f591      	brne	tasknot1
         ;
         ; tasker state 1: wait for relay command ready
         ;
00026d 9130 0068 	lds	temp,pulscmd
00026f 7830      	andi	temp,0x80
000270 f569      	brne	task1end	; = still busy, keep waiting
000271 9130 006f 	lds	temp,taskp1	; see what to do now
000273 3031      	cpi	temp,1		; BI-relay ON ?
000274 f411      	brne	task1not1
000275 ef3f      	ldi	temp,0xFF
000276 c003      	rjmp	task11com
          task1not1:
000277 3032      	cpi	temp,2		; BI-relay OFF ?
000278 f4a9      	brne	task1not2
000279 e030      	ldi	temp,0
          task11com:
00027a 9150 0070 	lds	i,taskp2	; get BI-relay number
00027c   +  	LDIWOFSR	xl,xh,birelaybuffer,i
00027c 935f      	push	i
00027d eca4      	ldi	xl,low(birelaybuffer)
00027e 0fa5      	add	xl,i
00027f e0b6      	ldi	xh,high(birelaybuffer)
000280 e050      	ldi	i,0
000281 1fb5      	adc	xh,i
000282 915f      	pop	i
          .ENDMACRO
000283 933c      	st	X,temp		; memorize new state
000284 fb30      	bst	temp,0		; keep new state in T
000285 0f55      	lsl	i		; build relay number in pulser command
000286 6850      	ori	i,0x80
000287 f950      	bld	i,0		; get new relay state from T
000288 9350 0068 	sts	pulscmd,i	; issue command to pulser
00028a e032      	ldi	temp,2
00028b 9330 006e 	sts	taskstat,temp	; change to state 2
00028d c010      	rjmp	task1end
          task1not2:
00028e 3033      	cpi	temp,3		; toggle BI relay ?
00028f f469      	brne	task1not3
000290 9150 0070 	lds	i,taskp2
000292   +  	LDIWOFSR	xl,xh,birelaybuffer,i
000292 935f      	push	i
000293 eca4      	ldi	xl,low(birelaybuffer)
000294 0fa5      	add	xl,i
000295 e0b6      	ldi	xh,high(birelaybuffer)
000296 e050      	ldi	i,0
000297 1fb5      	adc	xh,i
000298 915f      	pop	i
          .ENDMACRO
000299 913c      	ld	temp,X		; get relay state
00029a ef5f      	ldi	i,0xFF
00029b 2735      	eor	temp,i		; invert state
00029c cfdd      	rjmp	task11com
          task1not3:
00029d c00b      	rjmp	taskreset
          task1end:
00029e c01f      	rjmp	taskend
          tasknot1:
00029f 3032      	cpi	temp,2
0002a0 f441      	brne	tasknot2
         ;
         ; tasker state 2: wait for finally relay command ready
         ;
0002a1 9130 0068 	lds	temp,pulscmd
0002a3 7830      	andi	temp,0x80
0002a4 f419      	brne	task2end	; relay command not ready
0002a5 e030      	ldi	temp,0
0002a6 9330 006e 	sts	taskstat,temp	; return to state IDLE
          task2end:
0002a8 c015      	rjmp	taskend
          tasknot2:
          taskreset:
0002a9 e030      	ldi	temp,0		; reset tasker state to IDLE
          tasknewstate:
0002aa   +  	CHKDBG	tsknstdbg
0002aa 933f             push	temp
0002ab e034             ldi	temp,tsknstdbg
0002ac d07a             rcall	chk_debug
0002ad 913f             pop	temp
          .ENDMACRO
0002ae f069      	breq	tasknndbg
0002af   +  	DBGOUT	tsknstmsg,temp,temp
0002af 93ef             push	zl
0002b0 93ff             push	zh
0002b1 930f             push	p1
0002b2 931f             push	p2
0002b3 e0e0             ldi	zl,low(tsknstmsg*2)
0002b4 e0f4             ldi	zh,high(tsknstmsg*2)
0002b5 2f03             mov	p1,temp
0002b6 2f13             mov	p2,temp
0002b7 d075             rcall	debug_out
0002b8 911f             pop	p2
0002b9 910f             pop	p1
0002ba 91ff             pop	zh
0002bb 91ef             pop	zl
          .ENDMACRO
          tasknndbg:
0002bc 9330 006e 	sts	taskstat,temp
          taskend:
0002be 916f      	pop	j
0002bf 915f      	pop	i
0002c0 91bf      	pop	xh
0002c1 91af      	pop	xl
          taskerexit:
0002c2 913f      	pop	temp
0002c3 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          getevent:
0002c4 935f      	push	i
0002c5 933f      	push	temp
0002c6 e000      	ldi	p1,0
0002c7 9130 0067 	lds	temp,keycmd
0002c9 3030      	cpi	temp,0
0002ca f029      	breq	gevtnotkey
0002cb 2f13      	mov	p2,temp
0002cc e001      	ldi	p1,1
0002cd e050      	ldi	i,0
0002ce 9350 0067 	sts	keycmd,i
          gevtnotkey:
          gevtend:
0002d0 913f      	pop	temp
0002d1 915f      	pop	i
0002d2 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ;
         ; -------------------------------------------------------------------
         ;
         ; ACTION:	Find action (TASKP1)(TASKP2) for event (P1)(P2)
          FINDEVTACT:
0002d3 933f      	push	temp
0002d4 934f      	push	index
0002d5 93cf      	push	yl
0002d6 93df      	push	yh
0002d7 936f      	push	op3
0002d8 937f      	push	op4
0002d9 91c0 0071 	lds	yl,tasktabptr
0002db 91d0 0072 	lds	yh,tasktabptr+1
          fealoop:
0002dd 813a      	ldd	temp,Y+2	; fetch action class
0002de 9330 006f 	sts	taskp1,temp
0002e0 813b      	ldd	temp,Y+3	; fetch action ID
0002e1 9330 0070 	sts	taskp2,temp
0002e3 8138      	ld	temp,Y
0002e4 3030      	cpi	temp,0		;  end of tasker table
0002e5 f039      	breq	feaend		;  = yes, no action found
0002e6 1730      	cp	temp,p1			; matching event class ?
0002e7 f419      	brne	feanext
0002e8 8139      	ldd	temp,Y+1
0002e9 1731      	cp	temp,p2		; matching EVENT ID ?
0002ea f011      	breq	feaend		;  = yes, got the action
          feanext:
0002eb 9624      	adiw	yl,4
0002ec cff0      	rjmp	fealoop
          feaend:
0002ed 917f      	pop	op4
0002ee 916f      	pop	op3
0002ef 91df      	pop	yh
0002f0 91cf      	pop	yl
0002f1 914f      	pop	index
0002f2 913f      	pop	temp
0002f3 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ;
         ; -------------------------------------------------------------------
         ;
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	SO
         ; INPUT:	R16	-	character to be sent
         ; ACTION:	synchronously output 1 character to serial interface
         ;
          SO:
0002f4 b90c      	out	UDR,R16
          SO_WAIT:
0002f5 9b5e      	sbis	USR,TXC
0002f6 cffe      	rjmp	SO_WAIT		; loop until TXC set
0002f7 9a5e      	sbi	USR,TXC		; clear 
0002f8 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	PSSO
         ; INPUT:	R31,R30 (Z)	-	pointer to string
         ; CALLS:	PSSO
         ; DESTROYS:	-
         ; ACTION:	output string of characters until NUL
         ;		starting from (Z)  in CODE segment
         ;
          PSSO:
0002f9 920f      	push	r0
0002fa 933f      	push	temp
          PSSOLOOP:
0002fb 95c8      	lpm			; get (next) character
0002fc 2d00      	mov	p1,r0
0002fd 2300      	tst	p1		; check if 0 => end
0002fe f019      	breq	PSSO_END	; if so, terminate it
0002ff dff4      	rcall	SO		; output it
000300 9631      	adiw	zl,1		;  move to next character
000301 cff9      	rjmp	PSSOLOOP	; repeat
          PSSO_END:
000302 913f      	pop	temp
000303 900f      	pop	r0
000304 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          SOCRLF:
000305 e00d      	ldi	p1,0x0d
000306 dfed      	rcall	SO
000307 e00a      	ldi	p1,0x0a
000308 dfeb      	rcall	SO
000309 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          SODIG:
00030a 700f      	andi	p1,0x0F
00030b e310      	ldi	p2,0x30
00030c 0f01      	add	p1,p2
00030d 330a      	cpi	p1,0x3A
00030e f010      	brlo	SODIG_1
00030f e017      	ldi	p2,7
000310 0f01      	add	p1,p2
          SODIG_1:
000311 cfe2      	rjmp	SO
         ;
         ; -------------------------------------------------------------------
         ;
          SOBYT:
000312 930f      	push	p1
000313 9502      	swap	p1
000314 dff5      	rcall	SODIG
000315 910f      	pop	p1
000316 cff3      	rjmp	SODIG
         ;
         ; -------------------------------------------------------------------
         ;
          SOWRD:
000317 2f0f      	mov	p1,zh
000318 dff9      	rcall	SOBYT
000319 2f0e      	mov	p1,zl
00031a cff7      	rjmp	SOBYT
         ;
         ; -------------------------------------------------------------------
         ;
         ; OUTPUT:	Carry - set if there is a received byte available
         ;
          SISTAT:
00031b deea      	rcall	tasker
00031c 9408      	sec
00031d 9b5f      	sbis	USR,RXC
00031e 9488      	clc
00031f 9508      	ret	
         ;
         ; -------------------------------------------------------------------
         ;
          SIDATA:
000320 b10c      	in	r16,UDR
000321 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          SI:
000322 dee3      	rcall	tasker
000323 9b5f      	sbis	USR,RXC
000324 cffd      	rjmp	SI
000325 b10c      	in	r16,UDR
000326 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          chk_debug:
000327 938f      	push	mask
000328 9180 0074 	lds	mask,debugctl
00032a 2383      	and	mask,temp
00032b 918f      	pop	mask
00032c 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          debug_out:
00032d 930f      	push	p1
00032e 931f      	push	p2
00032f 930f      	push	p1
000330 dfc8      	rcall	PSSO
000331 910f      	pop	p1
000332 dfdf      	rcall	SOBYT
000333 e20f      	ldi	p1,'/'
000334 dfbf      	rcall	SO
000335 910f      	pop	p1
000336 dfdb      	rcall	SOBYT
000337 e00d      	ldi	p1,0x0d
000338 dfbb      	rcall	SO
000339 e00a      	ldi	p1,0x0a
00033a dfb9      	rcall	SO
00033b 910f      	pop	p1
00033c 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; ACTION:	get one hex digit from SI, set carry if non-digit
         ;
          GETDIG:
00033d dfe4      	rcall	SI
00033e 3200      	cpi	p1,' '
00033f f101      	breq	GETDIG_TERM
000340 300d      	cpi	p1,0x0d
000341 f0f1      	breq	GETDIG_TERM
000342 320b      	cpi	p1,'+'
000343 f0e1      	breq	GETDIG_TERM
000344 320d      	cpi	p1,'-'
000345 f0d1      	breq	GETDIG_TERM
000346 3300      	cpi	p1,0x30
000347 f3a8      	brlo	GETDIG
000348 330a      	cpi 	p1,0x3A
000349 f068      	brlo	GETDIG_NUM	; numeric charcter '0' .. '9'
00034a 3401      	cpi	p1,0x41
00034b f388      	brlo	GETDIG		; unaccepted non-alphanum character
00034c 3407      	cpi	p1,0x47
00034d f070      	brlo	GETDIG_AUP	; hex uppercase character 'A' .. 'F'
00034e 350b      	cpi	p1,0x5B
00034f f080      	brlo	GETDIG_CUP	; non-hex uppercase character
000350 3601      	cpi	p1,0x61
000351 f358      	brlo	GETDIG		; unaccepted non-alphanum character
000352 3607      	cpi	p1,0x67
000353 f038      	brlo	GETDIG_ALO	; hex lowercase character 'a' .. 'f'
000354 370b      	cpi	p1,0x7B
000355 f048      	brlo	GETDIG_CLO	; non-hex lowercase character
000356 cfe6      	rjmp	GETDIG
          GETDIG_NUM:
000357 df9c      	rcall	SO
000358 700f      	andi	p1,0x0f
          GETDIG_DIG:
000359 9488      	clc
00035a 9508      	ret
          GETDIG_ALO:			; lowercase alphameric 'a'..'f'
00035b 5200      	subi	p1,0x20		; convert to uppercase 'A'..'F'
          GETDIG_AUP:			; uppercase alphameric 'A'..'F'
00035c df97      	rcall	SO		; echo the uppercase hex digit
00035d 5307      	subi	p1,55		; convert to nibble 0x0A .. 0x0F
00035e cffa      	rjmp	GETDIG_DIG	; treat like any other digit
          GETDIG_CLO:
00035f 5200      	subi	p1,0x20
          GETDIG_CUP:
          GETDIG_TERM:
000360 9408      	sec
000361 9508      	ret	
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	GETCP	- get command (or other) 16-bit parameter
         ; OUTPUT:	X	- entered value
         ;		P1	- last character entered
         ;		Carry	- set if nothing was entered
         ;
          GETCP:
000362 e0a0      	ldi	xl,0
000363 e0b0      	ldi	xh,0
000364 94e8      	clt
          GETCP_LOOP:
000365 dfd7      	rcall	GETDIG
000366 f058      	brcs	GETCP_END
000367 9468      	set
000368 0faa      	lsl	xl
000369 1fbb      	rol	xh
00036a 0faa      	lsl	xl
00036b 1fbb      	rol	xh
00036c 0faa      	lsl	xl
00036d 1fbb      	rol	xh
00036e 0faa      	lsl	xl
00036f 1fbb      	rol	xh
000370 2ba0      	or	xl,p1
000371 cff3      	rjmp	GETCP_LOOP
          GETCP_END:
000372 f40e      	brtc	GETCP_EX
000373 9488      	clc
          GETCP_EX:
000374 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	GETCC 	- get command character from System Input
         ; OUTPUT:	P1	- ASCII command character
         ; 
          GETCC:
000375 dfac      	rcall	SI
000376 770f      	andi	p1,0x7F
000377 300d      	cpi	p1,0x0D
000378 f089      	breq	getcc_none
000379 3401      	cpi	p1,'A'
00037a f098      	brlo	GETCC_IGN	; ignore control characters
00037b 350b      	cpi	p1,'Z'+1
00037c f030      	brlo	GETCC_UP
00037d 3601      	cpi	p1,'a'
00037e f078      	brlo	GETCC_IGN
00037f 370b      	cpi	p1,'z'+1
000380 f008      	brlo	GETCC_LO
000381 c00c      	rjmp	GETCC_IGN
          GETCC_LO:
000382 5200      	subi	r16,0x20	; convert to uppercase if applicable
          GETCC_UP:
000383 2ef0      	mov	r15,p1		; memorize command in R15
000384 9300 0076 	sts	moncmd,p1	; ... and in MONCMD
000386 df6d      	rcall	SO
000387 e200      	ldi	p1,0x20
000388 df6b      	rcall	SO
000389 9508      	ret
          GETCC_NONE:
00038a 2ef0      	mov	r15,p1
00038b 9300 0076 	sts	moncmd,p1
00038d 9508      	ret
          GETCC_IGN:
00038e 930f      	push	p1
00038f e30c      	ldi	p1,'<'
000390 df63      	rcall	SO
000391 910f      	pop	p1
000392 df7f      	rcall	SOBYT
000393 e30e      	ldi	p1,'>'
000394 df5f      	rcall	SO
000395 df6f      	rcall	SOCRLF
000396 cfde      	rjmp	GETCC
         ;
         ; -------------------------------------------------------------------
         ;
          GETCMD:
000397 dfdd      	rcall	GETCC
000398 92f0 0076 	sts	moncmd,r15
00039a e030      	ldi	temp,0
00039b 9330 0077 	sts	monpcnt,temp
          GETCMD_P:
00039d dfc4      	rcall	GETCP
00039e f048      	brcs	GETCMD_P11
00039f 93a0 0078 	sts	monp1,xl
0003a1 93b0 0079 	sts	monp1+1,xh
0003a3 2eca      	mov	r12,xl
0003a4 2edb      	mov	r13,xh
0003a5 e031      	ldi	temp,1
0003a6 9330 0077 	sts	monpcnt,temp
          GETCMD_P11:
0003a8 300d      	cpi	r16,0x0d
0003a9 f0e1      	breq	GETCMD_END
0003aa e200      	ldi	r16,0x20
0003ab df48      	rcall	SO
0003ac dfb5      	rcall	GETCP
0003ad f048      	brcs	GETCMD_P21
0003ae 93a0 007a 	sts	monp2,xl
0003b0 93b0 007b 	sts	monp2+1,xh
0003b2 2eaa      	mov	r10,xl
0003b3 2ebb      	mov	r11,xh
0003b4 e032      	ldi	temp,2
0003b5 9330 0077 	sts	monpcnt,temp
          GETCMD_P21:
0003b7 300d      	cpi	r16,0x0d
0003b8 f069      	breq	GETCMD_END
0003b9 e200      	ldi	r16,0x20
0003ba df39      	rcall	SO
0003bb dfa6      	rcall	GETCP
0003bc f048      	brcs	GETCMD_P31
0003bd 93a0 007c 	sts	monp3,xl
0003bf 93b0 007d 	sts	monp3+1,xh
0003c1 2e8a      	mov	r8,xl
0003c2 2e9b      	mov	r9,xh
0003c3 e033      	ldi	temp,3
0003c4 9330 0077 	sts	monpcnt,temp
          GETCMD_P31:
          GETCMD_END:
0003c6 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          DISCMD:
0003c7 9100 0076 	lds	p1,moncmd
0003c9 300d      	cpi	p1,0x0D
0003ca f079      	breq	discmdend
0003cb 3404      	cpi	p1,'D'		; D-command
0003cc f071      	breq	CMDB_D
0003cd 3406      	cpi	p1,'F'		; F-command
0003ce f069      	breq	CMDB_F
0003cf 340d      	cpi	p1,'M'		; M-command
0003d0 f061      	breq	CMDB_M
0003d1 3502      	cpi	p1,'R'		; R-command
0003d2 f059      	breq	CMDB_R
0003d3 3504      	cpi	p1,'T'		; D-command
0003d4 f051      	breq	CMDB_T
0003d5 3507      	cpi	p1,'W'		; W-command
0003d6 f049      	breq	CMDB_W
0003d7 eee6      	ldi	r30,LOW(ERR_MSG*2)
0003d8 e0fa      	ldi	r31,HIGH(ERR_MSG*2)
0003d9 df1f      	rcall	PSSO
          discmdend:
0003da 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          CMDB_D:
0003db c0e3      	rjmp	CMD_D
         ;
          CMDB_F:
0003dc c119      	rjmp	CMD_F
         ;
          CMDB_M:
0003dd c08a      	rjmp	CMD_M
         ;
          CMDB_R:
0003de c112      	rjmp	CMD_R
         ;
          CMDB_T:
0003df c13f      	rjmp	CMD_T
         ;
          CMDB_W:
0003e0 c174      	rjmp	CMD_W
         ;
         ; -------------------------------------------------------------------
         ;
          SETUPSPORT:
0003e1 e030      	ldi	temp,0
0003e2 bb3a      	out	DDRA,temp	; ADxx to input
0003e3 ef3f      	ldi	temp,0xFF
0003e4 bb34      	out	DDRC,temp	; Axx to output
0003e5 b735      	in	temp,MCUCR
0003e6 733f      	andi	temp,0b00111111
0003e7 bf35      	out	MCUCR,temp	; disable external SRAM
0003e8 9130 0062 	lds	temp,pbbuf
0003ea 7f3d      	andi	temp,0b11111101	; disable ALE2 line
0003eb 9330 0062 	sts	pbbuf,temp
0003ed bb38      	out	PORTB,temp
0003ee 9130 0063 	lds	temp,pdbuf
0003f0 6c30      	ori	temp,0b11000000	; set \RD and \WR to inactive
0003f1 9330 0063 	sts	pdbuf,temp
0003f3 bb32      	out	PORTD,temp
0003f4 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          SETUPSRAM:
0003f5 e030      	ldi	temp,0x00
0003f6 bb3a      	out	DDRA,temp		; port A to input
0003f7 b735      	in	temp,MCUCR
0003f8 6c30      	ori	temp,0b11000000		; enable external SRAM with wait state
0003f9 bf35      	out	MCUCR,temp
0003fa 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          MGET:
0003fb 93ef      	push	zl
0003fc 93ff      	push	zh
0003fd 933f      	push	temp
0003fe 9130 007c 	lds	temp,monp3	; MONP3 tells mode
000400 3030      	cpi	temp,0		; normal SRAM mode
000401 f011      	breq	mget0
000402 3033      	cpi	temp,3		; PORT SRAM mode
000403 f031      	breq	mget3
          mget0:				; normal SRAM mode
000404 8100      	ld	p1,Z
000405 c01b      	rjmp	mgetend
          mget1:				; Program memory mode
000406 95c8      	lpm
000407 2d00      	mov	p1,r0
000408 c018      	rjmp	mgetend
          mget2:				; EEPROM mode
         
000409 c017      	rjmp	mgetend
          mget3:				; PORT SRAM mode, simulate hardware
00040a dfd6      	rcall   SETUPSPORT	; switch to PORT mode
00040b ef3f      	ldi     temp,0xFF
00040c bb3a      	out	DDRA,temp	; port A to output
00040d bbeb      	out	PORTA,zl	; output low address byte
00040e 9130 0062 	lds	temp,pbbuf
000410 6032      	ori	temp,0b00000010	; assert ALE2
000411 bb38      	out	PORTB,temp
000412 7f3d      	andi	temp,0b11111101	; negate ALE2
000413 bb38      	out	PORTB, temp
000414 bbf5      	out	PORTC,zh	; output high address byte
000415 e030      	ldi	temp,0
000416 bb3a      	out	DDRA,temp	; port A to input
000417 9130 0062 	lds	temp,pbbuf
000419 773f      	andi	temp,0b01111111	; assert \RD line
00041a bb38      	out	PORTB,temp
00041b b309      	in	p1,PINA
00041c 6830      	ori	temp,0b10000000	; negate \RD line
00041d ef3f      	ldi	temp,0xFF
00041e bb3a      	out	DDRA,temp	; port A to output again
00041f dfd5      	rcall	SETUPSRAM	; switch to SRAM again
000420 c000      	rjmp	mgetend
          mgetend:
000421 913f      	pop	temp
000422 91ff      	pop	zh
000423 91ef      	pop	zl
000424 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          MDISP:
000425 e00d      	ldi	p1,0x0D
000426 decd      	rcall	SO
000427 91e0 0078 	lds	zl,monp1
000429 91f0 0079 	lds	zh,monp1+1
00042b deeb      	rcall	SOWRD
00042c e200      	ldi	p1,0x20
00042d dec6      	rcall	SO
00042e 91e0 0078 	lds	zl,monp1
000430 91f0 0079 	lds	zh,monp1+1
000432 dfc8      	rcall	MGET	
000433 dede      	rcall	SOBYT
000434 e200      	ldi	p1,0x20
000435 debe      	rcall	SO
000436 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; ACTION:	store byte (R26) in (MONP1)
         ;
          MSTOR:
000437 93ef      	push	zl
000438 93ff      	push	zh
000439 933f      	push	temp
00043a 91e0 0078 	lds	zl,monp1
00043c 91f0 0079 	lds	zh,monp1+1
00043e 9130 007c 	lds	temp,monp3
000440 3030      	cpi	temp,0
000441 f031      	breq	mstor0
000442 3031      	cpi	temp,1
000443 f031      	breq	mstor1
000444 3032      	cpi	temp,2
000445 f029      	breq	mstor2
000446 3033      	cpi	temp,3
000447 f021      	breq	mstor3
          mstor0:				; normal SRAM mode
000448 83a0      	ST	Z,r26
000449 c016      	rjmp	mstorend
          mstor1:				; FLASH memory mode
00044a c015      	rjmp	mstorend
          mstor2:				; EEPROM mode
00044b c014      	rjmp	mstorend
          mstor3:				; PORT SRAM mode
00044c df94      	rcall   SETUPSPORT	; switch to PORT mode
00044d ef3f      	ldi     temp,0xFF
00044e bb3a      	out	DDRA,temp	; port A to output
00044f bbeb      	out	PORTA,zl	; output low address byte
000450 9130 0062 	lds	temp,pbbuf
000452 6032      	ori	temp,0b00000010	; assert ALE2
000453 bb38      	out	PORTB,temp
000454 7f3d      	andi	temp,0b11111101	; negate ALE2
000455 bb38      	out	PORTB, temp
000456 bbf5      	out	PORTC,zh	; output high address byte
000457 bb0b      	out	PORTA,p1	; output data to write
000458 9130 0062 	lds	temp,pbbuf
00045a 7b3f      	andi	temp,0b10111111	; assert \WR line
00045b bb38      	out	PORTB,temp
00045c b309      	in	p1,PINA
00045d 6430      	ori	temp,0b01000000	; negate \WR line
00045e df96      	rcall	SETUPSRAM	; switch to SRAM again
00045f c000      	rjmp	mstorend
          mstorend:
000460 913f      	pop	temp
000461 91ff      	pop	zh
000462 91ef      	pop	zl
000463 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	CALCTSTPAT
         ; INPUT:	Z	- address to data byte
         ; OUTPUT:	P1	- test pattern for byte (Z)
         ; ACTION:	calculates test pattern for byte at address (Z)
         ;
          CALCTSTPAT:
000464 ea05      	ldi	p1,0xA5
000465 0f0e      	add	p1,zl
000466 0f0f      	add	p1,zh
000467 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          CMD_M:
000468 9130 0077 	lds	temp,monpcnt
00046a 3033      	cpi	temp,3
00046b f42c      	brge	cmd_m_3par
00046c e030      	ldi	temp,0
00046d 9330 007c 	sts	monp3,temp
00046f 9330 007d 	sts	monp3+1,temp
          CMD_M_3PAR:
000471 e00a      	ldi	p1,0x0A
000472 de81      	rcall	SO
          CMD_M_LOOP:
000473 dfb1      	rcall	MDISP
000474 deed      	rcall	GETCP
000475 f028      	brcs	CMD_M_NOVAL
000476 91e0 0078 	lds	zl,monp1
000478 91f0 0079 	lds	zh,monp1+1
00047a dfbc      	rcall	MSTOR		; store low byte of entered value
          CMD_M_NOVAL:
00047b 300d      	cpi	p1,0x0d
00047c f409      	brne	cmd_m_noend
00047d c040      	rjmp	CMD_M_END
          cmd_m_noend:
00047e 3200      	cpi	p1,0x20
00047f f399      	breq	CMD_M_LOOP
000480 320b      	cpi	p1,0x2b		; + increments to next address
000481 f461      	brne	CMD_M_NOPLUS
000482 e00a      	ldi	p1,0x0A
000483 de70      	rcall	SO
000484 91e0 0078 	lds	zl,monp1
000486 91f0 0079 	lds	zh,monp1+1
000488 9631      	adiw	zl,1
000489 93e0 0078 	sts	monp1,zl
00048b 93f0 0079 	sts	monp1+1,zh
00048d cfe5      	rjmp	CMD_M_LOOP
          CMD_M_NOPLUS:
00048e 3502      	cpi	r16,0x52	; R displays memory contents continuously
00048f f421      	brne	CMD_M_NOR
          CMD_M_RLOOP:
000490 df94      	rcall	MDISP
000491 de89      	rcall	SISTAT		; key pressed ?
000492 f7e8      	brcc	CMD_M_RLOOP
000493 cfdf      	rjmp	CMD_M_LOOP
          CMD_M_NOR:
000494 320d      	cpi	p1,'-'		; '-' moves to previous location
000495 f541      	brne	CMD_M_NOMINUS
000496 e00a      	ldi	p1,0x0A
000497 de5c      	rcall	SO
000498 91e0 0078 	lds	zl,monp1
00049a 91f0 0079 	lds	zh,monp1+1
00049c 9731      	sbiw	zl,1
00049d f008      	brcs	CMDMNOVAL
00049e df98      	rcall	MSTOR		; store low byte of entered value
          CMDMNOVAL:
00049f 300d      	cpi	p1,0x0d
0004a0 f0e9      	breq	CMD_M_END
0004a1 3200      	cpi	p1,0x20
0004a2 f281      	breq	CMD_M_LOOP
0004a3 320b      	cpi	p1,0x2b		; + increments to next address
0004a4 f461      	brne	CMDMNOPLUS
0004a5 e00a      	ldi	p1,0x0A
0004a6 de4d      	rcall	SO
0004a7 91e0 0078 	lds	zl,monp1
0004a9 91f0 0079 	lds	zh,monp1+1
0004ab 9631      	adiw	zl,1
0004ac 93e0 0078 	sts	monp1,zl
0004ae 93f0 0079 	sts	monp1+1,zh
0004b0 cfc2      	rjmp	CMD_M_LOOP
          CMDMNOPLUS:
0004b1 3502      	cpi	r16,0x52	; R displays memory contents continuously
0004b2 f421      	brne	CMDMNOR
          CMDMRLOOP:
0004b3 df71      	rcall	MDISP
0004b4 de66      	rcall	SISTAT		; key pressed ?
0004b5 f7e8      	brcc	CMDMRLOOP
0004b6 cfbc      	rjmp	CMD_M_LOOP
          CMDMNOR:
0004b7 320d      	cpi	p1,'-'		; '-' moves to previous location
0004b8 f429      	brne	CMD_M_NOMINUS
         
0004b9 93e0 0078 	sts	monp1,zl
0004bb 93f0 0079 	sts	monp1+1,zh
0004bd cfb5      	rjmp	cmd_m_loop
          CMD_M_NOMINUS:
          CMD_M_END:
0004be 9508      	ret	
         ;
         ; -------------------------------------------------------------------
         ;
         ; ACTION:	Dump Memory from <MONP1> for <MONP2> lines
         ;
          CMD_D:
0004bf de45      	rcall	SOCRLF
0004c0 9130 0077 	lds	temp,monpcnt
0004c2 3033      	cpi	temp,3
0004c3 f42c      	brge	cmd_d_3p
0004c4 e030      	ldi	temp,0
0004c5 9330 007c 	sts	monp3,temp
0004c7 9330 007d 	sts	monp3+1,temp
          cmd_d_3p:
0004c9 9160 007a 	lds	j,monp2
0004cb 91e0 0078 	lds	zl,monp1
0004cd 91f0 0079 	lds	zh,monp1+1
          cmdpl1:
0004cf 93ef      	push	zl
0004d0 93ff      	push	zh		; memorize starting point
0004d1 de45      	rcall	SOWRD
0004d2 e150      	ldi	i,16
          cmdpl2:
0004d3 e200      	ldi	p1,' '		; blank before
0004d4 de1f      	rcall	SO
0004d5 df25      	rcall	MGET		; get byte
0004d6 9631      	adiw	zl,1
0004d7 de3a      	rcall	SOBYT		; dump it
0004d8 955a      	dec	i
0004d9 f7c9      	brne	cmdpl2
0004da e200      	ldi	p1,' '
0004db de18      	rcall	SO
0004dc 91ff      	pop	zh
0004dd 91ef      	pop	zl		; get starting point for line again
0004de e150      	ldi	i,16
          cmdpl3:
0004df df1b      	rcall	MGET		; get byte
0004e0 9631      	adiw	zl,1
0004e1 3200      	cpi	p1,' '
0004e2 f010      	brlo	cmdpl3np	; <32, not printable
0004e3 370f      	cpi	p1,0x7F
0004e4 f008      	brlo	cmdpl3pp	; 32..126, printable
          cmdpl3np:
0004e5 e20e      	ldi	p1,'.'		; display non-printable characters as '.'
          cmdpl3pp:
0004e6 de0d      	rcall	SO		; output printable version of byte
0004e7 955a      	dec	i
0004e8 f7b1      	brne	cmdpl3		; repeat for all characters
0004e9 93e0 0078 	sts	monp1,zl
0004eb 93f0 0079 	sts	monp1+1,zh	; update address pointer
0004ed de17      	rcall	SOCRLF
0004ee 956a      	dec	j
0004ef f6f9      	brne	cmdpl1		; repeat for all lines
0004f0 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          CMD_R:
0004f1 2d0c      	mov	r16,r12
0004f2 6800      	ori	r16,0x80	; set change flag
0004f3 9300 0064 	sts	repmod,r16	; memorize REPEAT mode
0004f5 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          CMD_F:	
0004f6 9130 0077 	lds	temp,monpcnt
0004f8 3033      	cpi	temp,3
0004f9 f42c      	brge	cmdf3p
0004fa e000      	ldi	p1,0
0004fb 9330 007c 	sts	monp3,temp
0004fd 9330 007d 	sts	monp3+1,temp
          cmdf3p:
0004ff 3032      	cpi	temp,2
000500 f434      	brge	cmdf2p
000501 e000      	ldi	p1,low(256)
000502 9330 007a 	sts	monp2,temp
000504 e001      	ldi	p1,high(256)
000505 9330 007b 	sts	monp2+1,temp
          cmdf2p:
000507 3031      	cpi	temp,1
000508 f42c      	brge	cmdf1p
000509 e000      	ldi	p1,0
00050a 9300 0078 	sts	monp1,p1
00050c 9300 0079 	sts	monp1+1,p1
          cmdf1p:
00050e 91e0 0078 	lds	zl,monp1
000510 91f0 0079 	lds	zh,monp1+1
000512 91c0 007a 	lds	yl,monp2
000514 91d0 007c 	lds	yh,monp2+2
          cmdfloop:
000516 df4d      	rcall	CALCTSTPAT
000517 2fa0      	mov	r26,p1
000518 df1e      	rcall	MSTOR
000519 9631      	adiw	zl,1
00051a 9721      	sbiw	yl,1
00051b 2f3c      	mov	temp,yl
00051c 2b3d      	or	temp,yh
00051d f7c1      	brne	cmdfloop
00051e 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          CMD_T:	
00051f 9130 0077 	lds	temp,monpcnt
000521 3033      	cpi	temp,3
000522 f42c      	brge	cmdt3p
000523 e000      	ldi	p1,0
000524 9330 007c 	sts	monp3,temp
000526 9330 007d 	sts	monp3+1,temp
          cmdt3p:
000528 3032      	cpi	temp,2
000529 f434      	brge	cmdt2p
00052a e000      	ldi	p1,low(256)
00052b 9330 007a 	sts	monp2,temp
00052d e001      	ldi	p1,high(256)
00052e 9330 007b 	sts	monp2+1,temp
          cmdt2p:
000530 3031      	cpi	temp,1
000531 f42c      	brge	cmdt1p
000532 e000      	ldi	p1,0
000533 9300 0078 	sts	monp1,p1
000535 9300 0079 	sts	monp1+1,p1
          cmdt1p:
000537 91e0 0078 	lds	zl,monp1
000539 91f0 0079 	lds	zh,monp1+1
00053b 91c0 007a 	lds	yl,monp2
00053d 91d0 007c 	lds	yh,monp2+2
          cmdtloop:
00053f debb      	rcall	MGET
000540 2fa0      	mov	r26,p1		; memorize ACTUAL value
000541 df22      	rcall	CALCTSTPAT
000542 2f90      	mov	r25,p1		; memorize EXPECTED value
000543 17a0      	cp	r26,p1
000544 f051      	breq	cmdtmatch
000545 ddbf      	rcall	SOCRLF		; mismatch, report adress expected/actual
000546 ddd0      	rcall	SOWRD
000547 e200      	ldi	p1,' '
000548 ddab      	rcall	SO
000549 2f09      	mov	p1,r25
00054a ddc7      	rcall	SOBYT
00054b e20f      	ldi	p1,'/'
00054c dda7      	rcall	SO
00054d 2f0a      	mov	p1,r26
00054e ddc3      	rcall	SOBYT
          cmdtmatch:
00054f 9631      	adiw	zl,1
000550 9721      	sbiw	yl,1
000551 2f3c      	mov	temp,yl
000552 2b3d      	or	temp,yh
000553 f759      	brne	cmdtloop
000554 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          CMD_W:
          cmdrloop:
000555 ddc5      	rcall	SISTAT
000556 f078      	brcs	cmdrdone
000557 9100 0067 	lds	r16,keycmd
000559 7800      	andi	r16,0x80
00055a f3d1      	breq	cmdrloop
00055b 9100 0067 	lds	r16,keycmd
00055d ddb4      	rcall	SOBYT
00055e e000      	ldi	r16,0
00055f 9300 0067 	sts	keycmd,r16
000561 e00d      	ldi	r16,0x0D
000562 dd91      	rcall	SO
000563 e00a      	ldi	r16,0x0A
000564 dd8f      	rcall	SO
000565 cfef      	rjmp	cmdrloop
          cmdrdone:
000566 ddbb      	rcall	SI
000567 9508      	ret
         ;
         ; -------------------------------------------------------------------
         ;
          RESET_MSG:
          	.DB	'H','C','S','0','1','m','o','n',' ','1','1','-','0','3',0x00
000568 4348
000569 3053
00056a 6d31
00056b 6e6f
00056c 3120
00056d 2d31
00056e 3330
00056f 0000
          PROMPT_MSG:
          	.DB	0x0D,0x0A,'>','>',' ',0x00
000570 0a0d
000571 3e3e
000572 0020
          ERR_MSG:
          	.DB	0x0D,0x0A,0x43,0x4D,0X44,0x20,0x45,0x52,0x52,0x00
000573 0a0d
000574 4d43
000575 2044
000576 5245
000577 0052
          NL_MSG:
          	.DB	0x0D,0x0A,0x00
000578 0a0d
000579 0000
          CLS_MSG:
          	.DB	0x1B,'[','0','H',0x1B,'[','0','J',0x00
00057a 5b1b
00057b 4830
00057c 5b1b
00057d 4a30
00057e 0000
          HOME_MSG:
          	.DB	0x1B,'[','0','H',0x00
00057f 5b1b
000580 4830
000581 0000
         ;
         ; -------------------------------------------------------------------
         ;
         ; FUNCTION:	RESET
         ; ACTION:	Main Hardware Reset Entry point
         ;
         	
          RESET:
000582 e002      	ldi r16,high(RAMEND) ;Intialize stackpointer
000583 bf0e      	out SPH,r16
000584 e50f      	ldi r16,low(RAMEND)
000585 bf0d      	out SPL,r16
000586 dae1      	rcall	INIT
000587 ede0      	ldi	r30,LOW(RESET_MSG*2)
000588 e0fa      	ldi	r31,HIGH(RESET_MSG*2)
000589 dd6f      	rcall	PSSO
          CYCLE:
00058a eee0      	ldi	r30,LOW(PROMPT_MSG*2)
00058b e0fa      	ldi	r31,HIGH(PROMPT_MSG*2)
00058c dd6c      	rcall	PSSO
00058d de09      	rcall	GETCMD
00058e 9130 0064 	lds	temp,repmod
000590 3031      	cpi	temp,1
000591 f419      	brne	repcmd
000592 efe4      	ldi	zl,low(cls_msg*2)
000593 e0fa      	ldi	zh,high(cls_msg*2)
000594 dd64      	rcall	psso
          repcmd:
000595 9130 0064 	lds	temp,repmod
000597 3030      	cpi	temp,0
000598 f029      	breq	docmd		; = no repeat measures
000599 3031      	cpi	temp,1
00059a f019      	breq	docmd		; = no control before command
00059b efee      	ldi	zl,low(home_msg*2)
00059c e0fa      	ldi	zh,high(home_msg*2)
00059d dd5b      	rcall	psso
          docmd:
00059e de28      	rcall	DISCMD
00059f 9130 0064 	lds	temp,repmod	; REPMOD changed ?
0005a1 7830      	andi	temp,0x80
0005a2 f431      	brne	cmdrchg
0005a3 9130 0064 	lds	temp,repmod
0005a5 773f      	andi	temp,0x7F
0005a6 9330 0064 	sts	repmod,temp
0005a8 c008      	rjmp	cmdnext
          cmdrchg:
0005a9 9130 0064 	lds	temp,repmod	; shall we repeat ?
0005ab 3030      	cpi	temp,0
0005ac f021      	breq	cmdnext
          cmdchkrep:
0005ad dd6d      	rcall	SISTAT		; check for interrupt by ser key
0005ae f010      	brcs	cmdnext		; = no char, repeat
0005af dd72      	rcall	SI
0005b0 cfe4      	rjmp	repcmd
          cmdnext:
0005b1 cfd8      	rjmp	CYCLE
         ;
         ; -------------------------------------------------------------------
         ;
         ; ----- initial task table fill ----------
         ;
          .SET	keyon	=	0xC0
          .SET	keyoff	=	0x80
         ;
          initasktab:
          	.DB	1,keyon+0,3,0		; on KEY 00 ON, TOGGLE_BI_RELAY 00
0005b2 c001
0005b3 0003
          	.DB	1,keyon+1,3,1		; on KEY 01 ON, TOGGLE_BI_RELAY 01
0005b4 c101
0005b5 0103
         
          	.DB	1,keyon+32,6,16		; on KEY 32 ON, TOGGLE_MO_RELAY 16
0005b6 e001
0005b7 1006
          	.DB	1,keyon+33,6,17		; on KEY 33 ON, TOGGLE_MO_RELAY 17
0005b8 e101
0005b9 1106
          	.DB	1,keyon+34,6,18		; on KEY 34 ON, TOGGLE_MO_RELAY 18
0005ba e201
0005bb 1206
          	.DB	1,keyon+35,6,19		; on KEY 35 ON, TOGGLE_MO_RELAY 19
0005bc e301
0005bd 1306
         
          	.DB	1,keyon+40,6,16		; on KEY 40 ON, TOGGLE_MO_RELAY 16
0005be e801
0005bf 1006
          	.DB	1,keyon+41,6,17		; on KEY 41 ON, TOGGLE_MO_RELAY 17
0005c0 e901
0005c1 1106
          	.DB	1,keyon+42,6,18		; on KEY 42 ON, TOGGLE_MO_RELAY 18
0005c2 ea01
0005c3 1206
          	.DB	1,keyon+43,6,19		; on KEY 43 ON, TOGGLE_MO_RELAY 19
0005c4 eb01
0005c5 1306
         
          	.DB	1,keyon+48,6,16		; on KEY 48 ON, TOGGLE_MO_RELAY 16
0005c6 f001
0005c7 1006
          	.DB	1,keyon+49,6,17		; on KEY 49 ON, TOGGLE_MO_RELAY 17
0005c8 f101
0005c9 1106
          	.DB	1,keyon+50,6,18		; on KEY 50 ON, TOGGLE_MO_RELAY 18
0005ca f201
0005cb 1206
          	.DB	1,keyon+51,6,19		; on KEY 51 ON, TOGGLE_MO_RELAY 19
0005cc f301
0005cd 1306
         
          	.DB	1,keyon+56,6,16		; on KEY 56 ON, TOGGLE_MO_RELAY 16
0005ce f801
0005cf 1006
          	.DB	1,keyon+57,6,17		; on KEY 57 ON, TOGGLE_MO_RELAY 17
0005d0 f901
0005d1 1106
          	.DB	1,keyon+58,6,18		; on KEY 58 ON, TOGGLE_MO_RELAY 18
0005d2 fa01
0005d3 1206
          	.DB	1,keyon+59,6,19		; on KEY 59 ON, TOGGLE_MO_RELAY 19
0005d4 fb01
0005d5 1306
         
          	.DB	0,0,0,0				; TERMINATING entry
0005d6 0000
0005d7 0000
         ;
         ; -------------------------------------------------------------------
         ;
         ;  END of HCS01MON
         ;
         ; -------------------------------------------------------------------
         ;
         	
Assembly complete with no errors.
