Hersiening van die Z80 -rekenaar: 6 stappe
Hersiening van die Z80 -rekenaar: 6 stappe
Anonim
Besoek die Z80 -rekenaar weer
Besoek die Z80 -rekenaar weer
Besoek die Z80 -rekenaar weer
Besoek die Z80 -rekenaar weer

In die verlede het ek 'n gids opgestel oor hoe om 'n Z80-rekenaar te bou, en ek het die kring so eenvoudig as moontlik ontwerp sodat dit so maklik as moontlik gebou kan word. Ek het ook 'n klein program geskryf met dieselfde idee van eenvoud. Hierdie ontwerp het redelik goed gewerk, maar ek was nie heeltemal tevrede daarmee nie. Ek het begin met die herskrywing van 'n program wat dit moontlik gemaak het om dit tydens looptyd te programmeer. Dit was om my stukke kode te laat toets sonder om dit aan EEPROM toe te wy, wat weer sou vereis dat ek die EEPROM herprogrammeer. Dit het vir my nie na 'n prettige idee geklink nie. Toe begin ek dink aan geheue spasies. As ek 'n hardeware (hoofsaaklik IO) wil koppel, kan 'n stuk kode moontlik die hoeveelheid geheue wat die stelsel beskikbaar het, oorskry. Onthou, die ontwerp het slegs die onderste byte van die adresbus gebruik, en dan is die onderste deel van die hoë byte gebruik om tussen ROM- en RAM -spasies te kies. Dit het beteken dat ek net 253 grepe spasie kon gebruik. U vra miskien waarom 253 in plaas van 256. Dit is omdat my nuwe kode drie grepe data aan die einde van 'n geskrewe program inspuit (dit word later behandel, aangesien ek dit verander het om aan die nuwe ontwerp te werk).

n

Ek het teruggegaan na my ou skemas om te sien wat nog aangaan. Ek het 'n klein fout gevind met die geheue seleksie kring, wat ek sal dek wanneer ek daar kom. Die vereenvoudigde weergawe: alle skryfversoeke sal eintlik deurgaan, hoewel dit altyd in die RAM is. Dit was waarskynlik nie die moeite werd om oor bekommerd te wees nie, maar ek wou dit hierdie keer behoorlik doen. En daarmee het ek 'n nuwe skema begin teken. Die twee foto's wat op hierdie bladsy aangeheg is, is voor en na die werklike stroombaan. Ek het soveel van die spaghetti -bedrading skoongemaak, dit is nie snaaks nie.

n

As u my oorspronklike voorlegging gevolg het en van plan is om dit te volg, sal u my haat. As u nuut begin, het u geluk. Gryp net die dele in die lys (of hul ekwivalent) en volg dit.

Benodighede:

LM7805 - 5 Volt regulator Z80 - die SVE; die brein van die systemAT28C64B - EEPROM. 'Permanente' datastoor wat gebruik word vir die rekenaar se firmwareIDT6116SA - SRAM; gebruik vir die stoor van gebruikerskode en /of algemene data stoorNE555 - Stelselklok74HC374 - Octal D -Latch met /OE; gebruik as insetskyf74LS273 - Octal D -Latch met /MR; output chip TLC59211 - LED driver chip (gebruik sodat die 74LS273 LED's kan dryf, aangesien dit alleen nie die huidige uitset kan lewer nie) MC14572 - Dit is 'n 'Line Driver' chip, maar ek het gevind dat dit perfek was vir die Memory Control logika. Dit het 4 omsetters en 'n NAND- en NOR -hek wat ingebou is in 74LS32 - Quad OF -hek CD4001 - Quad NOR -hek CD4040 - Ripple -teller met 12 fases; Getekende, maar nie geïmplementeerde klokverdeler (om die stelsel teen laer kloksnelhede te laat werk) 2 10K Ohm -weerstande - Een word gebruik in die 555 -tydkring, gebruik dus watter waarde u ook al wil hê 4 1K Ohm -weerstande - Een word gebruik vir die 555 timer stroombaan, so gebruik wat u wil. 'N Ander een word gebruik om LED's aan te dryf, dus verander dit ook as u 8x330 Ohm Weerstandsbus8x10K Ohm Weerstand Bus11 LED's wil hê - Drie word gebruik vir stelselstatus en die ander agt is uitsette. Vir die 8 het ek 'n staafgrafiekvertoning (HDSP -4836) gebruik; 4 kondensators - twee is die LM7805; 0.22uF en 0.1uF. Die een is vir die 555 -timer, dus gebruik wat u voel reg is. Die laaste is om aan te skakel; 100uF2 N. O. Drukknoppies - die een word gebruik vir invoer, die ander vir reset8 SPST DIP -skakelaars - data -invoer; Ek het Piano Key styleWire gebruik. Baie baie draad

n

LET WEL: die weergawe MC14572 deur die gat is verouderd, maar die SMD -weergawe is nog steeds aktief (selfs nie 'nie vir 'n nuwe ontwerp nie'), daarom moet u moontlik 'n printplaat aanskaf sodat u dit kan gebruik. 'N Tweede 74LS32 kan in die plek van die MC14572 gebruik word (verwys na die "geheue seleksie stroombaan" skema van vorige ible)

Stap 1: 'n vinnige oorsig van veranderinge en skemas

Vinnige oorsig van veranderinge + skema's
Vinnige oorsig van veranderinge + skema's

Hoe om die skemas te lees: 'n Pyl wat na 'n skyfie gerig is, is 'n invoer: Invoer> -''n Pyl wat van 'n skyf af wegwys, is 'n uitset: Uitset <-Busse gebruik 'n lyn in plaas van 'n pyl: Bus |-

n

Die meeste skyfies is getrek met hul presiese uitknipsels. Die klein duik is op hierdie skyfies getrek. Die meeste skyfies bevat ook speldnommers en etikette. Hulle is dalk 'n bietjie moeilik om te lees. My potlood het dof geword.

n

Wat stroomverbindings betref, is die uitleg van die nuwe ontwerp meestal onveranderd van die oorspronklike. Ek het die onderste nibble van die hoë -byte -adres aan die herinneringe gekoppel en dan die onderste gedeelte van die boonste nibble (A12) gebruik vir die keuse van RAM/ROM. Dit het beteken dat die ROM-ruimte van 0000-00FF tot 0000-0FFF gegaan het. Ramruimte het van 0100-01FF na 1000-1FFF gegaan. Ek het ook die Memory Control -logika vir 'n beter ontwerp verruil en twee nuwe status -LED's (en 'n bietjie gomlogika) bygevoeg. Ek het ook 'n klokverdelerkring getrek (maar nie bedraad nie). Dit was om twee funksies uit te voer. Die voor die hand liggende funksie is om die klokfrekwensie te verlaag. Die ander funksie is vir PWM (Pulse Width Modulation) doeleindes, aangesien die 555 nie golwe genereer met 50% dienssiklusse nie. Dit maak nie regtig saak in hierdie kring nie, maar as u met die horlosie 'n paar LED's wil gebruik, sal u beslis die effekte opmerk (een (stel) LED's) sal dowwer wees as die ander. Die res van die stroombane is in wese onveranderd.

Stap 2: CPU, geheue en geheue beheer

CPU, geheue en geheue beheer
CPU, geheue en geheue beheer
CPU, geheue en geheue beheer
CPU, geheue en geheue beheer
CPU, geheue en geheue beheer
CPU, geheue en geheue beheer
CPU, geheue en geheue beheer
CPU, geheue en geheue beheer

Dit is die deel waar lesers van my vorige weergawe my haat. In die oorspronklike konstruksie het ek net dele op die bord gegooi op 'n plek wat lyk asof hulle nie 'n probleem sou veroorsaak om aan te sluit nie. Die resultaat het gelyk asof iemand 'n bord spaghetti daarop gestort het en soos 'drade' was. Ek wou dit 'n bietjie skoonmaak, en ek het begin met alles behalwe die SVE, RAM en ROM. Ek het byna die hele ingangskring, uitsetkring en die gomlogika opgetrek. Dit het my amper seergemaak, maar dit was nodig. Ek het al die dataverbindings ongeskonde gelaat en die onderste byte van die adresbus. Ek verbind toe die volgende vier stukkies van die adresbus (A8-A11) aan die ROM-chip. Ek het hierdie keer om die chip gegaan om dit makliker te maak om te herprogrammeer. Ek het ook die adresverbindings na die RAM -chip gespring.

n

Met dit uit die weg geruim, moes ek nou die logika vir geheue -beheer in werking stel. In die oorspronklike skema het ek die verwerker se /MREQ -lyn direk aan /CE aan albei geheue -skyfies gekoppel, daarna het ek /WR aan die RAM /WE gekoppel. Toe het ek die CPU's /RD en /MREQ logies OF saam, sowel as A9. Dit is in wese so opgestel dat alle geheueversoeke beide RAM en ROM geaktiveer het, maar A9 is gebruik om te kies watter van die chips /OE gekies is. Dit was goed, en alles omdat die skyfies onaktief sou bly totdat 'n geheueversoek gedoen is en dan slegs een /OE aktief sou wees tydens 'n leesversoek. Dit het oorspraak voorkom, maar het 'n ongemaklike nuanse ingebring. Omdat A9 slegs gebruik is om vas te stel watter skyf data uitstuur en omdat die SVE direkte toegang tot die RAM /WE -pen gehad het, sal alle skryfversoeke deurgaan. Dit was goed vir die ROM, want die skryfmodus word belemmer deur /WE direk aan die 5V -toevoer te koppel. Die RAM sal egter geskryf word, ongeag A9. Dit het beteken dat 'n poging om na 'n ROM -ruimte te skryf, na dieselfde plek in die RAM -ruimte sou skryf.

n

Een oplossing hiervoor sou wees om die kontrolelogika weer te bedraad sodat die SVE direkte toegang tot die chips /OE- en /WE -penne het en dan MREQ en A12 te gebruik om te kies watter skyfies /CE aangedryf word. Ek het hierdie idee aangeneem, maar in plaas daarvan om vier NOR -hekke en 'n omskakelaar soos die oorspronklike ontwerp te gebruik, het ek 'n ongemaklike chip gevind wat perfek was vir die taak. Ek moes 'n stroombaan skep wat slegs die logiese hekke in die chip gebruik, maar dit was maklik genoeg. A12 voer direk in 'n NAND -hek en 'n NOR -hek in. /MREQ word in die NOR -hek ingevoer en die kompliment daarvan word in die NAND -hek ingevoer. Die NAND -hek word gebruik om te ry /CE vir die RAM en die NOR -uitvoer word omgekeerd en gebruik om die ROM /CE aan te dryf. Dit maak dat /MREQ laag moet wees voordat die chip gekies word, en dan kies A12 watter een gekies word. Met hierdie opset, sal enige skryfversoeke na ROM niks doen nie. Dit bespaar ook krag omdat slegs een chip aktief is in plaas van albei. Wat die logika -chip self betref, het ons nog twee ongebruikte omsetters binne. Die een sal later gewoond raak, maar ons kom daar as ons daar kom.

Stap 3: LED's vir stelselstatus

Stelsel status LED's
Stelsel status LED's
Stelsel status LED's
Stelsel status LED's

Voordat ek met hierdie projek begin het, het ek probeer om met 'n sekere IC te skakel, maar ek het probleme daarmee gehad. Onseker oor wat aan die gang was, het ek 'n paneel -LED gebruik om te ondersoek (een van die samestellings met 'n ingeboude weerstand). Dit het my 'n nostalgie -idee gegee wat vandag nog gebruik word: status -LED's wat gebruik word om aan te dui of daar van geheue gelees of geskryf word. Dit moes saam met die ingang -LED wat ek reeds gehad het, gebruik word. Die invoer -LED is gekoppel aan die /WAIT seinopwekker om aan te dui dat die stelsel wel op invoer wag (ek kom daar, moenie bekommerd wees nie). Ek het dit oorweeg om 'n LED by te voeg om 'n IO -skryf aan te dui, maar ek het gedink dat die uitset -LED's wat verander word, reeds 'n goeie aanduiding daarvan is. As ek daaroor nadink, kan ek dit nog steeds byvoeg. Tog vind ek dit nuttig om te weet of geheue gelees of geskryf word. Wel, dit is in elk geval nuttig vir die ontfouting van programme. Ek het dit as sodanig sterk gebruik as ek probeer om my program aan die gang te kry: “hoekom skryf dit in die geheue? Dit is nog nie veronderstel om dit te doen nie!”

n

Om hierdie LED's te beheer, het ek die vier NOR -hek gebruik. Ek het al die hekke gebruik. Slegs twee is gebruik om die statusseine te genereer, maar die chip het nie die krag om die LED's werklik aan te dryf nie. Hulle kan soveel krag sink, so ek het die ander twee NOR -hekke as omsetters gebruik en die LED's as sodanig verbind. Omdat die een LED gebruik word om lees en die ander vir skryf aan te dui, en 'n lees- en skryfversoek nie terselfdertyd voorkom nie, kon ek wegkom deur slegs een weerstand vir beide LED's te gebruik. Wat die seine betref wat ek moes dekodeer, dit was ook maklik genoeg. Ek wou hê dat alle geheue -leesversoeke aangedui moet word, dus het die eerste NOR -hek /MREQ en /RD op sy insette. Die skryfstatus was 'n bietjie moeiliker, maar net so maklik. Ek het nog steeds /MREQ as een invoer gebruik, maar die gebruik van /WR as die ander sou 'n geringe nuanse veroorsaak wat ek wou vermy. Dit sou ALLE skryfversoeke aangedui het. Ek wou net diegene hê wat eintlik deurgegaan het. So, hoe sou ek dit doen? Onthou ek hoe ek die stelsel opgestel het sodat slegs die RAM geskryf kan word? Ek het die RAM's /CE gebruik as die ander invoer na die NOR -hek. Dit beteken dat die LED slegs sal brand wanneer RAM gekies word en 'n skryfversoek gemaak word. Wat LED -kleur betref, het ek oranje gekies as die leesaanwyser (maar ek het net geel gekry) en rooi as die skryfaanwyser.

Stap 4: Invoer en uitvoer

Invoer en uitvoer
Invoer en uitvoer
Invoer en uitvoer
Invoer en uitvoer
Invoer en uitvoer
Invoer en uitvoer

In die vorige stap het u moontlik opgemerk dat ek 'n paar van die res van die komponente reeds op die bord gevoeg het. Ek het die ruimte gereserveer, sodat ek nie per ongeluk drade sou plaas waar ek 'n komponent wou hê nie (dus sou ek 'n nuwe plek vir die komponent moes vind). U het miskien ook opgemerk dat ek die ingangskakelaars op hul plek gelos het en na die kragrail gekoppel het. Ek het besluit dat die oorspronklike ligging die perfekte plek is, en ek het besluit om die LED's vir die uitvoer naby (hierbo) te plaas. Aan die regterkant van die balkweergawe is die invoergrendel. Daarbo is die uitsetgrendel, en links daarvan is die LED -bestuurder. Ek het begin deur die skerm aan die bestuurder te koppel, want dit was die maklikste om te doen. Toe koppel ek die skakelaars aan die ingangskant van die ingangsklem. Daarna het ek die uitvoerkant van die uitvoergrendel aan die LED -bestuurder gekoppel. Dit lyk miskien na 'n ongemaklike opdrag om hierdie bedrading te kry, maar dit was vir 'n rede. Die ingang van die uitsetgrendel moet gekoppel word aan die databus sowel as die uitset van die ingangsklem. Die idee was om die uitsette van die ingangsklem aan die insette van die uitsetgrendel te koppel, wat ek gedoen het. Al wat ek hoef te doen was om die gemors aan die databus te koppel. Dit maak nie saak waarheen hierdie verbindings fisies gegaan het nie, want hulle sou almal elektries gekoppel wees. Die rekenaar is nou amper klaar.

Stap 5: Herstel en voltooi invoer en uitvoer

Jammer, geen foto's vir hierdie stap nie. Verwys na die vorige stap vir die foto's.

n

U het moontlik op die laaste foto van die vorige stap opgemerk: ek het 'n groen knoppie en nog 'n logika -chip geïnstalleer. Die chip is die OF -hek. Twee hekke word gebruik om die /WAIT sein te genereer. Wel, 'n mens genereer die sein deur OR-ing /IORQ en /RD vanaf die verwerker. Die uitset word na die tweede hek gevoer, waar dit weer met 'n drukknop OR word. Die knoppie bring die ingang van die hek hoog en bring die uitset dus hoog. Hierdie uitset word na die verwerkers /WAIT -pen gevoer. Terwyl dit nie ingedruk word nie, hou 'n weerstand die inset laag. Ek het aanvanklik 'n 10K -weerstand gebruik, maar die LS32 sit eintlik spanning op die ingang. Die weerstand het dit nie laag genoeg laat val nie en ek moes dit vervang met 'n 1K. In elk geval, die idee is dat wanneer 'n IO -leesversoek gemaak word, die eerste en tweede OF -hekke die verwerker vertel om te wag. Sodra u die ingangskakelaars ingestel het op wat u wil, druk u op die knoppie en bring die SVE uit die wagtoestand. Die groen "ingang" -LED, soos ek dit in 'n vroeëre stap genoem het, is bedraad sodat wanneer die /WAIT -pen laag word, dit brand.

n

Maar ons is nog nie klaar nie. Die invoer -flipflop benodig 'n sein om dit te laat weet wanneer die data -invoer geldig is en na die SVE gestuur moet word. Hierdie klokpen is aktief hoog. Voorheen het ons dit net aan die knoppie gekoppel. Dit is nog steeds 'n geldige opsie, maar hierdie keer het ek gekies om dit op dieselfde uitset as die tweede OF -hek te plaas. Hierdie IC het ook 'n /OE -pen wat aangedryf moet word. As dit hoog gehou sou word, sou dit nooit data in die bus plaas nie. As dit laag gehou word, sou dit altyd met die bus ry. Om dit reg te stel, gebruik ek eenvoudig 'n derde OF -hek. Die insette is /IORQ en /RD en die uitset gaan direk na die grendel /OE.

n

Die uitsetgrendel moet ook die klokpen aangedryf word. Weereens, dit is aktief hoog. In my skematiese teken ek die vierde OF -hek direk met die pen met behulp van /IORQ en /WR. Dit het beteken dat die klokpen hoog gehou sou word totdat 'n skryfversoek gedoen is, dan sou dit laag word en dan weer hoog. Dit sou waarskynlik goed gewees het, want die databus sou onmiddellik na die poging tot skryf nog steeds geldige data hê, maar vanuit 'n ingenieurswese was dit 'n vullisontwerp. Ek het hierdie fout eers agtergekom nadat ek die laaste foto's geneem het, maar ek het die verbinding opgehaal en die OR -poortuitgang in een van die ongebruikte omvormers vanuit die geheue -beheerlogika gevoer en die uitset daarvan aan die klokpen gekoppel. Ek het ook die skema reggemaak en 'n ander fout gevind wat ek gemaak het. Ek het dit ook reggestel.

n

Met alles wat uiteindelik gedoen is, het ek 'n baie klein hoeveelheid werk gehad: die reset -kring. Ek het 'n knoppie op die bord gevoeg en 'n 10K -weerstand gebruik om die een kant hoog te hou. Die ander kant gaan direk grond toe. Die kant wat hoog gehou word, is die /RESET -uitvoer, wat na elke chip met 'n /RESET -pen (die SVE en uitvoergrendel) gegaan het. Om 'n herstelling aan te skakel, het ek 'n kondensator by die /RESET-uitgang gevoeg. Die idee is dat die weerstand met 'n groot waarde die relatiewe groot kondensator sou laat laai en die /RESET -penne vir 'n sekere aantal kloksiklusse laag hou (die SVE benodig vier kloksiklusse). U kan waarskynlik al raai wat die negatiewe kant van hierdie stroombaan is. Dit is dieselfde negatief as die vorige weergawe, want dit is dieselfde stroombaan. As die knoppie ingedruk word, word die kondensator in wese deur die knoppie ingekort. Dit is sleg vir die kap en die knoppie, so as u die gebou 'n bietjie meer permanent wil maak, wil u dit moontlik herontwerp. Ek het gedink aan nog 'n 555 timer wat in monostabiele modus ingestel is. Maar daarmee is die rekenaarbaan nou klaar. Yay. Nou moet dit geprogrammeer word.

Stap 6: Programmering

Die programmering van hierdie ding was 'n nagmerrie. Ek het 'n Arduino EEPROM -programmeerder gebou. Dit het nie gewerk nie. Ek het nog een gebou op grond van iemand anders se ontwerp en kodering. Nog steeds nie gewerk nie. Ek het teruggegaan na die beproefde metode om die adresse en datagrepe met die hand met die hand in te stel. Op een of ander manier het ek dit gemors. Ek het weer probeer en nog steeds het ek dit verkeerd. Ek het weer teruggegaan en ontdek dat dit met 'n enkele greep af is, so ek het dit reggestel en dit het uiteindelik gewerk, dank God.

n

Wat die werklike program betref, dit lyk asof dit super kompleks en moeilik is om te volg, maar dit is nie. Dit is eintlik redelik eenvoudig. Die helfte daarvan kopieer getalle. Die ander helfte word gedeel tussen 16-bis wiskunde, voorwaardelike spronge en nog meer kopieergetalle. Dus, laat ek daardeur gaan en vertel hoe dit werk.

n

Initialisering stel net 'n paar registerwaardes vir gebruik deur die program. Die programlus is 'n bietjie meer kompleks, maar nie veel nie. Eerstens aanvaar dit insette in die A -register op poort 00. Dan word die E -register in die geheue geskryf. Op die eerste twee lusse bevat die E -register rommeldata, so ons probeer dit na die laaste twee grepe ROM -ruimte skryf, want dit sal nie eintlik geskryf word nie; die adreswyser (IY) word dan verhoog. Die waarde wat in D gestoor word, word dan na E verskuif om daarna geskryf te word. A word dan in D gelaai en L en E word na H. gekopieer. Die eerste waarde waarteen dit vergelyk word, word in registers B gestoor en C. B en C word behandel as 'n enkele 16-bis register, BC. As die waardes dieselfde is, spring die program reguit in die RAM -ruimte, waar die gebruikerskode aanvaar word. As die kode in BC nie ooreenstem nie, word HL herlaai met die aanvanklike waardes van D en E en word dit weer vergelyk met die waarde in SP op dieselfde manier as met BC. As dit 'n pasmaat is, het dit dieselfde resultaat, maar drie ekstra grepe word in die geheue geskryf. Die grepe is 'n kode wat veroorsaak dat die SVE na die begin van sy program terugkeer ('n sagteware -herstel). As die tweede vergelyking egter nie ooreenstem nie, loop die program na waar dit 'n waarde van die gebruiker kry.

n

LD SP, EDBFH; exe -kode (voeg spring by)

n

LD IY, FFEH; aanvanklike geheuewyser vir kodeberging

n

LD BC, EDC3H; exe -kode (geen lus)

n

lus; samestellerriglyne, sodat ons nie hoef te weet waar hierdie gedeelte in die geheue geleë is nie

n

IN A, (00H); kry programdata

n

LD (IY+00H), E; E bevat kode wat gestoor moet word

n

INC IY; skuif na die volgende geheue -plek

n

LD E, D; ld D na E

n

LD D, A; ld A na D

n

LD H, E; l E na H

n

LD L, D; ld D na L

n

OF A; dra dra vlag terug

n

SBC HL, BC; gee 0 terug as exe -kode 2 ingevoer is

n

JP Z, 1000H; so ja, spring na en voer die program uit

n

LD H, E; andersins, verfris dit tot die regte waardes

n

LD L, D.

n

OF A; eerste aftrek het moontlik 'n dra -vlag gestel. Maak dit skoon

n

SBC HL, SP; gee 0 terug as exe -kode 1 ingevoer is

n

JP NZ, lus; so nie, herhaal die proses (begin met die verkryging van 'n waarde)

n

LD (IY+00H), C3H; andersins, spuit 'n sprongkode aan die einde van die gebruikersprogram in

n

LD (IY+01H), 00H; spring dien basies as 'n sagteware -herstel

n

LD (IY+02H), 00H; Dit is 'n volledige herstel as registers gewysig word

n

JP 1000H; spring na en voer 'n gebruikersprogram uit