Désassembleur Z80

C'est le lieu des discussions diverses et variées, mais toujours en rapport avec le thème général du forum et dans l'esprit de celui-ci. Contient des rubriques électroniques.

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: Désassembleur Z80

Message par hlide »

Problème qui peut sans doute se régler par un spécialiste 6809 via un "plugin" processeur à coder ici. Je ne suis pas aller regarder ailleurs pour savoir qu'il y a du code spécifique 6809 ailleurs.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: Désassembleur Z80

Message par Daniel »

Le problème semble connu : https://github.com/NationalSecurityAgen ... ssues/4600
Si toutes les instructions ne sont pas désassemblées, personne n'a pu utiliser ghidra avec le 6809. Il est difficile de lui faire confiance.
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Désassembleur Z80

Message par __sam__ »

L’examen des différences montre que le décodage de ce mode d’adressage a été changé dans la dernière version https://github.com/NationalSecurityAgen ... f34d07L218

Avant:
EA: "["addr"]" is imm8=0x9F;
Après:
EA: "["addr"]" is noOffset5=1 & idxReg=0b00 & idxMode=0b11101
Tel que je comprends, avant il utilisait bien $9f, mais à présent il associe un truc du genre [1,PCR], cf
EA: "["addr",PCR]" is noOffset5=1 & idxMode=0b11101
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: Désassembleur Z80

Message par Daniel »

Je n'ai pas bien compris la structure du fichier. Le premier problème est la non reconnaissance de l'instruction $6E (JMP indexé). Pour le désassembleur, c'est un code opération inconnu. Ensuite il y a peut-être un autre problème dans le calcul de l'adresse du saut, mais comme le code est inconnu l'adresse n'est même pas calculée.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: Désassembleur Z80

Message par hlide »

Je ne suis pas un expert en 6809, mais je trouve bizarre qu'un "imm8 = 0x9F" (opcode je suppose ?) devienne un "noOffset5=1 & idxReg=0b00 & idxMode=0b11101" (un $9F c'est 0b10011111). Admettons que c'est 1-00-11101, ça ferait $9D et non $9F.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: Désassembleur Z80

Message par hlide »

Code : Tout sélectionner

define token data8 (8)
    imm8      = (0,7)
    simm8     = (0,7) signed
    simm5     = (0,4) signed
    idxMode   = (0,4)
    noOffset5 = (7,7)
    idxReg    = (5,6)
    imm80     = (0,0)
    imm81     = (1,1)
    imm82     = (2,2)
    imm83     = (3,3)
    imm84     = (4,4)
    imm85     = (5,5)
    imm86     = (6,6)
    imm87     = (7,7)
    reg0_exg  = (4,7)
    reg1_exg  = (0,3)
;
Du coup, $6E, c'est noOffset5 = 0, idxReg = 11, idxMode = 01110 et je ne vois rien de le fichier de définition qui traite cet opcode comme il faut à par celle-ci :

Code : Tout sélectionner

EA: W,idxReg    is idxReg & noOffset5=1 & idxMode=0b01110 & W # W,R
{
     local addr:2 = idxReg + W;
     export addr; 
}
qui ne colle pas (noOffset5 != 0).
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: Désassembleur Z80

Message par Daniel »

J'en retiens que Ghidra ne sait pas désassembler le code 6809, et n'a probablement jamais été utilisable avec ce processeur vu le nombre de bugs signalés (et pas forcément corrigés) sur les adressages étendus et indexés. Ils ont encore du travail.

Pourtant ce n'est pas difficile, le 6809 a moins de 100 instructions et elles sont très bien documentées. Il m'a fallu moins de deux jours pour écrire et tester le désassembleur de dcmoto.

Comme Notator, je préfère reconstituer le code assembleur à la main, sauf que j'utilise un éditeur de texte au lieu d'une feuille de papier, c'est plus facile pour apporter des corrections.

Les programmes codés par Thomson (et d'autres) comportent pas mal de subtilités. Par exemple le branchement au deuxième octet d'une instruction qui est lui-même un code instruction valide. Ou encore le passage de paramètres à la suite d'une instruction (le SWI du MO5) ou après un appel de routine : les paramètres sont derrière le BSR ou JSR, et le retour ne se fait pas après cette instruction mais quelques octets plus loin. Pas sûr que Ghidra traite bien ces subtilités.

Exemple de désassemblage de dcmoto enrichi de flèches et de quelques commentaires :
(voir en particulier en $F201 le SWI suivi d'un paramètre et en $F22A-$F22B le branchement au deuxième octet de l'instruction CMPX) :

Code : Tout sélectionner

--------------------------------
GETCH lecture clavier
--------------------------------
F1FD  0D5D      TST    <$5D
F1FF  2638      BNE    $F239 --------
F201  3F0C      SWI    #$0C          | scrutation rapide du clavier
F203  3406      PSHS   B,A  <-----   |
F205  8E0271    LDX    #$0271     |  |
F208  301F      LEAX   -$01,X <-  |  | temporisation
F20A  26FC      BNE    $F208 ---  |  |
F20C  3F0C      SWI    #$0C       |  | scrutation rapide du clavier
F20E  10A3E1    CMPD   ,S++       |  |
F211  26F0      BNE    $F203 -----   |
F213  C13A      CMPB   #$3A          |
F215  2727      BEQ    $F23E --------|-----
F217  D137      CMPB   <$37          |     |
F219  2610      BNE    $F22B --      |     |
F21B  9638      LDA    <$38    |     |     |  compteur tempo repetition
F21D  9176      CMPA   <$76    |     |     |
F21F  251F      BLO    $F240 --|-----|-----|--
F221  8602      LDA    #$02    |     |     |  |
F223  9519      BITA   <$19    |     |     |  | status
F225  2619      BNE    $F240 --|-----|-----|->|
F227  BDF89D    JSR    $F89D   |     |     |  |
F22A  8C0F38    CMPX   #$0F38 -|--   |     |  |
F22B  0F38      CLR    <$38 <--   |  |     |  |
F22D  D737      STB    <$37 <-----   |     |  |
F22F  3F08      SWI    #$08          |     |  | beep
F231  0444      LSR    <$44          |     |  |
F233  240E      BHS    $F243 --      |     |  |       
F235  CA80      ORB    #$80    |     |     |  |  
F237  205E      BRA    $F297 --|-----|--   |  | 
F239  D65D      LDB    <$5D <--|-----   |  |  |
F23B  4F        CLRA           |        |  |  |
F23C  2057      BRA    $F295 --|-----   |  |  |
F23E  0F37      CLR    <$37 <--|-----|--|--   |
F240  5F        CLRB      <----|-----|--|----- 
F241  2056      BRA    $F299 --|-----|--|--
F243  9E6D      LDX    <$6D <--      |  |  | 
F245  E685      LDB    B,X           |  |  |
F247  0444      LSR    <$44          |  |  |
F249  2404      BHS    $F24F --      |  |  |
F24B  C4BF      ANDB   #$BF    |     |  |  |
F24D  204D      BRA    $F29C --|-----|--|--|--     
F24F  0444      LSR    <$44 <--      |  |  |  |
F251  2427      BHS    $F27A -----   |  |  |  |
F253  C120      CMPB   #$20       |  |  |  |  |
F255  2540      BLO    $F297 -----|--|->|  |  |
F257  2609      BNE    $F262 --   |  |  |  |  |
F259  8680      LDA    #$80    |  |  |  |  |  |
F25B  9819      EORA   <$19    |  |  |  |  |  |
F25D  9719      STA    <$19    |  |  |  |  |  | status
F25F  5F        CLRB           |  |  |  |  |  |
F260  2035      BRA    $F297 --|--|--|->|  |  |
F262  C12F      CMPB   #$2F <--   |  |  |  |  |
F264  2E04      BGT    $F26A --   |  |  |  |  |
F266  CA10      ORB    #$10    |  |  |  |  |  |
F268  202D      BRA    $F297 --|--|--|->|  |  |
F26A  C139      CMPB   #$39 <--   |  |  |  |  |
F26C  2E04      BGT    $F272 -    |  |  |  |  |
F26E  C4EF      ANDB   #$EF   |   |  |  |  |  |
F270  2012      BRA    $F284 -|-  |  |  |  |  |
F272  C140      CMPB   #$40 <-  | |  |  |  |  |
F274  2621      BNE    $F297 ---|-|--|->|  |  |
F276  C65E      LDB    #$5E     | |  |  |  |  |
F278  200A      BRA    $F284 -->| |  |  |  |  |
F27A  C141      CMPB   #$41 <---|-   |  |  |  |
F27C  2506      BLO    $F284 -->|    |  |  |  |
F27E  9619      LDA    <$19     |    |  |  |  | status
F280  2A15      BPL    $F297 ---|----|->|  |  |
F282  CB20      ADDB   #$20     |    |  |  |  |
F284  0D5C      TST    <$5C <---     |  |  |  |
F286  2714      BEQ    $F29C --------|--|--|->|
F288  860B      LDA    #$0B          |  |  |  |
F28A  4A        DECA      <----      |  |  |  |
F28B  270A      BEQ    $F297 --|-----|->|  |  |
F28D  301D      LEAX   -$03,X  |     |  |  |  |
F28F  E184      CMPB   ,X      |     |  |  |  |
F291  26F7      BNE    $F28A --      |  |  |  |
F293  EC01      LDD    $01,X         |  |  |  |
F295  975D      STA    <$5D <--------   |  |  |
                          <-------------   |  |
F297  0F5C      CLR    <$5C <-----         |  |
                          <-------|--------   |
F299  E764      STB    $04,S <-   |           |
F29B  39        RTS      ------|--|-----------|--> retour
F29C  C116      CMPB   #$16 <--|--|-----------
F29E  26F7      BNE    $F297 --|--
F2A0  0C5C      INC    <$5C    |
F2A2  20F5      BRA    $F299 --
Résultat du traitement manuel :

Code : Tout sélectionner

GETCH   TST     SS3GET        ; SS3GET est un flag de 3eme appel a GETCH dans les
        BNE     MINACC        ; sequences a 2 touches (contient le code minus.)
        CALL    KTST
CONFRM  PSHS    D             ; Premiere lecture
        LDX     #625          ; Anti-rebond de 5 Msec. = 625 * 8 Usec.
WAIT    LEAX    -1,X
        BNE     WAIT
        CALL    KTST          ; Relecture pour confirmation.
        CMPD    ,S++          ; même touche ?
        BNE     CONFRM        ; Non ! On recommence...
        CMPB    #$3A          ; B contient le code de la touche.
        BEQ     EXITER
        CMPB    KEY           ; Est-ce toujours la même touche ?
        BNE     NEWKEY        ; Non : donc pas de repetition possible.
        LDA     CMPTKB
        CMPA    LATCLV        ; Repeat apres LATCLV*l/10 SEC.
        BLO     EXIT01        ; CMPTKB incremente dans le traitement IRQ.
        LDA     #02           ; Masque bit 1 de STATUS
        BITA    STATUS        ; Bitl = 1 ==> trop rapide, ne pas repeter.
        BNE     EXIT01
        JSR     BRASHI        ; DRA avec STATUS , STA STATUS et RTS.
        SKIP2
NEWKEY  CLR     CMPTKB        ; Reset du compteur de touches.
        STB     KEY           ; B = code numerique.
        CALL    BIIP          ; Beep clavier.
        LSR     TEMP          ; Bit0 de TEMP = flag BASIC --> carry.
        BCC     CONTRL        ; C'est peut-être une touche control.
        ORB     #$80          ; Code numerique et Bit7 force a 1.
        BRA     EXITOK

MINACC  LDB     SS3GET        ; Envoi de la minuscule sauvegardee au 2eme appel
        CLRA
        BRA     STASS3        ; A --> SS3GET et sortie generale.

EXITER  CLR     KEY           ; Pas de touche mais n'efface pas
EXIT01  CLRB
        BRA     EXITB

CONTRL  LDX     CHRPTR        ; Pointeur sur la table de decodage.
        LDB     B,X           ; Transcodage en ASCII par la table.
        LSR     TEMP          ; Bit1 de TEMP = flag CONTROL --> carry.
        BCC     SHIFT         ; C'est peut-être une touche shift.
        ANDB    #$BF          ; Bit6 force a zero si control.
        BRA     CTRLVE

SHIFT   LSR     TEMP          ; Bit2 de TEMP = flag SHIFT --> carry.
        BCC     ONEKEY        ; Une seule touche enfoncee,"normale".
        CMPB    #SP
        BLO     EXITOK        ; Les codes < $20 ignorent le shift.
        BNE     NONINV        ; Shift-sp est le passage maj/min.
        LDA     #$80          ; Bit7 de STATUS = majuscule/minuscule.
        EORA    STATUS        ; Bit7 complemente.
        STA     STATUS
        CLRB
        BRA     EXITOK

NONINV  CMPB    #$2F          ; Entre $21 et $2F, forcer Bit4 a 1.
        BGT     SUPA2F
        ORB     #$10
        BRA     EXITOK        ; Il ne peut s'agir d'un accent.

SUPA2F  CMPB    #$39          ; Entre $30 et $39, forcer Bit4 a 0 (dans ce cas le
        BGT     SUPA39        ; SHIFT/0 sans sequence accent donne l'espace}.
        ANDB    #$EF
        CMPB    #$20          ; PATCH
        BNE     TSTSS2        ; PATCH
        LDB     #$60          ; PATCH
        BRA     TSTSS2        ; C'est peut être un accent aigu, grave ou trema.

SUPA39  CMPB    #$40          ; $40 = code de @.
        BNE     EXITOK        ; Shift/lettre --> majuscule.
        LDB     #$5E          ; $5E = code de ^ = shift/@.
        BRA     TSTSS2        ; C'est peut-être l'accent circonflexe.

ONEKEY  CMPB    #$41          ; $41 : code du A.
        BLO     TSTSS2        ; Si code du zero,c'est peut-être l'accent grave.
        LDA     STATUS        ; Test majuscule/minuscule.
        BPL     EXITOK        ; Bit7 = 0 ==> majuscule, donc on sort.
        ADDB    #$20          ; Code minuscule = code majuscule + $20.
TSTSS2  TST     SS2GET
        BEQ     CTRLVE        ; SS2GET non nul ==> sequence accent.
        LDA     #$0A          ; Compteur dans la table d'accents
NXTACC  DECA
        BEQ     EXITOK
        LEAX    -3,X
        CMPB    ,X            ; Code generant un accent ou une min. accentuee?
        BNE     NXTACC        ; On passe au code suivant
        LDD     1,X           ; Dans B le code de l'accent et dans A le code de
STASS3  STA     SS3GET
EXITOK  CLR     SS2GET        ; lncompatibilite avec sequence accent.
EXITB   STB     4,S           ; Resultat dans la pile.
        RTS
Pas sûr que Ghidra puisse faire aussi bien, en particulier pour les commentaires :wink:
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Désassembleur Z80

Message par __sam__ »

hlide a écrit : 19 sept. 2022 23:08 Du coup, $6E, c'est noOffset5 = 0, idxReg = 11, idxMode = 01110 et je ne vois rien de le fichier de définition qui traite cet opcode comme il faut à par celle-ci :

Code : Tout sélectionner

EA: W,idxReg    is idxReg & noOffset5=1 & idxMode=0b01110 & W # W,R
{
     local addr:2 = idxReg + W;
     export addr; 
}
qui ne colle pas (noOffset5 != 0).
Cela ne décode pas l’opcode, mais l’interprétation du post byte qui suit ce dernier. Ici c’est un adressage indirect sur W, un registre du 6309. Il doit y avoir un ifdef autour d’ailleurs.

Le bon post byte pour [addr] est $9f comme je l’indique plus haut. C’est le même postbyte quel que soit l’instruction (ex LDX, JMP, JSR, CLR,...).

La version précédente avait le bon décodage. La nouvelle version intégrant le support 6309 l’a modifié et depuis ca ne marche plus.
hlide a écrit : 19 sept. 2022 22:45 Je ne suis pas un expert en 6809, mais je trouve bizarre qu'un "imm8 = 0x9F" (opcode je suppose ?) devienne un "noOffset5=1 & idxReg=0b00 & idxMode=0b11101" (un $9F c'est 0b10011111). Admettons que c'est 1-00-11101, ça ferait $9D et non $9F.
Oui exactement. C’est là qu’est l’os hélas.

Pour avoir $9F, il faudrait juste noOffset5=31 tout court sans test sur idxReg qui est don’t care sur 6809 (et probablement pas sur 6309).
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
gotcha
Messages : 2759
Inscription : 30 mars 2017 11:39
Localisation : Isère
Contact :

Re: Désassembleur Z80

Message par gotcha »

@__sam__ @hlide Je vous sens motivés. Vous allez créer une pull-request pour fixer ça alors ? :)
Je m’intéresserai au 6809 quand je m'attaquerai au Vectrex et ça serait bien que le problème soit corrigé à ce moment là ;-)

Pour l'instant, je suis occupé avec le Z80 et je n'ai pas encore vu de truc bizarre en utilisant Ghidra.
Amstrad CPC et Goupil power :mrgreen:
Bénévole à l'association pour un conservatoire de l’informatique et de la télématique (https://www.aconit.org)
gotcha
Messages : 2759
Inscription : 30 mars 2017 11:39
Localisation : Isère
Contact :

Re: Désassembleur Z80

Message par gotcha »

J'ai maintenant besoin de connaitre le timing du code que j'ai désassemblé (le nombre de cycles des instructions ou des blocks d'instructions).
Savez vous s'il y a cette options dans Ghidra ?
Amstrad CPC et Goupil power :mrgreen:
Bénévole à l'association pour un conservatoire de l’informatique et de la télématique (https://www.aconit.org)
Répondre