; 25v8.ASM  Version: 8  Date: 14.June 2000
; Copyright (C) 1999  Georg Ziegler

; config & s31 register changed, progbit added, 
; PC_OFFSET moved from 0x07 to 0x35, 
; direct decoding for 28 speed step added

; NMRA-DCC decoder for iron core motors based on PIC12CE519 with si9986 H-Bridge
; 14/28/126 speed step mode, one internal speed curve
; and other features (please look at CVx definitions)
; direct, paged, register and on the main programming mode
; 25us timestep for polling of DCC signal
; DCC signal calibrating on 1, 1 = 25-75us
; SPDTAB in LINSPEED.XLS worksheet
; EEPROM read/write routine from MICROCHIP PIC12CE519 documentation

;    This program is free software; you can redistribute it and/or
;    modify it under the terms of the GNU General Public License as
;    published by the Free Software Foundation; either version 2 of
;    the License, or (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;    General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program; if not, write to the Free Software
;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

;    Contact:
;    Georg Ziegler
;    Zwehrener Weg 23a
;    34121 Kassel
;    g.zi@gmx.de
;--------------------------------------------------------------------
	LIST	P=12CE519, R=DEC
	INCLUDE <P12CE519.INC>
	 __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_ON & _IntRC_OSC 
;--------------------------------------------------------------------
; 0AAA AAAA  01DL SSSS -> Lok Adress Direction Light & Speed
; 0AAA AAAA  100D DDDD -> Lok Function F1-F4 & FL
; 0AAA AAAA  1011 DDDD -> Lok Function F5-F8
; 0000 0000            -> Broadcast Adress for all Lok Decoder
; 10AA AAAA  1AAA CDDD -> 9 Bit Accessory on/off F1-F8 
; 1011 1111  1000 CDDD -> Broadcast Command for all Accessory Decoder
; 11AA AAAA & AAAA AAAA -> long Adress
; 1111 1111  0000 0000 -> Idle Packet for all Decoder
;--------------------------------------------------------------------
CV8	EQU	0x0D	; Home Made Decoder
CV7	EQU	0x08	; Version No.  XX00 0000
			; 00=Analog(0x00) 01=Stepper(0x40)
			; 10=Fauli(0x80)  11=Other(0xC0)
TFLKON	EQU	60	; flickering firebox ontime
;--------------------------------------------------------------------
INDF	EQU	0x00	; Indirect Adressing
tmr0	EQU	0x01	; Timer
PC	EQU	0x02	; Programm Counter
STATUS	EQU	0x03	; Status Register
FSR	EQU	0x04	; Special Funcion Register
OSCCAL	EQU	0x05	; Calibration Register
GPIO	EQU	0x06	; GP0-GP5 input/output
;--------------------
S31	EQU	0x07	;
CONFIG	EQU	0x08	; 0=DIR 1=CONSIST 2=STEPOK/NOCV 5=FS126 6=BITHI 7=FLAG
SOLL	EQU	0x09	; speed to go
BT1	EQU	0x0A	; FSR auf 0x09
BT2	EQU	0x0B	;
BT3	EQU	0x0C	;
BT4	EQU	0x0D	;
BT5	EQU	0x0E	;
BT6	EQU	0x0F	; FSR auf 0x10
;--------------------
;	EQU	0x10	;
;	EQU	0x11	;
ACC	EQU	0x12	;
DEC	EQU	0x13	;
;	EQU	0x14	;
TFLKOFF	EQU	0x15	; flickering firebox offtime
FLAG	EQU	0x16	;
;	EQU	0x17	;
XOR	EQU	0x18	;
NOADR	EQU	0x19	; no adress since ... 
PWM	EQU	0x1A	; (Z1)
F1F8SET	EQU	0x1B	;
IST	EQU	0x1C	; actual speed
PRE	EQU	0x1D	; Preample 12 BIT
LO	EQU	0x1E	; low bit counter
HI	EQU	0x1F	; hi bit counter
;--------------------
CV1	EQU	0x30	; Primary Adress
CV2	EQU	0x31	; Vstart
CV3	EQU	0x32	; Acceleration Rate
CV4	EQU	0x33	; Deceleration Rate
CV29	EQU	0x34	; 0=DIR 1=14/28 2=PWRSRC 3=ADVACK 4=SPDTAB 5=LADRE 6= 7=ACCDEC
MAPCV	EQU	0x35	; rom CV's copied to here
CV5	EQU	0x36	; Vhigh
CV6	EQU	0x37	; Vmid
CV17	EQU	0x38	; Extended Adress Low Byte
CV18	EQU	0x39	; Extended Adress High Byte
CV19	EQU	0x3A	; Consist Adress
CV49	EQU	0x3B	; Output F1-F8 to GP2 (CV49-64)
CV50	EQU	0x3C	; Output F1-F8 to GP4
CV51	EQU	0x3D	; Output F1-F8 to GP5
CV55	EQU	0x3E	; Vmax 2
CV64	EQU	0x3F	; configuration byte
;---------------------
#DEFINE	FLOFF	CV64,0		; front light switch with cv50 (GP4)
#DEFINE	RANGIER	CV64,0		; low activ, mapped with FLOFF
#DEFINE	BLOFF	CV64,1		; back light switch with cv51 (GP5)
#DEFINE	SPEED2	CV64,1		; low activ, mapped with BLOFF
#DEFINE	RDLTON	CV64,2		; red light on (back light)
#DEFINE	BRKON	CV64,3		; brake light on
#DEFINE	HI2LOFS	CV64,4		; convert 126FS to 28FS with Vmin/Vmid/Vmax
#DEFINE	FLACKON	CV64,5		; flickering firebox
#DEFINE	LITAUTO	CV64,6		; firebox open/close automatically
#DEFINE	REDLT	CV64,7		; is set by program
;---------------------
CARRY	EQU	0
ZERO	EQU	2
SEITE	EQU	5

#DEFINE DIR	CONFIG,0	;
#DEFINE	CONSIST	CONFIG,1	;
#DEFINE	STEPOK?	CONFIG,2	;
#DEFINE	NOCV	CONFIG,2	; is mapped with STEPOK?
#DEFINE	ROMCV	CONFIG,3	; is mapped with FLACKER
#DEFINE	FLACKER	CONFIG,3	;
#DEFINE	BRAKE	CONFIG,4	;
#DEFINE FS126	CONFIG,5	;
#DEFINE	BITHI	CONFIG,6	;
#DEFINE	FLAGS2	CONFIG,7	;

#DEFINE	LITOPEN	FLAG,6		; for lit open/close (copy from CV64)

#DEFINE	DIRINV	CV29,0		; direction inverted (+light)
#DEFINE	FS28	CV29,1		; 14/28 speed step
#DEFINE	LIINV	CV29,2		; light inverted (PWRSRC never used)
#DEFINE	STAB	CV29,4		; speedtab / CV2,CV5&CV6
#DEFINE	LADRE	CV29,5		; long adress enable
#DEFINE	PROGBIT	CV29,6		;
#DEFINE	PROGBT1	CV29,7		;

#DEFINE	ACKBIT	STATUS,6	; never overwriten

#DEFINE LED	GPIO,2		;

;--------------------------------------------------------------------
	ORG     0		; Reset Vector

INIT	MOVLW	00001000b	; CALFST on
	MOVWF	OSCCAL		; write calibration value

	MOVLW	11010001b	; no wakeup, no pullup, T0 int., hightolow, T0, 1:4
	OPTION

;.....................................................................
CALI	BTFSS	GPIO,3		;-----------------
	GOTO	CALI		;	Anfang
CALI1	BTFSC	GPIO,3		;	finden
	GOTO	CALI1		;-----------------
	CLRF	tmr0		; Timer auf 0
CALI2	BTFSS	GPIO,3		;
	GOTO	CALI2		;-----------------
	MOVF	tmr0,0		; Timer 
	MOVWF	BT5		; sichern
	MOVLW	34		;-----------------
	SUBWF	BT5,0		;	LOW
	BTFSC	STATUS,CARRY	;	BIT
	GOTO	CALI		;-----------------
	MOVLW	27		; <- Schleife +2
	SUBWF	BT5,0		;
	BTFSC	STATUS,CARRY	; Hi BIT > 25?
	GOTO	CALEX		;-----------------
	MOVLW	00100000b	;
	ADDWF	OSCCAL,1	;
	GOTO	CALI		;-----------------
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
				; -----------------------------------
CALEX	MOVLW	00001000b	; GP3 input, rest output
	TRIS	GPIO		; tristate port GPIO

	MOVLW	11010110b	; no wakeup, no pullup, T0 int., hightolow, T0, 1:128
	OPTION

	COMF	XOR,0		; inverted stored for reset conditions (all zero)
	XORWF	SOLL,0		; for brown out to start	
	XORWF	IST,0		; with same speed
	BTFSC	STATUS,ZERO	; all Bytes ok?
	GOTO	START		; -----------------------------------

CLEAR	BCF	ACKBIT		;
	CLRF	IST		; -----------------------------------
	CLRF	SOLL		; set all register to start condition
	CLRF	S31		;
	CLRF	LO		;
	CLRF	HI		; set PWM to 1 to force a jump
	CLRF	PWM		; in STEP for stop condition
	INCF	PWM		; -----------------------------------

BEGIN
; EEPROM ............................................................

LOADREG	MOVLW	0x30		;
	MOVWF	FSR		; Pointer for indirect Adressing

	CLRF	EEADDR		;
EEREAD	BSF	STATUS,SEITE	; set to 200H begin EEPROM
	CALL	READ_RANDOM	; ********************************
	BCF	STATUS,SEITE	; auf ROM seite 0
	BTFSC	STATUS,ZERO	; ERROR?
	GOTO	EEREAD		;
	MOVF	EEDATA,0	;
	MOVWF	INDF		;
	MOVLW	0x3F		;
	XORWF	FSR,0		;
	ANDLW	00111111b	;
	BTFSC	STATUS,ZERO	;
	GOTO	EEEXIT		;
	INCF	FSR,1		;
	INCF	EEADDR		;
	GOTO	EEREAD		;

EEEXIT	MOVF	CV3,0		;
	BTFSC	STATUS,ZERO	;
	IORLW	1		;
	XORLW	0xFF		; complement W
	BCF	FSR,5		; rampage back to 0x10..
	MOVWF	ACC		;
	BSF	FSR,5		; rampage to 0x30..
	MOVF	CV4,0		;
	BTFSC	STATUS,ZERO	;
	IORLW	1		;
	XORLW	0xFF		; complement W
	BCF	FSR,5		; rampage back to 0x10..
	MOVWF	DEC		;
;--------------------------------
	BSF	FSR,5		;
	MOVF	CV64,0		; copy config
	BCF	FSR,5		; to
	MOVWF	FLAG		; lower ram page
;--------------------------------
	MOVLW	0x09		; adress = BT1 - 1
	MOVWF	FSR		; Pointer for indirect Adressing

	GOTO	START		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;..................................................................
SPDTAB	MOVF	S31,0	;13
	ADDWF	PC	;14
	RETLW	0	;15-16
	RETLW	0	;
	RETLW	0	;
	RETLW	0	;
	RETLW	2	; 1
	RETLW	3	; 2
	RETLW	5	; 3
	RETLW	7	; 4
	RETLW	10	; 5
	RETLW	13	; 6
	RETLW	18	; 7
	RETLW	22	; 8
	RETLW	28	; 9
	RETLW	34	; 10
	RETLW	41	; 11
	RETLW	48	; 12
	RETLW	56	; 13
	RETLW	65	; 14
	RETLW	74	; 15
	RETLW	84	; 16
	RETLW	95	; 17
	RETLW	106	; 18
	RETLW	118	; 19
	RETLW	131	; 20
	RETLW	144	; 21
	RETLW	158	; 22
	RETLW	173	; 23
	RETLW	188	; 24
	RETLW	204	; 25
	RETLW	220	; 26
	RETLW	237	; 27
	RETLW	255	; 28
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
;--------------------- multiply MULT1 * MULT2 = hi MULT1 low MULT2 --
MULTIP	MOVLW	9		;			1			
	MOVWF	COUNT		;			2
	CLRW			;			3
	BCF	STATUS,CARRY	;			4
MULTI	MOVWF	TEMP		;	1	
	RRF	TEMP,0		;	2	
	RRF	MULT2,1		;	3	
	BTFSC	STATUS,CARRY	;	4	
	ADDWF	MULT1,0		;	5	
	DECFSZ	COUNT,1		;	6	
	GOTO	MULTI		;	7-8	
	MOVWF	MULT1		;	9*8=72		76
	RETLW	0		;	END MULTIP	77-78
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

START	CLRWDT			;				12

	MOVLW	0xFF		;				13
	MOVWF	BT4		;				14
	MOVWF	BT5		;				15
	MOVWF	BT6		;				16

	MOVLW	0x09		; Pointer for ind. Adressing	17
	MOVWF	FSR		; (BT1 - 1)			18

	MOVLW	11		;				19
	MOVWF	PRE		; PRE to 10 Bit for Preample	20
;-------------
INTEST	CLRF	HI		;				20
INTST	BCF	STEPOK?		;				21
	NOP			;				22
	CALL	IN		;				23-24
	BTFSC	STEPOK?		;				4.
	GOTO	STEPOK		;				5.-6
	CALL	STEP		;				6.-7.
	BTFSC	GPIO,3		; ########### input ##########	1  (25)
	BSF	BITHI		;				2

	BTFSC	FLACKER		;				3
	BTFSC	BT2,3		;				4
	GOTO	STEPOK		;				5-6
	BSF	LED		;				6

STEPOK	MOVLW	11111100b	; FF-03				7
	MOVF	HI,1		;				8
	BTFSC	STATUS,ZERO	; 0? 				9
	GOTO	LOWBIT		; low half of bit		10-11
	ADDWF	HI,0		; BIT im Carry			11
	DECFSZ	PRE,1		; Pre=0?			12
	GOTO	PRETEST		;				13-14
	BTFSC	STATUS,CARRY	; waiting for 0			14
	GOTO	BYTE		; Preample ok!			15-16
	INCF	PRE,1		;				16
	NOP			;				17
	GOTO	INTEST		; next Bit			18-19

PRETEST	DECFSZ	HI,0		; HI=1?				15
	BTFSC	STATUS,CARRY	;				16
	GOTO	START19		; no Preample!			17-18
	GOTO	INTEST		;				18-19

LOWBIT	NOP			;				12
	GOTO	$+1		;				13-14
	BTFSC	BITHI		;				15
	INCF	HI		;				16
	BCF	BITHI		;				17
	INCFSZ	LO,1		;				18
	GOTO	INTST		;				19-20
	GOTO	BEGIN		; >10000uS			20-21

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IN	BTFSS	GPIO,3		; ########### input ##########	1  (25)
	RETLW	0		; 				2.-3.
	INCF	HI		;				3.
	CLRF	LO		;				4.
	BSF	STEPOK?		;				5.
	CALL	STEP		;				6.-7.
	BTFSS	GPIO,3		; ########### input ##########	1  (25)
	RETLW	0		; FF-03				2-3
	INCF	HI		;				3
	NOP			; -----------------------------	4
	MOVF	IST,0		; for brown out			5
	XORWF	SOLL,0		; to start with			6
	MOVWF	XOR		; same speed			7
	COMF	XOR,1		; -----------------------------	8
	BTFSC	FS126		;				9
	GOTO	FS126OV		;				10-11
;.....................SPEEDTAB..........................................
	CALL	SPDTAB		;  				11-12
	MOVWF	SOLL		;				17
	BCF	STATUS,CARRY	;				18
	BTFSC	FLAGS2		;				19
	RRF	SOLL,1		;				20
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FS126BK	BCF	STEPOK?		;				21
	INCFSZ	HI,0		;				22
	GOTO	IN		;				23-24
	GOTO	BEGIN		; >10000uS			24

FS126OV	NOP			;				12
	GOTO	$+1		;				13-14
	GOTO	$+1		;				15-16
	GOTO	$+1		;				17-18
	GOTO	FS126BK		;				19-20

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;.....................................................................
STEP	INCFSZ	tmr0,0		; ISO				25
	GOTO	INC		;				26-27
	MOVF	SOLL,0		;				27
	SUBWF	IST,0		;				28
	BTFSC	STATUS,ZERO	;				29
	GOTO	EQUAL		; Speed equal			30-31
	BTFSC	STATUS,CARRY	;				31
	GOTO	DECNEXT		;				32-33
	INCF	IST,1		;				33
	MOVF	ACC,0		;				34
	GOTO	ACCNEXT		;				35-36
DECNEXT	DECF	IST,1		;				34
	MOVF	DEC,0		;				35
	BSF	BRAKE		;				36	
ACCNEXT	MOVWF	tmr0		;				37
	NOP			;				38
	NOP			;				39
	RETLW	0		;				40-41

INC	DECFSZ	PWM,1		;				28
	GOTO	MOTOR		;				29-30
	BSF	GPIO,0		;				30
	BSF	GPIO,1		; HiZ				31
	MOVF	IST,0		;				32
	NOP			;				33
	NOP			;				34
	NOP			;				35
	NOP			;				36
	NOP			;				37
	NOP			;				38
	NOP			;				39
	RETLW	0		;				40-41
		
MOTOR	MOVF	PWM,0		;				31
	SUBWF	IST,0		;				32
	BTFSC	DIR		; BTFSC Vorward <-> Reverse	33
	GOTO	REWIND		;				34-35
	NOP			;				35
	BTFSC	STATUS,CARRY	;				36
	BCF	GPIO,0		; IST >= PWM			37
	BTFSS	STATUS,CARRY	;				38
	BSF	GPIO,0		; IST < PWM			39
	RETLW	0		;				40-41

REWIND	BTFSC	STATUS,CARRY	;				36
	BCF	GPIO,1		; IST >= PWM			37
	BTFSS	STATUS,CARRY	;				38
	BSF	GPIO,1		; IST < PWM			39
	RETLW	0		;				40-41

EQUAL	BCF	BRAKE		;				32
	MOVF	SOLL,0		;				33
	BTFSC	FLACKER		;				34
	DECFSZ	TFLKOFF,1	;				35
	GOTO	EQUEX		;				36-37
	MOVWF	TFLKOFF		;				37
	BTFSC	LITOPEN		;				38
	BCF	FLACKER		;				39
	BCF	LED		;				40
	RETLW	0		;				41-42

EQUEX	BTFSS	FLACKER		;				38
	INCFSZ	TFLKOFF,1	;				39
	RETLW	0		;				40-41
	MOVF	BT2,0		;				41
	ANDLW	01100111b	;				42
	IORLW	00010000b	;				43
	MOVWF	TFLKOFF		;				44
	BTFSC	LITOPEN		;				45
	BSF	FLACKER		;				46
	RETLW	0		;				47-48
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

LOWBIT1	MOVLW	0x10		; -----------------------------	12
	SUBWF	FSR,0		;				13
	ANDLW	00000111b	; more than 6 BYTE read		14
	BTFSC	STATUS,ZERO	; begin new!			15
	GOTO	START18		; -----------------------------	16-17
	BTFSC	BITHI		;				17
	INCF	HI		;				18
	GOTO	INTST1		;				19-20

BYTE	MOVLW	9		; PRE to 8 Bit for 1.Byte	17
	MOVWF	PRE		;				18
	INCF	FSR,1		; Pointer for ind. Adressing	19

INTEST1	CLRF	HI		;				20
INTST1	BCF	STEPOK?		;				21
	BCF	BITHI		;				22
	CALL	IN		;				23-24
	BTFSC	STEPOK?		;				4.
	GOTO	STEPOK1		;				5.-6
	CALL	STEP		;				6.-7.
	BTFSC	GPIO,3		; ########### input ##########	1  (25)
	BSF	BITHI		;				2

	BTFSC	FLACKER		;				3
	BTFSC	tmr0,3		;				4
	GOTO	STEPOK1		;				5-6
	BCF	LED		;				6

STEPOK1	MOVLW	11111100b	; FF-03				7
	MOVF	HI,1		;				8
	BTFSC	STATUS,ZERO	; 0? 				9
	GOTO	LOWBIT1		; low half of bit		10-11
	ADDWF	HI,0		; BIT im Carry			11
	DECFSZ	PRE,1		; Pre=0?			12
	GOTO	NEXT		;				13-14
	BTFSC	STATUS,CARRY	;				14
	GOTO	BYTE		; 9.Bit=0			15-16
;------------- Letztes BIT=1 -------------

	CLRF	NOADR		; for IB with M*

	MOVF	BT1,0		;				17
	XORWF	BT2,0		;				18
	XORWF	BT3,0		;				19
	XORWF	BT4,0		;				20
	XORWF	BT5,0		;				21
	XORWF	BT6,0		;				22
	BTFSS	STATUS,ZERO	; all Bytes ok?			23
	GOTO	START2.		;				24-1.
	COMF	BT1,1		; 9.Bit=1  (inverting BYTE)	1.
	COMF	BT2,1		; 	   (inverting BYTE)	2.
	COMF	BT3,1		; 	   (inverting BYTE)	3.
	COMF	BT4,1		; 	   (inverting BYTE)	4.
	COMF	BT5,1		; 	   (inverting BYTE)	5.
	CALL	STEP		;				6.-7.
	DECF	FSR,1		; auf vorletztes Byte		1

	MOVLW	00001000b	; GP3 input, rest output	2
	TRIS	GPIO		; set port GPIO			3

;....................................................................
CV	BSF	FSR,5		; rampage to 0x30..		4
;--------------------------------
	MOVF	BT1,0		;				5
	BTFSS	BT1,7		; >0<AAA AAAA			6
	GOTO	SHORTA		; short adress			7-8
	XORWF	CV17,0		;				8
	BTFSS	STATUS,ZERO	;				9
	GOTO	CHKPROG		;				10-11
	MOVF	BT2,0		;				11
	XORWF	CV18,0		;				12
	BTFSS	STATUS,ZERO	;				13
	GOTO	CHKPROG		;				14
	MOVLW	0x2C		; BT3				15
	MOVWF	FSR		; to 3. byte			16
	BTFSS	LADRE		; long adress enabled?		17
	GOTO	CHKPROG		;				18
	BTFSC	CONSIST		;				19
	GOTO	CHKPROG		;				20
	NOP			;				21
	BSF	STATUS,SEITE	;				22
	GOTO	DECOD		;				23-24
;--------------------------------
BCAST	NOP			;				12
	NOP			;				13
	NOP			;				14
	NOP			;				15
	GOTO	OVER1		;				16-17

OVER	BTFSC	CONSIST		;				16
	GOTO	START		;				17
OVER1	NOP			;				18
	GOTO	BCBCK		;				19-20
;--------------------------------
CHKPROG	MOVF	BT1,0		;
	ANDLW	11110000b	; untere 3bit ausblenden
	XORLW	01110000b	; >= 120 (120=CV1 121=CV2 ...)
	BTFSS	STATUS,ZERO	;
	GOTO	START		;
	BSF	STATUS,SEITE	;
	GOTO	PROG		; register mode (CV1-CV8)
;--------------------------------
SHORTA	BTFSC	STATUS,ZERO	; address = 0			9
	GOTO	BCAST		;				10-11
	BTFSS	LADRE		; long Adress enabled?		11
	XORWF	CV1,0		;				12
	BTFSC	STATUS,ZERO	;				13
	GOTO	OVER		;				14-15
	MOVF	CV19,0		;				15
	ANDLW	01111111b	;				16
	BCF	CONSIST		;				17
	BTFSS	STATUS,ZERO	;				18
	BSF	CONSIST		;				19
	XORWF	BT1,0		; consist?			20
BCBCK	BTFSS	STATUS,ZERO	;				21
	GOTO	CHKPROG		;				22-23
	MOVLW	0x2B		; BT2 + FSR,5			23
	MOVWF	FSR		; to 2. byte			24
	BSF	STATUS,SEITE	;				25
	GOTO	DECOD		;				26-27
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;--------------------------------
NEXT	NOP			;				15
	RLF	INDF,1		; 1.Byte zusammenbauen		16
	DECFSZ	HI,0		; HI=1?				17
	GOTO	INTEST1		; next bit			18-19
	GOTO	START21		;				19-20

;....................................................................
VMIDHI	EQU	0x0A	; BT1
VMIDLO	EQU	0x0B	; BT2
MULT1	EQU	0x0C	; BT3
MULT2	EQU	0x0D	; BT4
COUNT	EQU	0x0E	; BT5
TEMP	EQU	0x0F	; BT6
;--------------------------------
RSPEED	MOVF	CV55,1		;
	BTFSC	STATUS,ZERO	;
	GOTO	FSPEED		;
	SUBWF	CV55,0		;
	GOTO	RSPDEX		;

CV2CV5	MOVF	CV2,0		; CV2CV5
	MOVF	CV51,1		;
	BTFSS	SPEED2		; activ low
	BTFSC	STATUS,ZERO	; 2nd Vmax for direction if CV51 not set
	BTFSC	DIR		;
	BTFSC	FLAGS2		; flag for 2nd FS
	GOTO	RSPEED		;
FSPEED	SUBWF	CV5,0		;
RSPDEX	MOVWF	MULT1		;
	MOVWF	VMIDHI		; CV5-CV2

;................................ correction 28->32 .................
	BCF	STATUS,CARRY	;
	RRF	MULT1,1		; /2 (127)
	SWAPF	VMIDHI,0	; /16
	ANDLW	00001111b	;
	ADDWF	MULT1,1		; 127+15
	MOVWF	TEMP		;
	RRF	TEMP,0		;
	ADDWF	MULT1,1		; 142+7
	INCF	MULT1,1		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	MOVLW	4		; 4-31 -> 0-27
	SUBWF	S31,0		;
	MOVWF	MULT2		;
;-------
	CALL	MULTIP		;			104-105 (1-86)
;-------
	RRF	MULT1,1		;			77
	RRF	MULT2,1		; /4			78
	RRF	MULT1,1		;			79
	RRF	MULT2,1		; /8			80
	RRF	MULT1,1		;			81
	RRF	MULT2,1		; /16			82
	RRF	MULT1,1		;			83
	RRF	MULT2,1		; /32			84
;-------
	BTFSC	MULT1,0		; > 255 ?
	GOTO	BORROW		;
	MOVF	CV2,0		;
	ADDWF	MULT2,0		;
	BTFSC	STATUS,CARRY	;
BORROW	MOVLW	255		;
	MOVWF	SOLL		;

;----------------------------------------------VMID------------------

VMID	BCF	FSR,5		;-------------------
	CALL	STEP		; for better PWM 
	BSF	FSR,5		;-------------------

	CLRF	VMIDLO		;
	MOVF	CV6,0		;	
	BTFSC	STATUS,ZERO	;
	GOTO	VMIDEND		; no VMID

	ANDLW	01111111b	;	

	MOVWF	MULT1
	MOVF	VMIDHI,0	; CV5-CV2
	MOVWF	MULT2
;-------
	CALL	MULTIP
;-------
	MOVF	MULT1,0		; CV6*(CV5-CV2)/255
	MOVWF	VMIDHI		;
	BTFSS	CV6,7		;
	GOTO	NEGVMID		;

	MOVLW	4		;
	SUBWF	S31,0		; 4-31 > 0-27
	GOTO	VMID1		;

NEGVMID	COMF	S31,0		;
	ANDLW	00011111b	;

VMID1	MOVWF	COUNT		;
	BTFSS	COUNT,4		;
	BTFSC	COUNT,3		;
	GOTO	VMIDMUL		; > 7	lin

	MOVWF	TEMP		;
	BTFSC	STATUS,ZERO	;
	GOTO	VMID3		;
	BCF	STATUS,CARRY	;

VMID2	RRF	VMIDHI,1	; ->c	log
	RRF	VMIDLO,1	;   c->		/2
	DECFSZ	COUNT,1		;
	GOTO	VMID2		;

VMID3	MOVF	VMIDHI,0	;
	SUBWF	MULT1,0		;
	GOTO	VMIDEND		;
;--------------------------------
VMIDMUL	BCF	STATUS,CARRY
	RRF	VMIDHI,0	; CV6 /2
	ADDWF	VMIDHI,0	; CV6 - CV6 / 2
	MOVWF	MULT1		;

	MOVLW	7		;
	SUBWF	COUNT,0		; (S31)
	MOVWF	MULT2		;
	BCF	STATUS,CARRY	;
	RRF	MULT2,0		; /2
	ADDWF	MULT1,1		;
	BTFSC	MULT2,0		; odd
	INCF	MULT1,1		;
;-------
	CALL	MULTIP		;			248-249 (1-86)
;-------
	RLF	MULT2,1		;
	RLF	MULT1,1		; /128
	RLF	MULT2,1		;
	RLF	MULT1,1		; /64
	RLF	MULT2,1		;
	RLF	MULT1,1		; /32

	INCF	MULT1,0		;
	SUBWF	VMIDHI,0	;
;------------

VMIDEND	BTFSS	CV6,7		;
	GOTO	SUBVMID		;
	ADDWF	SOLL,0		;
	BTFSS	STATUS,CARRY	;
	MOVWF	SOLL		;
SUBEX	BSF	FS126		;

	BCF	FSR,5		;
	GOTO	START		;

SUBVMID	SUBWF	SOLL,0		;
	BTFSC	STATUS,CARRY	;
	MOVWF	SOLL		;
	GOTO	SUBEX		;

;------------------------------------------END VMID------------------

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;--------------------------------------------------------------------
START1.	NOP			;				1.
START2.	GOTO	$+1		;*				2.-3.
START4.	GOTO	$+1		;				4.-5.
START6.	CALL	STEP		;				6.-7.
START1	GOTO	$+1		;				1-2
START3	GOTO	$+1		;				3-4
START5	GOTO	$+1		;				5-6
START7	GOTO	$+1		;				7-8
START9	NOP			;				9
START10	GOTO	START		;				10-11
START11	GOTO	$+1		;				11-12
START13	GOTO	$+1		;				13-14
START15	GOTO	$+1		;				15-16
START17	NOP			;				17
START18	NOP			;*				18
;.....................................................................
START19	INCF	NOADR		; for IB with M*		19
START20	BTFSS	NOADR,7		; counts if no			20
START21	GOTO	START23		; DCC signal is 		21
	GOTO	INIT		; readable			22
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
START23	GOTO	START1.		;				23-24

;*******************************************************************
	ORG	0200h

	TITLE "PIC with EEPROM Data Memory Interface"
	LIST	P=12CE519

SCL	EQU	0x07		; EEPROM Clock, SCL (I/O bit 7)
SDA	EQU	0x06		; EEPROM Data,  SDA (I/O bit 6)

OK	EQU	1
NO	EQU	0
EE_OK	EQU	7		; Bit 7 in PC_OFFSET used as OK flag for EE

PC_OFFSET	EQU	0x35	; PC offset register (low order 4 bits),
				; value based on operating mode of EEPROM.
				; Also, bit 7 used for EE_OK flag
COUNTER		EQU	0x08	; Bit counter for serial transfer
EEBYTE		EQU	0x09	; Byte sent to or received from
				; EEPROM (control, address, or data)
EEADDR		EQU	0x0A	; EEPROM Address
EEDATA		EQU	0x0F	; EEPROM Data

;********************** Set up EEPROM control bytes ************************

WRITE_BYTE
	MOVLW	B'10000000'	; PC offset for write byte. EE_OK: bit7 = '1'
	GOTO	INIT_WRITE_CONTROL

READ_RANDOM
	MOVLW	B'10000011'	; PC offset for read random. EE_OK: bit7 = '1'

INIT_WRITE_CONTROL
	MOVWF	PC_OFFSET	; Load PC offset register, value preset in W
	MOVLW	B'10100000'	; Control byte with write bit, bit 0 = '0'

START_BIT
	BCF	GPIO,SDA	; Start bit, SDA and SCL preset to '1'

;******* Set up output data (control, address, or data) and counter ********

PREP_TRANSFER_BYTE
	MOVWF	EEBYTE		; Byte to transfer to EEPROM already in W
	MOVLW	8		; Counter to transfer 8 bits
	MOVWF	COUNTER

;************ Clock out data (control, address, or data) byte ************

OUTPUT_BYTE
	BCF	GPIO,SCL	; Set clock low during data set-up
	RLF	EEBYTE,1	; Rotate left, high order bit into carry bit
	BCF	GPIO,SDA	; Set data low, if rotated carry bit is
	BTFSC	STATUS,CARRY	;(SKPNC) a '1', then:
	BSF	GPIO,SDA	; reset data pin to a one, otherwise leave low
	NOP
	BSF	GPIO,SCL	; clock data into EEPROM
	DECFSZ	COUNTER,1	; Repeat until entire byte is sent
	GOTO	OUTPUT_BYTE
	NOP			; Needed to meet Timing (Thigh=4000nS)

;************************** Acknowkedge Check *****************************

	BCF	GPIO,SCL	; Set SCL low, 0.5us < ack valid < 3us
	NOP			; Needed to meet Timing (Tlow= 4700nS)
	BSF	GPIO,SDA
	NOP			; Necessary for SCL Tlow at low voltage,
	NOP			; Tlow=4700nS
	BSF	GPIO,SCL	; Raise SCL, EEPROM acknowledge still valid
	BTFSC	GPIO,SDA	; Check SDA for acknowledge (low)
	BCF	PC_OFFSET,EE_OK	; If SDA not low (no ack), set error flag
	BCF	GPIO,SCL	; Lower SCL, EEPROM release bus
	BTFSS	PC_OFFSET,EE_OK	; If no error continue, else stop bit
	GOTO	STOP_BIT

;***** Set up program counter offset, based on EEPROM operating mode *****

	MOVF	PC_OFFSET,0
	ANDLW	B'00001111'
	ADDWF	PC
	GOTO	INIT_ADDRESS		;PC offset=0, write control done, send address
	GOTO	INIT_WRITE_DATA		;PC offset=1, write address done, send data
	GOTO	STOP_BIT		;PC offset=2, write done, send stop bit
	GOTO	INIT_ADDRESS		;PC offset=3, write control done, send address
	GOTO	INIT_READ_CONTROL	;PC offset=4, send read control
	GOTO	READ_BIT_COUNTER	;PC offset=5, set counter and read byte
	GOTO	STOP_BIT		;PC offset=6, random read done, send stop

;********** Initalize EEPROM data (address, data, or control) bytes ******

INIT_ADDRESS
	INCF	PC_OFFSET,1	; Increment PC offset to 2 (write) or to 4 (read)
	MOVF	EEADDR,W	; Put EEPROM address in W, ready to send to EEPROM
	GOTO	PREP_TRANSFER_BYTE

INIT_WRITE_DATA
	INCF	PC_OFFSET,1	; Increment PC offset to go to STOP_BIT next
	MOVF	EEDATA,0	; Put EEPROM data in W, ready to send to EEPROM
	GOTO	PREP_TRANSFER_BYTE

INIT_READ_CONTROL
	BSF	GPIO,SCL	; Raise SCL
	BSF	GPIO,SDA	; raise SDA
	INCF	PC_OFFSET,1	; Increment PC offset to go to READ_BIT_COUNTER next
	MOVLW	B'10100001'	; Set up read control byte, ready to send to EEPROM
	GOTO	START_BIT	; bit 0 = '1' for read operation

;************************** Read EEPROM data *****************************

READ_BIT_COUNTER
	BSF	GPIO,SDA	; set data bit to 1 so we're not pulling bus down.
	NOP
	BSF	GPIO,SCL
	MOVLW	8		; Set counter so 8 bits will be read into EEDATA
	MOVWF	COUNTER

READ_BYTE
	BSF	GPIO,SCL	; Raise SCL, SDA valid. SDA still input from ack
	SETC			; Assume bit to be read = 1
	BTFSS	GPIO,SDA	; Check if SDA = 1
	BCF	STATUS,CARRY	;(CLRC) if SDA not = 1 then clear carry bit
	RLF	EEDATA,1	; rotate carry bit (=SDA) into EEDATA;
	BCF	GPIO,SCL	; Lower SCL
	bsf	GPIO,SDA	; reset SDA
	DECFSZ	COUNTER,1	; Decrement counter
	GOTO	READ_BYTE	; Read next bit if not finished reading byte
	BSF	GPIO,SCL
	NOP
	BCF	GPIO,SCL

;****************** Generate a STOP bit and RETURN ***********************

STOP_BIT
	BCF	GPIO,SDA	; SDA=0, on TRIS, to prepare for transition to '1'
	BSF	GPIO,SCL	; SCL = 1 to prepare for STOP bit
	GOTO	$+1		; equivalent 4 NOPs neccessary for I2C spec Tsu:sto = 4.7us
	GOTO	$+1
	BSF	GPIO,SDA	; Stop bit, SDA transition to '1' while SCL high
	BTFSS	PC_OFFSET,EE_OK ; Check for error
	RETLW	NO		; if error, send back NO
	RETLW	OK		; if no error, send back OK

;************************ End EEPROM Subroutines **************************
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;
; 0111 1RRR  DDDD DDDD  ->  register mode
;
; 0111 10AA  AAAA AAAA  111K DBBB ; Bit manipulation
;              verify/write^

;.....................................................................
DECOD	SWAPF	INDF,0		;				25
	MOVWF	BT6		;				26
	RRF	BT6,0		;				27
	ANDLW	00000111b	;				28
	ADDWF	PC		;				29
	GOTO	DECCON		; 000				30-31
	GOTO	ADVAN		; 001
	GOTO	FORWARD		; 010
	GOTO	REVERSE		; 011
	GOTO	FTION		; 100
	GOTO	FTION1		; 101
	GOTO	TELNEW		; 110

	MOVF	BT2,0		;--------------------------------
	XORLW	11111001b	; old acknowledge mode
	BTFSC	STATUS,ZERO	;
	GOTO	OLDACK		;--------------------------------

	MOVF	INDF,0		; OTM mode -copy bytes
	MOVWF	BT1		; 
	INCF	FSR,1		; 
	MOVF	INDF,0		; CV to pogram
	MOVWF	BT2		;
	INCF	FSR,1		; DATA for cv
	MOVF	INDF,0		; INDF looks to data
	MOVWF	BT3		;
	GOTO	PROGOTM		; 111
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
BITMAN	MOVWF	FSR		;
	MOVLW	00000111b	;
	ANDWF	BT3,0		;
	CALL	BITPOS		;
	BTFSS	BT3,4		;
	GOTO	VBIT		; verify bit
	BTFSC	BT3,3		;
	IORWF	INDF,1		; set bit
	XORLW	0XFF		;
	BTFSS	BT3,3		;
	ANDWF	INDF,1		; clear bit
	MOVF	FSR,0		; EEADDR
	GOTO	EEPROG		; write complete byte
;--------------------------------
VBIT	ANDWF	INDF,0		;
	BTFSC	STATUS,ZERO	;
	GOTO	BITCLR		;

BITSET	BTFSC	BT3,3		;
	GOTO	ACKNOW		; =1 
	GOTO	HOPP		;

BITCLR	BTFSS	BT3,3		;
	GOTO	ACKNOW		; =0
	GOTO	HOPP		;
;--------------------------------
BITPOS	ADDWF	PC		;
	RETLW	00000001b	; 0	
	RETLW	00000010b	; 1	
	RETLW	00000100b	; 2	
	RETLW	00001000b	; 3	
	RETLW	00010000b	; 4	
	RETLW	00100000b	; 5	
	RETLW	01000000b	; 6	
	RETLW	10000000b	; 7	
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
DECCON	BTFSC	INDF,4		; 000>0<CCCD
	GOTO	CONCON		; 0001 consist control

	RRF	INDF,0		; 0000CCC>D< moved to carry
	ANDLW	0xFF		;
	BTFSC	STATUS,ZERO	;
	GOTO	RESET		; 000 reset / hard reset
	GOTO	HOPP		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
LIGHT	BTFSS	RDLTON		;
	GOTO	LI		;
	BTFSC	REDLT		;
	GOTO	REDLIT		;
	GOTO	NOLIGHT		;
LI	BTFSS	BRKON		;
	GOTO	LI1		;
	BTFSC	BRAKE		;
	GOTO	REDLIT		;
	GOTO	NOLIGHT		;

LI1	BTFSS	INDF,4		;
	GOTO	NOLIGHT		;
REDLIT	BTFSC	DIR		; direction invert?
	GOTO	BLIGHT		;

FLIGHT	BTFSC	LIINV		; light invert?	(PWRSRC)
	GOTO	BLI		;

FLI	BTFSS	FLOFF		; cv50
	BSF	GPIO,4		;
	BTFSS	BLOFF		; cv51
	BCF	GPIO,5		;
	RETLW	0

BLIGHT	BTFSC	LIINV		; light invert?	(PWRSRC)
	GOTO	FLI		;

BLI	BTFSS	FLOFF		; cv50
	BCF	GPIO,4		;
	BTFSS	BLOFF		; cv51
	BSF	GPIO,5		;
	RETLW	0

NOLIGHT	BTFSS	FLOFF		; cv50
	BCF	GPIO,4		;
	BTFSS	BLOFF		; cv51
	BCF	GPIO,5		;
	RETLW	0
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
FINDCV	BCF	NOCV		;
	BCF	ROMCV		;

	XORLW	(1-1)		; CV1
	BTFSC	STATUS,ZERO	;
	RETLW	CV1		; Primary Adress

	XORLW	(1-1)^(2-1)	; CV2
	BTFSC	STATUS,ZERO	;
	RETLW	CV2		; Vstart

	XORLW	(2-1)^(3-1)	; CV3
	BTFSC	STATUS,ZERO	;
	RETLW	CV3		; Acceleration Rate

	XORLW	(3-1)^(4-1)	; CV4
	BTFSC	STATUS,ZERO	;
	RETLW	CV4		; Deceleration Rate

	XORLW	(4-1)^(5-1)	; CV5
	BTFSC	STATUS,ZERO	;
	RETLW	CV5		; Vhigh

	XORLW	(5-1)^(6-1)	; CV6
	BTFSC	STATUS,ZERO	;
	RETLW	CV6		; Vmid

	XORLW	(6-1)^(17-1)	; CV17
	BTFSC	STATUS,ZERO	;
	RETLW	CV17		; Extended Adress Low Byte

	XORLW	(17-1)^(18-1)	; CV18
	BTFSC	STATUS,ZERO	;
	RETLW	CV18		; Extended Adress High Byte

	XORLW	(18-1)^(19-1)	; CV19
	BTFSC	STATUS,ZERO	;
	RETLW	CV19		; Consist Adress

	XORLW	(19-1)^(29-1)	; CV29
	BTFSC	STATUS,ZERO	;
	RETLW	CV29		; 0=DIR 1=14/28 2=PWSRC 3=ADVACK 4=SPEEDTAB 5=LADRE 6= 7=ACCDEC

	XORLW	(29-1)^(49-1)	; CV49
	BTFSC	STATUS,ZERO	;
	RETLW	CV49		; Output F1-F8 to GP2

	XORLW	(49-1)^(50-1)	; CV50
	BTFSC	STATUS,ZERO	;
	RETLW	CV50		; front light switch with F1-F8

	XORLW	(50-1)^(51-1)	; CV51
	BTFSC	STATUS,ZERO	;
	RETLW	CV51		; back light switch with F1-F8

	XORLW	(51-1)^(55-1)	; CV55
	BTFSC	STATUS,ZERO	;
	RETLW	CV55		; second Vhigh

	XORLW	(55-1)^(64-1)	; CV64
	BTFSC	STATUS,ZERO	;
	RETLW	CV64		; configuration byte

	BSF	ROMCV		;
	XORLW	(64-1)^(7-1)	; CV7
	BTFSC	STATUS,ZERO	;
	RETLW	CV7		; Version No

	XORLW	(7-1)^(8-1)	; CV8
	BTFSC	STATUS,ZERO	;
	RETLW	CV8		; Manufacturer

	BCF	ROMCV		;
	BSF	NOCV		;
	RETLW	0xFF		; no CV's to program
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
PROG	MOVF	FSR,0		;
	ANDLW	00001111b	;
	XORLW	BT3		;
	BTFSS	STATUS,ZERO	;
	GOTO	PROGREG		; 3 byte command

PROGOTM	MOVF	BT2,0		;
	CALL	FINDCV		;
	BTFSC	NOCV		;
	GOTO	HOPP		;

	BTFSC	ROMCV		;
	BTFSS	BT1,3		; write/verify bit
	GOTO	ROMNEXT		;
	MOVWF	MAPCV		;
	MOVLW	MAPCV		;

ROMNEXT	BTFSS	BT1,2		;
	GOTO	BITMAN		; bit manipulation

	BTFSS	BT1,3		; write/verify bit
	GOTO	EEVERI		;
;--------------------------------

EEPROG	ANDLW	00001111b	;
	MOVWF	EEADDR		;
	CALL	READ_RANDOM	; *******************************
	CLRF	CONFIG
	MOVF	INDF,0		;
	XORWF	EEDATA,0	;

	BTFSC	STATUS,ZERO	;
	BCF	STATUS,SEITE	; auf ROM seite 0
	BTFSC	STATUS,ZERO	;
	GOTO	LOADREG		;

	MOVF	INDF,0		;
	MOVWF	EEDATA		;

	BTFSC	PROGBIT		;
	GOTO	PROG3		;
	BSF	PROGBIT		; 2x prog
	GOTO	PROGEX		;

PROG3	BTFSC	PROGBT1		;
	GOTO	EEIN		;
	BSF	PROGBT1		; 3x prog
	GOTO	PROGEX		;

EEIN	CALL	WRITE_BYTE	; ********************************
	BTFSC	STATUS,ZERO	; ERROR?
	GOTO	EEIN		;
	CLRF	CONFIG
	BCF	STATUS,SEITE	; auf ROM seite 0
	BCF	PROGBIT		;
	BCF	PROGBT1		;
	GOTO	INIT		; 
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................

OLDACK	MOVF	BT1,0		;------ for old DCC-Programmer ------
	MOVWF	INDF		; save loco adress
	CLRW			; CV1
	CLRF	MAPCV		; for old acknowledge
	GOTO	OACK		;

EEVERI	BTFSC	ROMCV		;
	GOTO	RDROMCV		;

	ANDLW	00001111b	;
OACK	MOVWF	EEADDR		;
	CALL	READ_RANDOM	; ********************************
	CLRF	CONFIG
	MOVF	INDF,0		;
	XORWF	EEDATA,0	;

VERIBK	BTFSS	STATUS,ZERO	;
	BCF	STATUS,SEITE	; to ROM page 0
	BTFSS	STATUS,ZERO	;
	GOTO	START		;

ACKNOW	BTFSC	ACKBIT		;
	GOTO	ACKNOW1		;
	BSF	ACKBIT		; 2x verify 
	GOTO	PROGEX		;

ACKNOW1	MOVLW	00110001b	; set FL/FR and motor on
	MOVWF	GPIO		;

LOOP	MOVLW	9		; 7x765uS (5355) 4,5,6,7 ok; 8 9 10 IB
	MOVWF	BT5		;
OLOOP	CLRF	BT6		; help register
	CLRWDT			;
ILOOP	INCFSZ	BT6,1		; 765uS ON	1
	GOTO	ILOOP		;		2-3
	DECFSZ	BT5,1		;		
	GOTO	OLOOP		;		

	CLRF	GPIO		;
	BCF	ACKBIT		;
	BCF	FSR,5		;
	BCF	STATUS,SEITE	; to ROM page 0

	GOTO	LOADREG		;

RDROMCV	XORWF	INDF,0		;
	GOTO	VERIBK		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................

PROGREG	MOVF	BT1,0		; CV5=CV29
	XORLW	01111101b	; reg6
	ANDLW	11110111b
	BTFSC	STATUS,ZERO	;
	GOTO	REG6		;
	XORLW	(01111101b)^(01111100b)	; reg5
	BTFSC	STATUS,ZERO	;
	GOTO	REG5		;
	MOVF	BT1,0		;
	ANDLW	00000111b	; lower 3bit
	ADDWF	MAPCV,0		;
	CALL	FINDCV		;
	BTFSC	NOCV		;
	GOTO	HOPP		;
PREG	BTFSS	BT1,3		;
	GOTO	EEVERI		;
	GOTO	EEPROG		;

REG6	DECF	BT2,1		;
	BCF	STATUS,CARRY	;
	RLF	BT2,1		;
	RLF	BT2,1		;

REG5	MOVF	BT1,0		;
	ANDLW	00000111b	; lower 3bit
	GOTO	PREG		;

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
FTION1	BTFSS	INDF,4		; 101>1<FFFF
	GOTO	FTION2		; 1010xxxx
	SWAPF	INDF,0		;
	ANDLW	11110000b	;
	BCF	FSR,5		;
	IORWF	F1F8SET,1	; xxxx00X0
	XORLW	0x0F		;
	GOTO	FT2		;
;--------------------------------
FTION	CALL	LIGHT		;
	BTFSC	INDF,4		; 100>L<FFFF 28 speed step
	BSF	FS28		; automatic detection

FT1	MOVF	INDF,0		;
	ANDLW	00001111b	; 1111xxXx
	BCF	FSR,5		;
	IORWF	F1F8SET,1	; xxxx00X0
	XORLW	0xF0		;
FT2	ANDWF	F1F8SET,0	;
	MOVWF	F1F8SET		;
	MOVWF	BT6		; save for switch to 2nd page
	BSF	FSR,5		;
;--------------------------------
	ANDWF	CV49,0		; F1F8->GP3
	BTFSC	STATUS,ZERO	;
	GOTO	FOFF		;

FON	BTFSC	FLACKON		;
	BSF	FLACKER		;
	BSF	LED		;
	GOTO	FT50		;

FOFF	BTFSC	LITAUTO		;
	GOTO	FT50		;
	BTFSC	FLACKON		;
	BCF	FLACKER		;
	BCF	LED		;
;--------------------------------
FT50	MOVF	BT6,0		;
	ANDWF	CV50,0		;
	BTFSC	STATUS,ZERO	;
	GOTO	NXFT50A		;
	BSF	REDLT		;
	BTFSC	RDLTON		;
	GOTO	FT51		;
	BTFSC	RANGIER		; low activ
	GOTO	NXFT50		;
	BSF	GPIO,5		;
NXFT50	BSF	GPIO,4		;
	GOTO	FT51		;

NXFT50A	BTFSC	RANGIER		; low activ
	BCF	GPIO,4		;
	BCF	REDLT		;
;--------------------------------
FT51	MOVF	BT6,0		;
	ANDWF	CV51,0		;
	BTFSC	STATUS,ZERO	;
	GOTO	NXFT51		;
	BTFSC	SPEED2		; low activ
	BSF	GPIO,5		;
	BTFSS	SPEED2		; low activ
	BSF	FLAGS2		;
	GOTO	HOPP		;
NXFT51	BTFSC	SPEED2		; low activ
	BCF	GPIO,5		;
	BCF	FLAGS2		;
	GOTO	HOPP
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
FORWARD	BTFSC	CV29,0		; CV29,0 (DIR) invert?		32
	GOTO	REV		;				33-34

FOR	BTFSC	CV19,7		; CV19,7 (DIR) invert?
	GOTO	REV1		;

FOR1	BTFSS	DIR		;				38
	GOTO	SPEED		;				39-40

FOREX	BCF	FSR,5
	MOVF	IST,0
	BTFSC	STATUS,ZERO
	BCF	DIR		;
	CLRF	SOLL
	CLRF	S31
	GOTO	HOPP
;--------------------------------
REVERSE	BTFSC	CV29,0		; CV29,0 (DIR) invert?
	GOTO	FOR		;

REV	BTFSC	CV19,7		; CV19,7 (DIR) invert?		35
	GOTO	FOR1		;				36-37

REV1	BTFSC	DIR		;
	GOTO	SPEED		;

REVEX	BCF	FSR,5
	MOVF	IST,0
	BTFSC	STATUS,ZERO
	BSF	DIR		;
	CLRF	SOLL
	CLRF	S31
	GOTO	HOPP
;--------------------------------------------------------------------
SPEED	BCF	FS126		;				40
	RLF	INDF,0		; 01DSSSSS			41
	ANDLW	00011110b	; xxx4321x			42
	MOVWF	S31		; 1D04321x			43
	BTFSC	INDF,4		; 01D>S<SSSS			44
	BSF	S31,0		; mov pos.4 to pos.0		45
;........................ Arnold Digital ............................
	BTFSS	FS28		; 14/28 Speed?			46
	BCF	S31,0		; <- 14 Speed			47
	BTFSS	FS28		; 14/28 Speed?			48
	CALL	LIGHT		;				49-50
;^^^^^^^^^^^^^^^^^^^^^^^^ Arnold Digital ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
HI2LOW	MOVF	S31,0		;
	BTFSC	STATUS,ZERO	;
	GOTO	STOP		;
	ANDLW	11111101b	;
	BTFSC	STATUS,ZERO	;
	GOTO	ESTOP		;
	BTFSC	STAB		;
	GOTO	HOPP		;
	BCF	STATUS,SEITE	;
	GOTO	CV2CV5		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

RESET	MOVLW	00001000b	; GP3 input, rest output
	TRIS	GPIO		; set port GPIO
	CLRF	GPIO		;

ESTOP	BCF	GPIO,0		; break
	BCF	GPIO,1		;
	BCF	FSR,5		;
	CLRF	PWM		;
	INCF	PWM,1		;
	CLRF	IST		;
STOP	CLRF	SOLL		;
	CLRF	S31
	GOTO	HOPP		;

;.....................................................................
CONCON	MOVF	BT3,0		;
	MOVWF	CV19		;
	MOVF	INDF,0		;
	XORLW	00010010b	;
	BTFSC	STATUS,ZERO	;
	BCF	CV19,7		;
	XORLW	(00010010b)^(00010011b);
	BTFSC	STATUS,ZERO	;
	BSF	CV19,7		;
	MOVLW	CV19		;
	MOVWF	FSR		;
	MOVF	CV19,0		;
	GOTO	EEPROG		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
ADVAN	MOVF	INDF,0		;
	XORLW	00111111b	; 126FS
	BTFSS	STATUS,ZERO	;
	GOTO	HOPP		; reserved for future use

	INCF	FSR,1		;
	BTFSC	INDF,7		;
	GOTO	AREVE		;
;--------------------------------
AFORW	BTFSC	CV29,0		; CV29,0 (DIR) invert?
	GOTO	AREV		;

AFOR	BTFSC	CV19,7		; CV19,7 (DIR) invert?
	GOTO	AREV1		;

AFOR1	BTFSC	DIR		;
	GOTO	FOREX
	GOTO	ASPEED		;
;--------------------------------
AREVE	BTFSC	CV29,0		; CV29,0 (DIR) invert?
	GOTO	AFOR		;

AREV	BTFSC	CV19,7		; CV19,7 (DIR) invert?
	GOTO	AFOR1		;

AREV1	BTFSS	DIR		;
	GOTO	REVEX
;--------------------------------
ASPEED	RRF	INDF,0		; xD654321->0
	MOVWF	BT6		;
	RRF	BT6,0		; xxD65432->10
	ANDLW	00011111b	; xxx65432
	MOVWF	S31		; xxx43210

	RLF	INDF,0		;
	BTFSS	HI2LOFS		;
	MOVWF	SOLL		;

	BSF	FS28		;
	BTFSC	HI2LOFS		;
	GOTO	HI2LOW		;

	BSF	FS126		;
	GOTO	HOPP		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

FTION2				;
TELNEW				;

HOPP	BCF	PROGBIT		;
	BCF	PROGBT1		;
	BCF	ACKBIT		;
PROGEX	BCF	STATUS,SEITE	;
	BCF	FSR,5		;
	GOTO	START		;

;********************************************************************

	ORG	03FFh
	MOVLW	0x70		; for OSCCAL

	END

