Autor Wątek: CP/M, karta CF i MCY7880  (Przeczytany 16060 razy)

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #15 dnia: 2024.06.24, 20:10:40 »
Myślę, że sprawy hardwarowe już ogarnąłeś, czas szukać błędu w software.

Właśnie co do tego cały czas mam wątpliwości. Założenie, że system załadował się poprawnie na dobrą sprawę stanowi akt zaufania względem karty CF. Po prostu na jej początku umieściłem 32 sektory (16 kB) w których trzyma binarny obraz systemu. Podczas rozruchu kopiuję ich zawartość do pamięci, zaczynając od adresu 0x0000, a następnie wykonuję skok pod ten adres.
Założenie, że wszystko jest w porządku wynika z faktu, że doskonale powtarzalnie odbywa się rozruch systemu, kończący się wyświetleniem prompta. Założyłem, że gdyby miały pojawiać się jakieś losowe problemy z transmisją, to raz na jakiś czas system wykrzaczałby się podczas uruchamiania. Problem tymczasem pojawia się dopiero wtedy, gdy próbuję listować zawartość dysku.
Tyle tylko, że zachowanie nie jest powtarzalne. Czasami wylistuje się większość zawartości i dostanę znów prompta (w takiej sytuacji kolejne zawołanie DIR powoduje już wylistowanie tylko ASM.COM). Czasem system wpadnie w jakiś dziwny cykl wiecznego czytania czegoś z karty CF (pali się dioda sygnalizująca odczyt) i printowania pustych linii. Czasem natomiast system zawoła WBOOT (jeszcze niezimplementowany, więc zatrzymuje się na nieskończonej pętli).


Cytuj
Poprawne załadowanie systemu operacyjnego świadczy o tym że interface CF działa, to co dzieje się już po uruchomieniu CP/M to kwestia BIOS.

No właśnie co do tego poprawnego załadowania nadal mam wątpliwości. Przydałoby się liczenie jakiegoś CRC kodu wykonywalnego, który trafia do pamięci. Wtedy wiedziałbym przynajmniej tyle, że za każdym razem trafia do niej dokładnie to samo. Masz jakiś pomysł odnośnie tego, co może powodować takie dziwne zachowanie systemu podczas próby wylistowania zawartości dysku?

Problem który opisywałeś na swojej stronie (ten wiążący się z koniecznością opóźniania sygnałów RD/WR względem CS) raczej nie powinien generować takich problemów? Użycie bufora na liniach danych należy uznać za wystarczające rozwiązanie?

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #16 dnia: 2024.06.24, 23:15:27 »
Ok, dodałem trochę prostego kodu odpowiedzialnego za liczenie CRC16 dla wykonywalnego kodu załadowanego z karty CF. Po każdym resecie mam taką samą wartość, która zmienia się po wprowadzeniu jakiejś modyfikacji w BIOS-ie, przebudowaniu CP/M i wgraniu go na na kartę. Jeszcze nie porównywałem tego z CRC tego samego fragmentu z obrazu na PC, ale jest to kolejny argument za tym, że zawartość karty jej poprawnie ładowana (albo przynajmniej jeśli występuje jakiś błąd, to jest on całkowicie powtarzalny).
Masz jakąś sugestię, w jaki sposób powinienem podejść do debugowania tego problemu?

tapy

  • ****
  • Wiadomości: 295
  • Z80 & CP/M
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #17 dnia: 2024.06.25, 00:26:45 »
Masz teraz do sprawdzenia cały podsystem dyskowy: blok parametrów dysku (DPB), procedurę deblock i obliczanie LBA. Najprościej posiłkować się prostym i skutecznym przykładem jaki możesz znaleźć w SCM, lub pochodną do niego -  link.

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #18 dnia: 2024.07.02, 08:40:53 »
Masz teraz do sprawdzenia cały podsystem dyskowy: blok parametrów dysku (DPB), procedurę deblock i obliczanie LBA.

Miałem chwilę wolnego czasu i dodałem do BIOS-a logi debugowe, printowane przez port RS232.
Niestety wygląda na to, że sam fakt dodania tych logów wpływa na działanie systemu, bo po ich włączeniu (dyrektywą if makroasemblera) system zaczął się zawieszać zaraz po wyświetleniu pierwszego prompta - zupełnie nie reaguje na klawiaturę.
W każdym razie udało mi się zebrać logi z pierwszego odczytu partycji po uruchomieniu systemu. Widać na nich, jak system woła poszczególne procedury i ustawia kolejne ścieżki i sektory, a także adresy buforów docelowych.
Niestety z uwagi na zawieszenie się systemu nie jestem w stanie sprawdzić co tak naprawdę się dzieje po wywołaniu komendy dir.

Masz jakiś pomysł co może powodować takie zachowanie komputera po dodaniu logów?
Kod źródłowy BIOS-a w jego obecnej formie też załączam do tego posta.

EDIT: Ok, już widzę, że mogę mieć kilka problemów związanych z ustawianiem osobnego stosu dla BIOS-a. Chociażby przez pomyłkę początki dyrektyw budowania warunkowego w paru procedurach znalazły sie w złych miejscach. Najpierw to poprawię i będę próbował dalej. :)
« Ostatnia zmiana: 2024.07.02, 08:53:41 wysłana przez Atlantis »

tapy

  • ****
  • Wiadomości: 295
  • Z80 & CP/M
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #19 dnia: 2024.07.02, 11:23:59 »
Myślę, że nie musisz debugować procedur BDOS, to na pewno działa (jedynie można sprawdzać czy żądane przez BDOS dysk/sektor/ścieżka jest poprawnie przekształcane w BIOS na LBA). W Twoim kodzie nie widzę odwołań do karty CF i jakiejś procedury dopasowującej odczytane 512B z dysku do obsługiwanego przez system 128B bloku. W dokumentacji CP/M 2.2 Alteration Guide w dodatku G masz kompletną procedurę dokonującej tej konwersji, poza tym jest tam szkielet BIOS z którego warto jednak skorzystać. Polecam zapoznać się z tym dokumentem, bo tak naprawdę są tam wszystkie odpowiedzi jak zbudować działający BIOS.

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #20 dnia: 2024.07.02, 16:44:33 »
Myślę, że nie musisz debugować procedur BDOS, to na pewno działa

Tego właśnie nie jestem w 100% pewien. Zastanawia mnie szczególnie zmiana zachowania kodu po warunkowym włączeniu kodu odpowiedzialnego za printy debugowe po RS232. W teorii powinno to tylko powodować dodanie odpowiednich fragmentów kodu, w praktyce przy wyłaczonym debugu dostaję działajacego prompta (system wywala się dopiero przy próbie wpisania polecenia DIR). Przy włączonym debugu klawiatura nie odpowiada po pojawieniu się prompta na ekranie.
Podejrzewam jakieś problemy ze stosem. Kilka potencjalnych błędów znalazłem od wrzucenia przykładowego kodu w poprzednim poście, ale to nie rozwiązało problemów, więc szukam dalej.


Cytuj
(jedynie można sprawdzać czy żądane przez BDOS dysk/sektor/ścieżka jest poprawnie przekształcane w BIOS na LBA)

Dobry pomysł, też poproszę o ich printowanie.

Cytuj
W Twoim kodzie nie widzę odwołań do karty CF

Procedury do obsługi karty CF nie znajdują się w BIOS-ie. Są umieszczone na stałe w pamięci EPROM. Ta część kodu buduje się osobno - obejmuje podstawowe procedury do obsługi sprzętu, bootloader CF oraz kopię TinyBasic-a (który można uruchomić zamiast CP/M-a). Jest tam też kilka przydatnych procedur, z których korzystam także w swoim BIOS-ie. Ich adresy są zdefiniowane w pliku labels.asm i są odświeżane automatycznie przez skrypt pythonowy wołany przez Makefile za każdym razem, gdy przebudowuję zawartość EPROM-u.


Cytuj
i jakiejś procedury dopasowującej odczytane 512B z dysku do obsługiwanego przez system 128B bloku.

Ten kod jest nieco prowizoryczny, ale jest obecny. W procedurze BIOS_READ_PROC czytamy do bufora sektor karty CF (w tej chwili wyliczany jako suma zahardcode'owanego początku partycji oraz wartości DISK_TRACK). Potem (od BIOS_READ_PROC_GET_SECT) wyliczamy adres sektora w buforze, dodając do jego adresu wynik mnożenia DISK_SECTOR przez 128.


Cytuj
Polecam zapoznać się z tym dokumentem, bo tak naprawdę są tam wszystkie odpowiedzi jak zbudować działający BIOS.

Ok, wczytam się w niego nieco dokładniej niż do tej pory. :)

tapy

  • ****
  • Wiadomości: 295
  • Z80 & CP/M
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #21 dnia: 2024.07.02, 19:16:56 »
Procedury do obsługi karty CF nie znajdują się w BIOS-ie. Są umieszczone na stałe w pamięci EPROM.

Nie bardzo rozumiem, ROM jest aktywny w trakcie działania systemu operacyjnego?

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #22 dnia: 2024.07.02, 22:52:09 »
Procedury do obsługi karty CF nie znajdują się w BIOS-ie. Są umieszczone na stałe w pamięci EPROM.

Nie bardzo rozumiem, ROM jest aktywny w trakcie działania systemu operacyjnego?

Tak. Nie mam zrobionego żadnego memory shadowingu, tak więc zawartość ROM-u jest cały czas dostępna powyżej adresu 0xC000. To pozwala mi korzystać z jego zawartości także podczas korzystania z CP/M, tak więc trzymam tam również procedury pomocnicze i dzięki temu oszczędzam RAM, bo nie muszą być one osobno ładowane z karty CF. Dodatkowo mam prostą logikę, która po resecie chwilowo ustawia linie A14 i A15 tak, że reszcie systemu wydaje się, że EPROM znajduje się pod adresem 0x0000 i to od niego zaczyna się praca systemu. Oczywiście przy rozruchu CP/M ten system nie jest wykorzystywany, bo użyty zostaje skok bezwarunkowy, a nie prawdziwy reset.

Wadą takiego rozwiązania jest to, że EPROM cały czas zajmuje 16kB przestrzeni adresowej, jednak to nie jest aż tak wielkim problemem.
Zasoby wyglądają następująco:
  • 32kB RAM-u dostępnego cały czas, począwszy od adresu 0x0000
  • 32kB RAM-u w formie dwóch stron po 16kB, począwszy od adresu 0x8000
  • 16Kb EPROM-u od adresu 0xC000

Na chwilę obecną cały CP/M i tak zajmuje jedynie pierwsze 16kB stałego RAM-u. W drugiej połówce chwilowo umieściłem bufory wykorzystywane m.in. podczas odczytu karty CF oraz przewijania ekranu. Docelowo trafią one jednak do stronnicowanego RAM-u, a CP/M dostanie do swojej dyspozycji (prawie) całe pierwsze 32kB.

W każdym razie - zebrałem jeszcze kolejne logi, w których printuję wartość LBA przy okazji odczytu karty CF. Wygląda na to, że wartość jest liczona poprawnie.

Naprawdę zastanawia mnie ta zmiana zachowania programu po włączeniu printów debugowych. Dlaczego po rozruchu w tym trybie system zawiesza się i nie pozwala na wpisywanie poleceń z klawiatury?

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #23 dnia: 2024.07.03, 17:34:54 »
Ok. Wygląda na to, że udało mi się nieco zawęzić pole poszukiwań.
Po pierwsze spróbowałem po kolei włączać printowanie logów debugowych w poszczególnych procedurach BIOS-a. W ten sposób doszedłem do tego, że to printy w SETDMA jakimś cudem wywalają mi system. Jeśli je włączę, po starcie systemu terminal zupełnie nie odpowiada. Jeśli pozostawię je wyłączone, prompt odpowiada normalnie, nawet jeśli wszystkie inne logi są włączone.

Jeśli chodzi o problem z wywalającym się poleceniem DIR, to dzięki obecności logów (za wyjątkiem tych z SETDMA) byłem w stanie sprawdzić co się dokładnie dzieje.
Na razie natknąłem się na dwa możliwe scenariusze:
  • DIR printuje niepełną listę plików (konkretnie tylko ASM.COM) - wołane sa po kolei procedury HOME, SETTRK (x2), SECTRN, SETSEC i READ. Ustawione zostają parametry pod odczyt pierwszej ścieżki/sektora DIR. Wołana jest procedura READ i z jej logu widzę, że adres DMA jest ustawiony prawidłowo i LBA też jest liczone poprawnie.
  • DIR zawiesza się po wyprintowaniu  kilku plików. W logach widać nieskończoną pętlę wywołań powtarzających odczyt całego DIR (ścieżki 0x20-0x3F).

tapy

  • ****
  • Wiadomości: 295
  • Z80 & CP/M
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #24 dnia: 2024.07.04, 09:48:23 »
To może inaczej, polecenia settrack, setsector, setdma są bardzo proste, polegają na przepisaniu z rejestrów BC do zdefiniowanych w BIOS komórek pamięci przekazanych przez BDOS parametrów, więc debugowanie tych elementów jest tak naprawdę kontrolą jądra systemu operacyjnego który na pewno działa (no chyba że został zmodyfikowany BDOS, ale tego się nie robi). Jedyne miejsce które powinno być sprawdzane to polecenia read i write (na tym etapie niekoniecznie, bo problem jest z odczytem i to najpierw należy rozwiązać) i tam też można odczytać te przygotowane informacje.
Kolejna sprawa, czy wszystkie sektory odczytywane w trakcie wykonywania polecenia DIR mają poprawną strukturę katalogów? Brak zdefiniowania tego obszaru może skutkować zapętleniem (wystarczy wypełnić ten obszar wartością 0xE5).
« Ostatnia zmiana: 2024.07.04, 09:55:14 wysłana przez tapy »

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #25 dnia: 2024.07.04, 11:02:54 »
To może inaczej, polecenia settrack, setsector, setdma są bardzo proste, polegają na przepisaniu z rejestrów BC do zdefiniowanych w BIOS komórek pamięci przekazanych przez BDOS parametrów, więc debugowanie tych elementów jest tak naprawdę kontrolą jądra systemu operacyjnego który na pewno działa (no chyba że został zmodyfikowany BDOS, ale tego się nie robi).

BDOS-a oczywiście nie modyfikowałem. Printy debugowe w tych pomniejszych procedurach dodałem tylko po to żeby mieć pewność, że wszystkie parametry są poprawnie ustawianie - wygląda na to, że tak.
Zastanawia mnie tutaj tylko wywalanie się systemu po dodaniu debugów do SETDMA - robię to dokładnie w taki sam sposób, jak we wszystkich innych procedurach, a tylko tutaj skutkuje to zawieszeniem systemu. Opcja z nadpisaniem jakiegoś rejestru odpada, bo robię pełne zrzucenie kontekstu na stos. Stos także nie jest nadpisywany, bo robię jego podmianę na czas wykonywania operacji i printuję wartość SP - nawet nie zbliżam się do końca stosu. Na pierwszy rzut oka nie widzę niczego, co mogłoby być nie tak w tym fragmencie kodu, a jednak dopuszczenie do jego warunkowego budowania wywala system...

BIOS_SETDMA_PROC:
PUSH H ; Save content  of HL on original stack
MOV L, C
MOV H, B
SHLD DISK_DMA

LXI H, 0000H ; then switch to bios stack
DAD SP ; HL = HL + SP
SHLD ORIGINAL_SP
LXI H, BIOS_STACK
SPHL ; Bios stack set.
IF DEBUG > 1
        PUSH PSW
        PUSH B
PUSH D
PUSH H
CALL IPUTS_RS232
DB 'SETDMA procedure entered: '
DB 00H
CALL PRINT_DISK_DEBUG
POP H
POP D
POP B
POP PSW
ENDIF
LHLD ORIGINAL_SP; Restore original stack
SPHL
POP H ; Restore original content of HL

RET


Cytuj
Jedyne miejsce które powinno być sprawdzane to polecenia read i write (na tym etapie niekoniecznie, bo problem jest z odczytem i to najpierw należy rozwiązać) i tam też można odczytać te przygotowane informacje.

Na chwilę obecną dodałem dodatkowe logi, które sprawdzają obliczanie wskaźnika na miejsce w buforze karty CF w zależności od obsługiwanego sektora:

sector=0x0000, calculated source address in CF bufffer = 0x447C
sector=0x0001, calculated source address in CF bufffer = 0x44FC
sector=0x0002, calculated source address in CF bufffer = 0x457C
sector=0x0003, calculated source address in CF bufffer = 0x45FC

Wygląda to ok. Teraz chyba jeszcze dodam robienie pełnego hexdumpa 128 bajtów spod tego adresu przed i po skopiowaniu do bufora wskazywanego w SETDMA, a potem upewnię się czy dane te są konsystentne z obszarem DIR w obrazie dysku.
W tej chwili system korzystania z karty CF nie jest zbyt optymalny, bo zawartość bufora jest odczytywana za każdym razem, nawet jeśli kolejny potrzebny sektor został już pobrany w poprzednim cyklu. Jeśli już uda mi się rozwiązać obecne problemy, zabiorę się za optymalizację.


Cytuj
Kolejna sprawa, czy wszystkie sektory odczytywane w trakcie wykonywania polecenia DIR mają poprawną strukturę katalogów? Brak zdefiniowania tego obszaru może skutkować zapętleniem (wystarczy wypełnić ten obszar wartością 0xE5).

Tego też nie jestem pewien. Swój kod opieram na przykładach z filmów na Youtube, w których gość portuje CP/M 2.2 na swój komputer retro (np. https://www.youtube.com/watch?v=EtcjFWUOVQw).

Konfiguracja dysku wygląda u mnie następująco:

; Plan:
; - Put 4 128-byte CP/M sectors into each 512-byte CF card block
; - Treat each CF card block as a CP/M track
;
; This filesystem has:
; 128 bytes/sector (CP/M requirement)
; 4 sectors/track (BIOS designer's choice)
; 65536 total sectors (CP/M limit)
; 65536*128 = 8388608 gross bytes (max CP/M limit)
; 65536/4 = 16384 tracks
; 2048 allocation block size BLS (BIOS designer's choice)
; 8388608/2048 = 4096 totalal allocation blocks
; 512 directory entries (BIOS designer's choice)
; 512*32 = 16384 total bytes in the directory
; ceiling(16384/2048) = 8 allocation blocks for the directory

; BLS BSH BLM ------EXM------
; DSM<256 DSM>255
; 1024 3 7 0 x
; 2048 4 15 1 0 <--------- This is what we are using
; 4096 5 31 3 1
; 8192 6 63 7 3
; 16384 7 127 15 7
;
; ** NOTE: This filesystem design is inefficient because it is unlikely
; that ALL of the allocation blocks will ultimately get used!

DISKA_DPH:
DW 0000H ; XLT
DW 0000H ; SCRPAD
DW 0000H
DW 0000H
DW DIRBUF ; DIRBUF
DW DISKA_DPB ; DPB
DW 0000H ; CSV
DW DISKA_ALV ; ALV

DISKA_DPB:
DW 4 ; SPT (four 128 bytes per 512 byte track)
DB 4 ; BSH (for BLS 2048)
DB 15 ; BLM (for BLS 2048)
DB 00H ; EXM
DW 4063 ; DSM (max allocation number)
DW 511 ; DRM
DB 0FFH ; AL0
DB 00H ; AL1
DW 0000H ; CKS
DW 0020H ; OFF

DISKA_ALV:
DS (4065/8)+1
DISKA_ALV_END

DIRBUF DS 128

Obraz jest budowany na komputerze za pomocą cpmtools, w Makefile:

mkfs.cpm -f polon-2k-8m -b cpm22.bin poloncpm.img
cpmcp -f polon-2k-8m poloncpm.img ./filesystem/* 0:

Definicja polon-2k-8m wygląda następująco:

diskdef polon-2k-8m
seclen 128
tracks 16384
sectrk 4
blocksize 2048
maxdir 512
skew 1
boottrk 32
os 2.2
end

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #26 dnia: 2024.07.04, 15:21:57 »
Tak natomiast wygląda obszar DIR w wygenerowanym obrazie dysku. Jakiś pomysł dlaczego nie jest czytany prawidłowo?

steev

  • *****
  • Wiadomości: 1409
  • Miejsce pobytu:
    inode 42
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #27 dnia: 2024.07.04, 17:23:49 »
Z ciekawości : to że numery AU są dwubajtowe BDOS sam rozpoznaje, czy trzeba to gdzieś ustawiać?
Machines should work. People should think.

Atlantis

  • ****
  • Wiadomości: 319
  • Miejsce pobytu:
    Kraków
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #28 dnia: 2024.07.04, 17:44:58 »
Z ciekawości : to że numery AU są dwubajtowe BDOS sam rozpoznaje, czy trzeba to gdzieś ustawiać?

O których numerach mówisz?

Ok, dodałem kolejne logi. Zrzuciłem hexdumpy odczytywanych sektorów. Wnioski wyglądają następująco:
  • Dane trafiające do bufora po odczycie z karty CF są konsystentne z obrazem na dysku. Więc nie widać błędów podczas odczytu.
  • Dane odpowiadające sektorowi kopiowanemu do bufora wskazywanego przez SETDMA są konsystentne z danymi odczytanymi z karty CF. Więc nie widać błędów podczas kopiowania.
  • Podczas uruchamiania systemu czytany jest cały DIR - najpierw cztery sektory zawierające rzeczywistą strukturę plików, a potem lecą już tylko sektory wypełnione bajtami E5.
  • Gdy po uruchomieniu systemu wywołam komendę DIR, printuje się jedynie plik ASM.COM, a w logach dostaje jeden sektor, którego zawartość jest konsystentna z wartościami oczytanymi przy uruchamianiu systemu (oraz obrazem na dysku). Przypadku z zapętleniem jak na razie nie udało mi się zreplikować.

Tak więc sam odczyt wydaje się działać prawidłowo. Więc teraz najważniejsze pytanie: dlaczego pomimo tego system nie potrafi poprawnie poradzić sobie z obsługą komendy DIR? Czyżbym miał jakiś problem ze strukturami konfigurującymi dysk? Czyżby "geometria" nie pasowała do tego, co zostaje wygenerowane przez cpmtools na komputerze?

steev

  • *****
  • Wiadomości: 1409
  • Miejsce pobytu:
    inode 42
Odp: CP/M, karta CF i MCY7880
« Odpowiedź #29 dnia: 2024.07.04, 18:27:47 »
Z ciekawości : to że numery AU są dwubajtowe BDOS sam rozpoznaje, czy trzeba to gdzieś ustawiać?
O których numerach mówisz?
Numerach jednostek alokacji (a.k.a. allocation unit, a.k.a. block size z definicji cpmtools) w katalogu dysku / dyskietki.
Na dyskietkach jest ich < 256, więc są zapisywane jako bajty.
Na obrazach dysków jednostek alokacji jest więcej więc są w katalogu dysku zapisywane na słowach (dwa bajty)
Jestem ciekawy czy system sam to sobie sprawdza, czy trzeba mu podać na tacy.
Ok, przypuszczam, że rozpoznaje to po polu DSM w definicji dysku.
Machines should work. People should think.