Pełna wersja iLoad z buforem kołowym.

  Przesyłanie plików zostało wstępnie opanowane, jednak pozostał niedosyt z powodu uproszczenia kodu. Mam rozwiązanie - zapraszam.

iLoad for CA80
Bezbłędnie przesłane pliki w pełnej wersji iLoad.


Jednoczesne wysyłanie i odbieranie dużej liczby znaków w pollingu grozi błędami transmisji. Najlepiej zrobić obsługę UART na przerwaniach, ale nie zawsze jest to konieczne. Nie przesyłamy przecież krytycznych danych, od których zależy czyjeś życie. 😉 Najważniejsze są dane odbierane, a wysyłane służą jedynie informacji o przebiegu procesu (można z nich odczytać zawartość pliku), więc nie są nam niezbędne. Skupmy się więc na odbiorze. W pollingu oczekujemy na gotowość odbiornika, czytając w pętli rejestr stanu i8251A. Zamiast marnować czas, możemy dodać do tej pętli wysyłanie znaków z bufora, które wcześniej tam zapisaliśmy, nie czekając na gotowość nadajnika. Potrzebujemy więc jeden bufor na dane do wysłania.

Circular buffer
Konwersacja z AI.


Żeby nie tracić czasu na wymyślanie obsługi bufora, poprosimy o to sztuczną inteligencję. Chat GPT nie jest doskonałym programistą, ale potrafi zrobić za nas "czarną robotę". Pierwsza wersja była bardzo niedoskonała - nie sprawdzała nawet, czy jest coś w buforze, ani czy jest w nim jeszcze wolne miejsce. Zgłosiłem zastrzeżenia i zaraz miałem odpowiedź. Była prawie dobra, bo niestety nie istnieje rozkaz CP (nnnn) 😂, ale tego już nie reklamowałem. I tak planowałem zmienić ten program. Podziękowałem więc i zająłem się pracą.

Ring buffer
Uwaga na pułapki - nieistniejące rozkazy Z80.


Znacznie łatwiej jest operować na buforze o długości 256 bajtów, więc zacząłem od tej zmiany. Wszystkie podstawowe rejestry Z80 są już zajęte przez iLoad, więc trzeba je chronić. Można użyć EXX i nie martwić się o nic, ale wybrałem inną metodę - rejestr indeksowy. Rozkazy używające IX są dłuższe od tych z HL, ale wystarczy ich mniejsza liczba, co w sumie się opłaca.

Ring buffer initialization
Rejestr indeksowy od tej chwili ma stałą wartość.


Teraz czas na wykorzystanie bufora w procedurach putc i getc. Zamiast czekać na gotowość Tx, tylko raz spróbujemy wysłać znak (nie ten, który właśnie mamy w akumulatorze, ale ten, który pierwszy wszedł do bufora). Niezależnie od powodzenia lub porażki nowy znak umieścimy w buforze, gdzie zaczeka na swoją kolej.

Get char & Put char
Procedury UART wykorzystujące bufor.


Na odbierany znak musimy czekać do skutku, ale z nudów będziemy sprawdzali w tym czasie gotowość Tx i wysyłali znaki z bufora (jeżeli będzie coś do wysłania). Transmisja jednego bajta trwa dokładnie tyle samo w jedną i w drugą stronę, więc w czasie oczekiwania na Rx prawdopodobnie uda nam się wysłać najwyżej jeden znak. Może to powodować gromadzenie się w buforze znaków do wysłania. Żeby wysłać wszystkie, trzeba dopisać dodatkową procedurę FLUSH_Tx. Ewentualne przepełnienie bufora spowoduje zgubienie znaków nadawanych, co nie ma wpływu na odbierane.

CHECK_TX
Nieblokujące wysyłanie znaku i czyszczenie bufora.


Z procedur zaproponowanych przez AI pozostały komentarze, ale i tak była to znacząca pomoc. Cały program jest w repozytorium.

Komentarze

Popularne posty z tego bloga

Uruchamiamy CA80 na RCbus.

Magnetofon CA80.