Fifo Assembler

Gast #1153851
Lesenswert?

Hallo
ich programmiere in Assembler und mir fehlen gerade ein paar 
Grundkenntnisse.
Ich möchte einen FIFO realisieren. Das Tutorial dazu habe ich schon 
gelesen. Einigermaßen klappt das auch mit dem FIFO, nur muss ich noch 
ein paar Bedingungen Abfragen. Hierbei bin ich mir nicht so sicher, ob 
bzw. wie ich das richtig in Assembler implementiere.

So muss ich z.B. den Fall das Lese- und Schreibpuffer auf der selben 
Stelle sind abfragen:

if (buffer.read == buffer.write)
    return FAIL;

  cp YL, XL
  cpc YH, XH
  breq fail

Ist das so richtig? Schreibzeige --> Y  Lesezeiger --> X

Und wie kann ich eine solche Abfrage realisieren bzw. wie frage ich auf 
die Adresse des Schreibpuffer +1 ab?

if (buffer.write + 1 == buffer.read || buffer.read == 0 && buffer.write 
+ 1 == BUFFER_SIZE)


Danke für die Mühe im Vorraus
#1153933
Lesenswert?

Elbegucker wrote:

> Und wie kann ich eine solche Abfrage realisieren bzw. wie frage ich auf
> die Adresse des Schreibpuffer +1 ab?

Mache eine Kopie (MOVW) in andere Register, addiere dort 1 und 
vergleiche dann.

Du kannst Dir ne ganze Menge Arbeit sparen, wenn ein FIFO mit max 255 
Byte ausreicht, indem Du mit Index arbeitest. Dann sind alle Rechnungen 
8-Bittig.
Nur beim eigentlichen FIFO-Zugriff muß 16-bittig die Startadresse 
addiert werden.

Versuche nicht, sämtliche Variablen in Registern zu halten. Definiere 
einige Arbeitsregister (Scratchpad) und speichere gerade nicht benötigte 
Variablen im RAM.

Definiere extra Arbeitsregister für Interrupts, spart ne Menge PUSH/POP.


Peter
Gast #1154060
Lesenswert?

Hallo Peter
ich habe jetzt mal versucht, die Abfrage mit movw zu realisieren. 
Könntest du mal auf den Quelltext schauen und gucken, ob das richtig 
ist?

.def   temp2=   r18
.def   temp1=   r17
.equ  buffersize    =  64     (beispielhaft)



init_buffer:
    ldi XL,low(buffer)    ; read-Pointer
    ldi XH,high(buffer)    ; +1 = erstes Byte aus UDR
    ldi YL,low(buffer)      ; write-Pointer
    ldi YH,high(buffer)
ret


write_SRAM:
  movw temp2:temp1,YH:YL
  inc temp1
  ldi temp3, 0
  adc temp2, temp3        ; erhöhen um eins
  cp temp1, XL
  cpc temp2, XH
  breq no_reset_PointerY      ; if (write_zeiger +1 == read_zeiger)
                              ; nix machen

  ; read == 0 && (write+1 == max. Pufferadresse)
    cpi temp1,low(buffer+buffersize)
    ldi temp3,high(buffer+buffersize)
    cpc temp2,temp3
    brne write_to_SRAM
    cpi XL,low(buffer)
    ldi temp1,high(buffer)
    cpc XH,temp1
    breq no_reset_PointerY

write_to_SRAM:
    in temp1, UDR                ; UART Daten lesen und in SRAM 
schreiben
    st Y+, temp1

    cpi YL,low(buffer+buffersize)      ; Startadresse buffer
                                       ; + Länge buffer
    ldi temp1,high(buffer+buffersize)  ; vergleiche mit der maximalen
                                       ; SRAM Adresse
    cpc YH,temp1
    brne no_reset_pointerY          ; wenn ungleich, springen
    ldi YL,low(buffer)             ; wenn gleich, Zeiger zurücksetzen
    ldi YH,high(buffer)
no_reset_PointerY:
ret


read_SRAM:
  cp YL, XL
  cpc YH, XH
  breq no_reset_pointerX     ; Lese- auf Schreibezeiger
                             ; --> Lesen nicht sinnvoll
                             ; Lesezeiger nicht erhöhen

  ld SRAM_register, X+
  cpi XL,low(buffer+buffersize)        ; Startadresse buffer
                                       ; + Länge buffer
  ldi temp1,high(buffer+buffersize)    ; vergleiche mit der maximalen
                                       ; SRAM Adresse
  cpc XH,temp1
  brne no_reset_pointerX          ; wenn ungleich, springen
  ldi XL,low(buffer)             ; wenn gleich, Zeiger zurücksetzen
  ldi XH,high(buffer)
no_reset_pointerX:
  ret

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren