Asembler procesora 68000 Działa w systemie Workbench     BasicDiag 1.04           Kompilacja


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 beta, 1.0, 1.1) zostaną rozpoz-
nane jako "Kickstart 1.x (xx.x)", natomiast nowsze (43+) jako "Kickstart 3.x (vv.rr)" z wersją i rewizją podaną w nawiasie.
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 lub prawy przycisk myszki.

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 tekstu (funkcja Intuition:DisplayAlert)
 move.l   A6,A1        ;adres bazowy biblioteki Intuition
 move.l   4.w,A6       ;adres bazowy biblioteki Exec
 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.04 (16.04.2017) 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,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: 928 B, linii kodu: 240