; 25v5.ASM (nohiz, flickering firebox)
; Version: 5    Date: 10. Sep. 1999
; Copyright (C) 1999  Georg Ziegler

; 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        0x05        ; 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
;--------------------
CONFIG        EQU        0x07        ; 0=DIR 1=CONSIST 2=STEPOK/NOCV 5=FS126 6=BITHI 7=FLAG
S31        EQU        0x08        ;
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        ACKBIT        STATUS,6        ; never overwriten

#DEFINE LED        GPIO,2                ;

;--------------------------------------------------------------------
        ORG     0                ; Reset Vector

;-------------------------TEST for POM----------------------
;#DEFINE TEST
;#DEFINE OLDA

#IFDEF        OLDA                        ;old acknowledge 00000001  11111001  11111000
START        MOVLW        0x2b                ;ADDR
        MOVWF        BT1
        MOVLW        11111001b        ;OACK
        MOVWF        BT2
        MOVLW        0x2B                ; BT2
        MOVWF        FSR                ; to 2. byte
        GOTO        CV                ; test (START outcomented)
#ENDIF

#IFDEF        CONS                        ;CONSIST 00000011 00010010 00000100
START        MOVLW        0x2B                ;ADDR
        MOVWF        BT1
        MOVLW        00010010b        ;CONSIST FORWARD
        MOVWF        BT2
        MOVLW        9                ;DATA
        MOVWF        BT3
        MOVLW        0x2C                ; BT3
        MOVWF        FSR                ; to 3. byte
        GOTO        CV                ; test (START outcomented)
#ENDIF

#IFDEF        POM                        ;programming on the main
START        MOVLW        0x2B      ;ADDR
        MOVWF        BT1
        MOVLW        11101100b ;OTM
        MOVWF        BT2
        MOVLW        0x00      ;CV
        MOVWF        BT3
        MOVLW        0x64      ;DATA
        MOVWF        BT4
        MOVLW        0x2D                ; BT4
        MOVWF        FSR                ; to 4. byte
        GOTO        CV                ; test (START outcomented)
#ENDIF

#IFDEF        DIRM                        ; direct mode
START        MOVLW        01111100b ;DIR
        MOVWF        BT1
        MOVLW        0x01      ;CV
        MOVWF        BT2
        MOVLW        0x64      ;DATA
        MOVWF        BT3
        MOVLW        0x2C                ; BT3
        MOVWF        FSR                ; to 3. byte
        GOTO        CV                ; test (START outcomented)
#ENDIF

#IFDEF        PAGR6                        ; paged/register mode
START        MOVLW        01111101b ;REG(6) 01111RRR
        MOVWF        BT1
        MOVLW        2        ;DATA
        MOVWF        BT2
        MOVLW        0x2B                ; BT2
        MOVWF        FSR                ; to 2. byte
        GOTO        CV                ; test (START outcomented)
#ENDIF
#IFDEF        PAGM                        ; paged/register mode
START        MOVLW        01111000b ;REG(1) 01111RRR
        MOVWF        BT1
        MOVLW        4        ;DATA
        MOVWF        BT2
        MOVLW        0x2B                ; BT2
        MOVWF        FSR                ; to 2. byte
        GOTO        CV                ; test (START outcomented)
#ENDIF

#IFDEF        CALLS                        ;
START        CALL        TEST1                ;test
TEST1        GOTO        EQUAL                ;test
        GOTO        START                ;test
#ENDIF
;---------------------------TEST----------------------------

INIT        MOVLW        00001000b        ; CALFST on
        MOVWF        OSCCAL                ; write calibration value

        MOVLW        11010000b        ; no wakeup, no pullup, T0 int., hightolow, T0, 1:2
        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 > 26?
        GOTO        CALEX                ;-----------------
        MOVLW        00100000b        ;
        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        SOLL,0                ; for brown out to start
        XORWF        IST,0                ; with same speed
        BTFSC        STATUS,ZERO        ; all Bytes ok?
        GOTO        START                ; -----------------------------------

CLEAR        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        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        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
        CLRF        MAPCV                ; for old acknowledge
        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
;--------------------------------
        RRF        MULT1,1                ;                        77
        RRF        MULT2,1                ;/2                        78
        RRF        MULT1,1                ;                        79
        RRF        MULT2,1                ;/4                        80
        RRF        MULT1,1                ;                        81
        RRF        MULT2,1                ;/8                        82
        RRF        MULT1,1                ;                        83
        RRF        MULT2,1                ;/16                        84

        RETLW        0                ;        END MULTIP        85-86
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
#IFNDEF TEST        ;------------------test mode----------------------
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
#ENDIF        ;------------------test mode-------------------------------
;-------------
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
        NOP                        ;                                13
        NOP                        ;                                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
        NOP                        ;                                13
        NOP                        ;                                14
        NOP                        ;                                15
        NOP                        ;                                16
        NOP                        ;                                17
        NOP                        ;                                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                ;                                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        00111111b        ;                                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 -------------
        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..
;--------------------------------
        MOVF        BT1,0                ;                                25
        BTFSS        BT1,7                ; >0<AAA AAAA                        26
        GOTO        SHORTA                ; short adress                        27
        XORWF        CV17,0                ;                                28
        BTFSS        STATUS,ZERO        ;                                29
        GOTO        CHKPROG                ;                                30-31
        MOVF        BT2,0                ;                                31
        XORWF        CV18,0                ;                                32
        BTFSS        STATUS,ZERO        ;                                33
        GOTO        CHKPROG                ;                                34
        MOVLW        0x2C                ; BT3                                35
        MOVWF        FSR                ; to 3. byte                        36
        BTFSS        LADRE                ; long adress enabled?                37
        GOTO        CHKPROG                ;                                38
        BTFSC        CONSIST                ;                                39
        GOTO        CHKPROG                ;                                40
;        NOP                        ;                                41
        BSF        STATUS,SEITE        ;                                42
        GOTO        DECOD                ;                                43-44
;--------------------------------
;BCAST        NOP                        ;                                32
;        NOP                        ;                                33
;        NOP                        ;                                34
;        NOP                        ;                                35
BCAST        GOTO        OVER1                ;                                36-37

OVER        BTFSC        CONSIST                ;                                36
        GOTO        START                ;                                37
;OVER1        NOP                        ;                                38
OVER1        GOTO        BCBCK                ;                                39-40
;--------------------------------
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                        29
        GOTO        BCAST                ;                                30-31
        BTFSS        LADRE                ; long Adress enabled?                31
        XORWF        CV1,0                ;                                32
        BTFSC        STATUS,ZERO        ;                                33
        GOTO        OVER                ;                                34-35
        MOVF        CV19,0                ;                                35
        ANDLW        01111111b        ;                                36
        BCF        CONSIST                ;                                37
        BTFSS        STATUS,ZERO        ;                                38
        BSF        CONSIST                ;                                39
        XORWF        BT1,0                ; consist?                        40
BCBCK        BTFSS        STATUS,ZERO        ;                                41
        GOTO        CHKPROG                ;                                42-43
        MOVLW        0x2B                ; BT2 + FSR,5                        43
        MOVWF        FSR                ; to 2. byte                        44
        BSF        STATUS,SEITE        ;                                42
        GOTO        DECOD                ;                                43-44
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;--------------------------------
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
;-------------------------------
BORROW        BTFSC        S31,4                ;                        198
        MOVF        CV5,0                ;                        199
        GOTO        BBACK                ;                        200-201
;--------------------------------
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                ;                        96
        BCF        STATUS,CARRY        ;                        97
        RRF        MULT1,1                ;/2                        98
        MOVLW        24                ; correction 28/32        99
        ADDWF        MULT1,1                ;                        100
        MOVLW        3                ;4-31 -> 1-28                101
        SUBWF        S31,0                ;                        102
        MOVWF        MULT2                ;                        103
;-------
        CALL        MULTIP                ;                        104-105 (1-86)
;-------
        MOVLW        9                ; correction 28/32        192
        SUBWF        MULT2,1                ;                        193
        MOVF        CV2,0                ;                        194
        BTFSS        STATUS,CARRY        ;                        195
        GOTO        BORROW                ;                        196-197
        NOP                        ;                        197
        NOP                        ;                        198
        ADDWF        MULT2,0                ;                        199
        BTFSC        STATUS,CARRY        ;                        200
        MOVF        CV5,0                ;                        201
BBACK        MOVWF        SOLL                ;                        202

;----------------------------------------------VMID------------------

VMID        CLRF        VMIDLO                ;                        200
        MOVF        CV6,0                ;                        201
        BTFSC        STATUS,ZERO        ;                        202
        GOTO        VMIDEND                ; no VMID                203
        ANDLW        01111111b        ;                        204
        MOVWF        VMIDHI                ;                        205
        BTFSS        CV6,7                ;                        206
        GOTO        NEGVMID                ;                        207-208
        MOVLW        4                ;                        208
        SUBWF        S31,0                ; 4-32 > 0-27                209
        GOTO        VMID1                ;                        210-211

NEGVMID        COMF        S31,0                ;                        211
        ANDLW        00011111b        ;                        212
        NOP                        ;                        213

VMID1        MOVWF        COUNT                ;                        214
        BTFSS        COUNT,4                ;                        215
        BTFSC        COUNT,3                ;                        216
        GOTO        VMIDMUL                ;                        217-218
        MOVWF        TEMP                ;                        218
        BTFSC        STATUS,ZERO        ;                        219
        GOTO        VMID3                ;                        220
        BCF        STATUS,CARRY        ;                        221
VMID2        RRF        VMIDHI,1        ; ->c                        222
        RRF        VMIDLO,1        ;   c->                /2        223
        DECFSZ        COUNT,1                ;                        224
        GOTO        VMID2                ;                        225

;VMID3        COMF        TEMP,0                ;                        226
;        ANDLW        00000111b        ;                        227
;        MOVWF        COUNT                ;                        228
;        BTFSC        STATUS,ZERO        ;                        229
;        GOTO        VMID5                ;                        230
;VMID4        NOP                        ;                        231
;        NOP                        ;                        232
;        DECFSZ        COUNT,1                ;                        233
;        GOTO        VMID4                ;                        234

VMID3        MOVF        CV6,0                ;                        235
        ANDLW        01111111b        ;                        236
        MOVWF        TEMP                ;                        237
        MOVF        VMIDHI,0        ;                        238
        SUBWF        TEMP,0                ;                        239

        GOTO        VMIDEND                ;                        240-241
;--------------------------------
VMIDMUL        SWAPF        VMIDHI,0        ;                        241
        ANDLW        00000111b        ;                        242
        ADDWF        VMIDHI,0        ; CV6 + CV6 / 16        243
        MOVWF        MULT1                ;                        244
        MOVLW        7                ;                        245
        SUBWF        COUNT,0                ;                        246
        MOVWF        MULT2                ;                        247
;-------
        CALL        MULTIP                ;                        248-249 (1-86)
;-------
        MOVF        MULT2,0                ;                        336
        MOVWF        TEMP                ;                        337
        RRF        MULT1,1                ;                        338
        RRF        MULT2,1                ;/2                        339
        RRF        MULT1,1                ;                        340
        RRF        MULT2,1                ;/4                        341
        DECF        MULT2,0                ;                        342
        SUBWF        TEMP,0                ;                        343

        SUBWF        VMIDHI,0        ;                        344
;------------

VMIDEND        BTFSS        CV6,7                ;        1                345
        GOTO        SUBVMID                ;        2-3                346-347
        ADDWF        SOLL,0                ;        3                347
        BTFSS        STATUS,CARRY        ;        6                350
        MOVWF        SOLL                ;        7                351
        NOP                        ;        8                352
SUBEX        BSF        FS126                ;        9                353

;-------------------------------
;        NOP                        ; test
;        GOTO        CV2CV5                ; test
;-------------------------------
        BCF        FSR,5                ;                        354
        GOTO        START                ;                        355-356

SUBVMID        SUBWF        SOLL,0                ;        4                348
        BTFSC        STATUS,CARRY        ;        5                349
        MOVWF        SOLL                ;        6                350
        GOTO        SUBEX                ;        7-8                351-352

;------------------------------------------END VMID------------------

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;--------------------------------------------------------------------
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        NOP                        ;                                19
START20        NOP                        ;                                20
START21        NOP                        ;                                21
START22        NOP                        ;                                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        0x07        ; 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                ;
        MOVWF        BT6                ;
        RRF        BT6,0                ;
        ANDLW        00000111b        ;
        ADDWF        PC                ;
        GOTO        DECCON                ; 000
        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        ACKNOW                ;--------------------------------

        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        00000111b        ;
        ADDWF        PC                ;
        GOTO        RESET                ; 000 reset / hard reset
        GOTO        HOPP        ;FTEST        ; 001 factory test instruction
        GOTO        HOPP                ; 010
        GOTO        ADVACK                ; 011 advance acknowl. CV29,3
        GOTO        HOPP                ; 100
        GOTO        ADVADR                ; 101 advance adressing CV29,5
        GOTO        HOPP                ; 110
        GOTO        HOPP ;ACKREQ                ; 111 acknowledge request
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;.....................................................................
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        ;
        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                ;

EEIN        CALL        WRITE_BYTE        ;
        BTFSC        STATUS,ZERO        ; ERROR?
        GOTO        EEIN                ;
        BCF        STATUS,SEITE        ; auf ROM seite 0
        GOTO        LOADREG                ;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
EEVERI        BTFSC        ROMCV                ;
        GOTO        RDROMCV                ;

        ANDLW        00001111b        ;
        MOVWF        EEADDR                ;
        CALL        READ_RANDOM        ;
        MOVF        INDF,0                ;
        XORWF        EEDATA,0        ;

VERIBK        BTFSS        STATUS,ZERO        ;
        BCF        STATUS,SEITE        ; auf ROM seite 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        7                ; 7x765uS (5355) 4,5,6,7 ok
        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        ; auf ROM seite 0
        GOTO        START                ;

RDROMCV        XORWF        INDF,0                ;
        GOTO        VERIBK                ;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................

PROGREG        MOVF        BT1,0                ; CV5=CV29
        XORLW        01111101b        ; reg6
        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                ;

REG5        MOVF        BT1,0                ;
        ANDLW        00000111b        ; lower 3bit
        GOTO        PREG                ;

REG6        DECF        BT2,1                ;
        BCF        STATUS,CARRY        ;
        RLF        BT2,1                ;
        RLF        BT2,0                ;
        MOVWF        MAPCV                ;
        GOTO        HOPP                ;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;....................................................................
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?
        GOTO        REV                ;

FOR        BTFSC        CV19,7                ; CV19,7 (DIR) invert?
        GOTO        REV1                ;

FOR1        BTFSS        DIR                ;
        GOTO        SPEED                ;
        BCF        DIR                ;
        GOTO        ESTOP                ;
;--------------------------------
REVERSE        BTFSC        CV29,0                ; CV29,0 (DIR) invert?
        GOTO        FOR                ;

REV        BTFSC        CV19,7                ; CV19,7 (DIR) invert?
        GOTO        FOR1                ;

REV1        BTFSC        DIR                ;
        GOTO        SPEED                ;
        BSF        DIR                ;
        GOTO        ESTOP                ;
;--------------------------------------------------------------------
SPEED        BCF        FS126                ;
        RLF        INDF,0                ; 01DSSSSS
        ANDLW        00011110b        ; xxx4321x
        MOVWF        S31                ; 1D04321x
        BTFSC        INDF,4                ; 01D>S<SSSS
        BSF        S31,0                ; mov pos.4 to pos.0
;........................ Arnold Digital ............................
        BTFSS        FS28                ; 14/28 Speed?
        BCF        S31,0                ; <- 14 Speed
        BTFSS        FS28                ; 14/28 Speed?
        CALL        LIGHT                ;
;^^^^^^^^^^^^^^^^^^^^^^^^ 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                ;
        GOTO        HOPP                ;

;.....................................................................
ADVACK        BCF        CV29,3                ;
        BTFSS        STATUS,CARRY        ;
        BSF        CV29,3                ;
        MOVLW        CV29                ;
        MOVWF        INDF                ;
        MOVF        CV29,0                ;
        GOTO        EEPROG                ;

ADVADR        BCF        LADRE                ;
        BTFSS        STATUS,CARRY        ;
        BSF        LADRE                ;
        MOVLW        CV29                ;
        MOVWF        INDF                ;
        MOVF        CV29,0                ;
        GOTO        EEPROG                ;

;ACKREQ        BCF        CV29,2                ; weiss nich
;        BTFSS        STATUS,CARRY        ;
;        BSF        CV29,2                ; weiss nich
;        MOVLW        CV29                ;
;        MOVWF        INDF                ;
;        MOVF        CV29,0                ;
;        GOTO        EEPROG                ;

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        BTFSS        DIR                ;
        GOTO        ASPEED                ;
        BCF        DIR                ;
        GOTO        ESTOP                ;
;--------------------------------
AREVE        BTFSC        CV29,0                ; CV29,0 (DIR) invert?
        GOTO        AFOR                ;

AREV        BTFSC        CV19,7                ; CV19,7 (DIR) invert?
        GOTO        AFOR1                ;

AREV1        BTFSC        DIR                ;
        GOTO        ASPEED                ;
        BSF        DIR                ;
        GOTO        ESTOP                ;
;--------------------------------
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        ACKBIT                ;
PROGEX        BCF        STATUS,SEITE        ;
        BCF        FSR,5                ;
        GOTO        START                ;

;********************************************************************

        ORG        03FFh
        MOVLW        0x70                ; for OSCCAL

        END
