Popularny post Leoneq Napisano Luty 9, 2021 Popularny post Udostępnij Napisano Luty 9, 2021 Po chwilowej przerwie w elektronice, wracam z kolejnym projektem. A jest nim kolejne urządzenie z rodziny iNap™, komputr. Jest to typowa konstrukcja oparta o stary, dobry procesor Z80. Komputer składa się z 3 platform, opisywanej kiedyś karcie graficznej, "płyty głównej", oraz płyty z urządzeniami I/O. Całość zacząłem robić w wakacje 2020 roku, obecnie mogę komputer zaprogramować wcześniej opisanym też programatorem. Przechodząc do rzeczy: Jak widać, sam komputer jest dość prosty w konstrukcji, nie wnosząc w zasadzie niczego nowego do branży komputerowej (kto by się spodziewał...) - podczas projektowania inspirowałem się wieloma projektami dostępnymi w internecie. Dostępne 64kB przestrzeni szyny adresów podzieliłem na pół, pamięć ROM - układ 29F002 - dostał przestrzeń 0x0000 - 0x7FFF, więc pamięć SRAM musiała dostać przestrzeń od 0x8000 do 0xFFFF. Mówiąc dokładniej, banki pamięci są sterowane pinem A15, do którego są podpięte piny "włączenia" poszczególnych pinów (zaznaczam, że piny te są aktywne w stanie niskim). Dlatego pin ten jest podpięty bezpośrednio do pinu /CE pamięci FLASH, i przez bramkę nie (zrealizowaną na UCY74LS04 od CEMI, chodź jeden tranzystor by wystarczył) do pinu /CE pamięci RAM. Przełącznikiem można wybrać źródło sygnału zegara, albo 3.68MHz z generatora, albo kilkanaście Hz z układu 555, który można regulować. Cztery bramki OR służą za "dekodowanie" sygnałów potrzebnych do odczytu i zapisu urządzeń: dzięki temu, pamięć RAM wie kiedy ma "wypluć" dane na szynę danych, a kiedy ma z niej wczytać dane do komórki. Na płytce znajduje się także mały zasilaczyk oparty na 7805, i konektor z starego odtwarzacza CD, do połączenia płytki z pozostałymi. Nie pokazałem na schemacie tylko przycisku reset, oraz matrycy LEDów, aby podpatrzeć co się obecnie dzieje w komputerze. Całość zlutowałem na płytce uniwersalnej, połączenia zrealizowałem na drucie .12mm z jakiejś cewki. Wszystkie podstawki pochodzą z rozlutu, za wyjątkiem tej zielonej - ZIF - która pozwala na bardzo łatwe wkładanie i wyjmowanie czipu, co robię często przy programowaniu. Do płytki rozszerzeń schematu jeszcze nie ma, jako że robię ją jak mi się podoba. Dałem chyba wszystko co miałem w szufladzie, przede wszystkim wyświetlacz na HD44780. Pod nim znajdują się układy P8259, P8253 i P8251, które są kolejno kontrolerem przerwań, programowalnym licznikiem i programowalnym interfejsem szeregowym (po prostu uart). Tych 3 układów nie będę na razie lutował, bo nie ma takiej potrzeby; muszę się najpierw nauczyć bardziej asemblera, i mieć chęci na kolejne dni lutowania. Wlutowałem od razu podwójny wyświetlacz siedmiosegmentowy (nie mam obecnie układów do sterowania), oraz port USB do P8251 (docelowo pomiędzy nimi będzie CH340G), co w zasadzie jest odrobiną świeżości w tym segmencie hobbystycznej elektroniki. W zasadzie każdy komputer jaki zobaczyłem w internecie miał MAX232 z portem szeregowym (DB9, kiedyś się nań podpinało myszkę) - obecnie zostały po nim goldpiny na płytach głównych komputerów, znane jako COM1, więc nie ma sensu na siłę stosować ten port. Zielone kostki ledowe na górze to urządzenie 0x00, port wyjścia/wejścia. Niestety, wymagały one napięcia aż 12V, więc pozostawiony bez wyboru wlutowałem tam scaloną przetwornicę napięcia 5 na 12V firmy Niezawodność®, aby przerzutnik flip-flop 74HC574 mógł nimi sterować przez klucze tranzystorowe na BC547 Do tego samego adresu jest podłączony ośmiosuwakowy DipSwitch, aktywuje go bufor 74HC244. Wyświetlacz jest podłączony wszystkimi bitami (chociaż wystarczyłyby 4) do szyny danych. Ostatni układ, po prawej, to demultiplekser CD4515. Czterobitowa liczba na wejściu pozwala określić, który z szesnastu pinów ma być "włączony". Do dyspozycji wdg. noty katalogowej procesora jest 256 urządzeń (0x00-0xFF, górna połówka szyny adresów), a że ich nie będę miał aż tyle, drugi zestaw czterech bitów przeznaczyłem na sterowanie urządzeniem docelowym - np. pinem R/S w wyświetlaczu, więc urządzenie o adresie 0x11 to dalej wyświetlacz, tylko ustawiony na odbiór znaków a nie komend (0x01). Całość przy zasilaniu 12V pobiera ok. 0.5A, co daje 6W - po wyłączeniu ledów pobór prądu spada do ok. 200mA, 2,4W. No i została kwestia programowania. Na razie całość działa jak arduino (bo w zasadzie mikrokontroler to taki komputer), gdyby to porównać do atmegi 328, komputer jest ok. 16x słabszy od niej (prędkość 4x mniejsza, Z80 potrzebuje 4 taktów do wykonania instrukcji, atmega potrzebuje najczęściej jednego taktu). Programowanie odbywa się w VS Code, w asemblerze. Docelowo planuję wgrać jakąś formę BASICa (jak ogarnę sterowanie kartą graficzną i klawiaturę lub terminal po uarcie), obecnie komputer robi to: Kod generuję programem tniASM, wygenerowany .hex otwieram w edytorze .hex, który następnie kopiuję do programu programatora i wgrywam go do pamięci. Pokrótce jeszcze wyjaśnię samo działanie "całości": po resecie procesora, "szuka" on instrukcji na szynie adresów, odczytując je z pamięci. Domyślnie wykonuje on instrukcję No OPeration (nop), czyli nic nie robi, tylko zwiększa liczbę na szynie adresów. Jeżeli znajdzie jakąś inną instrukcję, wykonuje ją - np. ładuje bajt do akumulatora a (ld a, *). Następnie może coś z tą wartością zrobić, np. obróbić bity (rrc a), lub dodać z innym akumulatorem - instrukcji jest dość dużo. Tak uzyskaną liczbę w akumulatorze a może wysłać do pamięci RAM lub urządzenia wyjścia (out (*), a). Liczba na szynie adresów (pc, program counter) będzie się zwiększać do przepełnienia lub wykonania instrukcji skoku (jp *). Przykładowy program może wyglądać tak: cpu z80 org 0x0000 main: ld a, 0x05 .loop: rrc a out (0), a jp .loop Wsad do pamięci po "skompilowaniu" tego programu będzie wyglądał tak: 3E 05 CB 0F D3 00 C3 02 00 Ciekawscy mogą teraz wejść np. tutaj i porównać otrzymane instrukcje z tabelą. Program ten zrobi "wężyka ledowego", pokazanego pod koniec filmu. Podsumowując: projekt tego typu pozwala na poznanie komputerów od podstaw (dzisiejsze funkcjonują podobnie, tylko mają więcej bitów), ale zajmuje on bardzo dużo czasu. Układy są dość tanie, procesor można dostać za 10zł, pamięć od 2 do 3 zł, resztę można nawet z tranzystorów zrobić. Jeżeli ktoś chciałby zrobić coś podobnego, to 4 układy scalone wystarczą; jeżeli ktoś biegle włada angielskim, to bardzo polecam obejrzeć serię filmów Bena Eatera (https://eater.net) - wytłumaczone jest wszy-ściu-ten-ko. Następnym moim celem będzie wgranie BASICa do tego cudeńka, dokończyć programator (planuję z niego zrobić coś więcej), i jak kiedyś kiedyś mi się to wszystko uda, to mam procesor D8088 w szufladzie 15 1 Cytuj Link do komentarza Share on other sites More sharing options...
marek1707 Luty 10, 2021 Udostępnij Luty 10, 2021 (edytowany) Do EEPROMu nie musiałeś doprowadzać A15, skoro z niego nie korzystasz. Mam nadzieję, że pozostałe dwa najstarsze adresy nie wiszą jednak w powietrzu. Na schemacie nie musisz pisać, że to bramka OR, bo to widać z symbolu. Natomiast zupełnie nie wiadomo jakiej tam użyłeś: 74HC32, CD4071 czy może 74LS32. Przyjmij sobie jakąś konwencję oznaczania sygnałów aktywnych w stanie niskim, bo na większych schematach się pogubisz. W tamtych czasach takie sygnały były w przeważającej większości a przecież czasem zdarza się je odwracać i wtedy o błąd nietrudno. Nie wiem, zaczynaj od znaku "/" lub "~" lub "#" - jest wiele konwencji, ale jakąś musisz stosować. Obecnie wprowadzasz sygnał MEMRD na wejście OE z kółkiem (czyli aktywne w stanie niskim) a to wygląda źle. Oczywiście tylko formalnie, bo układ jest poprawny. Schemat powinien być czytelny sam z siebie, bez dodatkowych komentarzy i domyślania się. Wybór kostki pamięci wyłącznie adresem powoduje, że pobierają dużo prądu. To właśnie wejście CE wyłącza mnóstwo elektroniki wewnątrz tych chipów (i przenosi ją do trybu low-power) więc gdybyś A15 (prosty i zanegowany) złożył z sygnałem /MREQ i dopiero tym odblokowywał pamięci, to takie sterowanie zaoszczędziłoby pewnie z 30- 50% prądu zasilania wybranej kostki. /MREQ ma właśnie takie mniej więcej wypełnienie podczas normalnej pracy Z80. W najbliższej przyszłości spróbuj tak zaprojektować otoczenie EEPROMu, byś miał możliwość zapisywania go z procesora i to do całej przestrzeni (stronicowanej np. po 32K) - albo pracując wtedy z RAMu albo wisząc na wait state. Będziesz miał wtedy sporą jak na te standardy pamięć nieulotną np. do zapisu programów w BASICu. Osadzanie jakiegoś gotowego BASICa (a jest ich trochę, tak na 8080 jak i dedykowanych do Z80) jest trywialne jeśli masz dostępny UART taki jak 8251. Funkcje znakowego we/wy są zwykle dokładnie wyróżnione i opisane, wystarczy je podmienić na swoją obsługę tego historycznego UARTa i jedziesz. Tutaj koniecznie jak najszybciej zainstaluj jakiś prosty tzw. monitor, czyli program do wpisywania (HEX lub simple-asm) i debugowania programów bezpośrednio w RAMie. To zajmuje zwykle 1...2K i jeśli podepniesz to pod UART, to łączysz się z terminalem na PC i działasz. Te podstawki, wyciąganie, programowanie to jakiś koszmar. Daleko tak nie zajedziesz, bo albo Ci się znudzi, albo za którymś razem spalisz pin/układ od ESD przy przekładaniu pamięci. Szkoda tego wysiłku. Widać, że hardware działa więc buduj oprogramowanie. Nie ma co się podniecać przesuwaniem bitów z zegarem 100Hz. Ten opis działania procesora to chyba jednak jakaś bajka. No weź, przecież on niczego nie "szuka". Sygnał RESET zeruje PC i od adresu 0x0000 rozpoczyna się pierwszy cykl M1 - pobrania kodu instrukcji. Każda kombinacja bitów jaką wczytasz jakoś się wykonuje. Potem następny rozkaz i następny. Jeśli pamięć wypełnisz NOPami (0x00) to rzeczywiście będzie po nich jechał aż dociągnie 0x7FFF, przejdzie do RAMu a tam kaszana.. Jeśli już chciałeś bawić się w analizę tak wolno i pracującego procka, to warto było zrobić układzik pracy krokowej. To bardzo prosta rzecz, a masz wtedy przycisk STEP, który powoduje wykonanie jednego cyklu maszynowego (mimo taktowania CPU normalnym zegarem kilku MHz). Możesz wtedy podglądać zawartość magistral i sygnały sterujące nawet na LEDach (buforowanych) i krok po kroku skumać jak wykonywane są poszczególne instrukcje. W każdym razie szacun za zacięcie. Może dołączysz do Homebrew CPU RIng? Chociaż nie, tam chyba nie przyjmują cheaterów co to posługują się procesorami w jednym scalaku 🙂 To co, może w następnej wersji 1-bitowiec liczący ciąg Fibonacciego? BTW: Dlaczego edytor Forum notorycznie zamienia mi "iks" na symbol mnożenia, gdy wpisuję liczbę szesnastkową tj. robi się 0x15 (o właśnie, znów to zrobił!) zamiast 0x00. EDIT: Poszedłem za Twoim opisem, ale coś mi nie pasowało. EEPROMy zaczynają się od 28.. a tu masz 29F czyli FLASH. Odpada zatem metoda programowania po bajcie i oczekiwania w wait state. Zapis zadziała tylko podczas zapisu całej strony podczas pobierania kodu z RAMu. Edytowano Luty 10, 2021 przez marek1707 2 Cytuj Link do komentarza Share on other sites More sharing options...
Leoneq Luty 10, 2021 Autor tematu Udostępnij Luty 10, 2021 Dziękuję za tak treściwą odpowiedź. Ma Pan rację, i powinienem przyjąć jeden umowny zapis, i mogłem inaczej zrealizować sterowanie pamięciami. Opis działania spróbowałem napisać tak, żeby i moi koledzy - 2 klasa technikum - zrozumieli o co chodzi, więc staram się jakoś na wyobraźnie działać, może faktycznie z tym przesadziłem xd Z początku zamiast 555 miał tam być właśnie przycisk step, lecz jakoś mój procesor "świruje" przy zbyt niskich częstotliwościach. Prototyp z przyciskiem nie chciał w ogóle działać normalnie, a z 555 poniżej pewnej częstotliwości też odmawia posłuszeństwa, nie wiem jaka jest tego przyczyna. Pamięć FLASH aktualnie procesor może zaprogramować, wysyłając odpowiednią sekwencję komend (jak pamiętam 3 bajty + bajt do zapisania). A15 aktualnie nie jest podłączone do pamięci, mały błąd - nieużyte piny pamięci podłączylem do masy. I muszę powiedzieć, że nie słyszałem o monitorze, ale bardzo chętnie spróbuję z niego skorzystać. Cytuj Link do komentarza Share on other sites More sharing options...
Wrodarek Luty 10, 2021 Udostępnij Luty 10, 2021 O jakże się cieszę, że Zetka jeszcze żyje. To był szczyt moich marzeń w końcu ubiegłego wieku. Zaczynałem z Intelem 4-ro bitowym, a potem 8080. Idę przeszukać swoje pudełka i co tam znajdę to zaoferuję "do wzięcia" dla wszystkich pasjonatów. Pozdrawiam Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
marek1707 Luty 10, 2021 Udostępnij Luty 10, 2021 Projektowanie układów scalonych w tamtych czasach wiązało się z koniecznością bezwzględnej minimalizacji liczby użytych tranzystorów. Elementy te były duże, chipy krzemowe miały bardzo ograniczone wymiary ze względów zarówno technologicznych jak i funkcjonalnych i nie można było bez umiaru stosować typowych w rozwiązaniach dyskretnych układów przerzutników czy bramek. Rzecz jasna pełno tam było "bramek" bo to podstawowy budulec logiki, ale były to uproszczone do granic możliwości zestawy tranzystorów a zamiast statycznych przerzutników mogących pamiętać raz wpisany stan w nieskończoność, używało się różnych sposobów przechowania informacji na pojemnościach. Przykładowo, obecnie chcąc podłączyć kilka pamięci do jednej magistrali robi się im bufory trójstanowe, załączane (w Twoim przypadku) odpowiednią kombinacją sygnałów /CE/OE/WE. Coś "wybiera" dany scalak a ten włącza swoje drivery linii i wystawia dane na magistralę, skąd jakiś "master" może je odczytać. To fajnie brzmi i jest proste, ale tylko koncepcyjnie. Bufory trójstanowe to stosunkowo duże struktury i w przypadku scalaka w którym ściubolisz każdy tranzystor, odpadają. Dlatego aby podłączyć kilka zasobów (np. rejestrów) do wspólnej magistrali (np. do wejścia ALU) mogłeś tam zrobić tak: zakładasz, że linie sygnałowe wraz z wejściami (bramki tranzystorów MOS) do bloku ALU mają jakąś niezerową pojemność, nie wiem, 0.1pF na przykład na początku ładujesz wszystkie linie do stanu wysokiego - do tego wystarczy tylko jeden tranzystor i 8 diod separujących - i odłączasz ten driver rejestr ma na wyjściach pojedyncze tranzystory umiejące tylko rozładować linię do stanu niskiego i w następnym cyklu zegara załączasz tylko te tranzystory z danego rejestru, których bity mają wartość zero po chwili ALU "wciąga" stan wybranego rejestru na swoje wejścia - pewne linie wciąż są (ale długo tak nie pociągną) naładowane a pewne zostały rozładowane Koniec, na takim prostym myku zaoszczędziłeś całe mnóstwo tranzystorów, bo każdy normalny bufor trójstanowy ma ich co najmniej 2 na wyjściu plus sterowanie. Niestety ma to jedną wadę i dlatego o tym wspominam: to (a także wiele innych mechanizmów w chipach z tamtego okresu) działa do jakiejś minimalnej częstotliwości zegara. Poniżej pewnej granicy, odległości czasowe między kolejnymi impulsami wyznaczającymi kolejne takty pracy są na tyle długie, że pojemności "zapominają" informację (przez rezystancje upływności) i system się rozpada. Dlatego trzeba tak samo uważnie patrzeć na maksymalne jak i na minimalne częstotliwości taktowania. A gdy chcesz swój procesor zwolnić do prędkości zauważalnych gołym okiem (albo nawet do zera) zachowując przy tym spójność jego stanu (wszystkich rejestrów i logiki) to musisz korzystać z dostępnych sygnałów. W Z80 istnieje wejście /WAIT, które służy do współpracy z wolnymi pamięciami. Jeśli procesor po wystawieniu adresu i sygnałów sterujących zobaczy stan niski na tym pinie, to wstrzyma bieżący odczyt/zapis do czasu "potwierdzenia" przez pamięć (lub port I/O), że ta jest gotowa do zakończenia cyklu magistrali. Przy czym jest to mechanizm wbudowany w procesor i nie naruszający żadnych jego reguł - w stanie wait kostka może stać w nieskończoność. Jeśli teraz dobudujesz układ, który "sztucznie" zgłasza niegotowość po rozpoczęciu każdego cyklu maszynowego, to masz spowolnienie o jakie chodziło. Zakończyć bieżący cykl możesz z przycisku albo z jakiegoś 555. Procesor w ciągu mikrosekundy zakończy to co zaczął i rozpocznie następny cykl wynikający z przebiegu realizacji programu. Wtedy znów dostanie wait i tak w kółko. Zegar wciąż jest MHz a Ty możesz spokojnie oglądać co się dzieje ma szynach. Poszukaj schematów do hasła np. "Z80 single step circuit" a wszystko się wyjaśni. No i uwaga: od czasu opanowania technologii CMOS raczej stosuje się układy statyczne więc proste procesory (o ile nie jest to wyraźnie zaznaczone) można zwalniać za pomocą zegara do 0Hz. Monitorek to konieczny w każdym tego typu systemie program "startowy". Wgrywasz raz do ROMu a potem już tylko stukasz w klawiaturę i dłubiesz swoje programiki w RAMie.. Kilka pierwszych z brzegu: https://github.com/fiskabollen/z80Monitor https://github.com/MatthewWCook/Z80Project/tree/master/Z80 Monitor Part 1 https://github.com/antbern/z80-monitor itd... 2 Cytuj Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Luty 11, 2021 Udostępnij Luty 11, 2021 19 godzin temu, marek1707 napisał: BTW: Dlaczego edytor Forum notorycznie zamienia mi "iks" na symbol mnożenia, gdy wpisuję liczbę szesnastkową tj. robi się 0x15 (o właśnie, znów to zrobił!) zamiast 0x00. @marek1707 dzięki za zgłoszenie, naprawione. Mega ciekawa sprawa, bo to była funkcja "zaszyta" w foncie... Wystarczyło wyłączyć i wszędzie się naprawiło z automatu, bo to cały czas były znaki "x" tylko wyświetlały się w taki pokrętny sposób 🙂 1 Cytuj Link do komentarza Share on other sites More sharing options...
marek1707 Luty 27, 2021 Udostępnij Luty 27, 2021 @Leoneq Jakieś postępy w pisaniu oprogramowania podstawowego? Udało Ci się wrzucić do ROMu i uruchomić jakiś monitorek? Piszesz coś dalej? A może masz już któryś BASIC albo podłączyłeś kontroler i napęd dyskietek (lub ich emulator na FLASHu) i właśnie odpalasz CP/M? @Wrodarek Jak tam przegląd pudełek? Też mam trochę zapasów muzealnych i także planuję kiedyś ich udostępnienie. A może wymiana? Mamy tu dział Sprzedam/Kupię/Zamienię 🙂 1 Cytuj Link do komentarza Share on other sites More sharing options...
Leoneq Luty 28, 2021 Autor tematu Udostępnij Luty 28, 2021 (edytowany) Obecnie w planach mam ogarnąć układ 8251, co robię, ale powoli - szkoła, inne projekty, itd. także basica spodziewałbym się do maja jak dobrze pójdzie. A napęd FDD bym bardzo chętnie podłączył, tylko nigdzie nie mogłem znaleźć jak. A tym bardziej poczytać jak działa system plików, więc chyba po prostu źle szukam. edit: jak mi się zechce posortować układy które mi się przydadzą a które nie (a mam ich z jakieś 2kg), to może i ja sprzedam Edytowano Luty 28, 2021 przez Leoneq 1 Cytuj Link do komentarza Share on other sites More sharing options...
Popularny post Leoneq Kwiecień 18, 2021 Autor tematu Popularny post Udostępnij Kwiecień 18, 2021 Aktualizacja 18 kwietnia 2021: uart działa, a przynajmniej nadawanie. Cały tydzień siedziałem nad notą katalogową i (błędnymi, o czym potem się przekonałem) prezentacjami z politechnik, nie spałem, wyrywałem sobie włosy z głowy, ale udało się. Jeżeli chodzi o sprzęt: podłączyłem układ 8251 do linii danych i adresów, do wybierania szybkości transmisji dodałem układ CD4040 jako dzielnik częstotliwości. Bramki NOT znalazły się jeszcze, tylko dlatego że przy 4MHz zatrzask linijki ledowej nie uchwytywał faktycznego stanu (przerzutniki załączają się przy narastającym zboczu, czyli "pod koniec" zapisu, więc odwróciłem do zapisu "na początku". Co do samego 8251: najsampierw przeczytałem trochę noty katalogowej, potem poszukałem, czy ktoś może tego nie robił (znalazłem prezentacje z politechniki). Najwięcej problemów o dziwo nie sprawił sam układ, a niestabilność (hm, no kto by się spodziewał 🤔) całej płytki, jak wykonywanie czegokolwiek z urządzeniami i/o po komendzie halt, czy zalewanie ciągle 8251 znakiem nowej linii. Krótko opisując układ: komputer widzi 8251 jako zwykłe urządzenia wejścia/wyjścia. W środku są dwa rejestry, słowo kontrolne i słowo danych. Ten kontrolny na początku zapisuje się dwa razy, na początku się podaje układowi tryb pracy (ilość bitów, szybkość, kontrola i bity stopu) - jest to wtedy słowo pracy. Po zapisie, rejestr ten automatycznie przekształca się w słowo kontrolne, pozwalające na sterowanie pinami DTR, RTS, włączenie/wyłączenie nadajnika/odbiornika, reset układu czy odczyt błędów i statusu. Do słowa danych - możemy zapisać słowo lub je odczytać. Układ samodzielnie dodaje pozostałe niezbędne bity, i samodzielnie odbiera/wysyła ramkę danych. Po dokładniejsze informacje - odsyłam do dokumentacji, lub prezentacji. Po napisaniu testowego programu na Arduino, trzeba było coś podobnego zrobić w asemblerze, z czym był już problem... nie mogłem znaleźć polskiego lub angielskiego (i przede wszystkim dobrego) kursu asemblera na Z80. Po kilku godzinach siedzenia na githubie, stronach z 2006 roku, i tabelki z op-codami, wystukałem takie coś: ; inapPC demo ; ; memory: 0x0000-0x7FFF ROM ; 0x8000-0xFFFF RAM ; ; i/o: A0-A3 device address: ; 0x00 PORT A ; 0x01 HD44780 ; 0x02 VGA card (in development!) ; 0x03 8251 UART ; A4-A7 device function: ; 0x11 high on R/S on device 0x01 (lcd) ; 0x13 high on D/C on device 0x03 (uart) ; licence opensauce ! ;+ ; made with lots of ☕ kakao by Leoneq ;3 cpu z80 org 0x0000 disableInterrupts: di ld a, 0 out (0), a initializeUART: ld a, 01001101B out (0x13), a ;initialize ld a, 0x11 out (0x13), a ;turn on transmitter, receiver, clear errors ld a, 0xA out (0x03), a ;send new line character ld bc, message print: ld a, msgend sub c jp z, loop call TXnotrdy ld a, (bc) out (0x03), a inc bc jp print loop: ld a, 0x55 out (0), a halt jp loop TXnotrdy: in a, (0x13) ;fetch the status bit 2, a ;test TXEmpty bit is set jp z, TXnotrdy ;loop till TX is ready ret message: ;message DB "hello there, straight from iNap z80!", 0xA, "by leonek :3" msgend: Program na początku wyłącza przerwania i czyści linijkę ledową. Następnie wysyła dwa bajty słowa kontrolnego do 8251, i znak nowej linii. Do pary rejestrów bc ładowany jest wskaźnik początku łańcucha znaków. Następnie "pętla" print jest trochę ułomnym zrealizowaniem pętli for. Najpierw sprawdzam warunek, czyli odejmuję liczbę znaków od liczby licznika (rejestr bc). Jeżeli wynik operacji będzie równy 0, wychodzimy z pętli aby zatrzymać urządzenie i zaświecić ledami. Jak nie, to sprawdzamy czy możemy nadać znak. Podczas odczytywania słowa kontrolnego bit 0 pokazuje, czy nadajnik jest gotowy, a bit 2, czy bufor jest pusty (gotowy do zapisu), co sprawdzamy. Jeżeli nie, sprawdzamy jeszcze raz. Jeżeli tak, to wracamy do pętli: wysyłamy słowo z odczytane z pamięci. Zwiększamy licznik, powtarzamy pętlę. Przykładowa transmisja: Przykładowy odbiór danych: I to chyba tyle. Teraz zajmę się odczytem z 8251, następnie połączeniem kodu, i przygotowaniem bootloadera do basica. Jeżeli jakiś weteran z80 chciałby się podzielić doświadczeniem, byłbym bardzo wdzięczny, bo samodzielnie naprawdę ciężko jest to wszystko ogarniać :< 3 Cytuj Link do komentarza Share on other sites More sharing options...
Leoneq Kwiecień 20, 2021 Autor tematu Udostępnij Kwiecień 20, 2021 Aktualizacja 20 kwietnia 2021: odbieranie po UART działa. Poszło o wiele szybciej, głównie dlatego że wiedziałem już konkretnie co trzeba zrobić. Program najpierw wysyła wiadomość "powitalną", potem nasłuchuje czy nie ma żadnych danych. Obecnie wykonuję tzw. polling, czyli procesor całą swoją uwagę skupia na 8251, w przyszłości planuję zaimplementować przerwanie bezpośrednio do procesora, lub przez 8259. Program po odebraniu danych pokazuje je na linijce ledowej (tutaj, będą to znaki ascii z klawiatury): ; inapPC demo ; ; memory: 0x0000-0x7FFF ROM ; 0x8000-0xFFFF RAM ; ; i/o: A0-A3 device address: ; 0x00 PORT A ; 0x01 HD44780 ; 0x02 VGA card (in development!) ; 0x03 8251 UART ; A4-A7 device function: ; 0x11 high on R/S on device 0x01 (lcd) ; 0x13 high on D/C on device 0x03 (uart) ; licence opensauce ! ;+ ; made with lots of ☕ kakao by Leoneq ;3 cpu z80 org 0x0000 disableInterrupts: di ld a, 0 out (0), a initializeLCD: ld a, 0x38 ;initialize out (0), a out (0x01), a ld a, 0x0F ;cursor on out (0), a out (0x01), a ld a, 0x1 ;clr out (0), a out (0x01), a initializeUART: ld a, 01001111B ;normally 01001110, for 57600 baud rate out (0x13), a ;initialize ld a, 0x15 out (0x13), a ;turn on transmitter, receiver, clear errors ld a, 0xA out (0x03), a ;send new line character ld bc, message ;initilize for print: ld a, msgend ;check condition sub c jp z, loop call TXnotrdy ;transmit character ld a, (bc) out (0x11), a out (0x03), a inc bc ;repeat jp print loop: call checkReceiver jp loop checkReceiver: in a, (0x13) bit 1, a jp z, notReceived jp nz, receivedChar receivedChar: in a, (0x03) out (0), a ret notReceived: ret TXnotrdy: in a, (0x13) ;fetch the status bit 2, a ;test TXEmpty bit is set jp z, TXnotrdy ;loop till TX is ready ret message: ;message DB "hello there, straight from iNap z80!", 0xA, "by leonek :3" msgend: Myślę że powoli mogę się zająć basiciem. A może nawet nie powoli, po prostu zacząć pisać bootloader. 1 Cytuj Link do komentarza Share on other sites More sharing options...
Popularny post Leoneq Maj 9, 2021 Autor tematu Popularny post Udostępnij Maj 9, 2021 (edytowany) No i udało się, mamy BASICa. Kod źródłowy wziąłem od pana Granta, dostałem jego pozwolenie na udostępnienie kodu tutaj. Kod basica został podzielony na dwie części, bootloader i "jądro", gdzie cały bootloader przeanalizowałem i przepisałem pod tniasm (oryginalnie kod był pod tasm), a kod pod oryginalnie wykorzystany 68B20 zmieniłem pod 8251. Wszystko działa, co mnie uradowało, bo w końcu to prawie rok temu podjąłem się nauki cyfrówki. Z przyczyn bardziej prywatnych, tutaj zawieszam projekt na czas nieokreślony, bo muszę się zająć dwoma innymi. Jak mi się kiedyś zechce, to do dokończenia będzie układ 8253 (timer), sterownik wyświetlaczy 7 segmentowych, możliwa jest implementacja GPU wraz z klawiaturą, planów ogólnie jest dużo. Mogę też wszystko to od razu zrealizować na 8088, to może i od razu dosa pójdzie odpalić. Może. Także dziękuję wszystkim którzy w jakimkolwiek stopniu byli zainteresowani, a przynajmniej panu Markowi, bo on przynajmniej na pewnym etapie był zainteresowany. inap pc.zip Edytowano Maj 10, 2021 przez Leoneq 4 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!