Taula de continguts:

Revisitació de l'ordinador Z80: 6 passos
Revisitació de l'ordinador Z80: 6 passos

Vídeo: Revisitació de l'ordinador Z80: 6 passos

Vídeo: Revisitació de l'ordinador Z80: 6 passos
Vídeo: Could this tiny tube of metal fix our broken suspension? - Edd China's Workshop Diaries 28 2024, Desembre
Anonim
Revisitant l’ordinador Z80
Revisitant l’ordinador Z80
Revisitant l’ordinador Z80
Revisitant l’ordinador Z80

En el passat, he redactat una guia sobre com construir un ordinador basat en Z80 i he dissenyat el circuit perquè sigui el més simplista possible perquè es pugui construir el més fàcilment possible. També vaig escriure un petit programa amb la mateixa idea de simplicitat. Aquest disseny va funcionar bastant bé, però no estava totalment satisfet. Vaig començar a reescriure un programa que permetia programar-lo durant el temps d'execució. Es tractava de deixar-me provar trossos de codi sense haver de dedicar-lo a EEPROM, que al seu torn em requeriria que reprogramés l'EEPROM. No em va semblar una idea divertida. Després vaig començar a pensar en espais de memòria. Si volgués connectar un fragment de maquinari (IO principalment), un fragment de codi podria superar la quantitat d'espai de memòria disponible per al sistema. Recordeu que el disseny només feia servir el byte inferior del bus d’adreces i, a continuació, el bit inferior del byte alt es feia servir per seleccionar entre espais ROM i RAM. Això significava que només tenia 253 bytes d'espai per utilitzar. És possible que us pregunteu per què 253 en lloc de 256. Això és degut a que el meu nou codi injecta tres bytes de dades al final d’un programa escrit (això es tractarà més endavant, ja que el vaig modificar per treballar en el nou disseny).

n

Vaig tornar a repassar els meus antics esquemes per veure què passava més. Vaig trobar un petit defecte amb el circuit de selecció de memòria, que cobriré quan hi arribi. La versió simplificada: totes les sol·licituds d’escriptura realment passarien, tot i que sempre es posava a la memòria RAM. Probablement això no valia la pena preocupar-me, però aquest cop volia fer-ho correctament. I amb això vaig començar a dibuixar un nou esquema. Les dues imatges adjuntes a aquesta pàgina són anteriors i posteriors al circuit real. He netejat molt el cablejat dels espaguetis, que no fa gràcia.

n

Si heu seguit la meva presentació original i teniu previst seguir-la, em odiarà. Si comenceu de nou, tindreu sort. Simplement agafeu les parts de la llista (o el seu equivalent) i seguiu-ho.

Subministraments:

LM7805 - Regulador de 5 volts Z80: la CPU; el cervell del sistemaAT28C64B - EEPROM. Emmagatzematge de dades "permanent" utilitzat per al firmware IDT6116SA - SRAM de l'ordinador; s’utilitza per emmagatzemar codi d’usuari i / o emmagatzematge de dades general NE555 - Rellotge del sistema 74HC374 - Octal D-Latch amb / OE; utilitzat com a xip d’entrada 74LS273 - Octal D-Latch amb / MR; xip de sortida TLC59211 - Xip de controlador LED (utilitzat perquè el 74LS273 pugui conduir LEDs, ja que per si sol no és capaç de produir la sortida actual) MC14572 - Es tracta d’un xip “Line Driver”, però el vaig trobar perfecte per a la lògica de control de memòria. Té 4 inversors i una porta NAND i NOR construïda a74LS32 - Quad OR gateCD4001 - Quad NOR gateCD4040 - 12 Stage Ripple Counter; Divisor de rellotge dibuixat, però no implementat (per fer funcionar el sistema a velocitats de rellotge més baixes) 2 resistències de 10 k ohmis: una s’utilitza al circuit de temporitzador 555, així que utilitzeu el valor que vulgueu per a ella. 4 resistències de 1 k ohmies. Circuit de temporitzador 555, així que utilitzeu el que vulgueu. Un altre s’utilitza per conduir LEDs; per tant, varieu-lo si voleu Bus de resistència de 8x330 Ohm LED de bus de resistència de 8x10K Ohm: tres s’utilitzen per a l’estat del sistema i els altres vuit són sortides. Per al vuit, he utilitzat una pantalla de gràfics de barres (HDSP-4836). 4 condensadors: es fan servir dos el LM7805; 0,22uF i 0,1uF. Un és el temporitzador 555, així que utilitzeu el que creieu correcte. L'últim és el restabliment de l'engegada; 100uF2 N. O. Botons automàtics: un s'utilitza per a l'entrada, l'altre per restablir 8 commutadors SPST DIP: entrada de dades; He utilitzat Piano Key styleWire. Molts i molts cables

n

NOTA: la versió de forat MC14572 està obsoleta, però la versió SMD continua activa (ni tan sols l'estat "no per a un disseny nou"), de manera que és possible que hagueu de comprar una placa de circuit per permetre-la utilitzar. Es pot utilitzar un segon 74LS32 en lloc del MC14572 (consulteu l'esquema del "circuit de selecció de memòria" de l'ible anterior)

Pas 1: Visió general ràpida dels canvis + esquemes

Descripció ràpida dels canvis + esquemes
Descripció ràpida dels canvis + esquemes

Com es llegeix l’esquema: Una fletxa apuntada a un xip és una entrada: Entrada> -Una sortida de fletxa apuntada cap a un xip: Sortida <-Els autobusos utilitzen una línia en lloc d’una fletxa: Bus | -

n

La majoria de les fitxes s’han dibuixat amb els seus pinouts exactes. La petita immersió s'ha dibuixat en aquestes fitxes. La majoria de les fitxes també tenen números i etiquetes. Pot ser que siguin una mica difícils de llegir. El meu llapis es tornava avorrit.

n

Pel que fa a les connexions de circuits, la disposició del nou disseny és majoritàriament inalterada respecte a l’original. Vaig connectar el pinyol inferior del byte d’adreça alt a les memòries i després vaig utilitzar el bit baix del pinyol superior (A12) per a la selecció de RAM / ROM. Això significava que l'espai ROM passava de 0000-00FF a 0000-0FFF. L'espai RAM va passar de 0100-01FF a 1000-1FFF. També vaig canviar la lògica de control de memòria per obtenir un millor disseny i vaig afegir dos nous LED d'estat (i alguna lògica de cola). També he dibuixat (però no he connectat) un circuit divisor de rellotge. Es tractava de realitzar dues funcions. La funció òbvia és dividir la freqüència del rellotge. L'altra funció és per a PWM (Pulse Width Modulation), ja que el 555 no genera ones amb un 50% de cicles de treball. Això realment no importa en aquest circuit, però si voleu utilitzar el rellotge per accionar alguns LEDs, definitivament notareu els efectes (un (conjunt de) LED serà més feble que l’altre). La resta del circuit es manté essencialment inalterable.

Pas 2: CPU, memòria i control de memòria

CPU, memòria i control de memòria
CPU, memòria i control de memòria
CPU, memòria i control de memòria
CPU, memòria i control de memòria
CPU, memòria i control de memòria
CPU, memòria i control de memòria
CPU, memòria i control de memòria
CPU, memòria i control de memòria

Aquesta és la part en què els lectors de la meva versió anterior m’odien. A la versió original, vaig llançar algunes peces al tauler en un lloc que semblava que imposarien pocs problemes per connectar-se. El resultat semblava que algú hi tirava un plat d'espaguetis i era com "cables". Volia netejar-lo una mica, així que vaig començar arrencant tot excepte la CPU, la memòria RAM i la ROM. Vaig arrencar gairebé tot el circuit d'entrada, el circuit de sortida i la lògica de cola. Gairebé em feia mal fer-ho, però era necessari. He deixat intactes totes les connexions de dades i el byte inferior del bus d’adreces. Després vaig connectar els següents quatre bits del bus d’adreces (A8-A11) al xip ROM. Aquesta vegada m’he ocupat de donar la volta al xip per facilitar la retirada per reprogramar-la. També vaig saltar les connexions d’adreça fins al xip RAM.

n

Amb això fora del camí, ara havia de tenir connectada la lògica de control de memòria. A l’esquema original, havia connectat la línia del processador / MREQ directament a / CE als dos xips de memòria, i després vaig connectar / WR a la RAM / WE. Llavors, tenia la CPU / RD i / MREQ lògicament OR junts, així com A9. Essencialment, es va configurar de manera que totes les sol·licituds de memòria activessin tant la memòria RAM com la ROM, però es va utilitzar A9 per seleccionar quina de les fitxes / OE es va seleccionar. Tot va estar bé, ja que els xips romandrien inactius fins que es fes una sol·licitud de memòria i només un / OE estaria actiu durant una sol·licitud de lectura. Això va evitar la diafonosi, però va introduir un matís incòmode. Com que A9 només s’utilitzava per determinar quin xip generava dades i perquè la CPU tenia accés directe al pin de la memòria RAM / WE, es produirien totes les sol·licituds d’escriptura. Això no estava bé per a la ROM perquè el seu mode d’escriptura s’inhibeix lligant / WE directament al subministrament de 5V. La memòria RAM, però, s’escriuria a independentment de A9. Això significava que un intent d'escriptura en una ubicació d'espai ROM escriuria a la mateixa ubicació a l'espai RAM.

n

Una solució per a això seria tornar a connectar la lògica de control perquè la CPU tingui accés directe als pins / OE i / WE dels xips i, a continuació, utilitzar MREQ i A12 per seleccionar quins xips / CE es van impulsar. Vaig seguir aquesta idea, però en lloc d’utilitzar quatre portes NOR i un inversor com el disseny original, vaig trobar un petit xip incòmode que era perfecte per a la tasca. Vaig haver de crear un circuit que utilitzés només les portes lògiques disponibles al xip, però que va ser prou fàcil. A12 s'alimenta directament a una porta NAND i una porta NOR. / MREQ s’introdueix a la porta NOR i el seu compliment s’introdueix a la porta NAND. La porta NAND s'utilitza per unir / CE per a la memòria RAM i la sortida NOR s'inverteix i s'utilitza per accionar la ROM / CE. Això fa que el / MREQ hagi de ser baix abans de seleccionar qualsevol dels xips i, a continuació, A12 tria quin es selecciona. Amb aquesta configuració, ara qualsevol sol·licitud d’escriptura a ROM no farà res. També estalvia energia perquè només hi ha un xip actiu en lloc de tots dos. Pel que fa al propi xip lògic, encara tenim dos inversors inutilitzats. Un s’acostumarà més tard, però hi arribarem quan hi arribem.

Pas 3: LED d'estat del sistema

LED d'estat del sistema
LED d'estat del sistema
LED d'estat del sistema
LED d'estat del sistema

Abans de començar aquest projecte, intentava connectar-me amb una determinada IC, però tenia problemes. No estic segur del que passava, vaig utilitzar un LED de muntatge en panell per provar (un d’aquests conjunts que té una resistència incorporada). Fer-ho em va donar una idea de nostàlgia que encara s’utilitza avui en dia: els LED d’estat que s’utilitzen per indicar si s’estava llegint o escrivint memòria. S'havia d'utilitzar juntament amb el LED d'entrada que ja tenia. El LED d’entrada s’ha connectat al generador de senyals / WAIT per indicar-nos que el sistema està esperant espera d’entrada (hi arribaré, no us preocupeu). Vaig considerar afegir un LED per indicar una escriptura IO, però vaig pensar que els LED de sortida que es canviaven ja serien un gran indicador d'això. Pensant-hi, encara puc afegir-lo encara. Tot i això, em sembla útil saber si s’està llegint o escrivint memòria. Bé, és útil per a la depuració de programes. De fet, en vaig fer un ús intens com a tal quan intentava que el meu programa funcionés: “per què escriu a la memòria? Encara no se suposa que ho faci!"

n

Per controlar aquests LEDs, he utilitzat la porta quad NOR. Vaig utilitzar totes les portes. Només es van utilitzar dos per generar els senyals d’estat, però el xip no té les capacitats d’alimentació per conduir els LED. Són capaços d’enfonsar tanta potència, de manera que vaig utilitzar les altres dues portes NOR com a inversors i vaig connectar els LEDs com a tals. Com que un LED s’utilitza per indicar lectures i l’altre per escriure, i que no es produeix una sol·licitud de lectura i escriptura al mateix temps, he pogut sortir només amb una resistència per als dos LED. Pel que fa als senyals que necessitava per descodificar, també va ser prou fàcil. Volia que s'indiquessin totes les sol·licituds de lectura de memòria, de manera que la primera porta NOR tenia / MREQ i / RD a les seves entrades. L’estat d’escriptura era una mica més complicat, però igual de fàcil. Encara feia servir / MREQ com a entrada, però utilitzar / WR com a altre provocaria un matís menor que volia evitar. Hauria indicat TOTES les sol·licituds d'escriptura. Només volia les que realment passaven. Llavors, com ho faria? Bé, recordeu com he configurat el sistema perquè només es pugui escriure la memòria RAM? He utilitzat les memòries RAM / CE com a altra entrada a la porta NOR. Això significa que el LED només s’encendrà quan se selecciona la memòria RAM i es fa una sol·licitud d’escriptura. Pel que fa al color del LED, he triat el taronja com a indicador de lectura (però només he trobat groc) i el vermell com a indicador d’escriptura.

Pas 4: entrada i sortida

Entrada i sortida
Entrada i sortida
Entrada i sortida
Entrada i sortida
Entrada i sortida
Entrada i sortida

Al pas anterior, és possible que us hàgiu adonat que ja he afegit part de la resta de components a la placa. Estava reservant l’espai, de manera que no col·locés els cables per casualitat on volgués un component (per tant, hauria de trobar una nova ubicació per a aquest component). És possible que també us hàgiu adonat que he deixat els commutadors d'entrada al seu lloc i que heu connectat el cable d'alimentació. Vaig decidir que la ubicació original era el lloc perfecte i vaig decidir col·locar els LED de sortida a prop (a sobre). A la dreta de la pantalla de la barra hi ha el pestell d’entrada. A sobre hi ha el pestell de sortida i, a l'esquerra, el controlador de LED. Vaig començar connectant la pantalla al controlador, ja que era el més fàcil de fer. Després vaig connectar els interruptors al costat d’entrada del pestell d’entrada. A continuació, vaig connectar el costat de sortida del pestell de sortida al controlador LED. Pot semblar un ordre incòmode per aconseguir aquests cables, però va ser per una raó. L'entrada del tancament de sortida s'havia de connectar al bus de dades, així com la sortida del tancament d'entrada. La idea era connectar les sortides del pestell d’entrada a les entrades del pestell de sortida, cosa que vaig fer. Llavors, tot el que havia de fer era connectar aquell embolic al bus de dades. No importava cap a on anaven aquestes connexions físicament perquè totes estarien connectades elèctricament. L’ordinador ja està gairebé acabat.

Pas 5: restabliment i acabat d'entrada i sortida

Ho sentim, no hi ha fotos per a aquest pas. Consulteu el pas anterior per obtenir les imatges.

n

És possible que hagueu notat a la darrera foto del pas anterior que tenia un botó verd i un altre xip lògic instal·lat. El xip és la porta OR. S’utilitzen dues portes per generar el senyal / WAIT. Bé, es genera el senyal mitjançant OR-ing / IORQ i / RD des del processador. La sortida s’introdueix a la segona porta, on torna a ser OR amb un polsador. El botó fa que l'entrada de la porta sigui elevada, de manera que la sortida sigui alta. Aquesta sortida s’alimenta als processadors / pin WAIT. Mentre no es prem, una resistència manté l’entrada baixa. Inicialment vaig utilitzar una resistència de 10K, però el LS32 realment estava posant tensió a l'entrada. La resistència no va baixar prou i vaig haver de substituir-la per una 1K. De totes maneres, la idea és que quan es fa una sol·licitud de lectura IO, la primera i la segona porta OR indiquen al processador que esperi. Una vegada que configureu els commutadors d’entrada al que vulgueu, premeu el botó i traurà la CPU fora de la condició d’espera. El LED verd “d’entrada”, tal com l’he anomenat en un pas anterior, està connectat de manera que, quan el pin / WAIT es baixa, s’encengui.

n

Però encara no hem acabat. El xanclet d’entrada necessita un senyal per fer-li saber quan l’entrada de dades és vàlida i s’ha de publicar a la CPU. Aquest passador del rellotge està actiu. Abans, només el connectàvem al botó. Aquesta encara és una opció vàlida, però aquesta vegada he escollit posar-la a la mateixa sortida que la segona porta OR. Aquest CI també té un pin / OE que s’ha de conduir. Si es mantingués elevat, mai inseriria dades al bus. Si es mantingués baix, sempre estaria conduint l’autobús. Per solucionar-ho, simplement he utilitzat una tercera porta OR. Les entrades són / IORQ i / RD i la sortida va directament al latch’s / OE.

n

El pestell de sortida també necessita accionar el passador del rellotge. Una vegada més, està actiu. En el meu esquema, vaig dibuixar la quarta porta O directament dirigint el passador mitjançant / IORQ i / WR. Això significava que el pin del rellotge es mantindria elevat fins que es fes una sol·licitud d'escriptura, i després tornaria a baixar i tornar a pujar. Probablement hauria estat bé perquè el bus de dades encara hi hauria tingut dades vàlides immediatament després de l’intent d’escriptura, però des del punt de vista de l’enginyeria, era un disseny d’escombraries. No vaig notar aquest error fins després d’haver fet les imatges finals, però vaig trencar aquesta connexió i després vaig alimentar la sortida de la porta OR a un dels inversors no utilitzats de la lògica de control de memòria, i després vaig connectar la seva sortida al pin del rellotge.. També vaig corregir l’esquema i vaig trobar un altre error que havia comès. Jo també ho vaig corregir.

n

Amb tot això finalment fet, vaig tenir molt poca feina a fer: el circuit de restabliment. Vaig afegir un botó al tauler i vaig utilitzar una resistència de 10K per mantenir un costat alt. L’altra banda va directament a terra. El costat alt és la sortida / RESET, que anava a tots els xips amb un pin / RESET (el latch de la CPU i la sortida). Per completar el reinici de l’engegada, he afegit un condensador a la sortida / RESET. La idea és que la resistència de gran valor faci que el condensador relativament gran es carregui lentament i mantingui els pins / RESET baixos durant una quantitat de cicles de rellotge (la CPU necessita quatre cicles de rellotge). Probablement ja podeu endevinar quina és la cara negativa d’aquest circuit. És el mateix negatiu que la versió anterior perquè és el mateix circuit. Quan es prem el botó, el condensador queda essencialment curt a través del botó. Això és dolent tant per a la tapa com per al botó, de manera que si voleu que la vostra construcció sigui una mica més permanent, és possible que vulgueu redissenyar-la. Pensava en un altre temporitzador 555 configurat en mode monoestable. Però amb això, el circuit informàtic ja està acabat. Visca. Ara cal programar-lo.

Pas 6: Programació

Programar aquesta cosa va ser un malson. Vaig construir un programador Arduino EEPROM. No va funcionar. N’he construït un altre basat en el disseny i la codificació d’una altra persona. Encara no funcionava. Vaig tornar al mètode provat de configurar manualment les adreces i els bytes de dades a mà. D'alguna manera, ho vaig desordenar. He tornat a intentar-ho i encara m’he equivocat. Vaig tornar una altra vegada i vaig descobrir que estava apagat per un sol byte, així que el vaig corregir i finalment va funcionar, gràcies a Déu.

n

Pel que fa al programa real, sembla que és molt complex i difícil de seguir, però no ho és. De fet, és bastant senzill. La meitat en copia números. L'altra meitat es comparteix entre matemàtiques de 16 bits, salts condicionals i, encara, més números de còpia al voltant. Així que deixeu-me que ho expliqui i us expliqui com funciona.

n

La inicialització només estableix alguns valors de registre per al programa. El bucle del programa és una mica més complex, però no molt. En primer lloc, accepta l'entrada al registre A al port 00. Després, el registre E s'escriu a la memòria. Als dos primers bucles, el registre E conté dades brossa, de manera que intentem escriure-les als dos darrers bytes d’espai ROM perquè realment no s’escriuran; el punter d'adreça (IY) s'incrementa. El valor emmagatzemat a D es trasllada a E per escriure-ho a continuació. A, a continuació, es carrega a D i L i E es copia a H. HL és on es fa la comparació de valors mitjançant la resta i la comprovació de ZF (zero flag). El primer valor comparat amb aquest s’emmagatzema als registres B i C. B i C es tracten com un únic registre de 16 bits, BC. Si els valors són els mateixos, el programa salta directament a l'espai RAM, on se suposa que resideix el codi d'usuari. Si el codi de BC no coincideix, es torna a carregar HL amb els valors inicials de D i E i es torna a comparar amb el valor de SP de la mateixa manera que es va comparar amb BC. Si és una coincidència, té el mateix resultat, però s’escriuen tres bytes addicionals a la memòria. Els bytes són un codi que fa que la CPU torni al principi del seu programa (un restabliment de programari). Tanmateix, si la segona comparació no coincideix, el programa es dirigeix cap a on obté un valor de l'usuari.

n

LD SP, EDBFH; codi exe (afegeix salt)

n

LD IY, FFEH; punter de memòria inicial per a emmagatzematge de codi

n

LD BC, EDC3H; codi exe (sense bucle)

n

bucle; directiva assembler, de manera que no hem de saber on resideix aquesta porció a la memòria

n

EN A, (00H); obtenir dades del programa

n

LD (IY + 00H), E; E conté codi per emmagatzemar

n

INC IY; passa a la següent ubicació de memòria

n

LD E, D; ld D a E

n

LD D, A; ld en D

n

LD H, E; ld E en H

n

LD L, D; ld D en L

n

O A; restableix el senyalador de transport

n

SBC HL, BC; retorna 0 si s'ha introduït el codi exe 2

n

JP Z, 1000 H; si és així, salteu i executeu el programa

n

LD H, E; en cas contrari, actualitzeu-los als valors adequats

n

LD L, D

n

O A; primer restar pot haver establert la bandera carry. Esborreu-ho

n

SBC HL, SP; retorna 0 si s'ha introduït el codi exe 1

n

JP NZ, bucle; si no, repetiu el procés (començant per obtenir un valor)

n

LD (IY + 00H), C3H; en cas contrari, injecteu un codi de salt al final del programa d'usuari

n

LD (IY + 01H), 00H; jump actua bàsicament com un restabliment de programari

n

LD (IY + 02H), 00H; és un restabliment complet en cas que es modifiquin els registres

n

JP 1000H; salta i executa el programa d'usuari

Recomanat: