Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a graphical Z80 emulator in C or C++ [closed]

Tags:

c++

c

emulation

z80

I want to take an interest in writing my own simple emulator for the Z80 processor. I have no experience with this type of programming. I am mostly fine with using C-based languages as they are the ones I know best.

What do I need to accomplish this and what are some good tutorials/references that could aid me in this project?

I would also like a tutorial for coding a ROM-dumping application for my TI-84 Plus calculator so I can use its ROM with this emulator.

like image 928
Bobice M. Avatar asked Aug 01 '09 03:08

Bobice M.


4 Answers

It's a bit of a side trip, but since you say you have no experience with this type of programming, you might want to start by building an emulator for the Universal Virtual Machine from the 2006 ICFP programming contest. This is a task that takes an experienced programmer 90 minutes, but many teams with no experience were able to complete it in a few days. When you finish the emulator it unlocks a bunch of fun stuff, and it might be a good warmup before you tackle the Z80.

like image 157
Norman Ramsey Avatar answered Oct 30 '22 08:10

Norman Ramsey


Some things to add (especially for Z80):

  1. Do not trust the documentation is 100% bug free

    I have not see any without bugs including those mentioned here.

  2. Test your CPU core for bugs properly

    It will save you from many headaches and confusion later.

For testing I am using three approaches:

  1. Stepping/tracing against known code (usually commented ROM disassembly)

    It's the first step when nothing works yet. You will see badly (de)coded instructions.

  2. Include different Z80 cores in your emulator and process everything as double emulation

    Make two 'separated' emulators with the same stepping, tracing, and running system. Both CPUs should have its own memory hardware, etc.

    My dual emulator example

    • Run the emulator and after each instruction compare registers and immediate memory locations like [hl],[sp],[sp-1]...
    • At the first difference stop and see what instruction caused it.
      Debug it and continue until you are 'bug-free'. Beware the second core can be also buggy so debug with caution.
  3. When you are more run-able use core tester

    Use ZEXALL Exerciser. It is the best on Z80 (at least from my experience). It helped me with very many things (my core is now 100% ZEXALL compatible). It's done against real hardware so there are no bugs in it. It's from CP/M so some versions need 64K RAM mode to run. Different OS/ROM or whatever can cause some instructions with memory access to fail, so for those you need to find corrected CRCs or compare against real hardware.

    For example, raw ZEXALL fails many things on ZX Spectrum (as it is done for MSX and 64K RAM without ROM), but there are versions done for real ZX Spectrum and they are 100% OK on ZX Spectrum (and on my emulator too :))

    Z80all instruction exerciser
    
    <adc,sbc> hl,<bc,de,hl,sp>...OK
    add hl,<bc,de,hl,sp>.........OK
    add ix,<bc,de,ix,sp>.........OK
    add iy,<bc,de,iy,sp>.........OK
    aluop a,nn...................OK
    aluop a,<b,c,d,e,h,l,(hl),a>.OK
    aluop a,<ixh,ixl,iyh,iyl>....OK
    aluop a,(<ix,iy>+1)..........OK
    bit n,(<ix,iy>+1)............OK
    bit n,<b,c,d,e,h,l,(hl),a>...OK
    cpd<r>.......................OK
    cpi<r>.......................OK
    <daa,cpl,scf,ccf>............OK
    <inc,dec> a..................OK
    <inc,dec> b..................OK
    <inc,dec> bc.................OK
    <inc,dec> c..................OK
    <inc,dec> d..................OK
    <inc,dec> de.................OK
    <inc,dec> e..................OK
    <inc,dec> h..................OK
    <inc,dec> hl.................OK
    <inc,dec> ix.................OK
    <inc,dec> iy.................OK
    <inc,dec> l..................OK
    <inc,dec> (hl)...............OK
    <inc,dec> sp.................OK
    <inc,dec> (<ix,iy>+1)........OK
    <inc,dec> ixh................OK
    <inc,dec> ixl................OK
    <inc,dec>  iyh...............OK
    <inc,dec> iyl................OK
    ld <bc,de>,(nnnn)............OK
    ld hl,(nnnn).................OK
    ld sp,(nnnn).................OK
    ld <ix,iy>,(nnnn)............OK
    ld (nnnn),<bc,de>............OK
    ld (nnnn),hl.................OK
    ld (nnnn),sp.................OK
    ld (nnnn),<ix,iy>............OK
    ld <bc,de,hl,sp>,nnnn........OK
    ld <ix,iy>,nnnn..............OK
    ld a,<(bc),(de)>.............OK
    ld <b,c,d,e,h,l,(hl),a>,nn...OK
    ld (<ix,iy>+1),nn............OK
    ld <b,c,d,e>,(<ix,iy>+1).....OK
    ld <h,l>,(<ix,iy>+1).........OK
    ld a,(<ix,iy>+1).............OK
    ld <ixh,ixl,iyh,iyl>,nn......OK
    ld <bcdehla>,<bcdehla>.......OK
    ld <bcdexya>,<bcdexya>.......OK
    ld a,(nnnn) / ld (nnnn),a....OK
    ldd<r> (1)...................OK
    ldd<r> (2)...................OK
    ldi<r> (1)...................OK
    ldi<r> (2)...................OK
    neg..........................OK
    <rrd,rld>....................OK
    <rlca,rrca,rla,rra>..........OK
    shf/rot (<ix,iy>+1)..........OK
    shf/rot <b,c,d,e,h,l,(hl),a>.OK
    <set,res> n,<bcdehl(hl)a>....OK
    <set,res> n,(<ix,iy>+1)......OK
    ld (<ix,iy>+1),<b,c,d,e>.....OK
    ld (<ix,iy>+1),<h,l>.........OK
    ld (<ix,iy>+1),a.............OK
    ld (<bc,de>),a...............OK
    Tests complete
    

    In case you are about to use ZEXALL beware it is really exhaustive test and IIRC on ~50MHz emulation it took around 30-60 min to complete. And it needs to press a key for scrolling few times ...

    If you need a contention model, add proper tests. Then find one. For ZX Spectrum there are many floating bus, interrupt and screen testers. For TI I have no idea... (I am not a TI calculator user)

BTW: How did it go with your emulator? (Have you done it?)

Instruction set

I would copy my instruction set here but it has 1792 lines and 121 KB so it will not fit into a 30 KB limit. Instead you can find it in a download link in this answer of mine

  • What's the proper implementation for hardware emulation.

It contains 'all' ZX instructions with correct OP codes, coding timing and machine cycles. It took me few years to put together all documentation, so I am passing ZEXALL 100% correctly. My emulator loads this (1792 instruction) text file to the core on init and configures the instruction decoder and processor at runtime, so I was able to change things really fast and simple enough (if a bug was detected)... It saved me a lot of time.

like image 26
Spektre Avatar answered Oct 30 '22 10:10

Spektre


Perhaps start by looking at these:

A good tutorial can be found here: Independent Z80 Assembly Guide

Z80 DOCUMENTATION

The Undocumented Z80 Documented v0.91 (pdf)

The Complete Z80 Instruction Reference

Z80 Microprocessor Instruction Set Summary

like image 16
Mitch Wheat Avatar answered Oct 30 '22 10:10

Mitch Wheat


Mitch is completely correct. Start by understanding the processor. Then play around a bit by writing code to implement particular instructions. Use C++ for this, BTW, not C, or the concepts of the processor will not map to classes in your code.

In the process of implementing instructions, you'll find you need to define things like the flags, and the instruction pointer. That should eventually get you to where you need to implement the memory model, and even the I/O model.

You'll eventually have to figure out how to load code and data into memory, and maybe how to dump it back out to disk.

Only then do you need to get to the point of emulating the execution of code, loaded into memory, at a given instruction pointer.

like image 5
John Saunders Avatar answered Oct 30 '22 10:10

John Saunders