Gå til innhold

Z80 Homebrew Datamaskin


Anbefalte innlegg

Ønsker du å følge denne arbeidsloggen så kan du trykke på "Følg denne tråden" oppe til høyre for denne førsteposten.
 
Jeg er nok fortsatt litt fersk i elektronikk, så dette er vel så mye for at
dere skal hjelpe meg, som at jeg skal vise dere hva jeg får til.
 
#0x00 - Hello World
 
IMG_20161129_174726.jpg
IMG_20161129_174735.jpg
 
Det har alltid vært en drøm å lage en homebrew datamaskin, da jeg alltid har
hatt maskinvare og low-level design som en guilty pleasure i denne abstraherte
dataverdenen. Det er noe attraktivt rundt det å finne ut hvordan en datamaskin
tikker.
 
Det er derfor jeg gikk på Ebay og kjøpte meg et lite kit med diverse chipper
(Se komponenter). Valget falt på Zilog Z80. Årsaken til at jeg valgte Z80 var
ganske så bevisst. Det var en svært populær prosessor, blant annet brukt i
TRS-80, Osborne 1, Sinclair ZX80 og ZX Spectrum, og Amstrad CPC (Gameboy sin
prosessor er også en slektning av Z80). Zilog Z80 er
en godt dokumentert prosessor med et enkelt CISC instruksjonssett. Den har også
rikelig med funksjoner, uten at det blir for komplisert. Virkemåten til denne
prosessoren er veldig lett, og den er svært, svært tilgivelig ovenfor slike
elektronikk-noobs som meg, så sjansen for at noe går opp i røyk er relativt
lav.
 
Jeg skal prøve så godt jeg klarer å holde dette forståelig for "the layperson",
men jeg kan til tider gå litt mye inn i tekniske detaljer, og om det blir helt
gresk for noen av dere så må dere gjerne be om forklaring.
 
#0x01 - Prosjekt Scope
Hvor dette prosjektet tar meg er ikke trygt å si. Jeg vil ikke forvente
ukentlige oppdateringer med et fungerende CP/M oppsett innen våren 2017. Jeg
liker ikke å planlegge langt frem i tid, så mitt nåværende mål er å få en
prosessor som kan lese programmer fra EPROM, gjøre noe Z80-magi og spytte ut
fibonnaci-sekvensen på adressebussen (Opcode OUT) eller noe. Mållinjen
eksisterer ikke, men potensialet går nok helt frem til vi har en datamaskin med
tastatur og skjerm der man kan skrive noen bokstaver og tegne enkle linjer. Om
jeg ikke kommer helt dit så har jeg muligens inspirert noen andre til å ta
fakkelen videre.
 
#0x02 - Komponenter
 
Finner hovedsaklig det jeg trenger på Ebay. Jeg kjøpte dette kittet, men før du bestiller så vil jeg anbefale litt grundig research for å finne ut hva du har lyst til å få ut av maskinen din.
 

IMG_20161129_174749.jpg

 
  • Zilog Z80 - 8-bit prosessor med 16-bit (64KB) minneaddressering. Kan kjøre på opp til 8 MHz, men har ingen store ambisjoner om å gå langt over 1 MHz i de første stadiene.

 

IMG_20161129_175655.jpg

 

  • Zilog Z80 CTC - Dette er en av Zilog Z80 sine partners in crime. CTC er en timer/counter som brukes til timekeeping. Er ikke helt sikker på hva dette innebærer, men slik jeg forstår det så kan denne brukes til å holde klokken, sende regelmessige interrupts (f.eks hvert sekund så skal programmet skrive klokken til en skjerm). Siden Z80 egentlig ikke har et tidskonsept integrert i prosessoren så blir dette ordnet av CTC. Alt dette her blir nok veldig lav prioritet inntil videre.

IMG_20161129_175737.jpg

  • ST M27C256B - 32KB med EPROM. EPROM er/var typisk der operativsystemet lå i gamle dager. Dette er minne som ikke kan skrives til uten videre, men som kan leses fra relativt raskt. ROM er Read Only Memory, som betyr at det kun kan leses fra, og programmeres fra fabrikk. PROM er Programmable Read Only Memory, og kan programmeres én gang, typisk også av fabrikk. EPROM er der jeg er, og dette er Erasable Programmable Read Only Memory, som betyr at minnet kan slettes ved hjelp av en UV lampe. Disse EPROM-chippene kan kjennes igjen når man ser det notoriske kvarts-vinduet på toppen av chippen. Går man over til disse nymotens duppedittene så snakker vi om EEPROM, Electrically Erasable Programmable Read Only Memory, der man har luksusen i å kunne slette minnet ved å sende inn en elektrisk puls. En worthy mention er Flash-minne, som er hva man har i dagens minnepenner og SD-kort. Dette er litt som EEPROM, bare at man kan slette segmenter istedet for hele chippen.

IMG_20161129_175803.jpg

  • Hitachi HM62256ALP-7 - 32KB med SRAM. God, gammeldags Static RAM. Static RAM er i kontrast til dynamisk RAM, og selv om Z80 egentlig tilhører eraen der dynamisk minne var vanlig, så har dynamisk RAM en enorm ulempe for oss hobby-folk, nemlig at det må oppfriskes jevnlig, og det veldig raskt. Dette betyr altså at du må lese minnet hele tiden for at innholdet i minnet ikke skal forsvinne, og hvis man skal klokke prosessoren manuelt (altså kjøre 1hz ved å trykke på en knapp én gang i sekundet) så betyr dette at minne vil lekke ut og forsvinne før det kan bli gjenoppfrisket. En av fordelene med Z80 er at den har DRAM-refresh innebygget i prosessoren, men dette trenger vi ikke å bry oss om når man brukes SRAM. Dynamisk RAM er godt egnet til applikasjoner der man vil ha lav pris og høy kapasitet, noe som har mistet litt av poenget nå, snart 30 år senere.

IMG_20161129_175831.jpg

  • OKI M82C55A - Dette er en programmerbar I/O enhet, som betyr at man kan utvide systemet til å bli litt som en mikrokontroller, der man kan styre logiske porter av og på for å blinke en diode eller styre en 7-segment skjerm. Denne chippen vil nok bli brukt ganske så tidlig for å kunne få en kjapp måte å styre noen 7-segment skjermer og få noe mer håndfast feedback.

IMG_20161129_175914.jpg

  • Annet - Bort sett fra det så har jeg et rikelig utvalg med LED, jumper-kabler, motstandere, DIP-switcher, kondensatorer, multipleksere og knapper. Det er viktig å ha mange og store breadboards, da dette blir elektronikk på nokså stor skala. Anbefaler også å ha en solid 5V strømforsyning, da gjerne fra en gammel mobillader eller whatever, eller en IC regulator slik som jeg har. Merk at Arduino sin 5V strømforsyning ikke er tilstrekkelig, da dette kan bli svært strømsultent, ihvertfall med ørten LED. Oscilloskop og logikkanalysator er sterkt anbefalt, men ikke nødvendig. Skal du bruke EPROM eller EEPROM så må du også ha en programmerer, slik som Minipro (TL866), og hvis du går for EPROM slik som meg så må du også ha en EPROM eraser, som er en UV-lampe i en lukket boks.

IMG_20161129_180025.jpg

 
#0x03 - Anbefalt literatur
Z80 CPU User's Manual - Absolutt, 100%, anbefalt. Dette er glimrende
referansemateriale, spesielt om du vil finne ut av grunnleggende ting.
 
Build Your Own Z80 Computer (Steve Ciarcia) - En bok som handler mer om å bygge
datamaskinen rundt Z80 prosessoren. Jeg har ikke helt kommet på det nivået der
jeg har brukt denne boken til noe, men det er en fin ressurs om du trenger å
vite f.eks. Hvordan man bygger oscillatoren, strømforsyningen eller hvordan man
kobler til keyboard og skjerm.
 
In the next episode...

Gavekort klokker inn instrukser manuelt, og noe helt sjokkerende skjer når Gavekort oppdaget denne rare detaljen med EPROM programmering. Tune in for next week.

 

Kommentartråd

Endret av Gavekort
  • Liker 4
Lenke til kommentar
  • 3 måneder senere...
Videoannonse
Annonse

Dette tok lang tid. Beklager forsinkelsene. Ny jobb, ny leilighet og dårlig
tilgjengelighet til verktøy har gjort dette prosjektet litt vanskelig å
prioritere.
 
Jeg har begynt å gjøre ting litt mer teknisk, så jeg forventer at ikke alt er
lett forståelig. Derfor oppfordrer jeg dere til å spørre om dere lurer på noe,
enten i kommentartråden eller over PM. Det er også mange ting jeg aldri kunne
kommet på å dekke, så om du lurer på noe relatert til Z80 eller low-level
datamaskiner så er det bare å spørre meg eller noen av de dyktige brukerne her
inne.
 
#0x10 - Enkel oversikt av koblinger
z80_pinout2.png
Z80 er fryktelig rett frem å koble opp så lenge du har litt grunnleggende
kunnskaper om hvordan en datamaskin fungerer på maskinvarenivå.
 
#0x11 - Basics av hexadecimaler og det binære tallsystemet
Hexadecimaler er et base-16 tallsystem som brukes ofte av ingeniører som jobber
med low-level datamaskiner og mikrokontrollere der man jobber med bits og bytes
istedet for abstraherte operasjoner.
 
Det skal ikke være et stort behov for å ha stålkontroll på hexadecimal og binær
representasjon, eller konvertering mellom de forskjellige rrepresentasjonene
Derimot så vil jeg gi dere basiskunnskapene slik at dere i det minste vet hva
dere ser på.
 
Det binære tallsystemet (base-2) skrives ofte slik som dette:
En prefix på 0b, og en serie av 0 og 1. Hver verdi fra høyre mot venstre dobler
i verdi, og vi summerer dem opp for å få et base-10 tall (base-10 er hva vi
bruker med tall fra 0 til 9).
 
Et 8-bit tall vil se slik ut i binært
 
256   128   64   32   16   8   4   2   1
------------------------------------------
 0        1      1     0     0    0   1   0   1
 
 128 + 64 + 4 + 1 = 197
 
Hexadecimaler skrives ofte slik som dette:
En prefix på 0x, og et tall mellom 0 og F på 4 bits hver (4 bits kan
representere 0 til 15. 16 verdier).
Et eksempel på dette er 0xDEADBEEF eller 0x1234ABCD. For å gjøre dette enkelt i
8-bit verdenen så pleier jeg å bryte det ned i chunks på 2 tall hver, som gir
8-bits. 0xDEADBEEF blir derfor til DE, AD, BE, EF.
 
I base-10 blir:
DE - 13 og 14
AD - 10 og 13
BE - 11 og 14
EF - 14 og 15
 
Med andre ord så blir f.eks.
0xDE til 1101 (13 i binært) og 1110 (14 i binært), så 0xDE er det samme som
0b11011110 eller 222 i base-10.
 
0xDEADBEEF er forøvrig en 32-bit verdi.
 
Men ikke bli skremt om du fortsatt ikke skjønner konvertering av hexadecimaler eller binærtall.

På dette stadiet her så er det sjeldent behov for å konvertere mellom representasjoner, så 0xFA vil forbli
0xFA, og det eneste du må vite er at 0xFB kommer etterpå, og 0xF9 kommer
før. Konverteringen skjer ikke før du skal taste inn dine base-10 verdier.

 
#0x12 - Grunnleggende funksjonalitet
Z80 i et nøtteskall
 
* Spesifikasjoner
5V logikk
Opp til 8 MHz klokkefrekvens
 
* Addressebussen

 

Z80.jpg

Hvis du ser på RAM/ROM som en stor hylle av skuffer, og hver skuffe inneholder 8
bits, så er addressebussen nummereringen av disse
skuffene. Selv om Z80 er en 8-bit prosessor (derav 8 bits i hver skuffe), så
har Z80 en 16-bit addressebuss, som betyr at den klarer å holde kontroll på
2^16 skuffer, altså 65536 skuffer med 8 bits i hver skuffe.
 
Som eksempel så sier vi at vi vil lagre tallet 42 i skuffe nummer 4814. Siden
vi er i binaryland så oversettes dette til: Vi vil lagre 0b00101010 (8-bits) i
skuffe nummer 0b0001001011001110 (16-bits).
 
Begynner vi fra venstre på addressen så vil pin A0 (se bildet) være 0V (ingen
logikkspenning), pin A1 vil være 5V, pin A2 vil være 5V, osv.
 
Adressebussen ser da slik ut:
A0, A1, A2 ... A15
0V, 5V, 5V ... 0V
 
Dette sier til minnet hvilken skuffe vi vil ha tilgang til.
 
Dette er litt forenklet, da addressebussen kan gjøre litt mer enn å bare peke
til RAM, og det å lese og skrive fra minnet krever noen kontroll-signaler, men
denne forenklingen skal være tilstrekkelig for nå.
 
* Databussen
Nå som vi addressebussen satt korrekt så må vi flytte innholdet til eller fra
minnet. Slik som addressebussen over så vil prosessoren sette portene til å bli
enten 0V eller 5V, og i dette tilfellet så er det D0 til D7, istedet for A0 til
A15.
 
Med A0 til A15 satt til verdiene som beskrevet over, så kan vi sette D0 til D7
til å representere tallet vi vil lagre i den "skuffen", så databussen settes
fra høyre mot venstre i den binære representasjonen av 42; 0b00101010
 
Databussen ser da slik ut:
D0, D1, D2, D3, D4, D5, D6, D7
0V, 5V, 0V, 5V, 0V, 5V, 0V, 0V
 
Husk at binær går fra høyre mot venstre. Dette er ikke alltid tilfellet på alle
prosessorer, men Z80 i likhet med Intel/AMD-prosessoren i datamaskinen din er
hva vi kaller for en little-endian prosessor, i kontrast til big-endian. Jeg
skal ikke gå for mye inn i detaljer på dette, så peker dere videre til
Wikipedia.
 
* Kontrollporter
En av ulempene ved å forenkle de to kategoriene over er at denne kategorien
kommer som en unødvendig atpåklatt. Ser du på Z80 pinout-bildet så ser du at
det er en rekke med innganger, utganger (se på pilene)
som jeg har latet som ikke er relevante. Jeg skal gi en superkort beskrivelse
til noen av de, men jeg anbefaler det varmeste å laste ned Z80 CPU Users Manual
og slå opp på disse navnene selv om du er nysgjerrig. Du finner dette på side
26 og utover i kapittelet "Pin description". De som jeg ønsker å nevne er INT,
RESET, RD, WR og CLK.
 
Noen av IO-portene har en svart strek (eller skråstrek i bildet over) over seg. 
dette betyr NOT, så logikken er reversert. Til ren
engelsk så betyr dette f.eks at "RESET is active on NOT high", så med andre ord
så vil RESET bli aktiv når spenningen er 0V, ikke når den er 5V. I praksis så
ønsker vi at 0V skal være en tilkobling til jord gjennom hva vi kaller for
pull-down. Dette konseptet skal jeg gå litt mer grundig gjennom senere.
 
**INT - Interrupt er litt som hva navnet tilsier. Om du har en harddisk som
prosessoren må vente på så kan prosessoren istedet for å vente, heller jobbe
med noe annet og bli "forstyrret" (Interrupted) av harddisken så snart den har
noe klart til prosessoren. Siden vi er litt mer modige når det kommer til
tekniske detaljer så betyr dette at prosessoren vil lagre alt det den husket på
et lurt sted og hoppe over til en subroutine, eller en interrupt-addresse på
minnet der prosedyren for en interrupt ligger programmert, før den vil si seg
ferdig med interrupt, hente det minne den lagret tidligere og fortsette med det
forrige arbeidet. Interrupt finnes av mange typer, men basiset for alle er det
samme.
 
**RESET - Når RESET blir satt lav, så vil prosessoren nullstille alle de interne
registerne sine og begynne helt på nytt.
I praksis så vil prosessoren bli i samme modus som når du først koblet den til
strøm. RESET er en operasjon som prosessoren utfører, og innebærer at
prosessoren må kunne få tre klokkesykluser før hele prosessoren er resatt.
Dette står beskrevet i brukermanualen på side 9 og 10.
 
**RD/WR - Disse to pinnene er bus-signaler for å indikere til RAM eller andre
enheter på bussen (Valgt av IORQ og MREQ) at man ønsker å lese eller skrive
data. En minnebrikke er nødt til å vite om adressen 0x45F8 med databussen satt
til 0x00 betyr at man skal skrive databussen 0x00 til minnelokasjon 0x45F8, eller om
man skal levere det minnebrikken har i 0x45F8 og erstatte verdien på
minnebussen. Dette er den typiske bruken av RD og WR i en databuss, men det er
ingen definert standard, så i hovedsak så trenger man bare å vite at RD og WR på Z80
skal kobles til RD og WR på den andre chippen din om den har en RD eller WR.
 
**CLK - Dette er klokkefrekvensen, enkelt og greit. Det er et square wave
signal som kjører på en gitt frekvens og er takten som prosessoren jobber på.
En hver ting som prosessoren gjør krever en viss mengde klokkesykluser, så når
jeg utfører en ADD operasjon så slår jeg opp ADD i Z80 brukermanualen og ser at
denne operasjonen krever 4 T states, som betyr at fra og med prosessoren leser
0b1000111 (ADD A) i RAM så må det komme fire klokkepulser før resultatet er
ferdig og prosessoren kan begynne på neste operasjon.
 
* Strømtilførsel
De resterende pinnene du ser på prosessoren er strømtilførsel, som er +5V og
GND (Ground). Z80 er ikke strømsulten relativt til dagens prosessorer, men jeg
vil anbefale en solid strømtilførsel, så en hacket mobillader eller en
laptop-lader koblet til en 7805 spenningsregulator er greie løsninger. Jeg vil
ikke anbefale å koble ting direkte til USB-port, eller bruke 5V fra en Arduino
eller Raspberry Pi.
 
#0x20 - Vi klokker inn instruksjoner
 

IMG_20161130_212122.jpg
 
DIP switchen her styrer databussen, så det denne gjør er å emulere RAM/ROM
eller annen enhet på bussen. EPROM som du ser på bildet er ikke i bruk. Det er
viktig å få med seg at vi later som om vi er EPROM her, så vi svarer på lysene på
adressebussene ved å endre på DIP switchen som om vi skulle vært en EPROM.
Hele systemet her baserer seg på lesing av data, og interne registre (som jeg skal
fokusere på litt senere når vi kommer til assembly delen).
 
Så på adresse 0x0000 (alle lysene av) begynner vi med en enkel JP (Jump) instruksjon
som har OPCODE 0b11000011.
Anbefaler at du finner frem vår kjære brukermanual og slår opp JP på side 238.
 
JP er enkelt og greit en instruksjon som skal endre Program Counter og få
prosessoren til å hente ting andre steder i RAM/ROM. Vi bytter med andre ord vår
metaforiske skuffe, og teorien her er at disse LED-lysene som viser 
adressebussen våres, skal endres til hva vi setter JP til.
 
Så JP har 3 M cycles, som betyr at det er en instruksjon som består av tre
segmenter:
 
OPCODE 0b11000011
Lower nibble av target adresse
Upper nibble av target adresse
 
Vi starter med andre ord med å sette DIP switchen til 11000011 og trykker på
klokken for 4 T states (eller frem til den prøver å lese adresse 0x0001).
Dette er slutten på første M cycle.
 
IMG_20161130_212200.jpg
IMG_20161130_212230.jpg
 
De neste M cycles av denne tre part instruksjonen er adressen den skal settes til.
Siden dette er en 8-bits maskin med 16-bits adresser, så er adressen splittet
opp i to "nibbles", en for de øvre 8 bits, og en for de lave 8 bits. Til sammen blir
dette en 16 bits adresse.
 
Vi slår inn et fint mønster 0b01010101 på DIP switchen og trykker på klokken i
3 T states, eller frem til den prøver å lese 0x0002.
 
Når den prøver å lese 0x0002 så endrer vi til et annet fint mønster 0b11001100,
trykker i 3 T states til, og... *drumroll*
 


IMG_20161130_212414.jpg
IMG_20161130_212553.jpg

 

 

I Z80 assembly så har vi nå utført instruksjonen:

JP 0x55CC
 
Kommentartråd

Endret av Gavekort
Lenke til kommentar

Bonus miniupdate:

 

Har kjøpt inn noen Z80 SIO chipper. Så jeg skal prøve å styre prosjektet mitt opp mot å koble Z80 datamaskinen min opp mot en terminal på min laptop. Dette innebærer derimot at jeg må ha en høy og stabil klokkefrekvens, som gjør prosjektet litt utfordrende i dette stadiet.

 

IMG_20170319_171058.jpg

Endret av Gavekort
Lenke til kommentar
  • 2 måneder senere...

Fikk litt flere leketøy i posten. Merker at breadboard begynner å bli litt for begrensende, så har kjøpt meg sokkler og ZIF-sokkler til EPROM og planlegger en overgang til veroboard.

 

Det som holder meg mest igjen nå er egentlig noe som simpelt som mangel på ledninger.

 

IMG_20170530_183634.jpg

Lenke til kommentar
  • 5 måneder senere...

Tidlig utkast med CPU, SIO (UART), EPROM og buss-kontroller på plass. Litt clunky routing noen steder, men bruker ikke så mye tid på det før alle komponenter er på plass.

 

Dette er et veldig tidlig utkast, og det er ikke lagt noe tanker bak verdier på komponenter eller andre mindre detaljer. Jeg tar fortsatt imot konstruktiv kritikk, om det er noen EE-folk her med faktisk erfaring.

 

Screenshot_20171112_222857.png

Screenshot_20171112_223306.png

Screenshot_20171112_224216.png

Z80_homebrew.pdf

Endret av Gavekort
Lenke til kommentar
  • 4 måneder senere...
  • 4 uker senere...
  • 1 år senere...
  • 1 år senere...

Enda en total overhaling. La til en STM32 mikrokontroller som en hjelpe-enhet og I/O enhet (tekst terminal osv). Siden prosjektet allerede er bastardisert med moderne elektronikk så skrotet jeg også THT passive komponenter og byttet kondensatorer og motstandere med 0406 SMD.

image.png

image.png

Har tatt meg nesten to dager å route det du ser her, men nå er det i hvert fall kompakt og fint.

  • Liker 3
Lenke til kommentar
  • 2 uker senere...

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...