Program sprawdza i wyświetla podstawowe informacje o konfiguracji sprzętowej Amigi, podczas
jej uruchamiania z dyskietki (lub obrazu ADF w emulatorze stacji dyskietek). Został napisany
w asemblerze i skompilowany za pomocą "ASM-One 1.44".
Do prawidłowego działania wymaga Kickstartu 1.1 (31.34) lub nowszego, ponieważ używa bitu
nr 0 (AFB_68010) z flag AttnFlags biblioteki Exec do ustalenia, czy zainstalowany procesor to
68000 lub 68010+. Na starszych Kickstartach 0.7/1.0 program zadziała tylko, gdy rejestr VBR=0
dla procesorów 68010+, ale każdy procesor zostanie wykryty jako "68000", a FPU w procesorze
68060 nie zostanie wykryty (napis "NONE"), jeśli jest programowo wyłączony (bit DFP=1 w reje-
strze PCR). Wynika to z tego, że te Kickstarty nie rozpoznają procesorów innych niż 68000
(bit AFB_68010 ma zawsze wartość 0).
Używa podstawowych funkcji systemowych z bibliotek Exec/DOS/Intuition oraz opracowanych
przeze mnie nisko-poziomowych procedur. Wykrywają one poszczególne komponenty przez:
programową obsługę wyjątków procesora (CPU/FPU), odczyt wartości identyfikacyjnej z rejestru
VPOSR (GFX), odczyt wersji/rewizji z pamięci Kickstart (ROM) oraz odczyt wartości zwracanych
przez funkcję systemową (CHIP/FAST). Wyświetlane o Amidze informacje obejmują:
CPU - model procesora z rodziny 680x0: "68000", "68010", "68020" (68EC020), "68030" (68EC030), "68040"
(68EC040/68LC040), "68060" (68EC060/68LC060). W przypadku procesora 68060 zostanie też podana jego
wersja: "68060" - pełna (zawiera FPU i MMU) lub "XX060" - EC (bez FPU i MMU)/LC (bez FPU) oraz rewizja
"(rev X)". Dodatkowe informacje o procesorze 68060 pochodzą z jego rejestru PCR.
FPU - model koprocesora matematycznego z rodziny 6888x: zewnętrzny "68881"/"68882" lub wewnętrzny,
wbudowany w procesor 68040 - "IN040"/68060 - "IN060". FPU w procesorze 68060 zostanie wykryty, nawet
jeśli jest programowo wyłączony (bit DFP=1 w rejestrze PCR). W przypadku braku koprocesora matematy-
cznego zostanie wyświetlony napis "NONE".
GFX - model układu graficznego: "OCS"/"ECS"/"AGA" oraz standard jego pracy: "(PAL)"/"(NTSC)".
Informacje o układzie graficznym Denise/Lisa pochodzą z rejestru VPOSR układu Agnus/Alice.
ROM - wersja Kickstartu od "1.2 (33.166)" do "3.1 (40.72)", ustalana na podstawie zapisanej w nim wersji
($Fx000C, 16-bit version) i rewizji ($Fx000E, 16-bit revision). Najstarsze Kickstarty 0.7/1.0/1.1 zostaną
rozpoznane jako "1.x ()", natomiast nowsze (43+) jako "3.x (vv.rr)" z wersją i rewizją podaną w nawiasie.
Kickstart 1.2.1 (34.4) zostanie rozpoznany jako "1.3 (34.4)", a Kickstart 3.5 (40.71) jako "3.1 (40.71)".
Wyświetlona wersja Kickstartu może nie być tą, która jest aktualnie używana przez system Amigi.
Zwłaszcza, jeśli Kickstart został załadowany (relokowany/remapowany) do pamięci RAM przez program
(np. ReKick, SKick), funkcję maprom/fastrom karty turbo lub jednostkę zarządzania pamięcią (MMU).
CHIP / FAST - ilość dostępnej wolnej pamięci RAM wyrażona w "kB" (maksymalnie 4194303 kB),
podana oddzielnie dla pamięci CHIP współdzielonej z chipsetem (m.in. układ graficzny) oraz dla
pamięci FAST (lub SLOW), do której procesor ma bezpośredni i dzięki temu szybszy dostęp.
Program uruchamia się z bootbloku dyskietki (pierwsze 1024-bajty) i powinien działać na każdej
Amidze. Kompilację najlepiej przeprowadzić przy użyciu kompilatora "ASM-One 1.44", który od razu
umożliwi zapisanie programu w bootbloku dyskietki, wraz z prawidłową sumą kontrolną (checksum).
W tym celu uruchamiamy "ASM-One" i wpisujemy "c"+enter, aby wybrać pamięć typu CHIP, w której
zostanie zarezerwowany bufor roboczy dla kompilatora. Następnie podajemy rozmiar tego bufora
w [kB], wpisując np. "100"+enter. Wpisujemy "r"+enter i w oknie wyboru, wskazujemy plik z kodem
źródłowym programu "BasicDiag.s". Po załadowaniu kodu źródłowego wpisujemy "a"+enter, aby
rozpocząć kompilację, która powinna zakończyć się bez żadnych błędów (komunikat "No Errors").
Teraz wkładamy dyskietkę, na której chcemy zapisać program i wpisujemy kolejno: "ws"+enter,
"Boot"+enter, "0"+enter, "2"+enter. Na koniec wpisujemy "cc"+enter, co spowoduje obliczenie
i zapisanie na dyskietce sumy kontrolnej jej bootbloku.
Po uruchomieniu programu z dyskietki pojawi się czarny ekran otoczony migającą ramką, wewnątrz
krórej zostaną wyświetlone informacje diagnostyczne. W zależności od wersji Kickstartu kolor tekstu
i ramki może być czerwony, pomarańczowy lub zielony. Aby zamknąć ekran programu i kontynuować
bootowanie z dyskietki (uruchomienie CLI startowego), należy nacisnąć lewy przycisk myszki. Naci-
śnięcie prawego przycisku myszki, spowoduje zresetowanie Amigi.
Program testowałem na mojej Amidze 500/600 oraz pod emulatorem "WinUAE" na Amigach,
o różnych konfiguracjach sprzętowych z prawie każdym obsługiwanym Kickstartem. Nie zauwa-
żyłem żadnych błędów/problemów w działaniu programu, ale w razie ich wystąpienia można
pisać na mój e-mail. Poniżej znajduje się kod źródłowy programu.
Boot:
dc.l $444F5300,0,880 ;napis "DOS" + bajt flag, suma kontrolna bootbloku, numer głównego bloku
;dyskietki. Bajt flag zawiera parametry dyskietki (bity 76543210):
; 0 - File System: 0=OFS (Old), 1=FFS (Fast)
; 1 - International Mode: 0=OFF, 1=ON
; 2 - Directory Cache & International Mode: 0=OFF, 1=ON
;Pozostałe bity (3-7) mają wartość 0.
movem.l A2-A6/D2-D7,-(A7)
jsr -132(A6) ;blokuje multitasking (funkcja Exec:Forbid)
lea Diag(pc),A5 ;adres procedury, która zostanie wykonana w trybie nadzorcy
jsr -30(A6) ;włącza tryb nadzorcy i wykonuje procedurę (funkcja Exec:Supervisor)
jsr -138(A6) ;odblokowuje multitasking (funkcja Exec:Permit)
lea INTn(pc),A1 ;nazwa biblioteki Intuition
jsr -408(A6) ;otwiera bibliotekę Intuition (funkcja Exec:OldOpenLibrary)
tst.l D0
beq.s Error ;nie otwarto biblioteki Intuition
move.l D0,A6 ;adres bazowy biblioteki Intuition
lea Text(pc),A0 ;adres tekstu do wyświetlenia
moveq #0,D0 ;kod błędu
move.l #201,D1 ;wysokość ramki komunikatu "Recoverable Alert"
jsr -90(A6) ;wyświetlenie komunikatu (funkcja Intuition:DisplayAlert)
move.l A6,A1 ;adres bazowy biblioteki Intuition
move.l 4.w,A6 ;adres bazowy biblioteki Exec
;Sprawdzanie, który przycisk myszki został naciśnięty
tst.l D0
bne.s Boot0
;Naciśnięto prawy przycisk myszki (reset)
lea Reset(pc),A5 ;adres procedury, która zostanie wykonana w trybie nadzorcy
jsr -30(A6) ;włącza tryb nadzorcy i wykonuje procedurę (funkcja Exec:Supervisor)
Reset:
move.l #$1000000,A0 ;adres za obszarem Kickstartu
sub.l -20(A0),A0 ;adres początku Kickstartu 256/512kB ($FC0000/$F80000)
move.l 4(A0),A0 ;początkowa wartość rejestru PC odczytana z Kickstartu
subq.l #2,A0 ;adres instrukcji RESET i reszty kodu startowego w Kickstarcie
reset ;wykonanie pierwszej instrukcji RESET
jmp (A0) ;skok do drugiej instrukcji RESET i reszty kodu startowego w Kickstarcie
;Naciśnięto lewy przycisk myszki (boot)
Boot0:
jsr -414(A6) ;zamyka bibliotekę Intuition (funkcja Exec:CloseLibrary)
lea DOSn(pc),A1 ;nazwa biblioteki DOS
jsr -96(A6) ;szuka modułu rezydentnego biblioteki DOS (funkcja Exec:FindResident)
tst.l D0
beq.s Error ;nie znaleziono modułu rezydentnego biblioteki DOS
move.l D0,A0
move.l $16(A0),A0 ;adres kodu inicjalizującego bibliotekę DOS
moveq #0,D0 ;powrót z bootbloku i wykonanie kodu o adresie w rejestrze A0
Exit:
movem.l (A7)+,A2-A6/D2-D7
rts
Error:
moveq #$FF,D0 ;powrót z bootbloku i wyświetlenie komunikatu "Recoverable Alert"
bra.s Exit
INTn: dc.b "intuition.library",0
DOSn: dc.b "dos.library",0
;##### Sprawdzanie modelu procesora (CPU)
Diag: ;procedura wykonywana przez funkcję Exec:Supervisor
move.l A7,A3 ;zapamiętanie wskaźnika stosu (A7=SSP)
moveq #0,D5 ;znacznik obecności FPU w procesorze 68060 (brak)
lea Text0(pc),A4
moveq #$30,D1 ;procesor 68000
moveq #$2C,D3
move.l D3,A2
btst #0,297(A6) ;wartość bitu określa procesor: 0=68000, 1=68010 lub nowszy (bit ten wchodzi
;w skład flag AttnFlags, wypełnianych przez bibliotekę Exec podczas startu Amigi).
beq.s Diag04 ;procesor 68000
;W tym miejscu procesor to 68010 lub nowszy
dc.l $4E7A3801 ;MOVEC VBR,D3 - instrukcja przenosi wartość rejestru VBR do rejestru D3.
;Jest obsługiwana przez procesory 68010/20/30/40/60.
moveq #$10,D2
move.l D2,A1
add.l D3,A1
move.l (A1),D2 ;wektor wyjątku nr 4 (Illegal Instruction), który wystąpi
;gdy procesor natrafi na kod nieobsługiwanej instrukcji.
lea Diag03(pc),A0
move.l A0,(A1) ;zmiana wektora wyjątku nr 4
add.l D3,A2
move.l (A2),D3 ;wektor wyjątku nr 11 (Line 1111 Emulator), który wystąpi gdy procesor
;natrafi na kod nieobsługiwanej instrukcji, rozpoczynający się słowem $Fnnn.
lea Diag02(pc),A0
move.l A0,(A2) ;zmiana wektora wyjątku nr 11
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.
;Przenosi wartość rejestru ITT0 (68040, 68LC040, 68060,
;68EC060, 68LC060)/IACR0 (68EC040) do rejestru D1.
moveq #$34,D1 ;procesor 68040
dc.l $4E7A1808 ;MOVEC PCR,D1 - instrukcja obsługiwana przez 68060
lea Text7(pc),A0
addq.l #3,A4
bsr.s Write
subq.l #2,A4
move.w D1,D4
ror.w #8,D4
add.b #$30,D4
move.b D4,(A4) ;numer rewizji procesora
subq.l #8,A4
btst #16,D1 ;wartość bitu określa wersję procesora: 0=68060, 1=68EC060/68LC060
beq.s Diag00 ;procesor 68060 w pełnej wersji
subq.l #3,A4 ;procesor 68060 w wersji LC (bez FPU)/EC (bez FPU i MMU)
move.w #"XX",(A4)+ ;68060 może zapisywać słowo pod nieparzysty adres
addq.l #1,A4
bra.s Diag01
Diag00:
moveq #$FF,D5 ;znacznik obecności FPU w procesorze 68060 (jest)
Diag01:
moveq #$36,D1 ;procesor 68060
Diag02: ;kod obsługi wyjątku nr 11 (tylko dla 68020)
move.l D2,(A1) ;przywrócenie wektora wyjątku nr 4
move.l A3,A7 ;przywrócenie wskaźnika stosu (A7=SSP)
bra.s Diag05
Diag03: ;kod obsługi wyjątku nr 4
cmp.b #$32,D1
bne.s Diag02
;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)/ACUSR (68EC030).
;Na procesorze 68020 powoduje wystąpienie wyjątku nr 11.
moveq #$33,D1 ;procesor 68030
bra.s Diag02
;##### Sprawdzanie modelu koprocesora matematycznego (FPU)
Diag04:
move.l (A2),D3 ;wektor wyjątku nr 11 (Line 1111 Emulator), który wystąpi gdy procesor
;natrafi na kod nieobsługiwanej instrukcji, rozpoczynający się słowem $Fnnn
;(prawidłowy tylko dla 68000).
Diag05:
move.b D1,(A4) ;wartość określa model procesora: $30-$36=68000-68060
lea Diag07(pc),A0
move.l A0,(A2) ;zmiana wektora wyjątku nr 11
;Sprawdzenie obecności FPU w procesorze 68060
tst.l D5 ;znacznik obecności FPU w procesorze 68060
bne.s Diag06 ;FPU jest w procesorze 68060 (może być wyłączony)
moveq #0,D1 ;brak koprocesora
dc.l $F201583A ;FTST.B D1 - instrukcja testuje najmłodszy bajt w rejestrze D1 procesora
;(zapobiega wygenerowaniu ramki NULL przez instrukcję FSAVE).
;Jeśli nie ma zainstalowanego FPU, powoduje wystąpienie wyjątku nr 11.
dc.w $F327 ;FSAVE -(A7) - instrukcja odkłada na stos (A7=SSP) ramkę ze stanem FPU
move.l A3,D2
sub.l A7,D2 ;rozmiar ramki odłożonej przez instrukcję FSAVE
moveq #5,D1 ;koprocesor 68881
cmp.b #$1C,D2 ;ramka IDLE
beq.s Diag07
moveq #11,D1 ;koprocesor 68882
cmp.b #$3C,D2 ;ramka IDLE
beq.s Diag07
moveq #17,D1 ;koprocesor wbudowany w 68040
cmp.b #4,D2 ;ramka IDLE
beq.s Diag07
bra.s Diag06
Write: move.b (A0)+,(A4)+
tst.b (A0)
bne.s Write
rts
Diag06:
moveq #23,D1 ;koprocesor wbudowany w 68060
Diag07: ;kod obsługi wyjątku nr 11 (tylko jeśli nie ma FPU)
move.l D3,(A2) ;przywrócenie wektora wyjątku nr 11
move.l A3,A7 ;przywrócenie wskaźnika stosu (A7=SSP)
lea Text8(pc),A0
lea Text1(pc),A4
add.l D1,A0 ;wartość określa model FPU: 0=brak, 5=68881, 11=68882, 17=68040, 23=68060
bsr.s Write
;##### Sprawdzanie modelu układu graficznego (GFX)
moveq #0,D1
move.w $DFF004,D1 ;odczyt rejestru VPOSR z układu Agnus/Alice
lsr.w #8,D1
bclr #7,D1 ;wyodrębnienie wartości identyfikacyjnej
lea TextA(pc),A0
lea Text3(pc),A4
btst #4,D1 ;wartość bitu określa standard układu: 0=PAL, 1=NTSC
beq.s Diag08 ;standard PAL
addq.l #5,A0
sub.b #$10,D1
Diag08:
bsr.s Write
lea Text9(pc),A0
lea Text2(pc),A4
tst.b D1
beq.s Diag09 ;układ OCS
sub.b #$20,D1
lsr.b #1,D1
rol.b #2,D1
add.l D1,A0 ;wartość określa model układu: 0=ECS, 4=AGA
addq.l #4,A0
Diag09:
bsr.s Write
;##### Sprawdzanie wersji Kickstartu (ROM)
move.l #$1000000,A0 ;adres za obszarem Kickstartu
sub.l -20(A0),A0 ;adres początku Kickstartu 256/512kB ($FC0000/$F80000)
move.w 12(A0),D2 ;wersja Kickstartu
move.w 14(A0),D3 ;rewizja Kickstartu
cmp.w #$FFFF,D2
beq.s Diag13 ;Kickstart 1.x (0.7/1.0/1.1)
lea Text4(pc),A4
moveq #$21,D1
cmp.w D1,D2
beq.s Diag11 ;Kickstart 1.2
moveq #$31,D1
cmp.w #$22,D2
beq.s Diag11 ;Kickstart 1.3 (1.2.1)
moveq #$02,D1
cmp.w #$24,D2
bne.s Diag10
cmp.w #$10,D3
bhi.s Diag11 ;Kickstart 2.0
moveq #$41,D1
bra.s Diag11 ;Kickstart 1.4
Diag10:
cmp.w #$25,D2
beq.s Diag11 ;Kickstart 2.0
moveq #$03,D1
cmp.w #$27,D2
beq.s Diag11 ;Kickstart 3.0
moveq #$13,D1
cmp.w #$28,D2
beq.s Diag11 ;Kickstart 3.1 (3.5)
addq.b #2,(A4)
addq.l #5,A4
bra.s Diag12 ;Kickstart 3.x
Diag11:
lsl.w #4,D1
ror.b #4,D1
add.w #$3030,D1
move.b D1,(A4)
ror.w #8,D1
addq.l #2,A4
move.b D1,(A4)
addq.l #3,A4
Diag12:
bsr.s ConWD
move.b #".",(A4)+
move.w D3,D2
bsr.s ConWD
move.b #")",(A4)
Diag13:
;##### Sprawdzanie dostępnej wolnej pamięci RAM (CHIP, FAST)
moveq #2,D1 ;pamięć CHIP
jsr -216(A6) ;ustala liczbę bajtów wolnej pamięci (funkcja Exec:AvailMem)
lea Text5(pc),A4
bsr.s Con24D
moveq #4,D1 ;pamięć FAST
jsr -216(A6) ;ustala liczbę bajtów wolnej pamięci (funkcja Exec:AvailMem)
lea Text6(pc),A4
bsr.s Con24D
rte ;powrót z funkcji Exec:Supervisor
;Konwersja 2-bajtów z rejestru D2 do systemu DEC-ASCII (nieznaczące zera są pomijane)
ConWD: moveq #$30,D1
move.l #$2710,D4
ConWD0: move.b #$2F,(A4)
ConWD1: addq.b #1,(A4)
sub.w D4,D2
bcc.s ConWD1
add.w D4,D2
cmp.b (A4),D1
beq.s ConWD2
moveq #0,D1
addq.l #1,A4
ConWD2: divu #$0A,D4
bne.s ConWD0
cmp.b #$20,(A4)
beq.s ConWD3
addq.l #1,A4
ConWD3: rts
;Konwersja 24-bitów (maks. $98967F) z rejestru D0 do systemu DEC-ASCII (nieznaczące zera są pomijane)
Con24D: lsr.l #8,D0
lsr.l #2,D0 ;dzielenie liczby bajtów pamięci przez 1024 (wynik w kB)
moveq #$30,D1
move.l #$0F4240,D2
move.l #$0927C0,D3
Con24D0: move.b #$2F,(A4)
Con24D1: addq.b #1,(A4)
sub.l D2,D0
bcc.s Con24D1
add.l D2,D0
cmp.b (A4),D1
beq.s Con24D2
moveq #0,D1
addq.l #1,A4
Con24D2: sub.l D3,D2
divu #$0A,D3
lsr.l #2,D2
tst.b D2
bne.s Con24D0
;Generowanie napisu "kB"
cmp.b #$20,(A4)+
beq.s Con24D3
addq.l #1,A4
Con24D3: move.b #"k",(A4)+
move.b #"B",(A4)
rts
Text: dc.b 0,20,20,"BasicDiag 1.07 (14.06.2025) by RomanWorkshop",0,1,0,20,30,0,1,0,20,40,"CPU: 680"
Text0: dc.b "x0 ",0,1,0,20,50,"FPU: "
Text1: dc.b "xxxx ",0,1,0,20,60,"GFX: "
Text2: dc.b "xxx ("
Text3: dc.b "xxxx ",0,1,0,20,70,"ROM: "
Text4: dc.b "1.x () ",0,1,0,20,90,"CHIP: "
Text5: dc.b "x ",0,1,0,20,100,"FAST: "
Text6: dc.b "x ",0,1,0,20,150,"LMB - boot, RMB - reset",0,0
Text7: dc.b "(rev x)",0
Text8: dc.b "NONE",0,"68881",0,"68882",0,"IN040",0,"IN060",0
Text9: dc.b "OCS",0,"ECS",0,"AGA",0
TextA: dc.b "PAL)",0,"NTSC)",0
END
;Konwersja 4-bajtów z rejestru D0 do systemu DEC-ASCII (nieznaczące zera są pomijane)
ConLD: lsr.l #8,D0
lsr.l #2,D0 ;dzielenie liczby bajtów pamięci przez 1024 (wynik w kB)
moveq #$30,D1
lea ConLD4(pc),A1
ConLD0: move.b #$2F,(A4)
ConLD1: addq.b #1,(A4)
sub.l (A1),D0
bcc.s ConLD1
add.l (A1)+,D0
cmp.b (A4),D1
beq.s ConLD2
moveq #0,D1
addq.l #1,A4
ConLD2: tst.b (A1)
bpl.s ConLD0
;Generowanie napisu "kB"
cmp.b #$20,(A4)+
beq.s ConLD3
addq.l #1,A4
ConLD3: move.b #"k",(A4)+
move.b #"B",(A4)
rts
ConLD4: dc.l 1000000000,100000000,10000000,1000000,100000,10000,1000,100,10,1
dc.b $80
;Rozmiar: 964 B, linii kodu: 251