Zainteresowało mnie w jaki sposób można sprawdzić model procesora 680x0 zainstalowanego w Amidze. Najpierw próbowałem deasemblować systemowe polecenie CPU, ale dałem sobie z nim spokój, bo i tak nie rozpoznaje procesora 68060, a kodu jest w nim dosyć dużo. Później przyszła kolej na bootblock gry "Wacuś the Detective". Kod w nim zawarty jest krótki i rozpoznaje każdy procesor rodziny 680x0, ale korzysta z procedur systemu, a ja chciałem otrzymać kod, jak najbardziej niezależny od platformy sprzętowej. Więc wziąłem się do roboty i... W oparciu o to, co udało mi się znaleźć w internecie, napisałem poniższą procedurę.
CPUmodel:
move.l $10,A1
;Wektor wewnętrznego wyjątku procesora nr 4 (Illegal Instruction). Zawiera on adres kodu, który ma być
;wykonany po wystąpieniu tego wyjątku. Wyjątek nr 4 wystąpi, gdy procesor natrafi na kod nieobsługiwanej
;instrukcji.
lea
CPUmodel0(pc),A0
move.l A0,$10 ;zmiana adresu wektora wyjątku nr 4
move.l $2C,A2
;Wektor wewnętrznego wyjątku procesora nr 11 (Line 1111 Emulator). Zawiera on adres kodu, który ma być
;wykonany po wystąpieniu tego wyjątku. Wyjątek nr 11 wystąpi, gdy procesor natrafi na kod nieobsługiwanej
;instrukcji, rozpoczynający się słowem $Fnnn.
lea
CPUmodel2(pc),A0
move.l A0,$2C ;zmiana adresu wektora wyjątku nr 11
dc.w $4AFC ;ILLEGAL - instrukcja wywołująca wyjątek nr 4 na każdym procesorze z rodziny 680x0
CPUmodel0: ;kod obsługi wyjątku nr 4
;W tym miejscu procesor pracuje w trybie "nadzorcy" (Supervisor mode) i korzysta z oddzielnego stosu
;oraz jego wskaźnika (rejestr A7=SSP). Na stosie tym znajdują się odłożone wartości rejestrów SR i PC,
;jakie miały one przed wystąpieniem wyjątku.
move.l A7,D2 ;zapamiętanie adresu wskaźnika stosu (A7=SSP)
lea
CPUmodel3(pc),A0
move.l A0,$02(A7) ;modyfikacja wartości rejestru PC, odłożonego na stosie
lea
CPUmodel1(pc),A0
move.l A0,$10 ;zmiana adresu wektora wyjątku nr 4
moveq #$30,D1 ;procesor 68000
dc.l $4E7A1801 ;MOVEC VBR,D1 - instrukcja obsługiwana przez 68010/20/30/40/60
moveq #$31,D1 ;procesor 68010
dc.l $4E7A1002 ;MOVEC CACR,D1 - instrukcja obsługiwana przez 68020/30/40/60
moveq #$32,D1 ;procesor 68020/68030
dc.l $4E7A1004 ;MOVEC ITT0,D1 - instrukcja obsługiwana przez 68040/60
moveq #$34,D1 ;procesor 68040
dc.l $4E7A1808 ;MOVEC PCR,D1 - instrukcja obsługiwana przez 68060
moveq #$36,D1 ;procesor 68060
rte ;powrót z wyjątku
CPUmodel1: ;kod obsługi wyjątku nr 4
cmp.b #$32,D1
bne.s
CPUmodel2
;rozpoznawanie procesora 68020/68030
dc.w $F02F,$6200,$FFFE
;PMOVE.W PSR,-2(A7) - instrukcja odkłada na stos (A7=SSP) wartość rejestru MMUSR (68030)
;lub ACUSR (68EC030). Na procesorze 68020 powoduje wystąpienie wyjątku nr 11.
moveq #$33,D1 ;procesor 68030
CPUmodel2: ;(kod obsługi wyjątku nr 11 dla procesora 68020)
move.l D2,A7 ;przywrócenie adresu wskaźnika stosu (A7=SSP)
rte ;powrót z wyjątku
;Po wykonaniu instrukcji RTE wartości rejestrów SR i PC, są przywracane ze stosu. Przywrócony rejestr SR
;wyłącza tryb "nadzorcy" (Supervisor mode). Przywrócony rejestr PC zawiera adres kodu, który zostanie
;wykonany po powrocie z wyjątku.
CPUmodel3:
move.l A1,$10 ;przywrócenie adresu wektora wyjątku nr 4
move.l A2,$2C ;przywrócenie adresu wektora wyjątku nr 11
lea
textbuf,A0 ;adres wyjścia danych
lea
CPUmodel5(pc),A1
CPUmodel4:
move.b (A1)+,(A0)+
bne.s
CPUmodel4
subq.l #3,A0
move.b D1,(A0) ;wartość określająca model procesora: $30-$36 = model 68000-68060.
rts
CPUmodel5:
dc.b "680x0",0
;Rozmiar: 138 B, linii kodu: 38
Procedura działa prawidłowo tylko wtedy, gdy wartość rejestru VBR=0 (nie dotyczy to procesora 68000, który nie posiada tego rejestru). Procedurę testowałem fizycznie tylko na procesorze 68000 (mam A500 i A600), resztę procesorów sprawdzałem na emulatorze "WinUAE 2.4.1". Tylko na emulatorze "WinFellow 0.4.4 build 4" procesor 68030 jest rozpoznawany jako 68020 (moim zdaniem jest to błąd w emulacji, a właściwie brak emulacji instrukcji PMOVE.W PSR,-2(A7)).
W każdym razie procedura jest mała, szybka, niezależna od systemu i może się komuś przydać. Czekam na uwagi, komentarze, a może ktoś ma lepszy kod sprawdzający model procesora 680x0. Bardziej przejrzystą wersję kodu tej procedury, a także inne procedury w asemblerze 68000 można znaleźć na mojej stronie
romanworkshop.zz.mu
Ostatnia aktualizacja: 24.05.2013 22:07:24 przez RomanWorkshop