Poniżej znajduje się kod źródłowy programu BasicDiag, który sprawdza konfigurację sprzętową Amigi
i wyświetla informacje o jej podstawowych elementach:
Model procesora (CPU) z rodziny 680x0: "68000", "68010", "68020" (68EC020), "68030" (68EC030), "68040"
(68EC040/68LC040), "68060" (68EC060/68LC060). W przypadku procesora 68060 jest wyświetlana jego wersja:
"68060" - pełna (zawiera FPU i MMU), "XX060" - EC (bez FPU i MMU) lub LC (bez FPU), a także jego rewizja "(rev X)".
Model koprocesora matematycznego (FPU) z rodziny 6888x: zewnętrzny "68881", "68882" lub wewnętrzny,
wbudowany w procesor 68040 - "IN040", 68060 - "IN060". W przypadku braku koprocesora matematycznego jest
wyświetlany napis "NONE".
Model układu graficznego (GFX): "OCS", "ECS", "AGA" oraz standard jego pracy "(PAL)" lub "(NTSC)".
Wersja Kickstartu (ROM): od "1.2 (33.166)" do "3.1 (40.72)". Starsze Kickstarty (0.7, 1.0, 1.1) zostaną rozpoznane
jako "Kickstart 1.x (xx.x)", natomiast nowsze (43+) jako "Kickstart 3.x (vv.rr)" z wersją i rewizją podaną w nawiasie.
Kickstart 1.2.1 (34.4) zostanie rozpoznany jako "Kickstart 1.3 (34.4)". Kickstart 3.5 (40.71) zostanie rozpoznany jako
"Kickstart 3.1 (40.71)".
Ilość dostępnej wolnej pamięci RAM: wyrażona w "kB", oddzielnie dla pamięci CHIP współdzielonej z chipsetem
(m.in. układy graficzne) 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 Ami-
dze. 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 zare-
zerwowany 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ę ekran otoczony migającą ramką z tekstem w środku.
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.
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
sub.l -20(A0),A0 ;adres początku Kickstartu
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 Txt00(pc),A4
moveq #$30,D1 ;procesor 68000
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
move.l D3,A2
moveq #$2C,D3
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 Txt07(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)
moveq #"X",D4
move.b D4,(A4)+
move.b D4,(A4)+
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:
moveq #$2C,D3
move.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
;(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
bra.s Diag07
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 Txt08(pc),A0
lea Txt01(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 Txt10(pc),A0
lea Txt03(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 Txt09(pc),A0
lea Txt02(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.w $F8000C,D2 ;odczyt wersji Kickstartu
move.w $F8000E,D3 ;odczyt rewizji Kickstartu
moveq #$F1,D1
cmp.w #$FFFF,D2
beq.s Diag11 ;Kickstart 1.x
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
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
moveq #$F3,D1 ;Kickstart 3.x
Diag11:
lsl.w #4,D1
ror.b #4,D1
add.w #$3030,D1
lea Txt04(pc),A4
move.b D1,(A4)
ror.w #8,D1
addq.l #2,A4
cmp.b #$2F,D1
bne.s Diag12
cmp.w #$312F,D1
beq.s Diag14 ;Kickstart 1.x
bra.s Diag13 ;Kickstart 3.x
Diag12:
move.b D1,(A4)
Diag13:
addq.l #3,A4
bsr.s ConWD
move.w D3,D2
addq.l #1,A4
bsr.s ConWD
move.b #")",(A4)
Diag14:
;##### 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 Txt05(pc),A4
bsr.s ConLD
moveq #4,D1 ;pamięć FAST
jsr -216(A6) ;ustala liczbę bajtów wolnej pamięci (funkcja Exec:AvailMem)
lea Txt06(pc),A4
bsr.s ConLD
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
rts
;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
Text: dc.b 0,20,20,"BasicDiag 1.05 (20.11.2018) by RomanWorkshop",0,1,0,20,30,0,1,0,20,40,"CPU: 680"
Txt00: dc.b "x0 ",0,1,0,20,50,"FPU: "
Txt01: dc.b "xxxx ",0,1,0,20,60,"GFX: "
Txt02: dc.b "xxx ("
Txt03: dc.b "xxx ",0,1,0,20,70,"ROM: Kickstart "
Txt04: dc.b "x.x (xx.x) ",0,1,0,20,90,"CHIP: "
Txt05: dc.b "x ",0,1,0,20,100,"FAST: "
Txt06: dc.b "x ",0,1,0,20,150,"LMB - boot, RMB - reset",0,0
Txt07: dc.b "(rev x)",0
Txt08: dc.b "NONE",0,"68881",0,"68882",0,"IN040",0,"IN060",0
Txt09: dc.b "OCS",0,"ECS",0,"AGA",0
Txt10: dc.b "PAL)",0,"NTSC)",0
;Rozmiar: 988 B, linii kodu: 250