;
;    Wuseldraht - Scurry Wire - A field bus
;    Copyright (C) 2013  Matthias Koch
;
;    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 3 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, see <http://www.gnu.org/licenses/>.
;

;------------------------------------------------------------------------------
Pause: ; ( Wartezeit -- ) Um eine kleine Pause einzulegen - ohne Interrupt.
;------------------------------------------------------------------------------
  mov #Basiszeit, r7

- dec r7 ; (1)
  nop    ; (1)
  jnz -  ; (2)

  ret
    
;------------------------------------------------------------------------------
wmw: ; warten, messen, warten. Speziell für den Wuseldraht.
     ; Liefert Ergebnis in r11.
;------------------------------------------------------------------------------  
  call #Pause
  bit.b #Wuselleitung, &P1IN
  rlc r11
  call #Pause
  ret

;------------------------------------------------------------------------------
entgleisen: ; Init für den Knoten, zum Anfang und zum Loslassen der Leitung 
            ; für längere Pausen in der Kommunikation
;------------------------------------------------------------------------------
  bic.b #Wuselleitung, &P1DIR  ; Ausschalten
  bis.b #Wuselleitung, &P1OUT  ; High bereitlegen  
  ret

;------------------------------------------------------------------------------
wuseldraht: ; ( Muster hinaus -- Muster hinein )
            ; Synchronisierende Kommunikationsroutine
;------------------------------------------------------------------------------
  push r11
  clr r11
;---------------------------------------------- I
- bit.b #Wuselleitung, &P1IN  ; Flanke zur Sync
  jnc - ; Warte auf High          suchen
  bic.b #Wuselleitung, &P1DIR ; Loslassen
- bit.b #Wuselleitung, &P1IN
  jc -  ; Warte auf Low
  call #wmw  
;---------------------------------------------- II
  bit #4, @r4 ; "0" oder "1" Zustand
  jnc +
  bis.b #Wuselleitung, &P1DIR
+ call #wmw
;---------------------------------------------- III
  bit #2, @r4 ; "N" Zustand
  jnc +
  bis.b #Wuselleitung, &P1DIR
+ call #wmw  
;---------------------------------------------- IV
  bis.b #Wuselleitung, &P1DIR
  call #wmw
;----------------------------------------------
  mov r11, @r4 ; ...0ZN1 wenn alles gutgeht !
  pop r11
  ret
 

wusel1 equ 0111b
wusel0 equ 0011b  
wuselN equ 0001b  

;------------------------------------------------------------------------------  
Wuselbit_senden: ; Gibt das Carry-Flag aus...
;------------------------------------------------------------------------------
  push r11
  mov #wusel0, r11
  jnc +
  bis #4, r11       ; Aus dem wusel0 eine wusel1 machen.
  jmp +
;------------------------------------------------------------------------------    
Wuselbit_lesen: ; Gibt ein N aus und liefert das Ergebnis im Carry-Flag mit.
;------------------------------------------------------------------------------
  push r11
  mov #wuselN, r11
+ pushda r11
  call #wuseldraht
  popda r11
  cmp #wusel0, r11
  jne +
  pop r11
  clrc
  ret
+ cmp #wusel1, r11
  jne +
  pop r11
  setc
  ret
;------------------------------------------------------------------------------  
+ ResetStacks           ; Stacks rücksetzen
  cmp #wuselN, r11      ; Bei einem N - neue Adresse
  je Finde_N
  jmp Busfehler         ; Ansonsten Busfehler !
  
;------------------------------------------------------------------------------
Sendebit: ; ( -- ), (F: C -- C)
          ; Schickt ein Bit hinaus, nimmt dieses aus dem Carry-Flag und ließt ein Bit ein --> Carry
;------------------------------------------------------------------------------
  push r10
  
  push sr
    call #Wuselbit_lesen
    mov sr, r10
  pop sr
  call #Wuselbit_senden
    mov r10, sr
      
  pop r10
  ret
        
;------------------------------------------------------------------------------
Sendeword:  ; ( TX -- RX )
            ; Schickt ein Word hinaus, nimm es aus r10, r11 Sendezähler, r12: Empfangenes
;------------------------------------------------------------------------------
  push sr
  push r10
  push r11  
  
  mov #16, r11                  ; 16 Bits sollen Übertragen werden
  mov @r4, r10                  ; Hole das zu sendende Word vom Datenstack
    
  ; Sendeschleife    
- bit #1, r10
  call #Sendebit               ; Senden/Empfangen
  rrc r10                       ; Carry ins Register rotieren, LSB zuerst

  dec r11
  jnz -                        ; Solange eben noch Bits übrig sind... Wiederhole !

  mov r10, @r4                  ; Empfangenes --> Datenstack

  pop r11
  pop r10
  pop sr
  
  ret      
 
