Z80 toolkit Franc Grootjen March 14, 2003 Abstract De Z80 is een eenvoudige 8 bit microprocessor uit de zeventiger jaren die nog steeds te koop is voor ongeveer de prijs van een heel brood. De Z80 wordt nog steeds gebruikt in embedded systems, rekenmachines (TI83) en computerspelletjes (Gameboy). Er is overigens enorm veel informatie op het net te vinden over deze processor1 . Dit document is een korte beschrijving van een toolkit waarmee je de werking van de Z80 kan doorgronden door middel van emulatie onder windows. Mocht je zelf interesse hebben om zelf een computer te bouwen rond deze processor, aarzel dan niet en stuur een mail naar [email protected]. 1 Machinetaal en assembly De Z80 voert op een hoge snelheid uiterst elementaire instructies uit. Deze instructies zijn opgeslagen in het geheugen als getalletjes. Zo’n rij van getalletjes wordt ook wel machinetaal genoemd. Omdat het programmeren in getalletjes nogal lastig is gebruiken we meestal een tool die een wat vriendelijker notatie van de instructies toestaat: een assembler. Zo’n assembler is in staat om die vriendelijke notatie (in zogenaamde mnemonics) om te zetten naar de getalletjes die de Z80 uitvoert. Het volgende assembly programma: ld ld add halt a,12 b,13 a,b kan door een assembler vertaald worden naar de (heximale) machinetaal getalrij 3e 0c 06 0d 80 76. Stel je voor dat je zelf die instructies zou moeten coderen in hex. Monnikkenwerk, en ook nog enorm vatbaar voor fouten. 1 Een goed startpunt is www.z80.info 1 1.1 zmac zmac is een Z80 macro assembler. Laten we het assembly programma van hierboven eens gaan vertalen. Gebruik notepad of een andere editor waarmee je platte text files kunt maken, tik het bovenstaande programma in (meestal worden tabs gebruikt om de kolommen te scheiden in assembly) en save de file as ’test.asm’. Gebruik nu (vanuit command.com of cmd) het commando zmac test.asm om je assembly programma te coderen. Als het goed is krijg je in de huidige directory de volgende files: • test.lst - Een overzichtelijke versie van je test.asm file, met de hexadecimale vertaling erbij. Deze file is handig om af te drukken voor naslag en debug werk. • test.hex - De machinetaal getalrij van je programma. Dit bestand bevat de instructiereeks (in hex) die een Z80 kan uitvoeren. Mocht je een tikfout gemaakt hebben in test.asm, dan geeft zmac een foutmelding, en kan je in test.lst zien hoever hij was gekomen. 1.2 emu Natuurlijk wil je weten of je programma werkt. Dit is te testen door middel van de emulator: Tik in: emu test.hex. Je krijgt als het goed is hetvolgende te zien: CPU halted PC SP IR IX IY A BC DE HL F 0006 0000 0000 0000 0000 19 0d00 0000 0000 18 (H) A’ BC’ DE’ HL’ F’ 00 0000 0000 0000 00 Je programma is uitgevoerd door de emulator. Omdat het programma eindigde met een halt instructie meldt de emulator dat de CPU gestopt is. Vervolgens wordt de inhoud van alle Z80 registers getoond. Je ziet dat de accumulator de (hexadecimale) waarde 19 heeft, dit is decimaal 25. Soms is het practisch om je programma stap voor stap door te lopen (tracing). Dit gaat via emu -t test.hex. De emulator geeft nu: 0000 (emu) ld a,0c De emulator laat zien wat de volgende instructie is die hij gaat uitvoeren, en vraagt om een commando. Tik step (of alleen de letter s) om een enkele instructie uit te voeren. Je krijgt dan: (emu) step 0002 ld (emu) b,0d 2 De volgende (nog uit te voeren instructie) staat op adres 2. Je kan tussentijds de inhoud van de registers bekijken met het commando examine (of kortweg e): (emu) examine PC SP IR IX IY A BC DE HL F 0002 0000 0000 0000 0000 0c 0000 0000 0000 00 (emu) Gebruik help om te kijken wat de emulator allemaal nog meer kan. 1.3 Labels Soms is het handig om een bepaalde geheugenlocatie een naam te geven. Dit kan handig zijn bij bijvoorbeeld sprongopdrachten, of opslag van tijdelijke variabelen. Beschouw het volgende programma wat de som uitrekent van de getallen 1 tot en met 10: ; ; Bereken de som van de getallen 1 tot en met 10 ; ld b,10 ld a,0 loop: add a,b djnz loop halt ; klaar! De djnz instructie trekt iedere keer 1 van het b register af, en springt terug naar de instructie ervoor, totdat het b register de waarde 0 bevat. We hebben de label loop gebruikt om het terugspringadres te benoemen. Natuurlijk is deze label niet meer terug te vinden in de rij machinetaal getallen (wat staat daar dan?!). Merk overigens op dat alles wat na een ; staat tot aan het eind van de regel door de assembler als commentaar wordt beschouwd (en dus genegeerd wordt). Het kan handig zijn om geheugen te reserveren voor tussenresultaten; bijvoorbeeld om de waarde in de accumulator even op te slaan, en later weer terug te halen. In het volgende voorbeeld gebruiken we de label opslag hiervoor: ; ... ld (opslag),a ; save a ld a,(opslag) ; restore a ; ... ; ... halt opslag: defb 0 Hier is defb geen instructie. Het is een aanwijzing aan de assembler om een geheugenlocatie te reserveren van 1 byte groot, met de beginwaarde 0. Vertaal dit stukje code eens met zmac en kijk in de .lst file hoe de assembler dit vertaalt. 3