♫ ♩ ♪ Michał Jelonek ⚡ ☘ ⚡ A Funeral Of A Provincial Vampire ♪ ♩
♫
https://youtu.be/Mbp3b7uehx0
Dobry wieczór.
Jednym z zagadnień, kóre wypadałoby poruszyć przy okazji omawiania Z80-SIO jest ładowanie programów do pamięci CA80 przy pomocy łącza szeregowego. Nadarzyła się ostatnio okazja, aby i ten temat domknąć - przedstawiam zatem proste rozwiązanie programowe, umożliwiające załadunek kodu do CA80 i bazujące na opisywanych już wariacjach podłączenia Z80-SIO/0 do CA.
calo (z80)
To prosty programik uplasowany pod adresem 0x4000, zajmuje nieco ponad 300 bajtów i odpowiedzialny na odbieranie i interpretację ramek danych w formacie Intel HEX. O IHEX gaweł napisał już wszystko, po szczegóły odsyłam do Format pliku Intel-hex.
Uruchomiona aplikacja `cALo` czeka na `:`, po jego wykryciu pracowicie chomikuje nadchodzące znaczki w buforze odbiorczym (górna pamięć RAM, 80 bajtów powyżej stosu użytkownika) - to procedurka loadHex. Po wykryciu znaku LF kończy się faza akwizycji znaków, calo zaczyna ich interpretację. Po pierwsze procedurą checkCRC sprawdzana jest suma kontrolna ramki, to ważne bo przecież nie chcemy załadować do RAM jakiejś lipy. Następnie sprawdzane jest czy załadowany rekord IHEX jest znacznikiem końca zbioru - isEOF, gdy tak, aplikacja kończy pracę.
Dalej, zebrane dane z ramki są wypakowywane do zadanej lokalizacji pamięci, funkcja procHex pilnuje przy okazji, aby wyładunek bajtów nie nadpisał kodu calo, w przypadku wykrycia tego zagrożenia - program kończy pracę odrzucając ramkę. Każda poprawnie obsłużona ramka z danymi potwierdzana jest do PC znaczkiem `.`, ramka z EOF - znaczkiem `-`. Wszelkie błędy sygnalizowane są wysłaniem znaku `!`, oczywiście dopchniętego LF-em, za to wszystko odpowiada funkcja-kameleon sendAck/Err/Done. Podczas ładowania danych adres bieżacego rekordu prezentowany jest na czterech najmłodszych pozycjach wyświetlacza. Nie ma to jakiegoś praktycznego uzasadnienia, w końcu chyba wiemy co i gdzie wgrywamy, ale fajnie wygląda więc zostało.
Program calo akceptuje rekordy IHEX o rozmiarze do 32 bajtów - wynika to długości bufora odbiorczego. Nie ma restrykcji na wielkość cyfr hex - radzi sobie spokojnie zarówno z zestawem a..f jak i A..F.
Aplikacja sama w sobie nie jest skomplikowana, choć starałam się napisać ją jak najoszczędniej, w sensie długości kodu maszynowego. Po prostu - wizja wpalcowania kilkuset bajtów zleceniem *D jest bardzo skutecznym motywatorem aby dłużej pomysleć. Programik obsługuje Z80-SIO na kanale B, ale elementarne funkcje komunikacyjne i ustawienia UART są wyizolowane do sioInit, putChar, getChar, a transmisja nie korzysta z systemu przerwań. Nie ma więc problemu, aby kod zaadaptować do np. układu UART typu Intel 8251 - możliwe nawet, że program nieco się skróci, ponieważ ta akurat kostka ma parę rejestrów na krzyż.
calo (PC)
Drugi koniec kabelka szeregowego obsługuje konsolowy programik ładujący - także nazwany calo. Nabazgrałam go w C i natywnie pod Linux, więc wielbiciele Windows to pewnie nie skorzystają za bardzo. Program jest równie prosty co poprzednik, a robi rzecz dokładnie odwrotną do bliźniaka z CA80 - wysyła ramki IHEX (linie pliku) skonfigurowanym łączem szeregowym stosownie reagując na odpowiedzi CA80 (.-!). W przypadku jakichkolwiek anomalii ładowanie jest przerywane ze stosownym komunikatem o błędzie. Wywołanie z konsoli to jak nietrudno zgadnąć:
konsola pisze:Kod: Zaznacz cały
calo nazwa_portu scieżka_do_pliku_hex
konsola pisze:Kod: Zaznacz cały
./calo /dev/ttyUSB1 ../test/8kb_8000.hex
Cały zestaw komunikuje się z szybkością 19200 baud, co jak dalej zobaczymy jest do radosnej dłubaniny przy CA80 w zupełności wystarczające. Testowy wsad - plik z 8kB danych ładuje się około 15 sekund, to chyba dobry wynik.
W ramach usprawnień - zastanawiam się nad podpięciem `calo` do zestawu zleceń systemowych, oczywiście po znalezieniu mu miejsca w oryginalnym EPROM z MIK33, to pewnie będzie wymagało poświęcenia jakiejś mało przydatnej rzeczy - może transmisja z ZX Spectrum? Zobaczymy jeszcze, a póki co siedzi on pod adresem 0x4000 w banku z NVRAM.
Tradycyjnie filmik z pary programików w działaniu - oprócz prezentacji ładowania 8kB kodu mamy też prosty test elementarnej idioto-odporności - błędne ramki są raportowane i zamykają aplikację.
https://youtu.be/JN0cCCYbeJI
A na koniec pożalę się deko - chcąc wprowadzić zabezpieczenie przez nadpisaniem się programu musiałam pozyskać wartość numeru strony z bieżącej wartości licznika rozkazów, czyli po prostu jego starszy bajt. Łomatko, co ja wyczyniałam... i próby z '>' i z przesunięciem bitowym, no nie szło i już. Wreszcie powstał potworek z rejestrem indeksowym IX i sztucznie wprowadzoną stałą na końcu kodu, tam się dla odmiany okazało, że assembler nie rozpoznaje rejestrów połówkowych IXH oraz IXL, no masakra normalnie. Mój ulubiony sbasm3 też w sumie tego nie ogarnia, ale przynajmniej tablice symboli z konkretnymi wartościami potrafi na koniec przygotować. I coś czuję, że finalna wersja `calo` będzie jednak z dialekcie sbasm3...
#slowanawiatr