Innholdsfortegnelse:
- Trinn 1: Rask oversikt over endringer + skjemaer
- Trinn 2: CPU, minne og minnekontroll
- Trinn 3: Lysdioder for systemstatus
- Trinn 4: Input og Output
- Trinn 5: Tilbakestill og avslutt input og output
- Trinn 6: Programmering
Video: Gå tilbake til Z80 -datamaskinen: 6 trinn
2024 Forfatter: John Day | [email protected]. Sist endret: 2024-01-30 11:20
Tidligere har jeg skrevet en veiledning om hvordan du bygger en Z80-basert datamaskin, og jeg designet kretsen for å være så enkel som mulig, slik at den kunne bygges så enkelt som mulig. Jeg skrev også et lite program med den samme ideen om enkelhet. Denne designen fungerte ganske bra, men jeg var ikke helt fornøyd med den. Jeg begynte med å skrive om et program for det som tillot det å bli programmert under kjøretid. Dette var for å la meg teste kodebiter uten å måtte dedikere den til EEPROM, noe som igjen ville kreve at jeg omprogrammerte EEPROM. Dette hørtes ikke ut som en morsom idé for meg. Så begynte jeg å tenke på minneområder. Hvis jeg ønsket å koble til en maskinvare (hovedsakelig IO), kan et stykke kode potensielt overstige mengden minne som er tilgjengelig for systemet. Husk at designet bare brukte den nedre byten til adressebussen, og deretter ble den nedre biten i den høye byten brukt til å velge mellom ROM- og RAM -mellomrom. Dette betydde at jeg bare hadde 253 byte plass å bruke. Du kan spørre hvorfor 253 i stedet for 256. Det er fordi min nye kode injiserer tre byte med data på slutten av et skriftlig program (dette vil bli dekket senere, da jeg endret det for å jobbe med det nye designet).
n
Jeg gikk tilbake til de gamle skjemaene mine for å se hva annet som foregikk. Jeg fant en liten feil med minnevalgskretsen, som jeg vil dekke når jeg kommer dit. Den forenklede versjonen: alle skriveforespørsler ville faktisk gå igjennom, selv om den alltid ble satt inn i RAM. Dette var sannsynligvis ikke noe verdt å bekymre seg for, men jeg ønsket å gjøre det ordentlig denne gangen. Og med det begynte jeg å tegne et nytt skjema. De to bildene vedlagt denne siden er før og etter selve kretsen. Jeg ryddet opp så mye av spaghettikablene, det er ikke morsomt.
n
Hvis du fulgte med min opprinnelige innsending og planlegger å følge med denne, kommer du til å hate meg. Hvis du begynner på nytt, har du lykke til. Bare ta delene i listen (eller tilsvarende) og følg med.
Rekvisita:
LM7805 - 5 Volt regulator Z80 - CPU; hjernen til systemetAT28C64B - EEPROM. "Permanent" datalagring som brukes for datamaskinens firmwareIDT6116SA - SRAM; brukes til lagring av brukerkode og /eller generell datalagringNE555 - Systemklokke74HC374 - Octal D -Latch med /OE; brukes som inngangsbrikke74LS273 - Octal D -Latch med /MR; utgangsbrikkeTLC59211 - LED -driverbrikke (brukt slik at 74LS273 kan drive lysdioder, ettersom den alene ikke er i stand til gjeldende utgang) MC14572 - Dette er en "Line Driver" -brikke, men jeg syntes den var perfekt for minnekontrolllogikken. Den har 4 omformere og en NAND- og NOR -port bygget in74LS32 - Quad OR gateCD4001 - Quad NOR gateCD4040 - 12 Stage Ripple Counter; Tegnet, men ikke implementert klokkeavdeler (for å kjøre systemet ved lavere klokkehastigheter) 2 10K Ohm motstander - Den ene brukes i 555 tidskretsen, så bruk hvilken verdi du vil for den 4 1K Ohm motstander - Den ene brukes for 555 timer krets, så bruk det du ønsker for det. En annen brukes til å kjøre lysdioder, så varier den også hvis du vil ha 8x330 ohm motstandsbuss 8 x 10 k ohm motstandsbuss11 lysdioder - tre brukes til systemstatus og de andre åtte er utganger. For de 8 brukte jeg et stolpediagram (HDSP -4836) 4 kondensatorer - To ble brukt LM7805; 0,22uF og 0,1uF. Den ene er for 555 -timeren, så bruk det du føler er riktig. Den siste er for oppstart. 100uF2 N. O. Trykknapper - Den ene brukes for inndata, den andre for tilbakestilling 8 SPST DIP -svitsjer - Datainngang; Jeg brukte Piano Key styleWire. Mange og mange ledninger
n
MERK: MC14572 gjennomgående hullversjon er foreldet, men SMD -versjonen er fortsatt aktiv (ikke engang "ikke for nytt design" -status), så det kan hende du må kjøpe et kretskort for å bruke det. En annen 74LS32 kan brukes i stedet for MC14572 (se skjemaet "minnevalgskrets" for tidligere ible)
Trinn 1: Rask oversikt over endringer + skjemaer
Slik leser jeg skjemaene: En pil som pekes inn i en brikke er en inngang: Inngang> -En pil som pekes vekk fra en brikke er en utgang: Utgang <-Busser bruker en linje i stedet for en pil: Buss |-
n
De fleste sjetongene har blitt trukket med sine eksakte pinouts. Den lille dippen er trukket på disse sjetongene. De fleste sjetonger har også pin -tall og etiketter. De kan være litt vanskelig å lese. Blyanten min ble matt.
n
Når det gjelder kretsforbindelser, er utformingen av det nye designet stort sett uendret fra originalen. Jeg koblet den nedre nibble av adressen high byte til minnene og brukte deretter den lave biten på den øvre nibble (A12) for valg av RAM/ROM. Dette betydde at ROM-plassen gikk fra 0000-00FF opp til 0000-0FFF. Ramplassen gikk fra 0100-01FF til 1000-1FFF. Jeg byttet også ut minnekontrolllogikken for et bedre design og la til to nye status -lysdioder (og litt limlogikk). Jeg har også tegnet (men ikke ledet) en klokkedelerkrets. Den skulle utføre to funksjoner. Den åpenbare funksjonen er å dele klokkefrekvensen ned. Den andre funksjonen er for PWM (Pulse Width Modulation) formål, da 555 ikke genererer bølger med 50% driftssykluser. Det spiller egentlig ingen rolle i denne kretsen, men hvis du skulle ønske å bruke klokken til å drive noen lysdioder, vil du definitivt legge merke til effektene (den ene (sett med) LED (er) vil være svakere enn den andre). Hele resten av kretsløpet er i hovedsak uendret.
Trinn 2: CPU, minne og minnekontroll
Dette er delen der leserne av min forrige versjon hater meg. I den opprinnelige konstruksjonen kastet jeg bare deler på brettet på et sted de så ut som om de ville påføre lite problem med å få kablet opp. Resultatet så ut som om noen dumpet en tallerken spaghetti på den og var som "ledninger!" Jeg ønsket å rydde opp litt, så jeg begynte med å rive opp alt unntatt CPU, RAM og ROM. Jeg dro opp nesten hele inngangskretsen, utgangskretsen og limlogikken. Det gjorde meg nesten vondt å gjøre det, men det var nødvendig. Jeg lot alle datatilkoblingene være intakte og den nedre byten til adressebussen. Jeg koblet deretter de fire neste bitene av adressebussen (A8-A11) til ROM-brikken. Jeg passet på å gå rundt brikken denne gangen for å gjøre det lettere å trekke opp for omprogrammering. Jeg hoppet også adressetilkoblingene ned til RAM -brikken.
n
Med det ute av veien, måtte jeg nå få minnekontrolllogikken til å koble til. I den originale skjemaet hadde jeg koblet prosessorens /MREQ -linjen direkte til /CE til begge minnebrikker, deretter koblet jeg /WR til RAM -en /WE. Deretter hadde jeg CPU /RD og /MREQ logisk OR sammen og A9. I hovedsak ble det satt opp slik at alle minneforespørsler aktiverte både RAM og ROM, men A9 ble brukt til å velge hvilken av brikkene /OE som ble valgt. Dette var greit og alt fordi sjetongene ville forbli inaktive til det ble fremsatt en minneforespørsel, og deretter ville bare én /OE være aktiv under en leseforespørsel. Dette forhindret kryssord, men introduserte en vanskelig nyanse. Fordi A9 bare ble brukt til å bestemme hvilken brikke som sendte ut data og fordi CPU -en hadde direkte tilgang til RAM /WE -pinnen, ville alle skriveforespørsler gå igjennom. Dette var greit for ROM -en fordi skrivemodusen er hemmet av å binde /WE direkte til 5V -forsyningen. RAM -en vil imidlertid bli skrevet til uavhengig av A9. Dette betydde at et forsøk på å skrive til en ROM -plassering ville skrive til det samme stedet i RAM -plass.
n
En løsning for dette ville være å koble kontrolllogikken til på nytt slik at CPU -en har direkte tilgang til chipsenes /OE- og /WE -pinner og deretter bruke MREQ og A12 for å velge hvilke chips /CE som ble drevet. Jeg gikk med denne ideen, men i stedet for å bruke fire NOR -porter og en omformer som det originale designet, fant jeg en vanskelig liten chip som var perfekt for oppgaven. Jeg måtte lage en krets som bare brukte de logiske portene som er tilgjengelige i brikken, men det var enkelt nok. A12 strømmer direkte inn i en NAND -port og en NOR -port. /MREQ mates inn i NOR -porten og komplimentet blir matet inn i NAND -porten. NAND -porten brukes til å kjøre /CE for RAM og NOR -utgangen blir invertert og brukt til å drive ROM /CE. Dette gjør det slik at /MREQ må være lav før en av brikkene velges, og deretter velger A12 hvilken som blir valgt. Med dette oppsettet vil ingen skriveforespørsler til ROM gjøre noe. Det sparer også strøm fordi bare en brikke er aktiv i stedet for begge. Når det gjelder selve logikkbrikken, har vi fortsatt to ubrukte omformere inne. Den ene vil bli brukt senere, men vi kommer dit når vi kommer dit.
Trinn 3: Lysdioder for systemstatus
Før jeg begynte dette prosjektet, prøvde jeg å koble til en bestemt IC, men jeg hadde problemer med det. Usikker på hva som foregikk, brukte jeg en panelmontert LED til å sondre rundt (en av de samlingene som har en innebygd motstand). Å gjøre dette ga meg en nostalgi -idé som fortsatt brukes i dag: status -LED -er som brukes til å indikere om minne ble lest fra eller skrevet til. Den skulle brukes sammen med inngangs -LED -en jeg allerede hadde. Inngangs -LED -en ble koblet til /WAIT -signalgeneratoren for å indikere for oss at systemet venter på innspill (jeg kommer dit, ikke bekymre deg). Jeg vurderte å legge til en LED for å indikere en IO -skriving, men jeg skjønte at utgangs -LEDene som ble endret allerede ville være en god indikator på det. Når jeg tenker på det, kan jeg fortsatt legge det til ennå. Likevel synes jeg det er nyttig å vite om minne blir lest eller skrevet. Vel, det er nyttig for programfeilsøking uansett. Jeg brukte faktisk det som sådan når jeg prøvde å få programmet mitt til å fungere: “hvorfor skriver det til minnet? Det skal ikke gjøre det enda!"
n
For å kontrollere disse lysdiodene brukte jeg quad NOR -porten. Jeg brukte alle portene. Bare to ble brukt til å generere statussignaler, men brikken har ikke strømfunksjoner for å faktisk drive lysdiodene. De er i stand til å synke så mye strøm, så jeg brukte de to andre NOR -portene som omformere og koblet lysdiodene som sådan. Fordi den ene lysdioden brukes til å indikere leser og den andre til skriving, og en lese- og skriveforespørsel ikke vil forekomme samtidig, klarte jeg å slippe unna med å bruke bare en motstand for begge lysdiodene. Når det gjelder signalene jeg trengte å dekode, var det også enkelt nok. Jeg ville at alle minneforespørsler skulle bli indikert, så den første NOR -porten hadde /MREQ og /RD på inngangene. Skrivestatusen var litt vanskeligere, men like enkelt. Jeg brukte fortsatt /MREQ som en inngang, men bruk av /WR som den andre ville forårsake en mindre nyanse jeg ønsket å unngå. Det ville ha indikert ALLE skriveforespørsler. Jeg ville bare ha de som faktisk gikk gjennom. Så hvordan skulle jeg gjøre det? Husker du hvordan jeg har konfigurert systemet slik at bare RAM kan skrives? Jeg brukte RAM /CE som den andre inngangen til NOR -porten. Dette betyr at lysdioden bare lyser når RAM er valgt og det blir skrevet en forespørsel. Når det gjelder LED -farge, valgte jeg oransje som leseindikator (men jeg fant bare gule) og rød som skriveindikator.
Trinn 4: Input og Output
I forrige trinn har du kanskje lagt merke til at jeg allerede har lagt til noen av resten av komponentene på brettet. Jeg reserverte plassen slik at jeg ikke ved et uhell ville plassere ledninger der jeg ønsket en komponent (derfor måtte jeg finne et nytt sted for komponenten). Du har kanskje også lagt merke til at jeg lot inngangsbryterne være på plass og koblet til strømskinnen. Jeg bestemte meg for at det opprinnelige stedet var det perfekte stedet, og bestemte meg for å plassere utgangs -LED -ene i nærheten (ovenfor). Til høyre for stolpedisplayet er inngangslåsen. Over det er utgangslåsen, og til venstre for den er LED -driveren. Jeg begynte med å koble skjermen til driveren siden det var det enkleste å gjøre. Deretter koblet jeg bryterne til inngangssiden av inngangslåsen. Deretter koblet jeg utgangssiden til utgangslåsen til LED -driveren. Dette kan virke som en vanskelig ordre å få disse kablet, men det var av en grunn. Inngangen til utgangslåsen skulle kobles til databussen samt inngangen til inngangslåsen. Tanken var å koble utgangene til inngangslåsen til inngangene til utgangslåsen, noe jeg gjorde. Da var det bare å få det rotet koblet til databussen. Det spilte ingen rolle hvor disse forbindelsene gikk fysisk fordi de alle ville være elektrisk tilkoblet. Datamaskinen er nå nesten ferdig.
Trinn 5: Tilbakestill og avslutt input og output
Beklager, ingen bilder for dette trinnet. Se forrige trinn for bildene.
n
Du har kanskje lagt merke til på det siste bildet av forrige trinn, jeg hadde en grønn knapp og en annen logikkbrikke installert. Brikken er OR -porten. To porter brukes til å generere /WAIT -signalet. Vel, en genererer signalet med OR-ing /IORQ og /RD fra prosessoren. Utgangen mates inn i den andre porten, hvor den får OR'd igjen til en trykknapp. Knappen bringer inngangen til porten høyt, og bringer dermed utgangen høy. Denne utgangen mates til prosessorene /VENT -pinnen. Selv om den ikke trykkes, holder en motstand inngangen lav. Jeg brukte opprinnelig en 10K motstand, men LS32 satte faktisk spenning ut på inngangen. Motstanden droppet den ikke lavt nok, og jeg måtte bytte den ut med en 1K. Uansett, tanken er at når en IO -leseforespørsel kommer, forteller den første og andre OR -porten prosessoren å vente. Når du har angitt inndatabryterne til det du vil, trykker du på knappen og det bringer CPU -en ut av ventetilstanden. Den grønne "inngangslampen", som jeg kalte det i et tidligere trinn, er koblet til slik at når /WAIT -pinnen går lavt, lyser den.
n
Men vi er ikke ferdige ennå. Inndata -vippen trenger et signal for å gi beskjed når datainngangen er gyldig og skal legges ut til CPU -en. Denne klokkestiften er aktiv høy. Før koblet vi den bare til knappen. Dette er fortsatt et gyldig alternativ, men denne gangen valgte jeg å sette det på samme utgang som den andre ELLER -porten. Denne IC har også en /OE -pinne som må kjøres. Hvis den skulle holdes høyt, ville den aldri sette inn data i bussen. Hvis den holdes lav, ville den alltid kjøre bussen. For å fikse dette brukte jeg bare en tredje ELLER -gate. Inngangene er /IORQ og /RD og utgangen går direkte til låsen /OE.
n
Utgangslåsen trenger også at klokkestiften skal drives. Igjen, det er aktivt høyt. I skjematikken min tegnet jeg den fjerde ELLER -porten direkte som kjørte pinnen ved hjelp av /IORQ og /WR. Dette betydde at klokkepinnen ble holdt høyt inntil det ble skrevet en forespørsel, så ville den gå lavt og deretter høyt igjen. Dette hadde sannsynligvis vært greit fordi databussen fremdeles ville ha hatt gyldige data om den umiddelbart etter forsøket på å skrive, men fra et teknisk synspunkt var en søppeldesign. Jeg la ikke merke til denne feilen før etter at jeg hadde tatt de siste bildene, men jeg tok opp den tilkoblingen og matet deretter OR -portutgangen til en av de ubrukte omformerne fra minnekontrolllogikken, og koblet deretter utgangen til klokkestiften. Jeg fikset også skjematikken og fant en annen feil jeg hadde gjort. Jeg rettet det også.
n
Med alt dette endelig gjort, hadde jeg en veldig liten mengde arbeid å gjøre: tilbakestillingskretsen. Jeg la til en knapp på brettet og brukte en 10K motstand for å holde den ene siden høy. Den andre siden går direkte til bakken. Siden holdt høyt er /RESET -utgangen, som gikk til hver brikke med en /RESET -pin (CPU og utgangslås). For å oppnå tilbakestilling av strømmen, la jeg til en kondensator i /RESET-utgangen. Tanken er at motstanden med stor verdi vil føre til at den relativt store kondensatoren lades sakte og holder /RESET -pinnene lave for en viss mengde klokkesykluser (CPUen trenger fire klokkesykluser). Du kan sikkert allerede gjette hva den negative siden av denne kretsen er. Det er det samme negative som den forrige versjonen fordi det er den samme kretsen. Når du trykker på knappen, blir kondensatoren i hovedsak kortsluttet gjennom knappen. Dette er dårlig for både hetten og knappen, så hvis du vil gjøre bygningen din litt mer permanent, kan det være lurt å redesigne den. Jeg tenkte på en annen 555 timer satt opp i monostabil modus. Men med det er datamaskinkretsen nå ferdig. Jippi. Nå må den programmeres.
Trinn 6: Programmering
Å programmere denne tingen var et mareritt. Jeg bygde en Arduino EEPROM programmerer. Det fungerte ikke. Jeg bygde en annen basert på andres design og koding. Virket fortsatt ikke. Jeg gikk tilbake til den velprøvde metoden for å angi adresser og databytes manuelt for hånd. På en eller annen måte rotet jeg det opp. Jeg prøvde igjen, og jeg fikk fortsatt feil. Jeg gikk tilbake igjen og oppdaget at det var slått av med en enkelt byte, så jeg korrigerte det og det fungerte til slutt, takk og lov.
n
Når det gjelder selve programmet, ser det ut til at det er superkompleks og vanskelig å følge, men det er det ikke. Det er ganske enkelt, faktisk. Halvparten kopierer tall rundt. Den andre halvdelen deles mellom 16-biters matematikk, betingede hopp og enda flere kopieringsnumre. Så la meg gå gjennom det og fortelle deg hvordan det fungerer.
n
Initialisering angir bare noen registerverdier for bruk av programmet. Programsløyfen er litt mer kompleks, men ikke mye. Først godtar den inngang til A -registeret på port 00. Deretter blir E -registeret skrevet til minnet. På de to første løkkene inneholder E -registeret søppeldata, så vi prøver å skrive det til de to siste bytesene med ROM -plass fordi det faktisk ikke blir skrevet; adressepekeren (IY) økes deretter. Verdien som er lagret i D flyttes deretter til E for å skrives videre. A lastes deretter inn i D og L og E kopieres til H. HL er hvor verdisammenligningen finner sted via subtraksjon og kontroll av ZF (nullflagg). Den første verdien sammenlignet med lagres i registerene B og C. B og C behandles som et enkelt 16-biters register, BC. Hvis verdiene er de samme, hopper programmet rett inn i RAM -rommet, der brukerkoden antas å ligge. Hvis koden i BC ikke er en kamp, lastes HL på nytt med de opprinnelige verdiene fra D og E og blir sammenlignet igjen med verdien i SP på samme måte som den ble sammenlignet med BC. Hvis det er en kamp, har det samme resultat, men tre ekstra byte skrives til minnet. Byte er en kode som får CPU til å hoppe tilbake til begynnelsen av programmet (en programvare -tilbakestilling). Hvis den andre sammenligningen imidlertid ikke var en match, går programmet til der det henter en verdi fra brukeren.
n
LD SP, EDBFH; exe -kode (legger til hopp)
n
LD IY, FFEH; første minnepekeren for kodelagring
n
LD BC, EDC3H; exe -kode (ingen loop)
n
Løkke; assembler -direktiv, slik at vi ikke trenger å vite hvor i minnet denne delen befinner seg
n
I A, (00H); få programdata
n
LD (IY+00H), E; E inneholder kode som skal lagres
n
INC IY; gå til neste minneplassering
n
LD E, D; ld D til E.
n
LD D, A; ld A til D
n
LD H, E; ld E til H
n
LD L, D; ld D til L
n
ELLER A; tilbakestill bæreflagget
n
SBC HL, BC; returnerer 0 hvis exe -kode 2 ble angitt
n
JP Z, 1000H; i så fall, gå til og kjør programmet
n
LD H, E; Ellers må du oppdatere disse til riktige verdier
n
LD L, D.
n
ELLER A; første trekk kan ha satt bæreflagg. Fjern det
n
SBC HL, SP; returnerer 0 hvis exe -kode 1 ble angitt
n
JP NZ, sløyfe; hvis ikke, gjenta prosessen (begynn med å få en verdi)
n
LD (IY+00H), C3H; ellers kan du injisere en hoppekode på slutten av brukerprogrammet
n
LD (IY+01H), 00H; hopp fungerer i utgangspunktet som en programvare -tilbakestilling
n
LD (IY+02H), 00H; det er en fullstendig tilbakestilling i tilfelle registre blir endret
n
JP 1000H; hoppe til og kjøre brukerprogram
Anbefalt:
Tilbake til det grunnleggende: Lodding for barn: 6 trinn (med bilder)
Tilbake til det grunnleggende: Lodding for barn: Enten du bygger en robot eller jobber med Arduino, kan du danne "hands-on" elektronikk til prototyping av en prosjektidee, å vite hvordan man lodder vil komme godt med. lodding er en viktig ferdighet å lære hvis noen virkelig er interessert i elektro
Tilbake til fremtiden Antigravity Water Drop - Seeeduino Lotus: 5 trinn
Tilbake til fremtiden Antigravity Water Drop - Seeeduino Lotus: StoryTime er som en torrent, og presser folk fremover. Er det et øyeblikk der du vil at tiden skal stå stille eller gå bakover? Se nøye på vanndråpen. Drypper det eller går det opp? Arbeidet er inspirert av fenomenet visuell persi
Å bringe en transistorradio fra 1955 tilbake til livet: 7 trinn
Bringing a 1955 Transistor Radio Back to Life: Jeg kjøpte denne Zenith Royal transistorradioen fra 1955 nylig, og da jeg inspiserte utsiden var den i veldig god stand, med tanke på at den er 63 år gammel. Alt var der, inkludert det originale klistremerket på baksiden av radioen. Jeg gjorde noen r
Kom tilbake til BBS'ing !!: 8 trinn
Kom tilbake til BBS'ing !!: Tilbake på dagen, før internett var en ting som het BBS, eller Bulletin Board Systems. Disse stedene var et sted du kan gå til ved å bruke datamaskinen og en telefonlinje. Du kan chatte med andre brukere online, spille spill, legge ut meldinger i distin
3D -trykt tilbake til fremtiden TIme Circuit Clock: 71 trinn (med bilder)
3D -utskrift tilbake til fremtiden TIme Circuit Clock: Den fremre venstre LED.stl -filen var feil og har blitt oppdatert. Tidskretsklokken viser følgende via LED -displayene. Destinasjonstid - (Øverst-rødt) Destinasjonstiden er et område som viser en fast dato og klokkeslett. Bruk dette er