Section courante

A propos

Section administrative du site

Conversion de code Z8000 en 68000

Cette page traite de la conversion de programmes écrits en assembleur Zilog Z8000 vers l'assembleur Motorola 68000. Le Z8000 et le 68000 sont des microprocesseurs 16/32 bits contemporains (tous deux lances en 1979), conçus comme successeurs de processeurs 8 bits (Z80 et 6800/6809 respectivement). Bien qu'ils partagent une philosophie CISC similaire, leurs jeux d'instructions, modes d'adressage et organisations de registres différent sensiblement. Le Z8000 existe en deux variantes : le Z8001 (segmente, 8 Mo) et le Z8002 (non segmente, 64 Ko). Cette section couvre principalement le Z8002 non segmente, plus simple a convertir.

Différences fondamentales entre Z8000 et 68000

Critère Zilog Z8000 Motorola 68000
Type d'architecture CISC CISC
Taille des instructions 16-48 bits (variable) 16-80 bits (variable)
Registres généraux 16 (R0-R15) 8 données + 8 adresses
Registres d'adresse (inclus dans généraux) A0-A7 (séparés)
Taille des registres 16 bits 32 bits
Paires de registres RR0-RR14 (32 bits) D0.L-D7.L natifs 32 bits
Quadruples de registres RQ0-RQ12 (64 bits) Pas d'équivalent direct
Espace d'adressage 64 Ko (Z8002)
8 Mo (Z8001 segmente)
16 Mo (24 bits)
Ordre des octets Big-endian Big-endian
Alignement mémoire Mots sur adresses paires Mots sur adresses paires
Pile Décroissante Décroissante (A7)
Pointeur de pile R15 (convention) A7 (dedie)
Modes de privilège Normal / Système Utilisateur / Superviseur
Coprocesseur flottant Non (Z8070 optionnel) 68881/68882 (separe)
Instructions sur blocs Oui (LDIR, CPIR...) Non (boucles manuelles)
Entrées/Sorties IN/OUT (espace E/S) Memory-mapped I/O
Flags (drapeaux) C,Z,S,P/V,D,H X,N,Z,V,C

Différences clefs pour la conversion :

Correspondance des registres

Registre Z8000 Équivalent 68000 Notes
R0 D0 Registre de travail
R1 D1 Registre de travail
R2 D2 Registre de travail
R3 D3 Registre de travail
R4 D4 Registre de travail
R5 D5 Registre de travail
R6 D6 Registre de travail
R7 D7 Registre de travail
R8 A0 Pointeur / adresse
R9 A1 Pointeur / adresse
R10 A2 Pointeur / adresse
R11 A3 Pointeur / adresse
R12 A4 Pointeur / adresse
R13 A5 Pointeur / adresse
R14 A6 (FP) Frame pointer (convention)
R15 A7 (SP) Pointeur de pile
FCW SR Registre d'état / contrôle
FLAGS CCR Drapeaux de condition
PC PC Compteur ordinal

Paires de registres (32 bits) :

Z8000 68000
RR0 (R0:R1) D0.L (registre 32 bits complet)
RR2 (R2:R3) D1.L
RR4 (R4:R5) D2.L
RR6 (R6:R7) D3.L
RR8 (R8:R9) A0 (déjà 32 bits)
RR10 (R10:R11) A1
RR12 (R12:R13) A2
RR14 (R14:R15) A6/A7 (selon contexte)

Notes sur la correspondance :

Correspondance des drapeaux :

Z8000 68000 Notes
C (Carry) C (Carry) Équivalents directs
Z (Zero) Z (Zero) Équivalents directs
S (Sign) N (Negative) Même signification
P/V (Parity/Ovf) V (Overflow) En mode overflow seulement
D (Decimal adjacent) (pas d'équivalent) Utiliser ABCD/SBCD
H (Half-carry) X (Extend) Usage different ; X est un carry étendu pour le BCD

Conversion des instructions de transfert

Le Z8000 dispose d'instructions de transfert avec des tailles d'opérandes variées : octet (B), mot (W = 16 bits) et long (L = 32 bits via paires RRn). Le 68000 supporte les mêmes tailles via les suffixes .B, .W et .L sur l'instruction MOVE.

Z8000 68000
LD Rd,Rs MOVE.W Rs,Dd
LD Rd,#imm MOVE.W #imm,Dd
LD Rd,@Rs MOVE.W (As),Dd
LD Rd,addr MOVE.W addr,Dd
LD Rd,addr(Rs) MOVE.W addr(As),Dd
LD @Rd,Rs MOVE.W Ds,(Ad)
LD addr,Rs MOVE.W Ds,addr
LD addr(Rd),Rs MOVE.W Ds,addr(Ad)
LDB Rd,Rs MOVE.B Rs,Dd
LDB Rd,#imm MOVE.B #imm,Dd
LDB Rd,@Rs MOVE.B (As),Dd
LDL RRd,RRs MOVE.L Ds,Dd
LDL RRd,#imm32 MOVE.L #imm32,Dd
LDL RRd,@Rs MOVE.L (As),Dd
LDL RRd,addr MOVE.L addr,Dd
LDA Rd,addr LEA addr,Ad
LDA Rd,addr(Rs) LEA addr(As),Ad
LDK Rd,#k MOVEQ #k,Dd (si k dans 0-15)
CLR Rd CLR.W Dd
CLRB Rd CLR.B Dd
EX Rd,Rs EXG Dd,Ds
EX Rd,@Rs MOVE.W (As),Dt
MOVE.W Dd,(As) MOVE.W Dt,Dd

Exemples de conversion détaillés :

  1.   ; Z8000 : Charger une valeur 16 bits en memoire
  2.   LD   R2,@R10                   ; Charger mot pointe par R10
  3.  
  4.   ; 68000 :
  5.   MOVE.W  (A2),D2                ; A2 = R10, D2 = R2
  6.  
  7.   ; Z8000 : Charger 32 bits via paire de registres
  8.   LDL  RR4,@R8                   ; Charger long depuis @R8
  9.  
  10.   ; 68000 :
  11.   MOVE.L  (A0),D2                ; A0 = R8, D2 = RR4 (R4:R5)
  12.  
  13.   ; Z8000 : Charger adresse effective
  14.   LDA  R9,table(R8)              ; R9 = adresse de table + R8
  15.  
  16.   ; 68000 :
  17.   LEA  table(A0),A1              ; A1 = R9, A0 = R8

Conversion des instructions arithmétiques

Le Z8000 supporte les opérations arithmétiques sur 8, 16 et 32 bits. Le 68000 supporte également ces trois tailles. La principale différence est que le Z8000 utilise des paires de registres pour le 32 bits, tandis que le 68000 opère directement en 32 bits.

Z8000 68000
ADD Rd,Rs ADD.W Ds,Dd
ADD Rd,#imm ADD.W #imm,Dd ou ADDI.W #imm,Dd
ADDB Rd,Rs ADD.B Ds,Dd
ADDL RRd,RRs ADD.L Ds,Dd
ADC Rd,Rs ADDX.W Ds,Dd
SUB Rd,Rs SUB.W Ds,Dd
SUB Rd,#imm SUB.W #imm,Dd ou SUBI.W #imm,Dd
SUBB Rd,Rs SUB.B Ds,Dd
SUBL RRd,RRs SUB.L Ds,Dd
SBC Rd,Rs SUBX.W Ds,Dd
CP Rd,Rs CMP.W Ds,Dd
CP Rd,#imm CMP.W #imm,Dd ou CMPI.W #imm,Dd
CPB Rd,Rs CMP.B Ds,Dd
CPL RRd,RRs CMP.L Ds,Dd
INC Rd,#n ADDQ.W #n,Dd (n = 1..8)
INCB Rd,#n ADDQ.B #n,Dd
DEC Rd,#n SUBQ.W #n,Dd (n = 1..8)
DECB Rd,#n SUBQ.B #n,Dd
NEG Rd NEG.W Dd
NEGB Rd NEG.B Dd
DAB Rd (pas d'équivalent direct) Utiliser ABCD/NBCD après l'opération

Multiplication et division :

Z8000 68000
MULT RRd,Rs MULU.W Ds,Dd (16x16→32) (résultat dans Dd.L)
MULTL RQd,RRs (pas d'équivalent direct, routine 32x32)
DIV RRd,Rs DIVU.W Ds,Dd (32/16->16q:16r)
DIVL RQd,RRs (pas d'équivalent direct, routine 32/32)

Note sur MULT : Le Z8000 MULT multiplie deux mots 16 bits et place le résultat 32 bits dans une paire RRd. Le 68000 MULU fait de même (Ds.W * Dd.W → Dd.L). La correspondance est directe.

Note sur DIV : Le Z8000 DIV divise un long 32 bits (RRd) par un mot 16 bits (Rs) et place le quotient et le reste dans la paire. Le 68000 DIVU divise Dd.L par Ds.W et place le quotient dans le mot bas et le reste dans le mot haut de Dd. Le format du résultat diffère, mais la fonctionnalité est équivalente.

Exemples :

  1.   ; Z8000 : Addition 32 bits
  2.   ADDL RR2,RR4                   ; RR2 = RR2 + RR4
  3.  
  4.   ; 68000 :
  5.   ADD.L  D2,D1                   ; D1 = D1 + D2
  6.  
  7.   ; Z8000 : Multiplication 16x16->32
  8.   MULT RR4,R2                    ; RR4 = R4 * R2
  9.  
  10.   ; 68000 :
  11.   MULU.W D2,D2                   ; D2.L = D2.W * D2.W
  12.  
  13.   ; Z8000 : Increment rapide
  14.   INC  R3,#1                     ; R3 = R3 + 1
  15.  
  16.   ; 68000 :
  17.   ADDQ.W #1,D3                   ; D3 = D3 + 1

Conversion des instructions logiques et de décalage

Les instructions logiques du Z8000 et du 68000 sont très similaires. Les deux processeurs supportent AND, OR, XOR sur 8 et 16 bits. Le Z8000 ajoute des opérations 32 bits via les paires de registres.

Instructions logiques :

Z8000 68000
AND Rd,Rs AND.W Ds,Dd
AND Rd,#imm AND.W #imm,Dd ou ANDI.W #imm,Dd
ANDB Rd,Rs AND.B Ds,Dd
OR Rd,Rs OR.W Ds,Dd
OR Rd,#imm OR.W #imm,Dd ou ORI.W #imm,Dd
ORB Rd,Rs OR.B Ds,Dd
XOR Rd,Rs EOR.W Ds,Dd
XOR Rd,#imm EOR.W #imm,Dd ou EORI.W #imm,Dd
XORB Rd,Rs EOR.B Ds,Dd
COM Rd NOT.W Dd
COMB Rd NOT.B Dd
TEST Rd TST.W Dd
TESTB Rd TST.B Dd
TESTL RRd TST.L Dd
BIT Rd,#b BTST #b,Dd
SET Rd,#b BSET #b,Dd
RES Rd,#b BCLR #b,Dd
TCC cc,Rd Scc Dd (Set conditionnel)

Instructions de décalage et rotation :

Z8000 68000
SLA Rd,#n ASL.W #n,Dd (décalage arithmétique gauche)
SLAB Rd,#n ASL.B #n,Dd
SLAL RRd,#n ASL.L #n,Dd
SRA Rd,#n ASR.W #n,Dd (décalage arithmétique droite)
SRAB Rd,#n ASR.B #n,Dd
SRAL RRd,#n ASR.L #n,Dd
SLL Rd,#n LSL.W #n,Dd (décalage logique gauche)
SLLB Rd,#n LSL.B #n,Dd
SLLL RRd,#n LSL.L #n,Dd
SRL Rd,#n LSR.W #n,Dd (décalage logique droite)
SRLB Rd,#n LSR.B #n,Dd
SRLL RRd,#n LSR.L #n,Dd
RL Rd,#n ROL.W #n,Dd (rotation gauche)
RLB Rd,#n ROL.B #n,Dd
RR Rd,#n ROR.W #n,Dd (rotation droite)
RRB Rd,#n ROR.B #n,Dd
RLC Rd,#n ROXL.W #n,Dd (rotation avec carry)
RLCB Rd,#n ROXL.B #n,Dd
RRC Rd,#n ROXR.W #n,Dd (rotation avec carry)
RRCB Rd,#n ROXR.B #n,Dd
SDA Rd,Rs ASL.W Ds,Dd / ASR.W Ds,Dd (selon signe de Rs)
SDL Rd,Rs LSL.W Ds,Dd / LSR.W Ds,Dd (selon signe de Rs)

Note sur SDA/SDL : Le Z8000 utilise le signe du registre source pour déterminer la direction du décalage (positif = gauche, négatif = droite). Le 68000 a des instructions séparées pour chaque direction. Il faut donc tester le signe et brancher.

  1. ; Z8000 : Decalage dynamique
  2. SDA  R3,R2                     ; Si R2>0 decalage gauche, sinon droit
  3.  
  4. ; 68000 :
  5. TST.W   D2
  6. BMI     .droite
  7. ASL.W   D2,D3
  8. BRA     .fin
  9. .droite:
  10. NEG.W   D2
  11. ASR.W   D2,D3
  12. NEG.W   D2                     ; Restaurer D2
  13. .fin:

Conversion des instructions de branchement

Le Z8000 et le 68000 possèdent tous deux des branchements conditionnels bases sur les drapeaux de condition. Les codes de condition sont largement équivalents.

Z8000 68000 Condition
JR cc,label Bcc label Branchement court
JP cc,addr Bcc addr Branchement long
JR T,label BRA label Toujours (True)
JR F,label (pas de saut) Jamais (False)
JP T,addr JMP addr Saut absolu
DJNZ Rd,label DBRA Dd,label Décrément + saut
DBJNZ Rd,label (équivalent DBRA) Version octet

Codes de condition :

Z8000 68000 Signification
Z EQ Égal (Zéro)
NZ NE Non égal (Non Zéro)
C CS Retenue (Carry Set)
NC CC Pas de retenue (Carry Clear)
MI MI Négatif (Minus)
PL PL Positif (Plus)
OV VS Overflow Set
NOV VC Overflow Clear
EQ EQ Egal (= Z)
NE NE Non egal (= NZ)
ULT CS Inférieur non signe
UGE CC Supérieur ou égal non signe
ULE LS Inférieur ou égal non signe
UGT HI Supérieur non signe
SLT LT Inférieur signe
SGE GE Supérieur ou égal signe
SLE LE Inférieur ou égal signe
SGT GT Supérieur signe

Instructions d'appel et retour :

Z8000 68000 Description
CALL addr JSR addr Appel sous-routine
CALL @Rd JSR (Ad) Appel indirect
RET cc Bcc .skip / RTS Retour conditionnel ou simplement RTS si cc = T
SC #trap TRAP #n Appel système

Note sur RET cc : Le Z8000 permet un retour conditionnel (RET NZ, RET Z, etc.). Le 68000 n'a pas de RTS conditionnel. Il faut convertir en branchement conditionnel + RTS :

  1. ; Z8000 :
  2. RET  NZ                        ; Retour si non zero
  3.  
  4. ; 68000 :
  5. BEQ  .skip                     ; Si zero, ne pas retourner
  6. RTS
  7. .skip:

Note sur DJNZ : L'instruction DJNZ du Z8000 décrémente un registre et saute si non zéro, exactement comme DBRA du 68000. La différence est que DJNZ est 16 bits tandis que DBRA ne décrémente que le mot bas (16 bits) du registre de données. La correspondance est donc directe.

  1. ; Z8000 :
  2. LD   R5,#10
  3. .boucle:
  4. (...)
  5. DJNZ R5,.boucle                ; R5--, saut si R5 != 0
  6.  
  7. ; 68000 :
  8. MOVEQ  #10-1,D5                ; DBRA teste apres decrement
  9. .boucle:
  10. (...)
  11. DBRA   D5,.boucle              ; D5--, saut si D5 != -1

Note : DBRA décrémente et saute si le résultat n'est pas -1, donc le compteur initial doit être décrémenté de 1 par rapport a DJNZ.

Conversion des modes d'adressage

Le Z8000 et le 68000 ont des modes d'adressage assez similaires, ce qui facilite grandement la conversion.

Z8000 68000 Description
Rd Dd Registre direct
#imm #imm Immédiat
@Rd (Ad) Indirect registre
addr addr Adresse directe
addr(Rd) addr(Ad) Base + déplacement
Rd(#disp) disp(Ad) Indirect + déplacement
@Rd+ (Ad)+ Post-incrément
-@Rd (ou @-Rd) -(Ad) Pré-decrément

Mode indexe : Le Z8000 supporte l'adressage indexe via la syntaxe addr(Rd). Le 68000 offre un mode similaire via d(An) et d(An,Dn.W) ou d(An,Dn.L). L'adressage indexe Z8000 est limité à un déplacement 16 bits, tandis que le 68000 supporte un déplacement 8 bits avec index ou 16 bits sans index.

  1.   ; Z8000 : Adressage indirect
  2.   LD   R0,@R8                    ; R0 = memoire[R8]
  3.  
  4.   ; 68000 :
  5.   MOVE.W  (A0),D0                ; D0 = memoire[A0]
  6.  
  7.   ; Z8000 : Adressage base + deplacement
  8.   LD   R1,table(R9)              ; R1 = memoire[R9 + table]
  9.  
  10.   ; 68000 :
  11.   MOVE.W  table(A1),D1           ; D1 = memoire[A1 + table]
  12.  
  13.   ; Z8000 : Post-increment
  14.   LD   R0,@R8+                   ; R0 = memoire[R8], R8 += 2
  15.  
  16.   ; 68000 :
  17.   MOVE.W  (A0)+,D0               ; D0 = memoire[A0], A0 += 2
  18.  
  19.   ; Z8000 : Pre-decrement (pour la pile)
  20.   LD   @-R15,R0                  ; R15 -= 2, memoire[R15] = R0
  21.  
  22.   ; 68000 :
  23.   MOVE.W  D0,-(A7)               ; A7 -= 2, memoire[A7] = D0

Mode relatif au PC : Le Z8000 et le 68000 supportent tous les deux l'adressage relatif au PC. Le Z8000 utilise les sauts relatifs (JR) et l'adressage relatif dans certaines instructions de chargement. Le 68000 supporte le mode d(PC) explicitement.

Conversion des instructions de pile et d'appels

Le Z8000 et le 68000 utilisent tous deux une pile décroissante. Le Z8000 utilise par convention R15 comme pointeur de pile, tandis que A7 est le pointeur de pile dédié du 68000.

Z8000 68000 Description
PUSH @R15,Rs MOVE.W Ds,-(A7) Empiler mot
PUSH @R15,#imm MOVE.W #imm,-(A7) Empiler immédiat
PUSHL @R15,RRs MOVE.L Ds,-(A7) Empiler long
POP Rd,@R15 MOVE.W (A7)+,Dd Dépiler mot
POPL RRd,@R15 MOVE.L (A7)+,Dd Dépiler long
CALL addr JSR addr Appel
RET RTS Retour

Convention d'appel (prologue/épilogue) :

  1.   ; Z8000 :
  2.   func:
  3.     PUSH @R15,R14                ; Sauvegarder frame pointer
  4.     LD   R14,R15                 ; Nouveau frame pointer
  5.     SUB  R15,#locales            ; Reserver espace local
  6.     (...)
  7.     LD   R15,R14                 ; Restaurer pile
  8.     POP  R14,@R15                ; Restaurer frame pointer
  9.     RET                          ; Retour
  10.  
  11.   ; 68000 :
  12.   func:
  13.     LINK   A6,#-locales          ; Sauver A6, A6=SP, SP-=locales
  14.     (...)
  15.     UNLK   A6                    ; SP=A6, restaurer A6
  16.     RTS                          ; Retour

Le 68000 simplifie considérablement le prologue/épilogue grâce aux instructions LINK et UNLK. Trois instructions Z8000 (PUSH + LD + SUB) sont remplacées par un seul LINK. De même, deux instructions (LD + POP) sont remplacées par UNLK.

Sauvegarde de registres multiples :

Le Z8000 n'a pas d'instruction de sauvegarde multiple de registres. Il faut empiler les registres un par un. Le 68000 dispose de MOVEM sauvegardeant/restaurant plusieurs registres en une seule instruction.

  1. ; Z8000 : Sauvegarde de registres
  2. PUSH @R15,R0
  3. PUSH @R15,R1
  4. PUSH @R15,R2
  5. PUSH @R15,R8
  6.  
  7. ; 68000 :
  8. MOVEM.L D0-D2/A0,-(A7)        ; Sauvegarder D0,D1,D2,A0
  9.  
  10. ; Z8000 : Restauration de registres
  11. POP  R8,@R15
  12. POP  R2,@R15
  13. POP  R1,@R15
  14. POP  R0,@R15
  15.  
  16. ; 68000 :
  17. MOVEM.L (A7)+,D0-D2/A0        ; Restaurer D0,D1,D2,A0

Conversion des instructions spécifiques au Z8000

Le Z8000 possède certaines instructions sans équivalent direct sur le 68000.

a) Instructions d'entrées/sorties :

Z8000 68000
IN Rd,#port MOVE.W port_addr,Dd (port cartographié en mémoire)
INB Rd,#port MOVE.B port_addr,Dd
OUT #port,Rs MOVE.W Ds,port_addr
OUTB #port,Rs MOVE.B Ds,port_addr
SINB Rd,Rs MOVE.B (As),Dd (Rs contient l'adresse du port)
SOUTB Rs,Rd MOVE.B Dd,(As)

Les adresses de ports doivent être converties en adresses mémoire correspondantes dans l'espace d'adressage du 68000. La correspondance exacte dépend du matériel cible.

b) Instructions multi-registres :

Z8000 68000
LDPS @Rs Pas d'équivalent direct
 (charge FCW + PC depuis mémoire)
 MOVE.W (As),SR ; charger SR
 MOVE.L 2(As),A3 ; charger nouvelle PC
 JMP (A3)
LDCTL Rd,FCW MOVE.W SR,Dd (mode superviseur)
LDCTL FCW,Rs MOVE.W Ds,SR (mode superviseur)
LDCTLB RH,FLAGS MOVE.W CCR,Dd
LDCTLB FLAGS,RH MOVE.W Ds,CCR
MREQ Rd (spécifique Z8000, pas d'équivalent)
MBIT (spécifique Z8000, pas d'équivalent)
MSET (spécifique Z8000, pas d'équivalent)
MRES (spécifique Z8000, pas d'équivalent)

c) Instructions de gestion système :

Z8000 68000 Description
DI vi,nvi ORI.W #$0700,SR Désactiver interruptions
EI vi,nvi ANDI.W #$F8FF,SR Activer interruptions
HALT STOP #$2000 Arrêter le processeur
IRET RTE Retour d'interruption
SC #n TRAP #n Appel superviseur
NOP NOP Pas d'opération

d) Ajustement décimal :

Z8000 68000
DAB Rd (pas d'équivalent direct)

L'instruction DAB (Decimal Adjust Byte) du Z8000 ajuste le résultat d'une addition BCD. Le 68000 utilise ABCD pour l'addition BCD et SBCD pour la soustraction BCD, effectuant l'ajustement automatiquement pendant l'opération. Il faut donc réorganiser le code pour utiliser ABCD/SBCD au lieu de ADD+DAB.

  1.   ; Z8000 : Addition BCD
  2.   ADDB R0,R1
  3.   DAB  R0                        ; Ajuster resultat BCD
  4.  
  5.   ; 68000 :
  6.   ABCD D1,D0                     ; Addition BCD avec ajustement

Conversion des opérations sur blocs et chaînes

Le Z8000 hérite du Z80 des instructions puissantes de manipulation de blocs mémoire. Le 68000 n'a pas d'équivalents directs et nécessite des boucles explicites.

a) Transfert de blocs :

  1. ; Z8000
  2. LDIR @Rd,@Rs,Rn               ; Copier Rn octets de @Rs vers @Rd
  3.                               ; avec auto-increment
  4.  
  5. ; 68000 (equivalent) :
  6. ; As = source, Ad = destination, Dn = compteur (en mots)
  7.   SUBQ.W  #1,Dn               ; Ajuster pour DBRA
  8. .copie:
  9.   MOVE.W  (As)+,(Ad)+
  10.   DBRA    Dn,.copie
  11.  
  12. ; Z8000
  13. LDDR @Rd,@Rs,Rn               ; Copier Rn octets avec auto-decrement
  14.  
  15. ; 68000 (equivalent) :
  16.   SUBQ.W  #1,Dn
  17. .copie:
  18.   MOVE.W  -(As),-(Ad)
  19.   DBRA    Dn,.copie

b) Comparaison de blocs :

  1. ; Z8000
  2. CPIR Rd,@Rs,Rn,cc             ; Chercher Rd dans @Rs (increment)
  3.                               ; sur Rn elements, condition cc
  4.  
  5. ; 68000 (equivalent pour recherche d'un mot) :
  6.   SUBQ.W  #1,Dn               ; Ajuster pour DBRA
  7. .cherche:
  8.   CMP.W   (As)+,Dd
  9.   DBEQ    Dn,.cherche          ; Continuer si non trouve
  10.  
  11. ; Z8000
  12. CPDR Rd,@Rs,Rn,cc             ; Chercher avec decrement
  13.  
  14. ; 68000 (equivalent) :
  15.   SUBQ.W  #1,Dn
  16. .cherche:
  17.   CMP.W   -(As),Dd
  18.   DBEQ    Dn,.cherche

c) Transferts de blocs d'entrée/sortie :

  1. ; Z8000
  2. INIR @Rd,@Rs,Rn               ; Lire Rn octets depuis port @Rs
  3. OTIR @Rs,@Rd,Rn               ; Ecrire Rn octets vers port @Rd
  4.  
  5. ; 68000 (equivalent pour INIR) :
  6. ; As = adresse du port mappe en memoire
  7. ; Ad = destination, Dn = compteur
  8.   SUBQ.W  #1,Dn
  9. .lecture:
  10.   MOVE.B  (As),(Ad)+           ; Lire depuis le port
  11.   DBRA    Dn,.lecture

d) Translation (table de correspondance) :

  1. ; Z8000
  2. TRDB @Rd,@Rs,Rn               ; Traduire bloc via table
  3.  
  4. ; 68000 (equivalent) :
  5. ; A0 = source, A1 = table de traduction, A2 = destination
  6. ; D0 = compteur
  7.   SUBQ.W  #1,D0
  8. .traduit:
  9.   CLR.W   D1
  10.   MOVE.B  (A0)+,D1             ; Lire caractere source
  11.   MOVE.B  0(A1,D1.W),(A2)+     ; Traduire via table
  12.   DBRA    D0,.traduit

Exemples complets de conversion Z8000 vers 68000

Exemple 1 : Calcul de la longueur d'une chaîne (strlen)

  1.   ; Z8000 :
  2.   strlen:
  3.     LD   R2,R8                   ; R2 = pointeur debut chaine
  4.     CLR  R0                      ; R0 = compteur = 0
  5.   .boucle:
  6.     LDB  RH0,@R2                 ; Charger octet
  7.     INC  R2,#1                   ; Avancer pointeur
  8.     TESTB RH0                    ; Test si zero
  9.     JR   NZ,.boucle              ; Continuer si non zero
  10.     RET                          ; R0 = longueur
  11.  
  12.   ; 68000 :
  13.   strlen:
  14.     MOVEA.L A0,A2                ; A2 = copie pointeur debut
  15.     CLR.L   D0                   ; D0 = compteur = 0
  16.   .boucle:
  17.     TST.B   (A0)+                ; Tester octet et avancer
  18.     BEQ     .fin                 ; Si zero, termine
  19.     ADDQ.L  #1,D0               ; Incrementer compteur
  20.     BRA     .boucle
  21.   .fin:
  22.     RTS                          ; D0 = longueur

Exemple 2 : Copie de mémoire (memcpy)

  1.   ; Z8000 :
  2.   memcpy:
  3.     ; R8 = destination, R9 = source, R2 = nombre d'octets
  4.     LDIR @R8,@R9,R2              ; Copie automatique
  5.  
  6.     RET
  7.  
  8.   ; 68000 :
  9.   memcpy:
  10.     ; A0 = destination, A1 = source, D0 = nombre de mots
  11.     SUBQ.W  #1,D0               ; Ajuster pour DBRA
  12.   .copie:
  13.     MOVE.W  (A1)+,(A0)+          ; Copier mot par mot
  14.     DBRA    D0,.copie
  15.     RTS

Exemple 3 : Recherche d'un caractère dans une chaîne

  1.   ; Z8000 :
  2.   chercher:
  3.     ; R0.B = caractere a chercher, R8 = debut chaine, R2 = taille
  4.     CPIRB R0,@R8,R2,Z           ; Chercher R0 dans @R8
  5.  
  6.     JR   Z,.trouve               ; Trouve si Z est positionne
  7.     CLR  R8                      ; Non trouve, retourner 0
  8.     RET
  9.   .trouve:
  10.     DEC  R8,#1                   ; R8 pointe apres le caractere
  11.     RET                          ; R8 = adresse du caractere
  12.  
  13.   ; 68000 :
  14.   chercher:
  15.     ; D0.B = caractere, A0 = debut chaine, D1 = taille
  16.     SUBQ.W  #1,D1               ; Ajuster pour DBRA
  17.   .boucle:
  18.     CMP.B   (A0)+,D0
  19.     DBEQ    D1,.boucle
  20.     BNE     .non_trouve          ; Si sorti par compteur
  21.     SUBQ.L  #1,A0               ; Ajuster : A0 pointe apres
  22.     RTS
  23.   .non_trouve:
  24.     SUBA.L  A0,A0                ; A0 = 0 (non trouve)
  25.     RTS

Exemple 4 : Tri à bulles (bubble sort)

  1.   ; Z8000 :
  2.   tri_bulles:
  3.     ; R8 = adresse du tableau, R2 = nombre d'elements
  4.   .passe:
  5.     CLR  R0                      ; R0 = indicateur d'echange
  6.     LD   R3,R2
  7.     DEC  R3,#1                   ; R3 = nombre de comparaisons
  8.     LD   R9,R8                   ; R9 = pointeur courant
  9.   .compare:
  10.     LD   R4,@R9                  ; R4 = element courant
  11.     LD   R5,2(R9)                ; R5 = element suivant
  12.     CP   R4,R5
  13.     JR   SLE,.pas_echange
  14.     LD   @R9,R5                  ; Echanger
  15.     LD   2(R9),R4
  16.     INC  R0,#1                   ; Signaler echange
  17.   .pas_echange:
  18.     INC  R9,#2                   ; Avancer pointeur
  19.     DJNZ R3,.compare
  20.     TEST R0
  21.     JR   NZ,.passe               ; Recommencer si echanges
  22.     RET
  23.  
  24.   ; 68000 :
  25.   tri_bulles:
  26.     ; A0 = adresse du tableau, D2 = nombre d'elements
  27.   .passe:
  28.     CLR.W   D0                   ; D0 = indicateur d'echange
  29.     MOVE.W  D2,D3
  30.     SUBQ.W  #2,D3               ; D3 = nb comparaisons - 1 (DBRA)
  31.     MOVEA.L A0,A1                ; A1 = pointeur courant
  32.   .compare:
  33.     MOVE.W  (A1),D4              ; D4 = element courant
  34.     CMP.W   2(A1),D4
  35.     BLE     .pas_echange
  36.     MOVE.W  2(A1),(A1)           ; Echanger
  37.     MOVE.W  D4,2(A1)
  38.     ADDQ.W  #1,D0               ; Signaler echange
  39.   .pas_echange:
  40.     ADDQ.L  #2,A1               ; Avancer pointeur
  41.     DBRA    D3,.compare
  42.     TST.W   D0
  43.     BNE     .passe               ; Recommencer si echanges
  44.     RTS

Exemple 5 : Routine d'interruption

  1.   ; Z8000 :
  2.   isr_timer:
  3.     PUSH @R15,R0
  4.     PUSH @R15,R1
  5.     INB  R0,#TIMER_PORT          ; Lire registre minuterie
  6.     LD   R1,compteur
  7.     INC  R1,#1
  8.     LD   compteur,R1
  9.     OUTB #TIMER_PORT,R0          ; Acquitter interruption
  10.     POP  R1,@R15
  11.     POP  R0,@R15
  12.     IRET                         ; Retour d'interruption
  13.  
  14.   ; 68000 :
  15.   isr_timer:
  16.     MOVEM.L D0-D1,-(A7)         ; Sauvegarder registres
  17.     MOVE.B  TIMER_ADDR,D0        ; Lire registre minuterie (mem-mapped)
  18.     MOVE.L  compteur,D1
  19.     ADDQ.L  #1,D1
  20.     MOVE.L  D1,compteur
  21.     MOVE.B  D0,TIMER_ADDR        ; Acquitter interruption
  22.     MOVEM.L (A7)+,D0-D1          ; Restaurer registres
  23.     RTE                          ; Retour d'interruption

Tableau récapitulatif Z8000 vers 68000

Z8000 68000 Catégorie
LD Rd,Rs MOVE.W Rs,Dd Transfert 16b
LDB Rd,Rs MOVE.B Rs,Dd Transfert 8b
LDL RRd,RRs MOVE.L Rs,Dd Transfert 32b
LDA Rd,addr LEA addr,Ad Charger adresse
LDK Rd,#k MOVEQ #k,Dd Chargement rapide
CLR Rd CLR.W Dd Effacer
EX Rd,Rs EXG Dd,Ds Echanger
PUSH @R15,Rs MOVE.W Ds,-(A7) Empiler
POP Rd,@R15 MOVE.W (A7)+,Dd Depiler
ADD Rd,Rs ADD.W Ds,Dd Addition 16b
ADDL RRd,RRs ADD.L Ds,Dd Addition 32b
ADC Rd,Rs ADDX.W Ds,Dd Addition + carry
SUB Rd,Rs SUB.W Ds,Dd Soustraction 16b
SUBL RRd,RRs SUB.L Ds,Dd Soustraction 32b
SBC Rd,Rs SUBX.W Ds,Dd Soustract. + carry
CP Rd,Rs CMP.W Ds,Dd Comparaison
INC Rd,#n ADDQ.W #n,Dd Incrément rapide
DEC Rd,#n SUBQ.W #n,Dd Décrément rapide
NEG Rd NEG.W Dd Complément a 2
MULT RRd,Rs MULU.W Ds,Dd Multiplication
DIV RRd,Rs DIVU.W Ds,Dd Division
AND Rd,Rs AND.W Ds,Dd ET logique
OR Rd,Rs OR.W Ds,Dd OU logique
XOR Rd,Rs EOR.W Ds,Dd OU exclusif
COM Rd NOT.W Dd Complément à 1
TEST Rd TST.W Dd Test zéro
BIT Rd,#b BTST #b,Dd Test bit
SET Rd,#b BSET #b,Dd Positionner bit
RES Rd,#b BCLR #b,Dd Effacer bit
SLA Rd,#n ASL.W #n,Dd Décalage arithmétique G
SRA Rd,#n ASR.W #n,Dd Décalage arithmétique D
SLL Rd,#n LSL.W #n,Dd Décalage logique G
SRL Rd,#n LSR.W #n,Dd Décalage logique D
RL Rd,#n ROL.W #n,Dd Rotation gauche
RR Rd,#n ROR.W #n,Dd Rotation droite
RLC Rd,#n ROXL.W #n,Dd Rot. gauche + C
RRC Rd,#n ROXR.W #n,Dd Rot. droite + C
JR cc,label Bcc label Saut conditionnel
JP T,addr JMP addr Saut absolu
DJNZ Rd,label DBRA Dd,label Boucle comptée
CALL addr JSR addr Appel sous-routine
RET RTS Retour
IRET RTE Retour interruption
SC #n TRAP #n Appel système
DI ORI #$0700,SR Désactive les interruptions
EI ANDI #$F8FF,SR Activer les interruptions
HALT STOP #$2000 Arrêter processeur
NOP NOP Pas d'opération
IN Rd,#port MOVE.W port,Dd Lecture port
OUT #port,Rs MOVE.W Ds,port Écriture port
LDIR boucle MOVE+DBRA Copie bloc
CPIR boucle CMP+DBEQ Recherche bloc
DAB ABCD BCD (reorganiser)

Résumé

La conversion de code Z8000 vers 68000 est facilitée par plusieurs facteurs :

Les principaux points d'attention sont :



Dernière mise à jour : Lundi, le 16 mars 2026