; WRITTEN BY 		G.C.Hartnup
; Copyright Reserved	G.C.Hartnup
; DATE	February 19 2021
;****CURRENT VERSION****** issue 4.1  12/3/21		 	
; FILE SAVED AS 	LocoX.ASM
; FOR 		PIC 12F683
	list	P=PIC12F683
; 8.00 MHz Internal Clock 
; INSTRUCTION CLOCK 	2.00 MHz  Tick = 0.5uS 
;
; FUNCTION	DCC Locomotive Speed Controller
;		L9110 version
;
;-------------------
;---CVs supported---
;-------------------
;	CV1	Short address
;	CV2	Start voltage
;	CV7	Firmware issue
;	CV8	Manufacturer
;	CV17	Long address hi byte
;	CV18	Long address lo byte
;	CV29	Configuration
;-----------------
;--- Port Usage---
;-----------------
;	GP0 =	direction 1	;Direction control
;	GP1 = 	F3		;Function 3
; 	GP2 = 	pwm o/p		;PWM pulses
;	GP3 =	dcc i/p		;Derived from rails
;	GP4 =	F1		;Function 1
;	GP5 =	F2		;Function 2
;---------------------
;---port directions---
;---------------------
_tris	  equ	0x08	;port i/p or o/p settings
;
#define	_dirn1	GPIO,GP0	;direction control 1
#define	_pwm	GPIO,GP2	;pulses out on gp2
#define	_in	GPIO,GP3	;DCC logic input
#define	_F1	GPIO,GP4	;Function outputs
#define	_F2	GPIO,GP5
#define	_F3	GPIO,GP1
#define	page1	bsf	STATUS,RP0	;set memory bank 1
#define	page0	bcf	STATUS,RP0	;set memory bank 0
;
	nolist
;----------------------	
;---Library Routines---
;----------------------
	include "P12F683.inc"	;standard assembler equates etc
	list
;-----------------------
;---Set Configuration---
;-----------------------
; Brown Out Off
; Data Code protection Off
; Code protection Off
; Master Clear OFF (Pin 3 available, MCLR tied to Vdd)
; Watch Dog Timer Off
; Internal Oscillator with no clock out
	__CONFIG   _FCMEN_OFF&_IESO_OFF&_BOD_OFF&_CPD_OFF&_CP_OFF& _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTOSCIO  
;
;--------------------------------------
;---local program variable locations---
;--------------------------------------
;
CC	equ	0x20	;general purpose registers
DD 	equ	0x21
EE 	equ	0x22
FF 	equ	0x23
temp	equ	0x24
;
address	equ	0x30	;packet address lo byte
address2	equ	0x31	;packet address hi byte
addrflag	equ	0x32	;long address flag
bcnt	equ	0x33	;bit counter used in getbyte 
bitno	equ	0x34	;bit no in addressed byte
bitval	equ	0x35	;"1" or "0"
byte	equ	0x36	;received byte
CV1	equ	0x37	;device short address
CV2	equ	0x38	;start speed value
CV3	equ	0x39	;acceleration rate (not currently used)
CV4	equ	0x3a	;deceleration rate (not currently used)
CV7	equ	0x3b	;firmware issue number
CV8	equ	0x3c	;manufacturer
CV17	equ	0x3d	;device long address hi byte
CV18	equ	0x3e	;device long address lo byte
CV29	equ	0x3f	;configuration
errb	equ	0x40	;error byte
mask	equ	0x41	;used in Bit Manipulation to isolate a bit
pcnt	equ	0x42	;preamble bit counter
qdata1	equ	0x43	;data byte 1
qdata2	equ	0x44	;data byte 2
qdata3	equ	0x45	;data byte 3
spdv	equ	0x46	;speed value
swap 	equ	0x47	;speed direction mask
;
;---------------
;---Constants---
;---------------
;ACK signal period  6 msec
;negated because clock counts up
;1 tick = 0.5 microseconds
;"& 0xFFFF" trims value to 16 bits and removes error message caused by - sign
ackhi	equ	High (-.12000 & 0xFFFF)	;ticks
acklo	equ	Low  (-.12000 & 0xFFFF)	;ticks
;
_OPTION	equ	0x0d		;0.5 seconds watch dog timer
	List
	List st = off, mm = off	;clean up assembled listing
	errorlevel -302
;-------------------
;---Program Start---
;-------------------
	org 	0		;reset vector
	page0		      	;set bank 0
	goto	init		;initialise
;----------------
;---Interrupts---
;----------------
	org	4		;interrupt vector
	retfie
;------------------------
;-----EERAM Control-------
;-------------------------
;---read EERAM---
; on entry w holds eeram address
; on exit w holds data
RRAM	page1
	bcf	EECON1,WREN
	movwf	EEADR           ; set address
	bsf	EECON1,RD       ; do a read
	movf	EEDATA,w        	; data to w
	page0
	return
;---write EERAM---
;on entry CC contains Address, DD contains data
WRAM	movf	CC,w
	page1
	movwf	EEADR	;where
	page0
	movf	DD,w	;to be stored
	page1
	movwf	EEDATA
	bsf	EECON1,WREN
;	bcf	INTCON,GIE	;disable interrupts
	movlw	0x55            	;do write sequence
	movwf	EECON2          	;       /
	movlw	0xaa            	;      / 
	movwf 	EECON2          	;     /  
	bsf	EECON1,WR      	;initiate write 
	btfsc	EECON1,WR
	goto	$-1
;	bsf	INTCON,GIE	;re-enable interrupts
	page0
	return
;-----------------------------
;---Get bit from DCC stream---
;-----------------------------
; returns 1 or 0 in w
; _in is the input port
getbit	btfsc	_in		;test input hi?
	goto	getbit
pb1	btfss	_in		;is it lo?
	goto	pb1
	clrf	TMR1L		;zero value of timer       
	clrf	TMR1H		;clear msb
	bsf	T1CON,TMR1ON    	;start timer 1
pb2	btfsc	_in
	goto	pb2
        	bcf	T1CON,TMR1ON    	;stop Timer 1
	movf	TMR1L,w		;get lo byte
	movwf	CC
	movf	TMR1H,w		;get hi byte
	movwf	DD
	clrc			;clear carry bit
	rrf	DD,f		;divide time by 2 because of 8MHz clock
	rrf	CC,f		
;determine if pulse is a one or a zero
;returns 1 or 0 in w
	movf	DD,w
	bnz	d1		;far too long
;threshold set at 80 to allow time for an interrupt
	movlw	.80		;less than 80 microseconds 
	subwf	CC,w
	btfss	STATUS,C		;it is a nought
	retlw	1		;report one
d1	retlw	0		;report nought
;-------------------------------------
;---get 8 bits from the data stream---
;--------returned in byte-------------
;------------------------------------- 	
getbyte	clrf	byte
	movlw	0x08	
	movwf	bcnt		;to count bits
gb1	call	getbit		;get bit in w from dcc stream
	movwf	FF
	rrf	FF,f		;bit into Carry
	rlf	byte,f		;hence into byte
	decfsz	bcnt,f		;test for 8 bits
	goto 	gb1		;next bit
	return
;-------------------
;---Set Direction---
;-------------------
rev	bsf	_dirn1		;direction control
	movlw	0		;normal pulses
	movwf	swap	
	return
fwd	bcf	_dirn1
	movlw	0x7f		;invert pulses
	movwf 	swap
	return
;----------------------------
;---RESET & INITIALISATION---
;----------------------------
init	clrwdt
	clrf	GPIO		;clear i/o port
	movlw	0x07
	movwf	CMCON0		;turn off comparator
	clrf	T1CON		;set timer 1 
	clrf	WDTCON		;wdt is off
	clrf	CCPR1L		;zero speed o/p
	movlw	0x02		;timer 2 prescaler 16
	movwf	T2CON
;set up oscillator
	page1			;set bank 1
	clrf	VRCON
	movlw	0x71		;set 8MHz
	movwf	OSCCON
	movlw	_OPTION		
	movwf	OPTION_REG
	clrf	ANSEL		;clear a/d
	clrf	 IOC		;clear "Interrupt on Change" Reg
	movlw	_tris		;set tris
	movwf	TRISIO		;set port directions
;---set period
	movlw	0x80
	movwf	PR2		;PR2 pwm period
	page0		      	;set bank 0
;---get CV values from EERAM
	movlw	0		;EERAM address
	call	RRAM		;get value
	movwf	CV1
	movlw	1
	call	RRAM
	movwf	CV2
	movlw	2
	call	RRAM
	movwf	CV3
	incf	CV3,f	;+1 to handle zero acc'n case
	movlw	3
	call	RRAM
	movwf	CV4
	incf	CV4,f	;+1 to handle zero acc'n case
	movlw	4
	call	RRAM
	movwf	CV7
	movlw	5
	call	RRAM
	movwf	CV8
	movlw	6
	call	RRAM
	movwf	CV17
	movlw	7
	call	RRAM
	movwf	CV18
	movlw	8
	call	RRAM
	movwf	CV29
;---now start up
	page0
;---zero speed
	clrf	spdv	;zero speed demand
	call	 fwd	;set direction
;set zero o/p
	clrw
	xorwf	swap,w	;modify pwm for direction
	movwf	CCPR1L
;set functions
	bsf	_F1	;set functions true
	bsf	_F2
	bsf	_F3
bq	bsf	T2CON,2	;start tmr2
	movlw	0x0e
	movwf	CCP1CON
;initialise everything
bp	page0	    	; set up Bank 0
	clrf	address	;lo byte
	clrf	address2	;hi byte
	clrf	addrflag	;set short address
	clrf	qdata1	;first data byte
	clrf	qdata2	;second data byte
	clrf	qdata3	;third data byte
	clrf 	pcnt	;preamble counter
p0	clrwdt
;-----------------------
;---look for Preamble---
;-----------------------
;short preamble >10  successive "1"s
;long preamble >26 successive bits ( note: Hornby short preamble of 22 bits)
p1	call 	getbit	;result returned in w
	iorlw	0	;test for "1"
	bz	bp	;it wasn't a "1",start again
p2	incf	pcnt,f	;increment counter
	bz	init	;overflow error, restart
	bz	p0	;overflow, far too long, restart
	call 	getbit	;result returned in w
	iorlw	0	;test for "0" (end of preamble)	
	bnz	p2	;not a "0", so retry
;test validity
	movlw	0x0a	;length 10 or more?
	subwf	pcnt,w
	btfss	STATUS,C
	goto 	bp	;too short
;pcnt now contains length of preamble
;---------------------
;--- Get Data Bytes---
;---------------------
;we have already received start bit so get the address byte
	call	getbyte
	movf	byte,w
	movwf	address	;save first byte in address
	movwf	errb	;first item in error check
;now look for a zero in next startbit
	call	getbit
	iorlw	0
	bnz	bp	;failed start again
;get data
	call 	getbyte	;result returned in byte
	movf	byte,w	
	movwf	qdata1	;save as data 1
	xorwf	errb,f	;compute Error Byte
;look for a zero in next startbit
	call	getbit	;returned in w
	iorlw	0
	bnz	p28	;end of packet
;get data byte and test
	call 	getbyte	;result returned in byte
	movf	byte,w
	movwf	qdata2	;save as data 2
	xorwf	errb,f	;compute Error Byte
;look for a one in startbit	(end of packet)
	call	getbit	;returned in w
	iorlw	0
	bnz	p28	;end of packet
	call 	getbyte	;result returned in byte
	movf	byte,w
	movwf	qdata3	;save as data 3
	xorwf	errb,f	;compute Error Byte
;look for a one in startbit	(end of packet)
	call	getbit	;returned in w
	iorlw	0
	bz	bp	;not stop bit
;--------------------------------------------------
;---end of packet, check error byte for validity---
;--------------------------------------------------
p28	movf	errb,f
	bnz	bp	;should be zero
;check data - did we receive a long address?
	incf	address,w
	bz	ns0	;address is 0xff, not long
	movlw	0xc0
	andwf	address,w
	movwf	temp
	movlw	0xc0
	xorwf	temp,w
	bnz	ns0	;not long address
;retrieve long address and adjust data
;note that upper byte retains leading "1"s
	movf	address,w
	movwf	address2	;upper byte
	movf	qdata1,w
	movwf	address	;lower byte
;shuffle up data
	movf	qdata2,w
	movwf	qdata1
	movf	qdata3,w
	movwf	qdata2
	decf	addrflag,f	;set address flag true
;-----------------------------
;---normal or service mode?---
;-----------------------------
ns0	movlw	0x18	;test for long preamble (> 24 pulses)
	subwf	pcnt,f
	btfss	pcnt,7
	goto 	service	;service mode
;-----------------
;---Normal Mode---
;-----------------
;-------------------
;---Check Address---
;-------------------
	btfss	addrflag,0	;long address ?
	goto	p29	;no
;check long address
	movf	address2,w
	xorwf	CV17,w
	bnz	bp	;fail, restart
	movf	address,w
	xorwf	CV18,w
	bnz	bp	;fail, restart
	goto	p30
;check short address
p29	movf	address,w
	bz	p30	;broadcast command
	subwf	CV1,w	;compare with device address number
	bnz	bp	;fail, restart
;----------------------------
;---Check Instruction Type---
;----------------------------
;if upper 3 bits of qdata1 are 100, then Function
p30	movlw	0xe0	;get top 3 bits
	andwf	qdata1,w
	xorlw	0x80	;test for 100
	bnz	spd	;not function, try Speed ?
;--------------
;---Function---
;--------------
;function states are in bit0 and bit1 of qdata1
;Function 1
	movlw	1	;bit 0
	andwf	qdata1,w
	bz	ff1
	bsf	_F1
	goto	ff2
ff1	bcf	_F1
;Function 2
ff2	movlw	2	;bit 1
	andwf	qdata1,w
	bz	ff3
	bsf	_F2
	goto	bp
ff3	bcf	_F2
	goto	bp
;-------------------
;---Speed Control---
;-------------------
;if (Not bit7) and  (bit 6) of qdata1, then 28 step instruction	
spd	btfsc	qdata1,7
	goto	spd1	;not 28 step speed instruction
	btfss	qdata1,6
 	goto	spd1	;not 28 step speed instruction
;-------------------------------
;---28 step speed instruction---
;-------------------------------
;decode qdata1 and build equivalent 128 step data in qdata2
	movlw	0x07
	andwf	qdata1,w
	movwf	qdata2
	clrc
	btfsc	qdata1,4	;rotate bit 4 to bit 0 position
	bsf	STATUS,C
	rlf	qdata2,f
	btfsc	qdata1,5	;direction bit
	bsf	qdata2,5	
	clrc
	rlf	qdata2,f	;stretch to 8 bits
	rlf	qdata2,f
	btfsc	qdata2,2	;set up bit 0 for stop/emergency stop
	bsf	qdata2,0
	goto	sp3	;and use 128 step code
;if qdata1 = 0x3F then 128 step speed instruction
spd1	movlw	0x3F	;is it 128 step speed control ?
	subwf	qdata1,w
	bnz	bp	;not a speed instruction
;speed and direction now in qdata2
;else resume here
sp3	movlw	0x7f	;strip direction bit
	andwf	qdata2,w
;w now contains speed
	movwf	spdv	;save speed value
;test for stop, speed 0 or 1
	movlw	0x7e
	andwf	spdv,w
	btfsc	STATUS,Z
	call	stp	;so stop		
	call	st1	;set direction
	movf	spdv,w	;include bit zero for speed
	addwf	CV2,w	;start voltage
	movwf	temp
	btfsc	temp,7	;overflow?
	movlw	0x7f	;restore maximum value (127)
	xorwf	swap,w	;modify for direction
	movwf	temp	;save speed setting
;CCPR1L controls the mark/space ratio
;this code prevents possible glitch when updating
wait	movf	TMR2,w
	page1
	subwf	PR2,w
	page0
	andlw	0x0f
	btfsc	STATUS,Z
	goto	wait	;not enough time
;update PWM
	movf	temp,w	;get speed setting
	movwf	CCPR1L	;update PWM
	goto	bp	;round again
;-------------------
;---set direction---
;-------------------
st1	btfss	qdata2,7	;Forward ?
	call	fwd
	btfsc	qdata2,7	;Reverse ?
	call	rev
	return
;set zero speed
stp	clrw
	xorwf	swap,w	;modify for direction
	movwf	CCPR1L
	return
;------------------
;---Service Mode---
;------------------
;on exit re-initialise, (goto init)
;to implement CV changes and restart TMR2 and PWM	
;
service	clrf	CCP1CON		;turn off PWM (clears TRISIO,2)
	bcf	T2CON,2		;stop tmr2
;-------------------------
;---What shall we do ?---
;-------------------------
	movlw	0xfc		;remove 2 low bits
	andwf	address,w
	movwf	temp
	movlw	0x74		;is it verify CV?
	subwf	temp,w
	bz	vfy		;yes
	movlw	0x7c		;is it write CV?
	subwf	temp,w
	bz	wcv		;yes
	movlw	0x78		;or Bit Manipulation ?
	subwf	temp,w
;none of these, so return to normal mode	
	bnz	bq
;----------------------
;---Bit Manipulation---
;----------------------
; used to read CVs
; value checked 1 bit at a time
; qdata1 contains CV number less 1
; bits 2-0 of qdata2 contain bit number of CV
; bit 3  1=write , 0 = bit verify
; bit 4 value of bit concerned
	movlw	0x07	;get 3 lowest bits
	andwf	qdata2,w	;which contain the bit no
	movwf	bitno
	btfsc	qdata2,4	;check for write operation
	goto	init	;write not implemented
	clrf	bitval	;get the value of the bit to be verified
	btfsc	qdata2,3	
	bsf	bitval,0	;bit value as lsb
;build mask for bit
	clrf	mask
	incf	mask,f
	clrc
	movf	bitno,w	;check for bit zero
	bz	ms2
ms1	rlf	mask,f	
	decfsz	bitno,f
	goto	ms1
;mask complete
;now identify CV at get current value in w
ms2	movf	qdata1,w	;get CV no
	bnz	c3
	movf	CV1,w
	goto	c11
c3	movf	qdata1,w	;get CV no
	sublw	0x01
	bnz	c4
	movf	CV2,w
	goto	c11
c4	movf	qdata1,w	;get CV no
	sublw	0x02
	bnz	c5
	movf	CV3,w
	sublw	1
	goto	c11
c5	movf	qdata1,w	;get CV no
	sublw	0x03
	bnz	c6
	movf	CV4,w
	sublw	1
	goto	c11
c6	movf	qdata1,w	;get CV no
	sublw	0x06
	bnz	c7
	movf	CV7,w
	goto	c11
c7	movf	qdata1,w	;get CV no
	sublw	0x07
	bnz	c8
	movf	CV8,w
	goto	c11
c8	movf	qdata1,w	;get CV no
	sublw	0x10
	bnz	c9
	movf	CV17,w
	goto	c11
c9	movf	qdata1,w	;get CV no
	sublw	0x11
	bnz	c10
	movf	CV18,w
	goto	c11
c10	sublw	0x1c	
	bnz	c9
	movf	CV29,w
	goto	c11
	clrw		;none of these, so value zero
;w now contains the value of CV addressed
c11	andwf	mask,w	;get the bit
	bnz	one	;it is a "1"
	btfsc	bitval,0	;compare with value sent
	goto 	init	;test failed
	goto	ak0	;send acknowledgement
one	btfss	bitval,0	;compare with value sent
	goto	init	;test failed, restart
	goto	ak0	;send acknowledgement
;---------------
;---Write CVs---
;---------------
;on entry
;qdata1 contains CV number less 1
;qdata2	contains new value
;identify EERAM address for CV number, put in CC
wcv	clrw	;EERAM base address
	movf	qdata1,w
	bnz	n0
	goto	n8	;it was CV1
n0	movlw	1	;CV2
	subwf	qdata1,w
	bnz	n1
	movlw	2	;EERAM address
	goto	n8
n1	movlw	2	;CV3
	subwf	qdata1,w
	bnz	n2
	movlw	3	;EERAM address
	goto	n8
n2	movlw	3	;CV4
	subwf	qdata1,w 
	bnz	n3	
	movlw	4	;EERAM address
	goto	n8
n3	movlw	0x06	;CV7
	subwf	qdata1,w 
	bnz	n4
	movlw	5	;EERAM address
	goto	n8
n4	movlw	0x07	;CV8 = reset
	subwf	qdata1,w
	bz	reset
n5	movlw	0x10	;CV17
	subwf	qdata1,w 
	bnz	n6
	movlw	7	;EERAM address
	goto	n8
n6	movlw	0x11	;CV18
	subwf	qdata1,w 
	bnz	n7
	movlw	8	;EERAM address
	goto	n8
n7	movlw	0x14	;CV29
	subwf	qdata1,w
	bnz	n9	;not supported CV, so out
	movlw	9	;EERAM address
;insert more CVs here
n8	movwf	CC
;get new value from qdata2
	movf	qdata2,w	;new value
	movwf	DD
;now CC = address, DD = value
	call	WRAM	;write new value
n9	goto	init	;exit service mode, re-initialise.
;---------------------------------
;---Reset CVs to Default Values---
;---------------------------------
;don't touch CV7, CV8
reset	movlw	0x10	;CV1
	call	RRAM
	movwf	DD
	clrf	CC
	call	WRAM
;
	movlw	0x11	;CV2
	call	RRAM
	movwf	DD
	movlw	1
	movwf	CC
	call	WRAM
;
	movlw	0x12	;CV3
	call	RRAM
	movwf	DD
	movlw	2
	movwf	CC
	call	WRAM
;
	movlw	0x13	;CV4
	call	RRAM
	movwf	DD
	movlw	3
	movwf	CC
	call	WRAM
;
	movlw	0x14	;CV7
	call	RRAM
	movwf	DD
	movlw	4
	movwf	CC
	call	WRAM
;
	movlw	0x15	;CV8
	call	RRAM
	movwf	DD
	movlw	5
	movwf	CC
	call	WRAM
;
	movlw	0x16	;CV17
	call	RRAM
	movwf	DD
	movlw	6
	movwf	CC
	call	WRAM
;
	movlw	0x17	;CV18
	call	RRAM
	movwf	DD
	movlw	7
	movwf	CC
	call	WRAM	
;
	movlw	0x18	;CV29
	call	RRAM
	movwf	DD
	movlw	8
	movwf	CC
	call	WRAM
	goto	init	;exit service mode, re-initialise.
;---------------
;---Verify CV---
;---------------
;on entry
;qdata1 contains CV number less 1
;qdata2	contains value to verify
;identify CV and get its current value
;comparison carried out at label v10
vfy	movf	qdata1,w
	bnz	v0
	movf	CV1,w	;CV1
	goto	v10
v0	movlw	1	;CV2	
	subwf	qdata1,w
	bnz	v1
	movf	CV2,w
	goto	v10
v1	movlw	2	;CV3
	subwf	qdata1,w
	bnz	v2
	movf	CV3,w
	goto	v10
v2	movlw	3	;CV4
	subwf	qdata1,w
	bnz	v3
	movf	CV4,w
	goto	v10
v3	movlw	6	;CV7
	subwf	qdata1,w
	bnz	v4
	movf	CV7,w
	goto	v10
v4	movlw	7	;CV8
	subwf	qdata1,w
	bnz	v5
	movf	CV8,w
	goto	v10
v5	movlw	0x10	;CV17
	subwf	qdata1,w
	bnz	v6
	movf	CV17,w
	goto	v10
v6	movlw	0x11	;CV18
	subwf	qdata1,w
	bnz	v7
	movf	CV18,w
	goto	v10
v7	movlw	0x1c	;CV29
	subwf	qdata1,W
	bnz	init	;unknown CV
	movf	CV29,w
v10	subwf	qdata2,w
	bnz	init
;-----------------
;---Acknowledge---
;-----------------
;use timer 1 to send 6 msec pulse to loco
ak0	movlw	ackhi		;load values
	movwf	TMR1H
	movlw	acklo
	movwf	TMR1L		     		
	bsf     T1CON,TMR1ON    ;start timer 1
	bcf	PIR1,0		;clear int flag
	bsf	_pwm		;turn on power
ak1	btfss	PIR1,0		;test int flag
	goto	ak1		;wait for timer
	bcf	_pwm		;turn off power
	bcf	T1CON,TMR1ON	;stop timer 1
	goto	init		;back for next preamble
;-----------------------
;---reserve copyright---
;-----------------------	
	de	"Copyright Reserved, G.C.Hartnup: February 2021"
	org	2100H
;---------------------------------
;-----------Data Ram--------------
;---------------------------------
;Current CV Settings
	org	2100H
	de	0x03	;CV1	Short address 
	de	0x0a	;CV2	Start speed
	de	0x10	;CV3	Acceleration Rate
	de	0x10	;CV4	Deceleration Rate
	de	0x41	;CV7	Firmware Issue 41
	de	0x0d	;CV8	Manufacturer (DIY)
	de	0xc0	;CV17	Long address hi
	de	0x64	;CV18	Long address lo
	de	0x00	;CV29	Configuration
;
;Default CV Settings
	org	2110H
	de	0x03	;CV1	Short address 
	de	0x0a	;CV2	Start Speed
	de	0x10	;CV3	Acceleration Rate
	de	0x10	;CV4	Deceleration Rate
	de	0x41	;CV7	Firmware Issue 41
	de	0x0d	;CV8	Manufacturer (DIY)
	de	0xc0	;CV17	Long address hi
	de	0x64	;CV18	Long address lo
	de	0x00	;CV29	Configuration
	End