Asembler procesora 68000     Różne procedury      Kompilacja


NAZWA
OPIS
ARGUMENTY
WEJŚCIOWE
WYJŚCIE
DANYCH
LenStrLiczenie znaków w ciągu ASCIIZtextbufD1.l
DelZeroUsuwanie zbędnych zer z wartości ASCIIZtextbuftextbuf
ClrZeroZamienianie zbędnych zer w wartości ASCIIZ na spacjetextbuftextbuf
CPUmodel Generowanie ciągu ASCIIZ z modelem procesora (680x0)-textbuf
FPUmodel Generowanie ciągu ASCIIZ z modelem koprocesora (6888x) -textbuf
RegCCRGenerowanie ciągu ASCIIZ z wartościami flag rejestru CCRCCRtextbuf

Objaśnienia:
D1.l - cały rejestr danych (32-bity)
CCR - rejestr kodów warunkowych (Condition Code Register)
textbuf - pamięć dla danych wejściowych/wyjściowych (RAM)


 LenStr: lea      textbuf,A0 ;adres wejścia danych
         moveq    #$FF,D1
LenStr0: addq.l   #1,D1      ;liczba znaków (maks. 4294967295)
         tst.b    (A0)+
         bne.s    LenStr0
         rts

;Rozmiar: 16 B, linii kodu: 6

LenStr: lea textbuf,A0 ;adres wejścia danych move.l A0,D1 LenStr0: tst.b (A0)+ bne.s LenStr0 subq.l #1,A0 sub.l D1,A0 move.l A0,D1 ;liczba znaków (maks. 4294967295) rts ;Rozmiar: 20 B, linii kodu: 8
 DelZero: lea      textbuf,A0 ;adres wejścia/wyjścia danych
          move.l   A0,A1
DelZero0: tst.b    (A1)
          beq.s    DelZero3
          cmp.b    #$30,(A1)+
          beq.s    DelZero0
          subq.l   #1,A1
          cmp.l    A0,A1
          beq.s    DelZero2
DelZero1: move.b   (A1)+,(A0)+
          bne.s    DelZero1
DelZero2: rts
DelZero3: clr.b    $01(A0)
          rts

;Rozmiar: 36 B, linii kodu: 14
 ClrZero: lea      textbuf,A0 ;adres wejścia/wyjścia danych
          moveq    #$30,D1
ClrZero0: cmp.b    (A0),D1
          beq.s    ClrZero1
          rts
ClrZero1: move.b   #$20,(A0)+ ;znak spacji
          tst.b    (A0)
          bne.s    ClrZero0
          move.b   D1,-(A0)
          rts

;Rozmiar: 26 B, linii kodu: 10
CPUmodel:
;Zakładam, że w tym miejscu procesor pracuje w trybie nadzorcy (Supervisor mode).
;Każdy procesor 680x0 pracuje w tym trybie, zaraz po włączeniu/resecie systemu.
;Ta procedura jest dedykowana do własnych systemów, opartych o procesory 680x0.

 moveq    #$30,D1    ;procesor 68000
 moveq    #$10,D2
 move.l   D2,A1
 move.l   (A1),D2    ;wektor wyjątku nr 4 (Illegal Instruction), który wystąpi gdy procesor
                     ;natrafi na kod nieobsługiwanej instrukcji (prawidłowy tylko dla 68000).
 lea      CPUmodel1(pc),A0
 move.l   A0,(A1)    ;zmiana wektora wyjątku nr 4 (prawidłowego tylko dla 68000)
 move.l   A7,A3      ;zapamiętanie wskaźnika stosu (A7=SSP)
 dc.l     $4E7A3801  ;MOVEC VBR,D3 - instrukcja przenosi wartość rejestru VBR do rejestru D3.
                     ;Tylko na procesorze 68000 powoduje wystąpienie wyjątku nr 4.

;W tym miejscu procesor to 68010 lub nowszy

 move.l   D2,(A1)    ;przywrócenie wektora wyjątku nr 4 (prawidłowego tylko dla 68000)
 add.l    D3,A1
 move.l   (A1),D2    ;wektor wyjątku nr 4 (prawidłowy dla 68010+)
 lea      CPUmodel3(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      CPUmodel0(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
 moveq    #$36,D1    ;procesor 68060
CPUmodel0:           ;kod obsługi wyjątku nr 11 (tylko dla 68020)
 move.l   D3,(A2)    ;przywrócenie wektora wyjątku nr 11
CPUmodel1:           ;kod obsługi wyjątku nr 4 (tylko dla 68000)
 move.l   D2,(A1)    ;przywrócenie wektora wyjątku nr 4
 move.l   A3,A7      ;przywrócenie wskaźnika stosu (A7=SSP)
 lea      textbuf,A0 ;adres wyjścia danych
 lea      CPUmodel4(pc),A1
 move.b   D1,3(A1)   ;wartość określa model procesora: $30-$36=68000-68060
CPUmodel2:
 move.b   (A1)+,(A0)+
 bne.s    CPUmodel2
 rts

CPUmodel3:           ;kod obsługi wyjątku nr 4
 cmp.b    #$32,D1
 bne.s    CPUmodel0

;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    CPUmodel0

CPUmodel4:
 dc.b     "680x0",0

;Rozmiar: 114 B, linii kodu: 41
FPUmodel:
;Zakładam, że w tym miejscu procesor pracuje w trybie nadzorcy (Supervisor mode).
;Każdy procesor 680x0 pracuje w tym trybie, zaraz po włączeniu/resecie systemu.
;Ta procedura jest dedykowana do własnych systemów, opartych o procesory 680x0.

 moveq    #$10,D2
 move.l   D2,A1
 move.l   (A1),D2    ;wektor wyjątku nr 4 (Illegal Instruction), który wystąpi gdy procesor
                     ;natrafi na kod nieobsługiwanej instrukcji (prawidłowy tylko dla 68000).
 lea      FPUmodel0(pc),A0
 move.l   A0,(A1)    ;zmiana wektora wyjątku nr 4 (prawidłowego tylko dla 68000)
 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).
 lea      FPUmodel1(pc),A4
 move.l   A4,(A2)    ;zmiana wektora wyjątku nr 11 (prawidłowego tylko dla 68000)
 move.l   A7,A3      ;zapamiętanie wskaźnika stosu (A7=SSP)
 dc.l     $4E7A1801  ;MOVEC VBR,D1 - instrukcja przenosi wartość rejestru VBR do rejestru D1.
                     ;Tylko na procesorze 68000 powoduje wystąpienie wyjątku nr 4.

;W tym miejscu procesor to 68010 lub nowszy

 move.l   D2,(A1)    ;przywrócenie wektora wyjątku nr 4 (prawidłowego tylko dla 68000)
 move.l   D3,(A2)    ;przywrócenie wektora wyjątku nr 11 (prawidłowego tylko dla 68000)
 add.l    D1,A1
 add.l    D1,A2
 move.l   (A1),D2    ;wektor wyjątku nr 4 (prawidłowy dla 68010+)
 move.l   (A2),D3    ;wektor wyjątku nr 11 (prawidłowy dla 68010+)
 move.l   A0,(A1)    ;zmiana wektora wyjątku nr 4
 move.l   A4,(A2)    ;zmiana wektora wyjątku nr 11
FPUmodel0:           ;kod obsługi wyjątku nr 4 (tylko dla 68000)
 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,D4
 sub.l    A7,D4      ;rozmiar ramki odłożonej przez instrukcję FSAVE
 moveq    #5,D1      ;koprocesor 68881
 cmp.b    #$1C,D4    ;ramka IDLE
 beq.s    FPUmodel1
 moveq    #11,D1     ;koprocesor 68882
 cmp.b    #$3C,D4    ;ramka IDLE
 beq.s    FPUmodel1
 moveq    #17,D1     ;koprocesor wbudowany w 68040
 cmp.b    #4,D4      ;ramka IDLE
 beq.s    FPUmodel1
 moveq    #23,D1     ;koprocesor wbudowany w 68060
FPUmodel1:           ;kod obsługi wyjątku nr 11 (tylko jeśli nie ma FPU)
 move.l   D2,(A1)    ;przywrócenie wektora wyjątku nr 4
 move.l   D3,(A2)    ;przywrócenie wektora wyjątku nr 11
 move.l   A3,A7      ;przywrócenie wskaźnika stosu (A7=SSP)
 lea      textbuf,A0 ;adres wyjścia danych
 lea      FPUmodel3(pc),A1
 add.l    D1,A1      ;wartość określa model FPU: 0=brak, 5=68881, 11=68882, 17=68040, 23=68060
FPUmodel2:
 move.b   (A1)+,(A0)+
 bne.s    FPUmodel2
 rts

FPUmodel3:
 dc.b     "NONE",0,"68881",0,"68882",0,"IN040",0,"IN060",0

;Rozmiar: 138 B, linii kodu: 45
RegCCR:
;Zakładam, że w tym miejscu procesor 680x0 pracuje w dowolnym trybie (użytkownika lub nadzorcy)

 moveq    #$10,D2
 move.l   D2,A1
 move.l   (A1),D2        ;wektor wyjątku nr 4 (Illegal Instruction), który wystąpi gdy procesor
                         ;natrafi na kod nieobsługiwanej instrukcji (prawidłowy tylko dla 68000).
 lea      RegCCR4(pc),A0
 move.l   A0,(A1)        ;zmiana wektora wyjątku nr 4 (prawidłowego tylko dla 68000)

;Procedura generuje wartości flag rejestru CCR, jakie mają one w tym miejscu

 dc.w     $42C1          ;MOVE CCR,D1 - instrukcja przenosi wartość rejestru CCR do rejestru D1.
                         ;Tylko na procesorze 68000 powoduje wystąpienie wyjątku nr 4.

;W tym miejscu procesor to 68010 lub nowszy

RegCCR0:
 move.l   D2,(A1)        ;przywrócenie wektora wyjątku nr 4 (prawidłowego tylko dla 68000)
 moveq    #$07,D2
 lea      textbuf,A0     ;adres wyjścia danych
 lea      RegCCR3(pc),A1
RegCCR1:
 move.b   (A1)+,(A0)+
 move.b   #$3A,(A0)+
 moveq    #$30,D3
 btst     D2,D1
 beq.s    RegCCR2
 addq.b   #1,D3
RegCCR2:
 move.b   D3,(A0)+
 move.b   #$20,(A0)+
 dbf      D2,RegCCR1
 clr.b    -(A0)
 rts
RegCCR3:
 dc.b     "---XNZVC"

RegCCR4:                 ;kod obsługi wyjątku nr 4 (tylko dla 68000)

;W tym miejscu procesor 68000 zawsze 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.w   (A7),D1        ;wartość rejestru SR ze stosu (młodszy bajt to rejestr CCR)
 lea      RegCCR0(pc),A0
 move.l   A0,$02(A7)     ;modyfikacja wartości rejestru PC na stosie
 rte                     ;powrót z wyjątku

;Po wykonaniu instrukcji RTE wartości rejestrów SR i PC, są przywracane ze stosu.
;Jeśli przed wystąpieniem wyjątku procesor 68000 pracował w trybie użytkownika
;(User mode), to 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.

;Rozmiar: 76 B, linii kodu: 26