; fdec.asm - function decoder - a modified version of 25v6.asm
; 5 additional I/O ports for minidecoder
; acknowledge off (activate with CV42,7)
; Version: 2    Date: 03 March 2002
; Copyright (C) 1999  Georg Ziegler

; 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
;--------------------------------------------------------------------
#DEFINE	DCCIN	3		; DCC input pin (GPIO,3 only input)
;--------------------------------------------------------------------
CV8	EQU	0x0D	; Home Made Decoder
CV7	EQU	0x02	; Version No.
;--------------------------------------------------------------------
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
GPIOOUT	EQU	0x09	;
BT1	EQU	0x0A	; FSR auf 0x09
BT2	EQU	0x0B	;
BT3	EQU	0x0C	;
BT4	EQU	0x0D	;
BT5	EQU	0x0E	;
BT6	EQU	0x0F	; FSR auf 0x10
;--------------------
SOLL	EQU	0x10	; speed to go
;	EQU	0x11	;
ACC	EQU	0x12	;
DEC	EQU	0x13	;
;	EQU	0x14	;
TFLKOFF	EQU	0x15	; flickering firebox offtime
FLAG	EQU	0x16	;
F1F8OLD	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
CV17	EQU	0x31	; Extended Adress Low Byte
CV18	EQU	0x32	; Extended Adress High Byte
CV19	EQU	0x33	; Consist Adress
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
CV33	EQU	0x36	; front light -> GPIO (xx54x210)
CV34	EQU	0x37	; back light  -> GPIO (xx54x210)
CV35	EQU	0x38	; F1 -> GPIO (xx54x210)
CV36	EQU	0x39	; F2 -> GPIO (xx54x210)
CV37	EQU	0x3A	; F3 -> GPIO (xx54x210)
CV38	EQU	0x3B	; F4 -> GPIO (xx54x210)
CV39	EQU	0x3C	; F5 -> GPIO (xx54x210)
CV40	EQU	0x3D	; F6 -> GPIO (xx54x210)
CV41	EQU	0x3E	; F7 -> GPIO (xx54x210)
CV42	EQU	0x3F	; F8 -> GPIO (xx54x210)
;---------------------
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 
#DEFINE	LASTLT	CONFIG,3	;
#DEFINE FS126	CONFIG,5	;
#DEFINE	BITHI	CONFIG,6	;
#DEFINE	FLAGS2	CONFIG,7	;
#DEFINE	LASTDIR	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	ACKON	CV42,7		; acknowledge on (for additional I/O ports must switch off)
;--------------------------------------------------------------------
	ORG     0		; Reset Vector

;-------------------------TEST------------------------------
;#DEFINE TEST

#IFDEF	CALL
TEST1	BSF	FSR,5
	BSF	STATUS,SEITE
	MOVLW	10010000b	; 100LDDDD
	MOVWF	BT2
	MOVLW	0x2B		; BT2
	MOVWF	FSR		; to 2. byte
	CALL	LIGHT
	BCF	STATUS,SEITE
	GOTO	TEST1
#ENDIF

#IFDEF	TEST
	MOVLW	(1<<DCCIN)	;
	TRIS	GPIO		; set port GPIO
START	MOVLW	0x2b		;ADDR
	MOVWF	BT1
	MOVLW	10000001b	; 100LDDDD
	MOVWF	BT2
	MOVLW	0x2B		; BT2
	MOVWF	FSR		; to 2. byte
	GOTO	CV		; test (START outcomented)
#ENDIF
;---------------------------TEST----------------------------

INIT	MOVLW	00000000b	; start value (information about OSCCAL in pdf file rong!! linear speed increase!)
	MOVWF	OSCCAL		; write calibration value

	MOVLW	11010001b	; no wakeup, no pullup, T0 int., hightolow, T0, 1:4
	OPTION

;.....................................................................
CALI	BTFSS	GPIO,DCCIN	;-----------------
	GOTO	CALI		;	Anfang
CALI1	BTFSC	GPIO,DCCIN	;	finden
	GOTO	CALI1		;-----------------
	CLRF	tmr0		; Timer auf 0
CALI2	BTFSS	GPIO,DCCIN	;
	GOTO	CALI2		;-----------------
	MOVF	tmr0,0		; Timer 
	MOVWF	BT5		; sichern
	MOVLW	34		;-----------------
	SUBWF	BT5,0		;	LOW
	BTFSC	STATUS,CARRY	;	BIT
	GOTO	CALI		;-----------------
	MOVLW	26		; <- Loop +1 (lowest 26; highest 27)
	SUBWF	BT5,0		;
	BTFSC	STATUS,CARRY	; Hi BIT > 25?
	GOTO	CALEX		;-----------------
	MOVLW	00001000b	;
	ADDWF	OSCCAL,1	;
	GOTO	CALI		;-----------------
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
				; -----------------------------------
CALEX	MOVLW	11010111b	; no wakeup, no pullup, T0 int., hightolow, T0, 1:256
	OPTION

	COMF	XOR,0		; inverted stored for reset conditions (all zero)
	XORWF	F1F8SET,0	; for brown out to start	
	XORWF	GPIOOUT,0	; with same speed
	BTFSC	STATUS,ZERO	; all Bytes ok?
	GOTO	START		; -----------------------------------

CLEAR	BCF	ACKBIT		;				5.
	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		; -----------------------------------
	CLRF	F1F8SET		; set all register to start condition
	CLRF	F1F8OLD		;
	BCF	LASTLT

BEGIN	MOVLW	00111111b	; all Input
	TRIS	GPIO		; tristate port GPIO

; 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	START		; START
	INCF	FSR,1		;
	INCF	EEADDR		;
	GOTO	EEREAD		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;..................................................................
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
#IFNDEF TEST
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
#ENDIF
	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

	GOTO	$+1		;				3-4
	GOTO	$+1		;				5-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	GPIOOUT,0	; for brown out			5
	XORWF	F1F8SET,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	GOTO	$+1		;				8.-9.
	GOTO	$+1		;				10.-11.
	GOTO	$+1		;				12.-13.
	GOTO	$+1		;				14.-15.
	GOTO	$+1		;				16.-17.
	GOTO	$+1		;				18.-19.
	GOTO	$+1		;				20.-21.
	NOP			;				22.
	RETLW	0		;				23.-24.
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

	NOP			;				3
	NOP			;				4
	NOP			;				5
	NOP			;				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	(1<<DCCIN)	;				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	GOTO	$+1		;				12-13
	GOTO	$+1		;				14-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
;--------------------------------
CV2CV5	MOVLW	151		; CV2=1 & CV5=255
	MOVWF	MULT1		;

	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		;
	MOVLW	1		;
	ADDWF	MULT2,0		;
	BTFSC	STATUS,CARRY	;
BORROW	MOVLW	255		;
	BCF	FSR,5		; 1st page
	MOVWF	SOLL		;
	GOTO	START		;

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;--------------------------------------------------------------------
START1.	NOP			;				1.
START2.	NOP			;				2.
START3.	NOP			;				3.
START4.	NOP			;				4.
START5.	NOP			;				5.
START6.	CALL	STEP		;				6.-7.
START1	NOP			;				1
START2	NOP			;				2
START3	NOP			;				3
START4	NOP			;				4
START5	NOP			;				5
START6	NOP			;				6
START7	NOP			;				7
START8	NOP			;				8
START9	NOP			;				9
START10	GOTO	START		;				10-11
START11	NOP			;				11
START12	NOP			;				12
START13	NOP			;				13
START14	NOP			;				14
START15	NOP			;				15
START16	NOP			;				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 ************************

READ_CURRENT
	MOVLW	B'10000100'	; PC offset for read current addr. EE_OK bit7='1'
	MOVWF	PC_OFFSET	; Load PC offset
	GOTO	INIT_READ_CONTROL

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
	GOTO	HOPP		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
LIGHT	BTFSS	INDF,4		;
	GOTO	NOLIGHT		;
	BTFSC	DIR		; direction invert?
	GOTO	BLIGHT		;

FLIGHT	BTFSC	LIINV		; light invert?	(PWRSRC)
	GOTO	BLI		;

FLI	BTFSS	LASTDIR
	GOTO	FLI1
	BTFSC	LASTLT
	RETLW	0
FLI1	COMF	CV34,0		;
	ANDWF	GPIOOUT,1	; off
	MOVF	CV33,0		;
	IORWF	GPIOOUT,1	; on
	BSF	LASTDIR
	BSF	LASTLT
	RETLW	0		;

BLIGHT	BTFSC	LIINV		; light invert?	(PWRSRC)
	GOTO	FLI		;

BLI	BTFSC	LASTDIR
	GOTO	BLI1
	BTFSC	LASTLT
	RETLW	0
BLI1	COMF	CV33,0		;
	ANDWF	GPIOOUT,1	; off
	MOVF	CV34,0		;
	IORWF	GPIOOUT,1	; on
	BCF	LASTDIR
	BSF	LASTLT
	RETLW	0		;

NOLIGHT	BTFSS	LASTLT
	RETLW	0
	COMF	CV33,0		;
	ANDWF	GPIOOUT,1	; off
	COMF	CV34,0		;
	ANDWF	GPIOOUT,1	; off
	BCF	LASTLT
	RETLW	0		;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
FINDCV	BCF	NOCV		;
	BCF	ROMCV		;

	XORLW	(1-1)		; CV1
	BTFSC	STATUS,ZERO	;
	RETLW	CV1		; Primary Adress

	XORLW	(1-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)^(33-1)	; CV33
	BTFSC	STATUS,ZERO	;
	RETLW	CV33		; front light to GPIO xx54x210

	XORLW	(33-1)^(34-1)	; CV34
	BTFSC	STATUS,ZERO	;
	RETLW	CV34		; back light to GPIO xx54x210

	XORLW	(34-1)^(35-1)	; CV35
	BTFSC	STATUS,ZERO	;
	RETLW	CV35		; F1 to GPIO xx54x210

	XORLW	(35-1)^(36-1)	; CV36
	BTFSC	STATUS,ZERO	;
	RETLW	CV36		; F2 to GPIO xx54x210

	XORLW	(36-1)^(37-1)	; CV37
	BTFSC	STATUS,ZERO	;
	RETLW	CV37		; F3 to GPIO xx54x210

	XORLW	(37-1)^(38-1)	; CV38
	BTFSC	STATUS,ZERO	;
	RETLW	CV38		; F4 to GPIO xx54x210

	XORLW	(38-1)^(39-1)	; CV39
	BTFSC	STATUS,ZERO	;
	RETLW	CV39		; F5 to GPIO xx54x210

	XORLW	(39-1)^(40-1)	; CV40
	BTFSC	STATUS,ZERO	;
	RETLW	CV40		; F6 to GPIO xx54x210

	XORLW	(40-1)^(41-1)	; CV41
	BTFSC	STATUS,ZERO	;
	RETLW	CV41		; F7 to GPIO xx54x210

	XORLW	(41-1)^(42-1)	; CV42
	BTFSC	STATUS,ZERO	;
	RETLW	CV42		; F8 to GPIO xx54x210

	BSF	ROMCV		;
	XORLW	(42-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	EEIN		;
	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	BTFSS	ACKON		; acknowledge on?
	GOTO	HOPP		;
	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	START		;

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	BT5		; actual F1-F8 set
	XORWF	F1F8OLD,0	;
	MOVWF	BT6		; only difference to switch
	BSF	FSR,5		;
;--------------------------------
	CLRF	MAPCV		;
FSET	MOVF	MAPCV,0		;
	CALL	BITPOS		;
	ANDWF	BT6,0		; difference
	BTFSS	STATUS,ZERO	; changes?
	GOTO	FSET1		;

FSET2	INCF	MAPCV,1		;
	BTFSS	MAPCV,3		;
	GOTO	FSET		;
	MOVF	GPIOOUT,0	;
	MOVWF	GPIO		;
	BCF	FSR,5		;
	MOVF	F1F8SET,0	;
	MOVWF	F1F8OLD		;
	GOTO	HOPP		;

FSET1	MOVLW	CV35		; base adress
	ADDWF	MAPCV,0		; add counter
	MOVWF	FSR		; indirect adressing
	MOVF	MAPCV,0		;
	CALL	BITPOS		;
	ANDWF	BT5,0		;
	BTFSC	STATUS,ZERO	; SET?
	GOTO	FSOFF		;
FSON	MOVF	INDF,0		;
	IORWF	GPIOOUT,1	; on
	GOTO	FSET2		;
FSOFF	COMF	INDF,0		;
	ANDWF	GPIOOUT,1	; off
	GOTO	FSET2		;

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
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		;
	BCF	FSR,5		;
	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		;
	BCF	FSR,5		;
	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	(1<<DCCIN)	;
	TRIS	GPIO		; set port GPIO
	CLRF	GPIO		;

ESTOP
STOP	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

	BSF	FS28		;
	BSF	FS126		;

	RLF	INDF,0		;
	BCF	FSR,5		;
	MOVWF	SOLL		;
	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

