v0.5 - Issues slave breaks seemingly without hickups (!)
authorWerner Johansson <wj@xnk.nu>
Sat, 8 Mar 2003 09:22:05 +0000 (01:22 -0800)
committerWerner Johansson <wj@xnk.nu>
Sun, 17 Oct 2010 00:33:49 +0000 (17:33 -0700)
Signed-off-by: Werner Johansson <wj@xnk.nu>

wj-uni.asm

index 31f5bc1..08ddc24 100644 (file)
@@ -1,4 +1,4 @@
-       title   "PIC16F870 Unilink(R) Interface by Werner Johansson (c) 2003"\r
+       title   "PIC16F870 Unilink(R) Interface by Werner Johansson (c) 2002-2003"\r
        subtitl "Definitions"\r
        list    c=150,P=16F870,R=DEC,F=inhx8m\r
         include "p16f870.inc"           ; Standard equates & Macros\r
@@ -25,6 +25,7 @@
 ;----------------------------------------------------------------\r
 ;  Version\r
 ;\r
+;  0.5  Issues slave breaks seemingly without hickups (!)\r
 ;  0.4  Some fixups in the bootstrap code (I actually had to put the PIC in my PICSTART Plus programmer again :))\r
 ;  0.3  Implementing more Unilink commands and RingIndicator control (to wake the computer from sleep)\r
 ;  0.2  First attempt at responding to the Anyone command\r
 ;----------------------------------------------------------------\r
 ;  FILE REGISTER USAGE\r
 ;----------------------------------------------------------------\r
-Dcount         equ     20h\r
-e_LEN          equ     21h\r
-\r
-Counter                equ     22h\r
-SlaveBreakState        equ     23h             ; Hold state and time-out information about slave break, indicates when it can happen\r
-Icount         equ     2Dh             ; Offset of string to print\r
-TxTemp         equ     2Eh             ; blahblah\r
-TxTemp2                equ     2Fh             ; Blahblah2\r
-\r
-LCDWTmp        equ     30h\r
-Dcount2                equ     31h\r
-temp           equ     32h\r
-\r
-DataCount      equ     33h             ; Temp storage for the bit counter used during bit shifts (Unilink TX/RX)\r
-DataStore      equ     34h             ; This is a kludge\r
-\r
-UnilinkSelected        equ     3bh\r
-UnilinkBit     equ     3ch             ; This is my "bitmask" to be used for requests\r
-UnilinkID      equ     3dh             ; This is my Bus ID\r
-UnilinkCmdLen  equ     3eh             ; This gets updated with the actual packet length after CMD1 has been received\r
-UnilinkTXRX    equ     3fh             ; This is a pointer to the Unilink packet below, used with indirect addressing\r
-\r
-UnilinkRAD     equ     40h             ; Beginning of Unilink packet - the Receiving Address\r
-UnilinkTAD     equ     41h             ; Transmitter address\r
-UnilinkCMD1    equ     42h             ; CMD1 byte\r
-UnilinkCMD2    equ     43h             ; CMD2 byte\r
-UnilinkParity1 equ     44h             ; First or only parity byte for short packets (6 bytes)\r
-UnilinkData1   equ     45h             ; Extra data for medium/large packets, or zero for short packets\r
-UnilinkData2   equ     46h             ;\r
-UnilinkData3   equ     47h             ;\r
-UnilinkData4   equ     48h             ;\r
-UnilinkData5   equ     49h             ; Data5 if this is a large packet\r
-UnilinkParity2M        equ     49h             ; Parity2 shares the same byte if it's a medium sized packet\r
-UnilinkData6   equ     4ah             ; Extra data for large packets, or zero for medium packets\r
-UnilinkData7   equ     4bh             ;\r
-UnilinkData8   equ     4ch             ;\r
-UnilinkData9   equ     4dh             ;\r
-UnilinkParity2 equ     4eh             ; Parity byte for large packets\r
-UnilinkZero    equ     4fh             ; Should always be zero (possibly used to signal corrupt packets from slave to master?)\r
+TrackName00    equ     20h             ; Buffer for TrackName\r
+TrackName01    equ     21h\r
+TrackName02    equ     22h\r
+TrackName03    equ     23h\r
+TrackName04    equ     24h\r
+TrackName05    equ     25h\r
+TrackName06    equ     26h\r
+TrackName07    equ     27h\r
+TrackName08    equ     28h\r
+TrackName09    equ     29h\r
+TrackName0a    equ     2ah\r
+TrackName0b    equ     2bh\r
+TrackName0c    equ     2ch\r
+TrackName0d    equ     2dh\r
+TrackName0e    equ     2eh\r
+TrackName0f    equ     2fh\r
+TrackName10    equ     30h\r
+TrackName11    equ     31h\r
+TrackName12    equ     32h\r
+TrackName13    equ     33h\r
+TrackName14    equ     34h\r
+TrackName15    equ     35h\r
+TrackName16    equ     36h\r
+TrackName17    equ     37h\r
+TrackName18    equ     38h\r
+TrackName19    equ     39h\r
+TrackName1a    equ     3ah\r
+TrackName1b    equ     3bh\r
+TrackName1c    equ     3ch\r
+TrackName1d    equ     3dh\r
+TrackName1e    equ     3eh\r
+TrackName1f    equ     3fh\r
+TrackName20    equ     40h\r
+TrackName21    equ     41h\r
+TrackName22    equ     42h\r
+TrackName23    equ     43h\r
+TrackName24    equ     44h\r
+TrackName25    equ     45h\r
+TrackName26    equ     46h\r
+TrackName27    equ     47h\r
+TrackName28    equ     48h\r
+TrackName29    equ     49h\r
+TrackName2a    equ     4ah\r
+TrackName2b    equ     4bh\r
+TrackName2c    equ     4ch\r
+TrackName2d    equ     4dh\r
+TrackName2e    equ     4eh\r
+TrackName2f    equ     4fh\r
+\r
+UnilinkRAD     equ     50h             ; Beginning of Unilink packet - the Receiving Address\r
+UnilinkTAD     equ     51h             ; Transmitter address\r
+UnilinkCMD1    equ     52h             ; CMD1 byte\r
+UnilinkCMD2    equ     53h             ; CMD2 byte\r
+UnilinkParity1 equ     54h             ; First or only parity byte for short packets (6 bytes)\r
+UnilinkData1   equ     55h             ; Extra data for medium/large packets, or zero for short packets\r
+UnilinkData2   equ     56h             ;\r
+UnilinkData3   equ     57h             ;\r
+UnilinkData4   equ     58h             ;\r
+UnilinkData5   equ     59h             ; Data5 if this is a large packet\r
+UnilinkParity2M        equ     59h             ; Parity2 shares the same byte if it's a medium sized packet\r
+UnilinkData6   equ     5ah             ; Extra data for large packets, or zero for medium packets\r
+UnilinkData7   equ     5bh             ;\r
+UnilinkData8   equ     5ch             ;\r
+UnilinkData9   equ     5dh             ;\r
+UnilinkParity2 equ     5eh             ; Parity byte for large packets\r
+UnilinkZero    equ     5fh             ; Should always be zero (possibly used to signal corrupt packets from slave to master?)\r
+\r
+UnilinkTimeout equ     60h             ; Counts up every 0.5ms to "age out" faulty bytes clocked in\r
+UnilinkSelected        equ     61h             ; High bit is set when selected\r
+UnilinkBit     equ     62h             ; This is my "bitmask" to be used for requests\r
+UnilinkID      equ     63h             ; This is my Bus ID\r
+UnilinkCmdLen  equ     64h             ; This gets updated with the actual packet length after CMD1 has been received\r
+UnilinkTXRX    equ     65h             ; This is a pointer to the Unilink packet above, used with indirect addressing\r
+SlaveBreakState        equ     66h             ; Hold state and time-out information about slave break, indicates when it can happen\r
+DisplayStatus  equ     67h             ; What information will be put on the display next, bit 7 cleared if nothing\r
+Icount         equ     68h             ; Offset of string to print\r
+TxTemp         equ     69h             ; blahblah\r
+TxTemp2                equ     6ah             ; Blahblah2\r
+LCDWTmp        equ     6bh\r
+Dcount2                equ     6ch\r
+temp           equ     6dh\r
+Dcount         equ     6eh\r
+e_LEN          equ     6fh\r
+\r
+\r
+Counter                equ     70h\r
+DataCount      equ     71h             ; Temp storage for the bit counter used during bit shifts (Unilink TX/RX)\r
+DataStore      equ     72h             ; This is a kludge\r
 \r
 IRQPCLATH      equ     7dh             ; ISH storage\r
 IRQSTATUS      equ     7eh             ; Needs to be located in a shared area accessible from all register banks\r
 IRQW           equ     7fh             ; \r
 \r
+DiscName00     equ     0a0h            ; Buffer for DiscName\r
+DiscName01     equ     0a1h\r
+DiscName02     equ     0a2h\r
+DiscName03     equ     0a3h\r
+DiscName04     equ     0a4h\r
+DiscName05     equ     0a5h\r
+DiscName06     equ     0a6h\r
+DiscName07     equ     0a7h\r
+DiscName08     equ     0a8h\r
+DiscName09     equ     0a9h\r
+DiscName0a     equ     0aah\r
+DiscName0b     equ     0abh\r
+DiscName0c     equ     0ach\r
+DiscName0d     equ     0adh\r
+DiscName0e     equ     0aeh\r
+DiscName0f     equ     0afh\r
+DiscName10     equ     0b0h\r
+DiscName11     equ     0b1h\r
+DiscName12     equ     0b2h\r
+DiscName13     equ     0b3h\r
+DiscName14     equ     0b4h\r
+DiscName15     equ     0b5h\r
+DiscName16     equ     0b6h\r
+DiscName17     equ     0b7h\r
+DiscName18     equ     0b8h\r
+DiscName19     equ     0b9h\r
+DiscName1a     equ     0bah\r
+DiscName1b     equ     0bbh\r
+DiscName1c     equ     0bch\r
+DiscName1d     equ     0bdh\r
+DiscName1e     equ     0beh\r
+DiscName1f     equ     0bfh\r
+\r
        subtitl "Startup"\r
        page\r
 ;----------------------------------------------------------------\r
@@ -137,7 +220,8 @@ IRQW                equ     7fh             ;
        swapf   STATUS,w                ; Get the status register into w\r
        clrf    STATUS                  ; Zero out the status reg, gives Reg Bank0\r
        movwf   IRQSTATUS               ; Store the STATUS reg\r
-       movf    PCLATH,w                ; Get the PCLATH reg\r
+; Not using PCLATH for anything in the ISR right now\r
+;      movf    PCLATH,w                ; Get the PCLATH reg\r
 ;      movwf   IRQPCLATH               ; And store it\r
 ;      clrf    PCLATH                  ; Go to low memory\r
 ; Maybe save FSR here as well (if there's a need for it in the non-ISR code)\r
@@ -240,7 +324,7 @@ IRQINTRecvNotCMD1
        andlw   0fh                     ; and mask - this results in a zero result when finished receiving\r
        bnz     IRQINTRecvIncomplete    ; Packet not ready yet\r
 \r
-; Here a packet is actually received a packet, should check the checksum(s) as well, but I don't care right now\r
+; Here a packet is actually received, should check the checksum(s) as well, but I don't care right now\r
 ; (I need music in my car! :))\r
 ; This is inefficient, I know, I'll improve it later... (Not that it matters, there's plenty of time here\r
 ; (there won't be any more communication for at least another 4.8ms))\r
@@ -254,13 +338,11 @@ IRQINTRecvNotCMD1
 \r
 ; Check for 01 00 (Bus Re-Initialization)\r
        movf    UnilinkCMD2,w\r
-;      xorlw   00h\r
        bnz     IRQINTParseNot0100\r
 \r
-       clrf    UnilinkID               ; Clear the existing Unilink ID, if any\r
-       bcf     BUSON_OUT_BIT           ; Clear the cascade BUSON pin, not activated again until we have a new ID\r
+       call    ClearUnilinkStatus      ; Clear everything Unilink (ID, BUSON_OUT)\r
 \r
-       goto    IRQINTParseComplete     ; Don't send any reply to this\r
+       goto    IRQINTParseComplete     ; Don't send any reply to this (clear the packet buffer though)\r
 \r
 IRQINTParseNot0100\r
 \r
@@ -272,27 +354,39 @@ IRQINTParseNot0100
        movf    UnilinkID,w             ; Do I have an ID already?\r
        bnz     IRQINTParseNot0102      ; Yep, I don't want another one!\r
 \r
+;      clrf    UnilinkParity1\r
+       call    ClearUnilinkBuffer      ; Zero it out completely\r
+\r
        movlw   10h                     ; Sending to Master\r
+       addwf   UnilinkParity1,f\r
        movwf   UnilinkRAD\r
        movlw   0d0h                    ; I'm in the MD changer group\r
+       addwf   UnilinkParity1,f\r
        movwf   UnilinkTAD\r
        movlw   8ch                     ; Device discovery command reply\r
+       addwf   UnilinkParity1,f\r
        movwf   UnilinkCMD1\r
-       movlw   00h                     ; 00??\r
+       movlw   10h                     ; 00??\r
+       addwf   UnilinkParity1,f\r
        movwf   UnilinkCMD2\r
-       movlw   6ch                     ; Hard coded parity (!)\r
-       movwf   UnilinkParity1\r
+\r
+       movf    UnilinkParity1,w\r
+       movwf   UnilinkParity2M\r
+\r
        movlw   24h                     ; My internal MD sends 25 here first time, and then 24 when appointed!??\r
+       addwf   UnilinkParity2M,f\r
        movwf   UnilinkData1\r
-       movlw   2ch                     ; 2c??\r
+       movlw   0a8h                    ; 2c??\r
+       addwf   UnilinkParity2M,f\r
        movwf   UnilinkData2\r
-       movlw   22h                     ; 22??\r
+       movlw   17h                     ; 22??\r
+       addwf   UnilinkParity2M,f\r
        movwf   UnilinkData3\r
-       movlw   00h                     ; 00??\r
+       movlw   0a0h                    ; 00?? 0a0=10 disc?\r
+       addwf   UnilinkParity2M,f\r
        movwf   UnilinkData4\r
-       movlw   0deh                    ; Hard coded parity 2 (!)\r
-       movwf   UnilinkData5\r
-        clrf   UnilinkData6\r
+\r
+;        clrf  UnilinkData6\r
        goto    IRQINTParseBypassClear  ; Don't clear the data, the buffer will be sent as the next packet\r
 \r
 IRQINTParseNot0102\r
@@ -306,7 +400,8 @@ IRQINTParseNot0102
        xorwf   UnilinkID,w             ; Is it for me?\r
        bnz     IRQINTParseNot0112      ; Nope\r
 \r
-       clrf    UnilinkParity1\r
+;      clrf    UnilinkParity1\r
+       call    ClearUnilinkBuffer\r
        movlw   10h                     ; Sending to Master\r
        addwf   UnilinkParity1,f\r
        movwf   UnilinkRAD\r
@@ -323,11 +418,146 @@ IRQINTParseNot0102
        \r
        addwf   UnilinkParity1,f\r
        movwf   UnilinkCMD2\r
-        clrf   UnilinkData6\r
+;        clrf  UnilinkData1\r
        goto    IRQINTParseBypassClear  ; Don't clear the data, the buffer will be sent as the next packet\r
 \r
 IRQINTParseNot0112\r
 \r
+; Check for 01 13 (Request Time poll)\r
+       movf    UnilinkCMD2,w\r
+       xorlw   13h\r
+       bnz     IRQINTParseNot0113\r
+\r
+       movf    UnilinkRAD,w\r
+       xorwf   UnilinkID,w             ; Is it for me?\r
+       bnz     IRQINTParseNot0113      ; Nope\r
+\r
+       btfss   DisplayStatus,7         ; If not displaying, skip this\r
+       goto    IRQINTParseComplete\r
+\r
+;      clrf    UnilinkParity1\r
+       call    ClearUnilinkBuffer\r
+       movlw   70h                     ; Sending to Display Group\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkRAD\r
+       movf    UnilinkID,w             ; This is my ID\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkTAD\r
+       movlw   90h\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkCMD1\r
+       movlw   50h\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkCMD2\r
+\r
+       movf    UnilinkParity1,w        ; Carry the parity forward\r
+       movwf   UnilinkParity2M\r
+\r
+;      movlw   01h\r
+       movf    DisplayStatus,w\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData1\r
+       movlw   00h\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData2\r
+       movlw   01h\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData3\r
+;      movlw   0c0h\r
+       movf    DisplayStatus,w\r
+       andlw   0f0h\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData4\r
+       \r
+;        clrf  UnilinkData6\r
+\r
+       incf    DisplayStatus,f         ; Temporary debug info\r
+       bsf     DisplayStatus,7\r
+\r
+       goto    IRQINTParseBypassClear  ; Don't clear the data, the buffer will be sent as the next packet\r
+\r
+IRQINTParseNot0113\r
+\r
+; Check for 01 15 (Who sent the slave break?)\r
+       movf    UnilinkCMD2,w\r
+       xorlw   15h\r
+       bnz     IRQINTParseNot0115\r
+\r
+       btfss   DisplayStatus,7         ; First of all check if there should be anything displayed\r
+       goto    IRQINTParseComplete     ; No, not at this time\r
+       \r
+;      clrf    UnilinkParity1\r
+       call    ClearUnilinkBuffer\r
+       movlw   10h                     ; Sending to Master\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkRAD\r
+       movlw   18h                     ; Broadcast address sending in this special case\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkTAD\r
+       movlw   82h                     ; Who wants to talk reply command\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkCMD1\r
+\r
+       clrw\r
+       call    Bit_Frig\r
+       addwf   UnilinkParity1,f\r
+       movwf   UnilinkCMD2\r
+\r
+       movf    UnilinkParity1,w        ; Carry the parity forward\r
+       movwf   UnilinkParity2M\r
+\r
+       movlw   20h\r
+       call    Bit_Frig\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData1\r
+       movlw   40h\r
+       call    Bit_Frig\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData2\r
+       movlw   60h\r
+       call    Bit_Frig\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData3\r
+       movlw   80h\r
+       call    Bit_Frig\r
+       addwf   UnilinkParity2M,f\r
+       movwf   UnilinkData4\r
+\r
+;      clrf    UnilinkData6\r
+\r
+       goto    IRQINTParseBypassClear  ; Don't clear the data, the buffer will be sent as the next packet\r
+\r
+;******************************************************************************\r
+; Bit frig - works out which bit to set in the response to Master Poll\r
+\r
+; W register is input of which stage you are on (0x00, 0x20, 0x30, 0x40 etc)\r
+; and is returned with the byte to write (0x00 if wrong stage).\r
+\r
+Bit_Frig:\r
+       xorwf   UnilinkBit, 0\r
+       andlw   0xe0                            ; Strip off low bits\r
+\r
+       btfsc   STATUS, Z                       ; Do we have a hit?\r
+       goto    Bit_Frig_Hit\r
+\r
+       movlw   0x00\r
+       return\r
+\r
+Bit_Frig_Hit:\r
+       btfss   UnilinkBit, 4                   ; Do we need to swap nybbles?\r
+       goto    Bit_Frig_Swap\r
+\r
+       movf    UnilinkBit, 0\r
+       andlw   0x0F\r
+       return\r
+\r
+Bit_Frig_Swap:\r
+       swapf   UnilinkBit, 0\r
+       andlw   0xF0\r
+       return\r
+\r
+IRQINTParseNot0115\r
+\r
 IRQINTParseNot01\r
 \r
 ; Check for CMD1 = 02h (Appoint)\r
@@ -342,7 +572,8 @@ IRQINTParseNot01
        movf    UnilinkCMD2,w           ; Get the bitmask\r
        movwf   UnilinkBit              ; And store it (this is needed when doing slave breaks and actually responding)\r
 \r
-       clrf    UnilinkParity1\r
+;      clrf    UnilinkParity1\r
+       call    ClearUnilinkBuffer\r
        movlw   10h                     ; Sending to Master\r
        addwf   UnilinkParity1,f\r
        movwf   UnilinkRAD\r
@@ -352,7 +583,7 @@ IRQINTParseNot01
        movlw   8ch                     ; Device discovery command again\r
        addwf   UnilinkParity1,f\r
        movwf   UnilinkCMD1\r
-       movlw   00h\r
+       movlw   10h\r
        addwf   UnilinkParity1,f\r
        movwf   UnilinkCMD2\r
 \r
@@ -362,17 +593,17 @@ IRQINTParseNot01
        movlw   24h\r
        addwf   UnilinkParity2M,f\r
        movwf   UnilinkData1\r
-       movlw   2ch                     ; My internal MD sends 1c here... (external/internal difference)\r
+       movlw   0a8h                    ; My internal MD sends 1c here... (external/internal difference)\r
        addwf   UnilinkParity2M,f\r
        movwf   UnilinkData2\r
-       movlw   22h\r
+       movlw   17h\r
        addwf   UnilinkParity2M,f\r
        movwf   UnilinkData3\r
-       movlw   00h\r
+       movlw   0a0h                    ; 0a0=10disc\r
        addwf   UnilinkParity2M,f\r
        movwf   UnilinkData4\r
 \r
-        clrf   UnilinkData6\r
+;        clrf  UnilinkData6\r
        goto    IRQINTParseBypassClear  ; Don't clear the data, the buffer will be sent as the next packet\r
 \r
 IRQINTParseNot02\r
@@ -405,37 +636,23 @@ IRQINTParseNot87
        bnz     IRQINTParseF0Deselect\r
 \r
        bsf     UnilinkSelected,7       ; Now we're selected\r
+       bsf     DisplayStatus,7\r
        goto    IRQINTParseComplete\r
 \r
 IRQINTParseF0Deselect\r
 \r
        bcf     UnilinkSelected,7       ; Now we're de-selected\r
+       bcf     DisplayStatus,7\r
        goto    IRQINTParseComplete\r
 \r
 IRQINTParseNotF0\r
 \r
 IRQINTParseComplete\r
 \r
-; The CPU ends up here when parsing is complete and it's not interested in sending any reply back to the master\r
+; The code ends up here when parsing is complete and it's not interested in sending any reply back to the master\r
 ; (that's why we clear out all the packet buffer bytes)\r
-; TODO: Replace this with an FSR access to save space and make the code neater\r
 \r
-       clrf    UnilinkRAD\r
-       clrf    UnilinkTAD\r
-       clrf    UnilinkCMD1\r
-       clrf    UnilinkCMD2\r
-       clrf    UnilinkParity1\r
-       clrf    UnilinkData1\r
-       clrf    UnilinkData2\r
-       clrf    UnilinkData3\r
-       clrf    UnilinkData4\r
-       clrf    UnilinkData5\r
-       clrf    UnilinkData6\r
-       clrf    UnilinkData7\r
-       clrf    UnilinkData8\r
-       clrf    UnilinkData9\r
-       clrf    UnilinkParity2\r
-       clrf    UnilinkZero\r
+       call    ClearUnilinkBuffer\r
 \r
 IRQINTParseBypassClear\r
 \r
@@ -462,8 +679,8 @@ IRQNotINT
 ; Slave break opportunity detection here - the logic works as follows:\r
 ; Look for a data low period of at least 5 ms (10 loops)\r
 ; Look for a data high period of at least 2 ms (4 loops)\r
-; If the Slave Break request bit has been set, issue a slave break by holding the data line low for 5ms (10 loops)\r
-; If a packet would be received the packet handler automatically clears out the SlaveBreakState, which means start all over\r
+; If the Slave Break request bit has been set, issue a slave break by holding the data line low for 4ms (8 loops)\r
+; If a bit would be received (CLK activates) the packet handler automatically clears out the SlaveBreakState, which means start all over\r
 \r
 ;      incf    Counter,f               ; Increment the general purpose counter\r
 \r
@@ -481,7 +698,7 @@ IRQTMR2HighData
        btfsc   DATA_BIT                ; Looking for a high data line, if it's high - increment state, otherwise wait\r
        goto    IRQTMR2HighDataOK\r
        movlw   080h\r
-       btfss   SlaveBreakState,6       ; Test the "first time around" bit\r
+       btfsc   SlaveBreakState,6       ; Test the "first time around" bit\r
        clrw                            ; Not the beginning of the state, have to restart the entire thing now, not just this state\r
        andwf   SlaveBreakState,f       ; Mask out the 1 upper control bits and restart this state\r
        goto    IRQAfterTMR2\r
@@ -489,8 +706,6 @@ IRQTMR2HighData
 IRQTMR2HighDataOK\r
 IRQTMR2LowDataOK\r
        bsf     SlaveBreakState,6       ; Set the "first time around" bit\r
-       btfss   SlaveBreakState,4       ; Only increment to 0x10\r
-       incf    SlaveBreakState,f\r
        \r
        movf    SlaveBreakState,w\r
        andlw   1fh\r
@@ -503,8 +718,14 @@ IRQTMR2LowDataOK
        goto    IRQAfterTMR2\r
 \r
 ; Issue slave break here\r
+\r
+       clrf    SlaveBreakState\r
+\r
        incf    Counter,f\r
-;      clrf    SlaveBreakState\r
+\r
+       btfss   DisplayStatus,7         ; Only do this if high bit is set\r
+       goto    IRQAfterTMR2\r
+\r
        movlw   20h\r
        movwf   SlaveBreakState\r
        bcf     DATA_BIT\r
@@ -514,7 +735,7 @@ IRQTMR2LowDataOK
        goto    IRQAfterTMR2\r
 \r
 IRQTMR2FoundLow\r
-       xorlw   7\r
+       xorlw   10\r
        skpz\r
        goto    IRQAfterTMR2\r
        movlw   80h                     ; Prepare for state 2, looking for data line high\r
@@ -524,7 +745,7 @@ IRQTMR2FoundLow
 IRQTMR2SlaveBreak\r
        movf    SlaveBreakState,w\r
        andlw   01fh\r
-       xorlw   4\r
+       xorlw   8\r
        skpz\r
        goto    IRQAfterTMR2\r
        bsf     STATUS,RP0\r
@@ -533,6 +754,8 @@ IRQTMR2SlaveBreak
        clrf    SlaveBreakState\r
 \r
 IRQAfterTMR2\r
+       btfss   SlaveBreakState,4       ; Only increment to 0x10\r
+       incf    SlaveBreakState,f\r
        bcf     PIR1,TMR2IF             ; Clear the IRQ source bit to re-enable TMR2 interrupts again\r
 \r
 IRQNotTMR2\r
@@ -549,14 +772,60 @@ IRQNotTMR2
        swapf   IRQW,w                  ; Restore W\r
        retfie                          ; Interrupt return\r
 \r
+;----------------------------------------------------------------\r
+; ClearUnilinkStatus - Zeroes out the Unilink state (used when initializing)\r
+\r
+ClearUnilinkStatus\r
+\r
+       clrf    UnilinkID               ; Clear the existing Unilink ID, if any\r
+       bcf     BUSON_OUT_BIT           ; Clear the cascade BUSON pin, not activated again until we have a new ID\r
+       clrf    DisplayStatus           ; No crazy display updates when resetting.. :)\r
+       clrf    UnilinkSelected         ; We're not selected anymore\r
+\r
+       bsf     STATUS,RP0              ; Reg bank 1\r
+       bsf     DATA_BIT                ; Make sure data is tristated\r
+       bcf     STATUS,RP0              ; Reg bank 0\r
+\r
+       movlw   UnilinkRAD              ; Get the pointer to the first byte in the receive buffer\r
+       movwf   UnilinkTXRX             ; Store it - this way the next byte that gets received goes into RAD\r
+\r
+       clrf    UnilinkCmdLen           ; No command length while waiting for a new packet\r
+\r
+       return\r
+       \r
+;----------------------------------------------------------------\r
+; ClearUnilinkBuffer - Zeroes out the Unilink packet buffer\r
+\r
+ClearUnilinkBuffer\r
+\r
+; TODO: Replace this with an FSR access to save space and make the code neater\r
+       clrf    UnilinkRAD\r
+       clrf    UnilinkTAD\r
+       clrf    UnilinkCMD1\r
+       clrf    UnilinkCMD2\r
+       clrf    UnilinkParity1\r
+       clrf    UnilinkData1\r
+       clrf    UnilinkData2\r
+       clrf    UnilinkData3\r
+       clrf    UnilinkData4\r
+       clrf    UnilinkData5\r
+       clrf    UnilinkData6\r
+       clrf    UnilinkData7\r
+       clrf    UnilinkData8\r
+       clrf    UnilinkData9\r
+       clrf    UnilinkParity2\r
+       clrf    UnilinkZero\r
+\r
+       return\r
+\r
 \r
        subtitl "Main loop"\r
        page\r
 \r
 ;----------------------------------------------------------------\r
-;  Main program begins here. [Called after bootloader, lcdinit and irqinit...]\r
+; Main program begins here. [Called after bootloader, lcdinit and irqinit...]\r
+; Here all other house keeping tasks are performed, like displaying info on the LCD.. \r
 \r
-;      org     100h                    ; Maybe not force this to a specific address later\r
 Main\r
        movlw   high LookUp\r
        movwf   PCLATH\r
@@ -579,6 +848,7 @@ MainLoop
 \r
 ;      movlw   '0'\r
        movf    SlaveBreakState,w\r
+       andlw   80h\r
        btfsc   PORTB,0                 ; Test CLK\r
        movlw   'C'\r
        call    TxLCDB\r
@@ -620,6 +890,7 @@ IRQInit
 ; Start with clearing the Unilink packet buffer before enabling any interrupts, otherwise the first packet might become corrupt\r
 ; TODO: Replace this with FSR access\r
        clrf    UnilinkSelected\r
+       clrf    DisplayStatus\r
        clrf    UnilinkID\r
        clrf    UnilinkBit\r
        clrf    UnilinkCmdLen\r
@@ -898,7 +1169,9 @@ DelayInner
        org     600h\r
 StartUpText1\r
        DT      "----- WJ UniLink"\r
-               \r
+\r
+InfoText1\r
+       DT      "WJ UniLink      "               \r
 LookUp movwf   PCL                     ; Go to it (this assumes PCLATH == 06h)\r
 \r
 \r