Modyfikacje sprzętowe procesora: Różnice pomiędzy wersjami

Z MERA 400 wiki
Przejdź do nawigacji Przejdź do wyszukiwania
Nie podano opisu zmian
(Nie pokazano 16 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 1: Linia 1:
Procesor MERY-400 nie jest pojedynczym układem scalonym, a modułem, składającym się z pakietów (płyt drukowanych o wymiarach 300x300mm). Pakiety zbudowane są z układów scalonych z serii 74 oraz innych elementów dyskretnych. Taka konstrukcja powoduje, że stosunkowo łatwo jest wprowadzać w nim modyfikacje sprzętowe. Zadanie ułatwia dodatkowo fakt, że na poszczególnych pakietach procesora można znaleźć "wolne" bramki i przerzutniki.
{{TOC limit|2}}


Znane są dwie modyfikacje procesora MERY-400. Obie powstały na Politechnice Gdańskiej w zespole rozwijającym system operacyjny CROOK i obie były wykorzystywane zarówno przez CROOK-a jak i oprogramowanie, które dla niego powstawało.
Procesor MERY-400 nie jest pojedynczym układem scalonym, a sporym modułem, składającym się z pakietów (płyt o wymiarach 300x300mm). Pakiety zbudowane są z układów scalonych z serii 7400 oraz elementów dyskretnych. Taka konstrukcja powoduje, że stosunkowo łatwo jest wprowadzać w nim modyfikacje sprzętowe. Zadanie ułatwia dodatkowo fakt, że na poszczególnych pakietach procesora można znaleźć "wolne" bramki i przerzutniki.
 
Na przestrzeni lat, głównie w Instytucie Okrętowym Politechniki Gdańskiej, w zespole rozwijającym system operacyjny CROOK, ale również w Amepol-u, powstało kilka modyfikacji procesora MERY-400. Wykorzystywał je zarówno CROOK jak i oprogramowanie na nim działające. Były one implelentowane w istniejących instalacjach MERY-400, a ostatecznie wszystkie złożyły się na poprawioną wersję procesora używanego w [[MX-16]].
 
Przeróbki procesora dotyczą pakietów ''P-A'', ''P-D'', ''P-R'' i ''P-P'', a ich umiejscowienie związane jest z obecnością wolnych bramek i przerzutników. Schematy przedstawione dalej pokazują zmiany (wyróżnione kolorem czerwonym) względem [http://mera400.pl/files/mera400-dtr-t4-cz2-mjc400-schematy.pdf schematów] znajdujących się w DTR. Nazwy nowych sygnałów, nie ujętych w dokumentacji, zostały nadane w celu ułatwienia przedstawienia zmian i nie pokrywają się z nazwami nadanymi przez autorów modyfikacji (te są nieznane).
 
= Automatyczny bootstrap =
 
[[Pamięć MEGA]] zawiera bootloader(-y) zapisane w pamięci EPROM, dostępnej po starcie systemu od adresu 0xf000. Można uruchomić zawarty tam kod ustawiając z pulpitu technicznego zawartość licznika rozkazów i startując maszynę. Problem pojawi się w przypadku komputera [[MX-16]], który dostarczany był bez pulpitu - bootloader musiał zostać załadowany automatycznie.
 
Zostało to zrobione poprzez modyfikację procesora, która tuż po włączeniu zasilania ustawia licznik rozkazów na adres 0xf000.
 
Przeróbka ta nie ma żadnego efektu, jeśli w systemie nie jest zainstalowana pamięć MEGA, bądź bootstrap z pamięci MEGA nie został skonfigurowany.
 
== Realizacja techniczna ==
 
Do pakietu P-A doprowadzony jest sygnał '''+BOOTL''' z pamięci MEGA. Jego dokładne źródło nie jest znane, jednak charakter modyfikacji wskazuje, że informuje on o gotowości pamięci MEGA do dostarczenia programu rozruchowego od adresu 0xf000. Sygnał '''-PON''' generowany jest w zasilaczu i informuje o włączeniu zasilania maszyny.
 
[[File:cpumod-p-a-boot.png|650px|center]]
 
Układ '''M54''' to 4-bit rejestr przechowujący najstarszy kwartet bitów licznika rozkazów IC. Istniejące połączenie jego wejścia '''CD''' (Count Down) do stanu wysokiego zostało przerwane i zastąpione iloczynem sygnałów '''+BOOTL''' i '''+PON'''. Aktywne "0" na wyjściu bramki NAND (układ '''M21''') powoduje zmniejszenie o jeden zawartości rejestru '''M54''', a co za tym idzie ustawienie licznika rozkazów na adres 0xf000.
 
= Instrukcja włączająca modyfikacje =
 
Ponieważ chciano zapewnić możliwie najpełniejszą kompatybilność wsteczną z oryginalnym procesorem MERY-400, funkcjonalność opisanych dalej przeróbek dostępna jest dopiero po programowym ich aktywowaniu nową instrukcją procesora.
 
W grupie rozkazowej S dodano instrukcję CRON o kodzie 0166500. Maszyna zmodyfikowana uruchamia się w trybie kompatybilności z oryginalnym procesorem, a dopiero jej wywołanie aktywuje modyfikacje. Zerowanie maszyny kluczem CLEAR bądź rozkazem MCL przywraca procesor do pierwotnego stanu kompatybilności.
 
== Realizacja techniczna ==
 
Modyfikacja obejmuje pakiety P-D i P-P. Na pakiecie P-D użyto wyjścia 6 układu '''M44''', na którym stan niski wskazuje binarną wartość "101" w polu A rozkazu z grupy S. Sygnał ten jest rozpatrywany w iloczynie z niskim poziomem sygnału '''+Q'''. Tak wypracowany sygnał '''+CRON''' wskazuje na wydanie instrukcji CRON w systemie operacyjnym.
 
[[File:cpumod-p-d-cron.png|600px|center]]
 
Należy zauważyć, że instrukcja ta wciąż jest instrukcją nielegalną, co zapewnia kompatybilność wsteczną. Programista używający instrukcji CRON w systemie operacyjnym musi obsłużyć fakt, że po jej wydaniu zgłoszone zostanie przerwanie "niepoprawny rozkaz".
 
Rezultatem wydania instrukcji CRON musiało być "przełączenie" procesora w tryb pracy z modyfikacjami aż do następnego zerowania, a więc sygnał '''+CRON''' musi zostać gdzieś zapamiętany. Dzieje się to na pakiecie P-P.
 
[[File:cpumod-p-p-cpumod.png|550px|center]]
 
Przerzutnik '''M72''' służy do zapamiętania aktywowania modyfikacji. Na wejście D przerzutnika podana jest na stałe wartość "1", a wejściem sterującym, powodującym jej wpisanie, jest wejście zegarowe. Podany jest na nie sygnał '''+CRON''' w iloczynie z sygnałem '''+P2''', który informuje, że procesor jest w stanie P2 - wykryta została instrukcja nieefektywna (którą instrukcja CRON jest).
 
Jedynym sposobem na wyzerowanie wartości zapisanej w przerzutniku jest podanie niskiego poziomu na wejście R. Doprowadzony do niego jest sygnał '''-CLM''' sygnalizujący zerowanie maszyny. Powtórzone wywołania instrukcji CRON nie wnoszą niczego - do przerzutnika wpisywana jest ponownie "1".


= 17-bitowe adresowanie bajtów =
= 17-bitowe adresowanie bajtów =


W oryginalnej konstrukcji procesora adres bajtu był 16-bitowy, z czego 15 najstarszych bitów adresowało słowo w pamięci, a najmłodszy bit wskazywał lewy lub prawy bajt w 16-bitowym słowie maszyny. Oznacza to, że za pomocą instrukcji używających adresowania bajtowego (LB, RB, CB) można było odwołać się jedynie do pierwszych 32k słów w maksymalnie 64k słowowym bloku. Fakt ten powodował również nieścisłości w dokumentacji (patrz [[Adresowanie pamięci]]).
W oryginalnej konstrukcji procesora adres bajtu jest 16-bitowy, z czego 15 najstarszych bitów adresuje słowo w pamięci, a najmłodszy bit wskazuje lewy lub prawy bajt w 16-bitowym słowie maszyny. Oznacza to, że za pomocą instrukcji używających adresowania bajtowego (LB, RB, CB) można odwołać się jedynie do pierwszych 32k słów w 64k bloku. Fakt ten jest również źródłem nieścisłości w dokumentacji (patrz [[Adresowanie pamięci]]).


Adresowanie bajtu w nie zmodyfikowanym procesorze realizowane jest w następujący sposób:
Adresowanie bajtu w nie zmodyfikowanym procesorze realizowane jest w następujący sposób:
Linia 13: Linia 55:
* "Wypadający" najmłodszy bit zachowywany jest, aby później na podstawie jego wartości z komórki pamięci wybrać odpowiedni bajt (lewy bądź prawy).
* "Wypadający" najmłodszy bit zachowywany jest, aby później na podstawie jego wartości z komórki pamięci wybrać odpowiedni bajt (lewy bądź prawy).


Przeróbka procesora wykorzystuje fakt, że argument normalny, którym jest również adres bajtowy, podlega B- i pre-modyfikacji. Zarówno B- jak i pre-modyfikacja są niczym innym, jak operacjami dodawania modyfikatora do argumentu, wykonywanymi w arytmometrze procesora. W wyniku tej operacji może wystąpić przeniesienie, które w standardowym procesorze jest w tym wypadku ignorowane. Przeróbka zmienia to zachowanie.
Adres bajtu (jako argument normalny) podlega również pre- i B-modyfikacji. Obie te operacje są niczym innym, jak dodawaniem modyfikatora do argumentu, wykonywanym w arytmometrze procesora. W wyniku tej operacji może więc wystąpić przeniesienie, które w standardowym procesorze jest zaniedbywane.


W przerobionym procesorze przeniesienie, które wystąpiło w wyniku B- i pre-modyfikacji, jest zapamiętywane. Później, kiedy adres bajtowy przesuwany jest w prawo, aby otrzymać docelowy adres słowa w pamięci, na najstarszy bit adresu, zamiast zera, wsuwana jest wartość przeniesienia. W ten sposób, używając B- lub pre-modyfikacj można przygotować 17-bitowy adres bajtu tak, aby możliwe było zaadresowanie dowolnego bajtu w 64k słowowym bloku.
Przeróbka procesora zmienia to zachowanie. Gdy do pierwotnego argumentu dodawana jest pre-, lub B-modyfikacja, przeniesienie, które występuje przy tej operacji zapamiętywane jest każdorazowo w dodatkowym rejestrze. Później, kiedy adres bajtowy przesuwany jest w prawo, aby otrzymać docelowy adres słowa w pamięci, na najstarszy bit adresu, zamiast zera, wsuwana jest zawartość ostatniego zapamiętanego przeniesienia. W ten sposób, używając pre- lub B-modyfikacj można przygotować 17-bitowy adres bajtu tak, aby możliwe było zaadresowanie dowolnego bajtu w 64k słowowym bloku.  
 
Przykładowe konstrukcje używające 17-bit adresowania bajtów (w składni assemblera [[EMAS]]):
 
LW r2, 0x9400    ; 0x9400 to adres słowa, w którym adresujemy bajt
MD 1            ; wskazanie bajtu w słowie
LB r1, r2+r2    ; załadowanie bajtu; adresem bajtowym staje się 2*r2+1
 
LW r5, 0xAAAA    ; 0xAAAA to słowowy adres bazowy obszaru, który chcemy adresować
LW r6, r5+r1    ; w r6 do adresu bazowego dodajemy również przesunięcie (indeks) przechowywany w rejestrze r1
MD r6            ; pre-modyfikacja zapewnia dodanie do argumentu wartości r5+r1
RB r3, r5        ; zapamiętanie bajtu pod bajtowym adresem 2*0xAAAA+r1
 
17-bitowe adresowanie bajtów może rodzić problemy w specyficznych przypadkach użycia go w oprogramowaniu pisanym na oryginalny procesor. Rozpatrzmy następujący przykład:
 
LW r2, 0x3b00
LW r3, -12
MD r2
LB r1, r2+r3
 
Jeśli przeniesienia przy obliczaniu argumentu normalnego są zaniedbywane (jak w oryginalnym procesorze), adres bajtowy zostanie obliczony zgodnie z intencją programisty w następujący sposób:
 
# argument pierwotny = '''0x3b00'''
# dodanie pre-modyfikacji (0x3b00) = '''0x7600''' (przeniesienie = 0)
# dodanie B-modyfikacji (-12) = '''0x75f4''' (przeniesienie = 1)
# przesunięcie w prawo dla otrzymania adresu bajtowego = '''0x3afa'''
 
W kroku 3 występuje przeniesienie, ponieważ arytmometr do argumentu dodaje B-modyfikację, która w zapisie U2 wygląda: 0xfff4. Jeśli procesor jest zmodyfikowany, to zapamiętane przeniesienie zostanie w ostatnim kroku użyte i wsunięte na najstarszą pozycję ostatecznego wyniku, dając w efekcie adres '''0xbafa'''.
 
Należy więc zapewnić możliwość poprawnego uruchamiania również i takich programów na zmodyfikowanym procesorze, pod kontrolą systemu operacyjnego, który aktywował modyfikacje. Zostało to osiągnięte przez ustalenie następujących warunków, w których 17-bit adresowanie bajtów jest możliwe:
 
* wykonywany jest program w trybie systemu operacyjnego (Q=0)
* lub wykonowyany jest program w trybie użytkownika i nie jest ustawiony bit specjalny (BS=0)
 
Dzięki temu, dla programów (procesów), o których wiadomo było, że nie pracują poprawnie z 17-bit adresowaniem, system operacyjny może je dezaktywować, ustawiając przed przełączeniem kontekstu bit BS w rejestrze SR na 1. Takie zachowanie jest kompatybilne z oryginalnym procesorem, ponieważ na takim sprzęcie bit BS nie ma znaczenia, gdy wykonywany jest program w blokach użytkowych.
 
== Realizacja techniczna ==
 
Ta modyfikacja jest jedną z najbardziej złożonych i obejmuje zmiany na pakietach P-P, P-R i P-A. Na pakiecie P-P wypracowywany jest sygnał '''-LRCBM''' mówiący o tym, że instrukcja LB, RB lub CB została wydana na procesorze z aktywnymi modyfikacjami.
 
[[File:cpumod-p-p-lrcbm.png|450px|center]]
 
Na pakiecie P-R znajduje się przerzutnik '''M16''', w którym pamiętany jest 17. bit używany w adresowaniu bajtowym.
 
[[File:cpumod-p-r-bab17.png|780px|center]]
 
Taktowany jest on sygnałem '''+STROB1''' w iloczynie z sygnałem '''+P4''', mówiącym o tym, że procesor jest w stanie P4, w którym następuje pre- i B-modyfikacja argumentu normalnego. Na wejściu D pojawia się sygnał, który w rezultacie wpisuje do przerzutnika wartość '''-CARRY''', gdy spełnione są wszystkie niezbędne warunki:
 
D = ~(CARRY & LRCBM & (~Q | ~BS))
 
czyli:
 
* wydany został rozkaz LB, RB lub CB na procesorze z aktywną modyfikacją
* procesor pracuje w trybie systemu operacyjnego (Q=0) lub bit specjalny jest wyzerowany (BS=0)
 
Zapamiętywana w przerzutniku wartość jest zanegowana, stąd bramka NOT ('''M55''') na wyjściu.
 
Na wejście S (które w związku z negacją na wyjściu '''M53''' jest efektywnie wejściem zerującym) podane są sygnały '''-P1''' (stan, w którym odczytywany jest rozkaz) i '''-P5''' (stan, w którym pobierany jest argument pośredni). Wystąpienie któregokolwiek z nich powoduje zapamiętanie "1", czyli efektywne wyzerowanie zawartości przerzutnika.
 
Ostatecznie sygnał '''+BAB17''' niesie informację o 17 bicie powstałym w wyniku B-modyfikacji lub pre-modyfikacji argumentu normalnego rozkazów bajtowych:
 
BAB17 = CARRY & LRCBM & (~Q | ~BS)
 
Dzięki modyfikacji wprowadzonej na pakiecie P-A, wartość ta wsuwana jest z lewej strony do rejestru AT w chwili przesuwania jego zawartości podczas przygotowywania adresu słowa przy adresowaniu bajtowym:
 
[[File:cpumod-p-a-eat0.png|500px|center]]


= Przerwanie programowe o wysokim priorytecie =
= Przerwanie programowe o wysokim priorytecie =


System operacyjny CROOK wymaga istnienia przerwania programowego, którego priorytet byłby wyższy niż przerwań pochodzących z urządzeń zewnętrznych (kanałowych). W [[Przerwania|systemie przerwań MERY-400]] takie przerwanie nie istnieje. Wersje systemu CROOK od 1 do 5 obchodziły ten problem następująco: W jądrze systemu używana była pseudo-instrukcja SIN o kodzie (ósemkowo) 036000. Z punktu widzenia procesora jest to instrukcja niepoprawna, generująca przerwanie "nieprawidłowy rozkaz". Jednocześnie procedura obsługi tego przerwania w CROOK-u skonstruowana jest tak, aby w przypadku pseudo-rozkazu SIN zapewnić jego obsługę jak przerwania programowego o wysokim priorytecie. To obejście wykorzystywane jest we wszystkich wersjach systemu, aż do ostatniej rewizji CROOK-5.
System operacyjny CROOK wymaga istnienia przerwania programowego, którego priorytet byłby wyższy niż przerwań pochodzących z urządzeń zewnętrznych (kanałowych) i z zegara systemowego. W [[Przerwania|systemie przerwań MERY-400]] takie przerwanie nie istnieje. Wersje systemu CROOK od 1 do 5 obchodziły ten problem następująco: W jądrze systemu używana jest pseudo-instrukcja SIN o kodzie (ósemkowo) 036000. Z punktu widzenia procesora jest to instrukcja niepoprawna, generująca przerwanie "nieprawidłowy rozkaz". Jednocześnie procedura obsługi tego przerwania w CROOK-u skonstruowana jest tak, aby w przypadku pseudo-rozkazu SIN zapewnić jego obsługę jak przerwania programowego o wysokim priorytecie. To obejście wykorzystywane jest we wszystkich wersjach systemu, aż do ostatniej rewizji CROOK-5.


Istnieje jednak alternatywne jądro CROOK-5 w rewizjach 7 i 8, potrafiące pracować z procesorem z dodanymi dwiema nowymi, legalnymi instrukcjami: SINT i SIND. Zastępują one funkcjonalnie pseudo-instrukcję SIN.
Istnieje jednak alternatywne jądro CROOK-5 w rewizjach 7 i 8, potrafiące pracować z procesorem z dodanymi dwiema nowymi, legalnymi instrukcjami: SINT i SIND. Zastępują one funkcjonalnie pseudo-instrukcję SIN.


Na tę przeróbkę procesora składały się zmiany w kilku jego obszarach:
Na tę przeróbkę procesora składają się zmiany w kilku jego obszarach:
# W dekoderze rozkazów znaleziono "miejsce" na dwie nowe instrukcje: w grupie rozkazów bezargumentowych S (patrz: [[Skorowidz kodów rozkazów]]). Jest to jedyna grupa w obszarze rozkazów legalnych, gdzie część bitów kodu rozkazu nie jest w ogóle wykorzystana (odpowiednie linie dekodera rozkazów nie są użyte). Nowym rozkazom zostały nadane kody (ósemkowo):
# W dekoderze rozkazów znaleziono "miejsce" na dwie nowe instrukcje: w grupie rozkazów bezargumentowych S (patrz: [[Skorowidz kodów rozkazów]]). Jest to jedyna grupa w obszarze rozkazów legalnych, gdzie część bitów kodu rozkazu nie jest w ogóle wykorzystana (odpowiednie linie dekodera rozkazów nie są użyte). Nowym rozkazom zostały nadane kody (ósemkowo):
#* SINT = 0166204
#* SINT = 0166204
#* SIND = 0167204
#* SIND = 0167204
# Przerwanie zegarowe (pozycja 5) zostało przeniesione na pozycję 11, w standardowym procesorze nie skojarzoną z żadnym źródłem przerwania.
# Przerwanie zegarowe (pozycja 5) zostało przeniesione na pozycję 11, w standardowym procesorze nie skojarzoną z żadnym źródłem przerwania.
# Przerwanie 5 zostało użyte jako przerwanie programowe o wysokim priorytecie, sterowane instrukcjami SINT i SIND (analogicznie do instrukcji SIT i CIT).
# Przerwanie 5 zostało użyte jako przerwanie programowe o wysokim priorytecie, sterowane instrukcjami SINT i SIND.
# Prawdopodobnie wprowadzono też zmiany w systemie maskowania przerwań, ale ten fragment przeróbki nie jest obecnie zweryfikowany.
 
== Realizacja techniczna ==
 
Modyfikacja ma miejsce na pakiecie P-P. Oryginalne połączenie źródła przerwania zegarowego do przerzutnika '''M37''' zostało przerwane. Przerwanie 11 nie ma w oryginalnym procesorze żadnego źródła, na wejściu S jest zawsze logiczna "1". Zmodyfikowany układ przerwań kieruje przerwanie zegarowe na przerzutnik '''M31''' lub '''M37''' w zależności od tego, czy modyfikacja procesora jest (odpowiednio) aktywna, czy nie.
 
[[File:cpumod-p-p-int5-int11.png|700px|center]]
 
Dodatkowo badana jest pozycja 13 rejestru rozkazu ('''+IR13''') w iloczynie z sygnałem '''+(WX & SIN)''', oznaczającym stan WX dla grupy rozkazów SIN, SIT, SIL, CIT. Jest to "dekoder" rozkazów SINT i SIND, które ulokowane są w grupie ze wspomnianymi wcześniej rozkazami (rozkazy grupy S z polem A = "010"). Jeśli najstarszy bit pola C jest dla nich zapalony (IR13=1), to procesor zgłasza przerwanie 11.
 
Przeróbka ma tę drobną wadę, że jeśli modyfikacje procesora nie są aktywne, a wydana zostanie instrukcja SIND lub SINT, to zgłoszone zostanie nadmiarowe przerwanie zegarowe.
 
Należy też zauważyć, że instrukcje SINT i SIND nie są tak naprawdę osobnymi instrukcjami, a specjalnym przypadkiem instrukcji SIN, SIL, SIT, CIT, dla których ustawiony jest najstarszy bit pola C (ignorowany w niezmodyfikowanym procesorze). W efekcie, wydanie instrukcji SINT lub SIND oprócz zamierzonego efektu (zgłoszenie przerwania 11), będzie miało efekt dodatkowy, zależny od zawartości dwóch najmłodszych bitów pola C. Zgodnie z treścią rozkazów SIT, SIL, SIN, CIT, które te pola wykorzystują, zgłoszone lub wyzerowane zostaną przerwania 30 i/lub 31. W systemie CROOK instrukcje SINT i SIND mają pole C=100, a więc zgłoszeniu przerwania 11 towarzyszy wyzerowanie przerwań 30 i 31.
 
= Zmiana maskowania przerwań =
 
CROOK-5 ma jeszcze jedno wymaganie, które ostatecznie zostało spełnione za pomocą modyfikacji sprzętowej. Należało zapewnić, aby w trakcie obsługi przerwania kanałowego nie pojawiło się przerwanie o wyższym priorytecie (w szczególności zegarowe). W procesorze bez przeróbek wymuszane to było przez programowe maskowanie przerwań na początku procedury obsługi przerwań kanałowych. W procesorze przerobionym zrealizowane to było sprzętowo: Przyjęcie przerwania kanałowego powodowało automatyczne zamaskowanie przerwań od 5 do 31.
 
== Realizacja techniczna ==
 
Modyfikacja została wprowadzona na pakiecie P-P. W niezmodyfikowanym procesorze, na podstawie przyjętych przerwań, sygnały '''+ZI4''' - '''+ZI7''' maskują odpowiednie grupy przerwań.
 
[[File:cpumod-p-p-mask.png|400px|center]]
 
Jeśli modyfikacja procesora jest aktywna, sygnał '''+ZI8''', oprócz swojej pierwotnej funkcji, powoduje też zamaskowanie przerwań w grupach 4, 5, 6 i 7.
 
= Reakcja procesora na brak pamięci =
 
'''Uwaga:''' Na istnienie poniższej zmiany silnie wskazuje analiza zawartości kości EPROM pamięci MEGA oraz inne zmiany w procesorze MX-16, jednak nie została ona definitywnie potwierdzona.
 
Ponieważ MX-16 nie był wyposażony w pulpit techniczny, konieczna była zmiana w sposobie, w jaki procesor reaguje na odwołanie do nieskonfigurowanego segmentu pamięci w obszarze systemowym. Oryginalny procesor przechodził w stan STOP, z którego można go było wybudzić jedynie kluczem START/STOP. W MX-16 nie było takiej możliwości, więc obsługa takiego przypadku musiała być w pełni programowa i ograniczać się do zgłoszenia przerwania, podobnie jak w przypadku błędów dostępu do pamięci programów użytkowych.
 
== Realizacja techniczna ==
 
Zostało to osiągnięte nie tyle przez modyfikację, co rekonfigurację procesora. Na pakiecie P-X istnieje zwora S-R (nie opisana w dokumentacji), która decyduje o tym, czy w opisanym wyżej przypadku wymuszany jest stan STOP. W komputerach MX-16 była ona najprawdopodobniej rozwarta.
 
= Połączenia na platerze procesora =
 
Poza zmianami wprowadzonymi na samych pakietach, powstały też nowe połączenia na platerze procesora:
 
{| class="wikitable"
! colspan="2" | Z !! colspan="2" | DO !! rowspan="2" | Sygnał
|-
! Pakiet !! Piórko !! Pakiet !! Piórko
|-
| P-D || B48 || P-P || B68 || +CRON
|-
| P-P || B40 || P-R || B38 || -LRCBM
|-
| P-P || B55 || P-D || A45 || -LRCB
|-
| P-P || B60 || P-M || A07 || -P2
|-
| P-P || B68 || P-D || B48 || +CRON
|-
| P-P || B70 || P-M || B52 || +IR13
|-
| P-R || B35 || P-A || B70 || +BAB17
|-
| P-R || B36 || P-M || A29 || -P1
|-
| P-R || B37 || P-M || B55 || -P5
|-
| P-R || B38 || P-P || B40 || -LRCBM
|-
| P-R || B51 || P-D || A77 || -P4
|-
| P-A || B70 || P-R || B35 || +BAB17
|-
| P-A || B72 || P-M || A12 || -PON
|-
| P-A || B92 || ME-GA-400 || W48 || +BOOTL
|}
 
 
{{source|title=Opracowanie własne}}

Wersja z 17:42, 6 sty 2016

Procesor MERY-400 nie jest pojedynczym układem scalonym, a sporym modułem, składającym się z pakietów (płyt o wymiarach 300x300mm). Pakiety zbudowane są z układów scalonych z serii 7400 oraz elementów dyskretnych. Taka konstrukcja powoduje, że stosunkowo łatwo jest wprowadzać w nim modyfikacje sprzętowe. Zadanie ułatwia dodatkowo fakt, że na poszczególnych pakietach procesora można znaleźć "wolne" bramki i przerzutniki.

Na przestrzeni lat, głównie w Instytucie Okrętowym Politechniki Gdańskiej, w zespole rozwijającym system operacyjny CROOK, ale również w Amepol-u, powstało kilka modyfikacji procesora MERY-400. Wykorzystywał je zarówno CROOK jak i oprogramowanie na nim działające. Były one implelentowane w istniejących instalacjach MERY-400, a ostatecznie wszystkie złożyły się na poprawioną wersję procesora używanego w MX-16.

Przeróbki procesora dotyczą pakietów P-A, P-D, P-R i P-P, a ich umiejscowienie związane jest z obecnością wolnych bramek i przerzutników. Schematy przedstawione dalej pokazują zmiany (wyróżnione kolorem czerwonym) względem schematów znajdujących się w DTR. Nazwy nowych sygnałów, nie ujętych w dokumentacji, zostały nadane w celu ułatwienia przedstawienia zmian i nie pokrywają się z nazwami nadanymi przez autorów modyfikacji (te są nieznane).

Automatyczny bootstrap

Pamięć MEGA zawiera bootloader(-y) zapisane w pamięci EPROM, dostępnej po starcie systemu od adresu 0xf000. Można uruchomić zawarty tam kod ustawiając z pulpitu technicznego zawartość licznika rozkazów i startując maszynę. Problem pojawi się w przypadku komputera MX-16, który dostarczany był bez pulpitu - bootloader musiał zostać załadowany automatycznie.

Zostało to zrobione poprzez modyfikację procesora, która tuż po włączeniu zasilania ustawia licznik rozkazów na adres 0xf000.

Przeróbka ta nie ma żadnego efektu, jeśli w systemie nie jest zainstalowana pamięć MEGA, bądź bootstrap z pamięci MEGA nie został skonfigurowany.

Realizacja techniczna

Do pakietu P-A doprowadzony jest sygnał +BOOTL z pamięci MEGA. Jego dokładne źródło nie jest znane, jednak charakter modyfikacji wskazuje, że informuje on o gotowości pamięci MEGA do dostarczenia programu rozruchowego od adresu 0xf000. Sygnał -PON generowany jest w zasilaczu i informuje o włączeniu zasilania maszyny.

Układ M54 to 4-bit rejestr przechowujący najstarszy kwartet bitów licznika rozkazów IC. Istniejące połączenie jego wejścia CD (Count Down) do stanu wysokiego zostało przerwane i zastąpione iloczynem sygnałów +BOOTL i +PON. Aktywne "0" na wyjściu bramki NAND (układ M21) powoduje zmniejszenie o jeden zawartości rejestru M54, a co za tym idzie ustawienie licznika rozkazów na adres 0xf000.

Instrukcja włączająca modyfikacje

Ponieważ chciano zapewnić możliwie najpełniejszą kompatybilność wsteczną z oryginalnym procesorem MERY-400, funkcjonalność opisanych dalej przeróbek dostępna jest dopiero po programowym ich aktywowaniu nową instrukcją procesora.

W grupie rozkazowej S dodano instrukcję CRON o kodzie 0166500. Maszyna zmodyfikowana uruchamia się w trybie kompatybilności z oryginalnym procesorem, a dopiero jej wywołanie aktywuje modyfikacje. Zerowanie maszyny kluczem CLEAR bądź rozkazem MCL przywraca procesor do pierwotnego stanu kompatybilności.

Realizacja techniczna

Modyfikacja obejmuje pakiety P-D i P-P. Na pakiecie P-D użyto wyjścia 6 układu M44, na którym stan niski wskazuje binarną wartość "101" w polu A rozkazu z grupy S. Sygnał ten jest rozpatrywany w iloczynie z niskim poziomem sygnału +Q. Tak wypracowany sygnał +CRON wskazuje na wydanie instrukcji CRON w systemie operacyjnym.

Należy zauważyć, że instrukcja ta wciąż jest instrukcją nielegalną, co zapewnia kompatybilność wsteczną. Programista używający instrukcji CRON w systemie operacyjnym musi obsłużyć fakt, że po jej wydaniu zgłoszone zostanie przerwanie "niepoprawny rozkaz".

Rezultatem wydania instrukcji CRON musiało być "przełączenie" procesora w tryb pracy z modyfikacjami aż do następnego zerowania, a więc sygnał +CRON musi zostać gdzieś zapamiętany. Dzieje się to na pakiecie P-P.

Przerzutnik M72 służy do zapamiętania aktywowania modyfikacji. Na wejście D przerzutnika podana jest na stałe wartość "1", a wejściem sterującym, powodującym jej wpisanie, jest wejście zegarowe. Podany jest na nie sygnał +CRON w iloczynie z sygnałem +P2, który informuje, że procesor jest w stanie P2 - wykryta została instrukcja nieefektywna (którą instrukcja CRON jest).

Jedynym sposobem na wyzerowanie wartości zapisanej w przerzutniku jest podanie niskiego poziomu na wejście R. Doprowadzony do niego jest sygnał -CLM sygnalizujący zerowanie maszyny. Powtórzone wywołania instrukcji CRON nie wnoszą niczego - do przerzutnika wpisywana jest ponownie "1".

17-bitowe adresowanie bajtów

W oryginalnej konstrukcji procesora adres bajtu jest 16-bitowy, z czego 15 najstarszych bitów adresuje słowo w pamięci, a najmłodszy bit wskazuje lewy lub prawy bajt w 16-bitowym słowie maszyny. Oznacza to, że za pomocą instrukcji używających adresowania bajtowego (LB, RB, CB) można odwołać się jedynie do pierwszych 32k słów w 64k bloku. Fakt ten jest również źródłem nieścisłości w dokumentacji (patrz Adresowanie pamięci).

Adresowanie bajtu w nie zmodyfikowanym procesorze realizowane jest w następujący sposób:

  • Użytkownik dostarcza adres bajtu w postaci: 15 bitów adresu słowa, 1 bit (najmłodszy) wskazujący bajt w słowie.
  • Tak dostarczony adres procesor przesuwa o jeden bit w prawo. W wyniku otrzymuje poprawny, 16-bitowy adres słowa w pamięci, którego najstarszy bit jest zawsze zerem
  • "Wypadający" najmłodszy bit zachowywany jest, aby później na podstawie jego wartości z komórki pamięci wybrać odpowiedni bajt (lewy bądź prawy).

Adres bajtu (jako argument normalny) podlega również pre- i B-modyfikacji. Obie te operacje są niczym innym, jak dodawaniem modyfikatora do argumentu, wykonywanym w arytmometrze procesora. W wyniku tej operacji może więc wystąpić przeniesienie, które w standardowym procesorze jest zaniedbywane.

Przeróbka procesora zmienia to zachowanie. Gdy do pierwotnego argumentu dodawana jest pre-, lub B-modyfikacja, przeniesienie, które występuje przy tej operacji zapamiętywane jest każdorazowo w dodatkowym rejestrze. Później, kiedy adres bajtowy przesuwany jest w prawo, aby otrzymać docelowy adres słowa w pamięci, na najstarszy bit adresu, zamiast zera, wsuwana jest zawartość ostatniego zapamiętanego przeniesienia. W ten sposób, używając pre- lub B-modyfikacj można przygotować 17-bitowy adres bajtu tak, aby możliwe było zaadresowanie dowolnego bajtu w 64k słowowym bloku.

Przykładowe konstrukcje używające 17-bit adresowania bajtów (w składni assemblera EMAS):

LW r2, 0x9400    ; 0x9400 to adres słowa, w którym adresujemy bajt
MD 1             ; wskazanie bajtu w słowie
LB r1, r2+r2     ; załadowanie bajtu; adresem bajtowym staje się 2*r2+1
LW r5, 0xAAAA    ; 0xAAAA to słowowy adres bazowy obszaru, który chcemy adresować
LW r6, r5+r1     ; w r6 do adresu bazowego dodajemy również przesunięcie (indeks) przechowywany w rejestrze r1
MD r6            ; pre-modyfikacja zapewnia dodanie do argumentu wartości r5+r1
RB r3, r5        ; zapamiętanie bajtu pod bajtowym adresem 2*0xAAAA+r1

17-bitowe adresowanie bajtów może rodzić problemy w specyficznych przypadkach użycia go w oprogramowaniu pisanym na oryginalny procesor. Rozpatrzmy następujący przykład:

LW r2, 0x3b00
LW r3, -12
MD r2
LB r1, r2+r3

Jeśli przeniesienia przy obliczaniu argumentu normalnego są zaniedbywane (jak w oryginalnym procesorze), adres bajtowy zostanie obliczony zgodnie z intencją programisty w następujący sposób:

  1. argument pierwotny = 0x3b00
  2. dodanie pre-modyfikacji (0x3b00) = 0x7600 (przeniesienie = 0)
  3. dodanie B-modyfikacji (-12) = 0x75f4 (przeniesienie = 1)
  4. przesunięcie w prawo dla otrzymania adresu bajtowego = 0x3afa

W kroku 3 występuje przeniesienie, ponieważ arytmometr do argumentu dodaje B-modyfikację, która w zapisie U2 wygląda: 0xfff4. Jeśli procesor jest zmodyfikowany, to zapamiętane przeniesienie zostanie w ostatnim kroku użyte i wsunięte na najstarszą pozycję ostatecznego wyniku, dając w efekcie adres 0xbafa.

Należy więc zapewnić możliwość poprawnego uruchamiania również i takich programów na zmodyfikowanym procesorze, pod kontrolą systemu operacyjnego, który aktywował modyfikacje. Zostało to osiągnięte przez ustalenie następujących warunków, w których 17-bit adresowanie bajtów jest możliwe:

  • wykonywany jest program w trybie systemu operacyjnego (Q=0)
  • lub wykonowyany jest program w trybie użytkownika i nie jest ustawiony bit specjalny (BS=0)

Dzięki temu, dla programów (procesów), o których wiadomo było, że nie pracują poprawnie z 17-bit adresowaniem, system operacyjny może je dezaktywować, ustawiając przed przełączeniem kontekstu bit BS w rejestrze SR na 1. Takie zachowanie jest kompatybilne z oryginalnym procesorem, ponieważ na takim sprzęcie bit BS nie ma znaczenia, gdy wykonywany jest program w blokach użytkowych.

Realizacja techniczna

Ta modyfikacja jest jedną z najbardziej złożonych i obejmuje zmiany na pakietach P-P, P-R i P-A. Na pakiecie P-P wypracowywany jest sygnał -LRCBM mówiący o tym, że instrukcja LB, RB lub CB została wydana na procesorze z aktywnymi modyfikacjami.

Na pakiecie P-R znajduje się przerzutnik M16, w którym pamiętany jest 17. bit używany w adresowaniu bajtowym.

Taktowany jest on sygnałem +STROB1 w iloczynie z sygnałem +P4, mówiącym o tym, że procesor jest w stanie P4, w którym następuje pre- i B-modyfikacja argumentu normalnego. Na wejściu D pojawia się sygnał, który w rezultacie wpisuje do przerzutnika wartość -CARRY, gdy spełnione są wszystkie niezbędne warunki:

D = ~(CARRY & LRCBM & (~Q | ~BS))

czyli:

  • wydany został rozkaz LB, RB lub CB na procesorze z aktywną modyfikacją
  • procesor pracuje w trybie systemu operacyjnego (Q=0) lub bit specjalny jest wyzerowany (BS=0)

Zapamiętywana w przerzutniku wartość jest zanegowana, stąd bramka NOT (M55) na wyjściu.

Na wejście S (które w związku z negacją na wyjściu M53 jest efektywnie wejściem zerującym) podane są sygnały -P1 (stan, w którym odczytywany jest rozkaz) i -P5 (stan, w którym pobierany jest argument pośredni). Wystąpienie któregokolwiek z nich powoduje zapamiętanie "1", czyli efektywne wyzerowanie zawartości przerzutnika.

Ostatecznie sygnał +BAB17 niesie informację o 17 bicie powstałym w wyniku B-modyfikacji lub pre-modyfikacji argumentu normalnego rozkazów bajtowych:

BAB17 = CARRY & LRCBM & (~Q | ~BS)

Dzięki modyfikacji wprowadzonej na pakiecie P-A, wartość ta wsuwana jest z lewej strony do rejestru AT w chwili przesuwania jego zawartości podczas przygotowywania adresu słowa przy adresowaniu bajtowym:

Przerwanie programowe o wysokim priorytecie

System operacyjny CROOK wymaga istnienia przerwania programowego, którego priorytet byłby wyższy niż przerwań pochodzących z urządzeń zewnętrznych (kanałowych) i z zegara systemowego. W systemie przerwań MERY-400 takie przerwanie nie istnieje. Wersje systemu CROOK od 1 do 5 obchodziły ten problem następująco: W jądrze systemu używana jest pseudo-instrukcja SIN o kodzie (ósemkowo) 036000. Z punktu widzenia procesora jest to instrukcja niepoprawna, generująca przerwanie "nieprawidłowy rozkaz". Jednocześnie procedura obsługi tego przerwania w CROOK-u skonstruowana jest tak, aby w przypadku pseudo-rozkazu SIN zapewnić jego obsługę jak przerwania programowego o wysokim priorytecie. To obejście wykorzystywane jest we wszystkich wersjach systemu, aż do ostatniej rewizji CROOK-5.

Istnieje jednak alternatywne jądro CROOK-5 w rewizjach 7 i 8, potrafiące pracować z procesorem z dodanymi dwiema nowymi, legalnymi instrukcjami: SINT i SIND. Zastępują one funkcjonalnie pseudo-instrukcję SIN.

Na tę przeróbkę procesora składają się zmiany w kilku jego obszarach:

  1. W dekoderze rozkazów znaleziono "miejsce" na dwie nowe instrukcje: w grupie rozkazów bezargumentowych S (patrz: Skorowidz kodów rozkazów). Jest to jedyna grupa w obszarze rozkazów legalnych, gdzie część bitów kodu rozkazu nie jest w ogóle wykorzystana (odpowiednie linie dekodera rozkazów nie są użyte). Nowym rozkazom zostały nadane kody (ósemkowo):
    • SINT = 0166204
    • SIND = 0167204
  2. Przerwanie zegarowe (pozycja 5) zostało przeniesione na pozycję 11, w standardowym procesorze nie skojarzoną z żadnym źródłem przerwania.
  3. Przerwanie 5 zostało użyte jako przerwanie programowe o wysokim priorytecie, sterowane instrukcjami SINT i SIND.

Realizacja techniczna

Modyfikacja ma miejsce na pakiecie P-P. Oryginalne połączenie źródła przerwania zegarowego do przerzutnika M37 zostało przerwane. Przerwanie 11 nie ma w oryginalnym procesorze żadnego źródła, na wejściu S jest zawsze logiczna "1". Zmodyfikowany układ przerwań kieruje przerwanie zegarowe na przerzutnik M31 lub M37 w zależności od tego, czy modyfikacja procesora jest (odpowiednio) aktywna, czy nie.

Dodatkowo badana jest pozycja 13 rejestru rozkazu (+IR13) w iloczynie z sygnałem +(WX & SIN), oznaczającym stan WX dla grupy rozkazów SIN, SIT, SIL, CIT. Jest to "dekoder" rozkazów SINT i SIND, które ulokowane są w grupie ze wspomnianymi wcześniej rozkazami (rozkazy grupy S z polem A = "010"). Jeśli najstarszy bit pola C jest dla nich zapalony (IR13=1), to procesor zgłasza przerwanie 11.

Przeróbka ma tę drobną wadę, że jeśli modyfikacje procesora nie są aktywne, a wydana zostanie instrukcja SIND lub SINT, to zgłoszone zostanie nadmiarowe przerwanie zegarowe.

Należy też zauważyć, że instrukcje SINT i SIND nie są tak naprawdę osobnymi instrukcjami, a specjalnym przypadkiem instrukcji SIN, SIL, SIT, CIT, dla których ustawiony jest najstarszy bit pola C (ignorowany w niezmodyfikowanym procesorze). W efekcie, wydanie instrukcji SINT lub SIND oprócz zamierzonego efektu (zgłoszenie przerwania 11), będzie miało efekt dodatkowy, zależny od zawartości dwóch najmłodszych bitów pola C. Zgodnie z treścią rozkazów SIT, SIL, SIN, CIT, które te pola wykorzystują, zgłoszone lub wyzerowane zostaną przerwania 30 i/lub 31. W systemie CROOK instrukcje SINT i SIND mają pole C=100, a więc zgłoszeniu przerwania 11 towarzyszy wyzerowanie przerwań 30 i 31.

Zmiana maskowania przerwań

CROOK-5 ma jeszcze jedno wymaganie, które ostatecznie zostało spełnione za pomocą modyfikacji sprzętowej. Należało zapewnić, aby w trakcie obsługi przerwania kanałowego nie pojawiło się przerwanie o wyższym priorytecie (w szczególności zegarowe). W procesorze bez przeróbek wymuszane to było przez programowe maskowanie przerwań na początku procedury obsługi przerwań kanałowych. W procesorze przerobionym zrealizowane to było sprzętowo: Przyjęcie przerwania kanałowego powodowało automatyczne zamaskowanie przerwań od 5 do 31.

Realizacja techniczna

Modyfikacja została wprowadzona na pakiecie P-P. W niezmodyfikowanym procesorze, na podstawie przyjętych przerwań, sygnały +ZI4 - +ZI7 maskują odpowiednie grupy przerwań.

Jeśli modyfikacja procesora jest aktywna, sygnał +ZI8, oprócz swojej pierwotnej funkcji, powoduje też zamaskowanie przerwań w grupach 4, 5, 6 i 7.

Reakcja procesora na brak pamięci

Uwaga: Na istnienie poniższej zmiany silnie wskazuje analiza zawartości kości EPROM pamięci MEGA oraz inne zmiany w procesorze MX-16, jednak nie została ona definitywnie potwierdzona.

Ponieważ MX-16 nie był wyposażony w pulpit techniczny, konieczna była zmiana w sposobie, w jaki procesor reaguje na odwołanie do nieskonfigurowanego segmentu pamięci w obszarze systemowym. Oryginalny procesor przechodził w stan STOP, z którego można go było wybudzić jedynie kluczem START/STOP. W MX-16 nie było takiej możliwości, więc obsługa takiego przypadku musiała być w pełni programowa i ograniczać się do zgłoszenia przerwania, podobnie jak w przypadku błędów dostępu do pamięci programów użytkowych.

Realizacja techniczna

Zostało to osiągnięte nie tyle przez modyfikację, co rekonfigurację procesora. Na pakiecie P-X istnieje zwora S-R (nie opisana w dokumentacji), która decyduje o tym, czy w opisanym wyżej przypadku wymuszany jest stan STOP. W komputerach MX-16 była ona najprawdopodobniej rozwarta.

Połączenia na platerze procesora

Poza zmianami wprowadzonymi na samych pakietach, powstały też nowe połączenia na platerze procesora:

Z DO Sygnał
Pakiet Piórko Pakiet Piórko
P-D B48 P-P B68 +CRON
P-P B40 P-R  B38 -LRCBM
P-P B55 P-D A45 -LRCB
P-P B60 P-M A07 -P2
P-P B68 P-D B48 +CRON
P-P B70 P-M B52 +IR13
P-R B35 P-A B70 +BAB17
P-R B36 P-M A29 -P1
P-R B37 P-M B55 -P5
P-R B38 P-P B40 -LRCBM
P-R B51 P-D A77 -P4
P-A B70 P-R B35 +BAB17
P-A B72 P-M A12 -PON
P-A B92 ME-GA-400 W48 +BOOTL


Źródło: Opracowanie własne