Rétro-ingénierie d'une puce informatique Commodore

Contexte et premiers échantillons



Dans un ancien post, j'ai écrit que je travaillais sur l'ingénierie inverse de la puce PLA du Commodore 128. Maintenant, j'ai presque terminé ce processus, il est donc temps de partager mes découvertes.



C'était un projet très intéressant car je ne connaissais pas grand-chose à la conception et à la fabrication de semi-conducteurs. Mes connaissances se limitaient à regarder des images de cristaux et à admirer ces belles photographies.



Pour moi, mes recherches ont commencé par l'achat d'un microscope bon marché pour souder des composants à montage en surface (SMD).





Microscope pas cher



Après un certain temps, j'ai trouvé une vidéo sur Youtube montrant un moyen plus simple de retirer les cristaux de silicium d'un boîtier.





La méthode semblait assez simple à mettre en œuvre chez moi, car j'avais déjà tout l'équipement nécessaire. Le retrait d'un circuit intégré d'un emballage nécessite généralement de l'acide sulfurique chauffé ou d'autres produits chimiques dangereux que je ne voulais pas vraiment expérimenter à la maison. J'ai donc déterré quelques puces MOS cassées dans mon inventaire (ne jetez jamais rien, cela pourrait être utile). Avec un peu de travail, j'ai obtenu deux matrices 8521R0 et une 8721 PLA. Dans le post précédent, j'ai montré la première vraie photo.





Photo complète de la puce PLA 8721



Meilleur microscope



Bien que l'expérience ait été un succès, j'ai immédiatement réalisé que le microscope n'avait pas une résolution suffisante pour prendre des photos avec une qualité suffisante pour moi. Avec un objectif Barlow 2x, le grossissement maximum est de 90x. De plus, le microscope n'a pas de platine, j'ai donc dû placer le cristal sur la table puis déplacer le microscope entier; cette conception est très instable et il est difficile de retirer les pièces nécessaires avec son aide.



J'ai donc trouvé et acheté un meilleur microscope, également à un prix raisonnable.





Microscope AmScope ME580-T Il a fait un



bien meilleur travail en prenant des photos de qualité décente, mais j'étais mécontent de l'appareil photo que j'ai acheté avec. Il s'agit d'un appareil photo bon marché sans télécommande, sauf pour l'application AmScope. À cette époque, la fondation Raspberry Pi a publié une nouvelle caméra de haute qualité pour le Raspberry Pi. Cette caméra a une monture C compatible avec le microscope, je l'ai donc immédiatement achetée et installée sur le microscope. Il fait un travail incroyable en fournissant un contrôle complet dans le confort de Linux.





Partie de la matrice en silicium 8521R0



Par rapport au système précédent, il s'agit d'une énorme amélioration. En raison de la résolution accrue, j'ai dû assembler les photos pour obtenir des images plus grandes. Cela semble simple au début, mais cela s'est avéré (comme vous l'avez peut-être deviné) pas du tout une tâche facile. J'ai encore du mal à assembler des photos, mais j'améliore progressivement mes compétences. L'un des facteurs clés pour une prise de vue panoramique réussie est l'uniformité de la mise au point, la balance des blancs, etc. Plus les photographies sont uniformes, plus l'assemblage est facile et meilleur.



Mécanisation



Tout cela m'a fait commencer à mécaniser la table. J'ai commencé à être très fatigué de déplacer manuellement la table, dans laquelle les photos étaient déplacées le long de plusieurs axes et d'autres déformations se produisaient.



Après avoir fait beaucoup de conception, d'impression 3D et de recherche sur le micrologiciel CNC, j'ai trouvé le design suivant:





Microscope modifié AmScope ME580-T



Sur le dessus se trouve un écran Raspberry 7 pouces, derrière lequel se trouve un Raspberry Pi4. La photo ne montre pas la caméra RPi HiQ montée sur le microscope. Le RPi prend des photos, les affiche sur l'écran et exécute également le code Python qui pilote la carte CNC.



L'étage en question et l'étage de nivellement sont entraînés par des moteurs pas à pas 28BYJ-48, qui sont entraînés par une petite carte ESP32 exécutant Grbl_Esp32 , ainsi que par quatre contrôleurs de moteur pas à pas AD4498.



Le circuit a certains problèmes logiciels et matériels, mais fonctionne assez bien pour mes besoins.



Inverser la puce



Après m'être occupé de la logistique, je suis retourné à l'ingénierie inverse de la puce elle-même. Je voulais à l'origine m'attaquer à la puce PLA parce que ce serait la chose la plus facile à comprendre. PLA signifie Programmable Logic Array ; des structures similaires étaient très courantes à l'époque du Commodore.



Sur la base du diagramme de Wikipedia, nous devrions nous attendre à ce qu'il y ait deux tableaux principaux sur la puce, ET et OU. Les entrées sont connectées à AND et les broches sortent du tableau OR.



Pour revenir au plan précédent de la matrice, nous pouvons l'améliorer en ajoutant des annotations aux broches et aux zones de la puce. Après avoir traité le but des cristaux, nous voyons que toutes les entrées sont connectées à un tableau et toutes les sorties sont connectées à un autre, comme prévu. aussi, cela nous aidera à comprendre où est quel tableau.





Snapshot of 8721 PLA die with annotations



Ici nous voyons les broches d'E / S marquées et leur connexion au cadre de connexion et aux broches du DIP lui-même. Sont également visibles les deux zones principales qui composent la structure PLA, le tableau AND et le tableau OR. En outre, il y a une logique supplémentaire ici marquée d'un point d'interrogation. Son but m'était inconnu, mais comme tous les contacts de sortie le traversent, j'ai supposé qu'il s'agissait d'une sorte d'étage de sortie.



ET tableau



Donc, si nous commençons à examiner de plus près la matrice ET, nous verrons l'image ci-dessous. Les couleurs sont un peu déformées, car cette photo a été prise avec un appareil photo AmScope et je ne pouvais pas comprendre comment régler la balance des blancs dessus.





ET matrice avec couche métallique



L'image n'est pas très utile pour comprendre ce qui se passe, car toutes les parties intéressantes sont recouvertes par la couche métallique supérieure. Je commençais tout juste à apprendre à l'époque, alors j'ai utilisé la force brute pour enlever le métal. J'ai effacé le métal par un fort impact mécanique; après avoir étudié au microscope, il s'est avéré que tout était enlevé en général, à l'exception du substrat lui-même.



Heureusement, les détails dont j'avais besoin se trouvaient dans la couche de diffusion située dans le substrat:





Substrat de la matrice ET



En regardant de près l'image, vous pouvez voir de petites lignes ondulées où se trouve le transistor pour créer une connexion dans la matrice.



OU tableau



En passant au tableau OR, nous voyons exactement le même format. Difficile à analyser sans enlever la couche métallique, mais plus facile par rapport à la matrice AND. Et c'est beaucoup plus facile lorsqu'il ne reste plus que le substrat et la couche de diffusion.





OU mourir avec une couche de métal





OU Substrat Matrix



Décodage matriciel complet



Forts de ces connaissances, nous pouvons procéder à la récupération de la matrice logique PLA complète à partir d'images.



J'ai marqué tous les transistors de chaque matrice avec des points et j'ai obtenu l'image suivante:





Une matrice AND avec une couche métallique



Dans une matrice AND, toutes les entrées sont horizontales et un signal normal et inversé est envoyé à chaque ligne. Dans une matrice OU, toutes les dérivations sont horizontales et connectées à des lignes verticales appelées minterms.



Après avoir examiné les points, nous pouvons décoder les minterms en exécutant la logique "ET" pour toutes les lignes verticales de la matrice ET, par exemple



p0 = CHAREN & HIRAM & BA & !MS3 & GAME & RW & AEC & A12 & !A13 & A14 & A15



Pour les broches, nous prenons une ligne horizontale pour chaque broche et la combinons avec "ou", par exemple



SDEN = p42 | p43 | p66 | p69



Voici comment nous avons obtenu l'ensemble des équations logiques. Hourra!



Étape de sortie



Revenons à la photo complète du cristal - maintenant nous avons tout sauf le rectangle marqué d'un point d'interrogation sur le chemin de sortie.



En regardant les photographies à plus haute résolution de cette zone, nous voyons des motifs similaires pour chaque broche. Dans tous les cas sauf deux, cette structure est contournée et la sortie de la matrice OU va directement à la broche de sortie. Cependant, cela ne s'applique pas à deux contacts: DWEet CASENB.



DWELe signal d'activation d'écriture est-il appliqué aux puces DRAM du système principal et CASENB transmet le signal CAS à la RAM. Ces deux signaux sont en quelque sorte traités par ces structures de portes de sortie, j'ai donc dû faire de l'ingénierie inverse sur ce bloc.





Bloc de sortie avec couche métallique





Substrat du bloc de sortie



Après avoir passé beaucoup de temps à lire des informations sur la conception et la fabrication de puces en silicium, ainsi que plusieurs tentatives, j'ai pu créer un circuit d'apparence logique. Je n'entrerai pas dans les détails de tout le processus ici, mais je le documenterai et le publierai plus tard. Ici, je voudrais également remercier Frank Wolfe pour son aide, si possible soutenir son projet!





Circuit de bloc de sortie



En regardant un peu plus loin, la façon dont ce circuit est utilisé est avec des broches DWEet le CASENBtransforme en un verrou D régulier. Le verrou qui permet cela est représenté dans le PLA par une paire de lignes dans le OU.



Résultat



Nous avons donc obtenu le résultat final et maintenant nous pouvons écrire le code HDL complet pour la puce PLA C128. Pour cela, j'utiliserai Verilog. Considérer. qu'il s'agit de mon premier code Verilog, donc ce n'est peut-être pas optimal. L'utilisation d'un verrou D pour une broche est généralement considérée comme une mauvaise pratique dans Verilog, mais dans ce cas, je réplique la logique et la fonctionnalité de la puce finie.



Je l'ai vérifié si possible, mais s'il me manque quelque chose, veuillez le signaler!



Contrairement au PLA C64, la puce PLA C128 ne peut pas être remplacée par une simple EPROM ou quelque chose de similaire en raison de la présence de verrous de sortie.



module pla_8721(
    input rom_256,
    input va14,
    input charen,
    input hiram,
    input loram,
    input ba,
    input vma5,
    input vma4,
    input ms0,
    input ms1,
    input ms2,
    input ms3,
    input z80io,
    input z80en,
    input exrom,
    input game,
    input rw,
    input aec,
    input dmaack,
    input vicfix,
    input a10,
    input a11,
    input a12,
    input a13,
    input a14,
    input a15,
    input clk,

    output sden,
    output roml,
    output romh,
    output clrbnk,
    output from,
    output rom4,
    output rom3,
    output rom2,
    output rom1,
    output iocs,
    output dir,
    output reg dwe,
    output reg casenb,
    output vic,
    output ioacc,
    output gwe,
    output colram,
    output charom);

wire p0;
wire p1;
wire p2;
wire p3;
wire p4;
wire p5;
wire p6;
wire p7;
wire p8;
wire p9;
wire p10;
wire p11;
wire p12;
wire p13;
wire p14;
wire p15;
wire p16;
wire p17;
wire p18;
wire p19;
wire p20;
wire p21;
wire p22;
wire p23;
wire p24;
wire p25;
wire p26;
wire p27;
wire p28;
wire p29;
wire p30;
wire p31;
wire p32;
wire p33;
wire p34;
wire p35;
wire p36;
wire p37;
wire p38;
wire p39;
wire p40;
wire p41;
wire p42;
wire p43;
wire p44;
wire p45;
wire p46;
wire p47;
wire p48;
wire p49;
wire p50;
wire p51;
wire p52;
wire p53;
wire p54;
wire p55;
wire p56;
wire p57;
wire p58;
wire p59;
wire p60;
wire p61;
wire p62;
wire p63;
wire p64;
wire p65;
wire p66;
wire p67;
wire p68;
wire p69;
wire p70;
wire p71;
wire p72;
wire p73;
wire p74;
wire p75;
wire p76;
wire p77;
wire p78;
wire p79;
wire p80;
wire p81;
wire p82;
wire p83;
wire p84;
wire p85;
wire p86;
wire p87;
wire p88;
wire p89;

wire casenb_int;
wire casenb_latch;

/* Product terms */

assign p0 = charen & hiram & ba & !ms3 & game &  rw & aec & a12 & !a13 & a14 & a15;
assign p1 = charen & hiram &      !ms3 & game & !rw & aec & a12 & !a13 & a14 & a15;
assign p2 = charen & loram & ba & !ms3 & game &  rw & aec & a12 & !a13 & a14 & a15;
assign p3 = charen & loram &      !ms3 & game & !rw & aec & a12 & !a13 & a14 & a15;

assign p4 = charen & hiram & ba & !ms3 & !exrom & !game &  rw & aec & a12 & !a13 & a14 & a15;
assign p5 = charen & hiram &      !ms3 & !exrom & !game & !rw & aec & a12 & !a13 & a14 & a15;
assign p6 = charen & loram & ba & !ms3 & !exrom & !game &  rw & aec & a12 & !a13 & a14 & a15;
assign p7 = charen & loram &      !ms3 & !exrom & !game & !rw & aec & a12 & !a13 & a14 & a15;

assign p8 = ba & !ms3 & exrom & !game & rw & aec & a13 & !a13 & a14 & a15;
assign p9 =      !ms3 & exrom & !game & rw & aec & a12 & !a13 & a14 & a15;

assign p10 = ba & !ms2 & ms3 &  rw & aec & a12 & !a13 & a14 & a15;
assign p11 =      !ms2 & ms3 & !rw & aec & a12 & !a13 & a14 & a15;

assign p12 = charen & hiram & ba & !ms3 & game &  rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p13 = charen & hiram &      !ms3 & game & !rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p14 = charen & loram & ba & !ms3 & game &  rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p15 = charen & loram &      !ms3 & game & !rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;

assign p16 = charen & hiram & ba & !ms3 & !exrom & !game &  rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p17 = charen & hiram &      !ms3 & !exrom & !game & !rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p18 = charen & loram & ba & !ms3 & !exrom & !game &  rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p19 = charen & loram &      !ms3 & !exrom & !game & !rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;

assign p20 = ba & !ms3 & exrom & !game & rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p21 =      !ms3 & exrom & !game & rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;

assign p22 = ba & !ms2 & ms3 &  rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;
assign p23 =      !ms2 & ms3 & !rw & aec & !a10 & !a11 & a12 & !a13 & a14 & a15;

assign p24 = charen & hiram & ba & !ms3 & game &  rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p25 = charen & hiram &      !ms3 & game & !rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p26 = charen & loram & ba & !ms3 & game &  rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p27 = charen & loram &      !ms3 & game & !rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;

assign p28 = charen & hiram & ba & !ms3 & !exrom & !game &  rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p29 = charen & hiram &      !ms3 & !exrom & !game & !rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p30 = charen & loram & ba & !ms3 & !exrom & !game &  rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p31 = charen & loram &      !ms3 & !exrom & !game & !rw & aec & !a10 & a11 & a12 & !a13       & a15;

assign p32 = ba & !ms3 & exrom & !game & rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p33 =      !ms3 & exrom & !game & rw & aec & !a10 & a11 & a12 & !a13       & a15;

assign p34 = ba & !ms2 & ms3 &  rw & aec & !a10 & a11 & a12 & !a13 & a14 & a15;
assign p35 =      !ms2 & ms3 & !rw & aec & !a10 & a11 & a12 & !a13       & a15;

assign p36 = !aec;
assign p37 = !rw & aec & !a10 & a11 & a12 & !a13 & a15;

assign p39 = !charen & hiram & !ms3 &           game & rw & aec & a12 & !a13 & a14 & a15;
assign p40 = !charen & loram & !ms3 &           game & rw & aec & a12 & !a13 & a14 & a15;
assign p41 = !charen & hiram & !ms3 & !exrom & !game & rw & aec & a12 & !a13 & a14 & a15;

assign p42 = va14 & !vma5 & vma4 & !ms3          &  game & !aec;
assign p43 = va14 & !vma5 & vma4 & !ms3 & !exrom & !game & !aec;

assign p44 = !ms0 & !ms1 & ms2 &ms3 & z80en & rw & aec & a12 & !a13 & a14 & a15;
assign p45 = hiram & loram & !ms3 & !exrom & rw & aec & !a13 & !a14 & a15;

assign p46 = !ms3 & exrom & !game & aec & !a13 & !a14 & a15;
assign p47 = ms0 & !ms1 & ms3 & exrom & !game & aec & !a14 & a15;
assign p48 = !ms0 & ms1 & ms3                 & aec & !a14 & a15;

assign p49 = hiram & !ms3 & !exrom & !game & aec & a13 & !a14 & a15;
assign p50 = ms3 & exrom & !game & aec & a13 & !a14 & a15;

assign p51 = vma5 & vma4 & !ms3 & exrom & !game & !aec;
assign p52 =  ms0 & !ms1 & ms3 & rw & aec & !a12 & !a13 & a14 & a15;
assign p53 = !ms0 &  ms1 & ms3 & rw & aec & !a12 & !a13 & a14 & a15;
assign p54 = !ms0 & !ms1 & ms3 & rw & aec & !a12 & !a13 & a14 & a15;

assign p55 = !ms0 & !ms1 & z80io & !z80en & rw & aec & !a12 & !a13 & !a14 & !a15;
assign p56 = !ms0 & !ms1 & ms3 & rw & aec & !a14 &  a15;
assign p57 = !ms0 & !ms1 & ms3 & rw & aec &  a14 & !a15;

assign p58 = hiram         & !ms3          &  game & rw & aec & a13 &  a14 & a15;
assign p59 = hiram         & !ms3 & !exrom & !game & rw & aec & a13 &  a14 & a15;
assign p60 = hiram & loram & !ms3          &  game & rw & aec & a13 & !a14 & a15;

assign p61 = !z80io & !z80en & aec & !a10 & !a11        & !a13 & a14 & a15;
assign p62 = !z80io & !z80en & aec               &  a12 & !a13 & a14 & a15;
assign p63 = !z80io & !z80en & aec & !a10 &  a11 &  a12 & !a13 & a14 & a15;

assign p64 = !rw & aec;
assign p65 =  rw & aec;
assign p66 = !aec;

assign p67 = !ms2 & !z80en       & aec & !a10 & !a11 & a12 & !a13 & !a14 & !a15;
assign p68 = !ms2 & !z80en & !rw & aec & !a10 & !a11 & a12 & !a13 & !a14 & !a15;

assign p69 = !charen & !vma5 & vma4 & ms3 & aec;

assign p70 = !rom_256 & !ms0 & !ms1 & ms3 & rw & aec               & a14 & !a15;
assign p71 = !rom_256 & !ms0 & !ms1 & ms3 & rw & aec & !a12 & !a13 & a14 &  a15;
assign p72 = !rom_256 & !ms0 & !ms1 & z80io & !z80en & rw & aec & !a12 & !a13 & !a14 & !a15;

assign p73 = clk;
assign p74 = rw & !aec & vicfix;

assign p75 =            !ms0 & !ms1       & ms3 & rw & aec       &  a13 & a14 & a15;
assign p76 = !rom_256 & !ms0 & !ms1       & ms3 & rw & aec       &  a13 & a14 & a15;
assign p77 =            !ms0 &  ms1       & ms3 & rw & aec       &  a13 & a14 & a15;
assign p78 =            !ms0 &  ms1 & ms2 & ms3 & rw & aec & a12 & !a13 & a14 & a15;
assign p79 =             ms0 & !ms1       & ms3 & rw & aec       &  a13 & a14 & a15;
assign p80 =             ms0 & !ms1 & ms2 & ms3 & rw & aec & a12 & !a13 & a14 & a15;

assign p81 = !ms3 & exrom & !game & aec &  a12        & !a14 & !a15;
assign p82 = !ms3 & exrom & !game & aec        &  a13 & !a14;
assign p83 = !ms3 & exrom & !game & aec               &  a14;
assign p84 = !ms3 & exrom & !game & aec & !a12 & !a13 &  a14 &  a15;

assign p85 = !loram & ms3 &  aec;
assign p86 = !hiram & ms3 & !aec;

/* outputs */

assign sden = p42 || p43 || p66 || p69;
assign roml = p45 || p46 || p47;
assign romh = p49 || p50 || p51 || p52 || p79 || p80;
assign clrbnk = p85 || p86;
assign from = p48 || p53 || p77 || p78;
assign rom4 = p54 || p55 || p75;
assign rom3 = p56 || p70;
assign rom2 = p57;
assign rom1 = p58 || p59 || p60 || p71 || p71 || p76;
assign iocs = p0 || p1 || p2 || p3 || p4 || p5 || p6 || p7 || p8 || p9 || p10 || p11 || p62;
assign dir = p12 || p14 || p16 || p18 || p20 || p22 || p24 || p26 || p28 || p30 || p32 || p34 || p39 || p40 || p41 || p44 || p65;
assign vic = p12 || p13 || p14 || p15 || p16 || p17 || p18 || p19 || p20 || p21 || p22 || p23 || p61;
assign ioacc = p0 || p1 || p2 || p3 || p4 || p5 || p6 || p7 || p8 || p9 || p10 || p11 || 
               p12 || p13 || p14 || p15 || p16 || p17 || p18 || p19 || p20 || p21 || p22 || p61 || p62;
assign gwe = p37;
assign colram = p24 || p25 || p26 || p27 || p28 || p29 || p30 || p31 || p32 || p33 || p34 || p35 || p36 || p63 || p67;
assign charrom = p39 || p40 || p41 || p42 || p43 || p44 || p69;

assign casenb_latch = p73 || p74;

assign casenb_int = p0 || p1 || p2 || p3 || p4 || p5 || p6 || p7 || p8 || p9
                || p10 || p11 || p12 || p13 || p14 || p15 || p16 || p17 || p18 || p19
                || p20 || p21 || p22 || p23 || p39 || p40 || p41 || p42 || p43 || p44
                || p45 || p46 || p47 || p48 || p49 || p50 || p51 || p52 || p53 || p54
                || p55 || p56 || p57 || p58 || p59 || p60 || p61 || p62 || p63 || p67
                || p69 || p70 || p71 || p72 || p75 || p76 || p77 || p78 || p79 || p80
                || p81 || p82 || p83 || p84;

/* Latched outputs */

always @ (clk or p64)
  if (clk)
    dwe <= p64;

always @ (casenb_latch or casenb_int)
  if (casenb_latch)
    casenb <= casenb_int;

endmodule


Et après



La prochaine puce analysée sera la puce MMU de l'ordinateur C128, qui prendra beaucoup plus de temps à travailler, car ce n'est pas seulement du PLA ordinaire.



Voir également:






All Articles