Click here to Skip to main content
15,123,819 members
Articles / All Topics
Technical Blog
Posted 26 Apr 2016

Tagged as

Stats

10K views
2 bookmarked

Z80 CPU - A New Project

Rate me:
Please Sign up or sign in to vote.
4.80/5 (2 votes)
26 Apr 2016CPOL2 min read
Z80 CPU - A New Project

Inspired by Eric Lippert's series on creating a Z-Machine interpreter, I decided to create a Z80 CPU Emulator and write about it.

This will very much be a 'I'm just going to do it' and then learn from it, so expect me to make some very silly stupid mistakes as well as going back on decisions that I have made in the past.

I am in the enviable position of having no deadline and doing this just for the fun of it, so I will probably spend a lot of time re factoring; to make the code neater and easier to understand.

A CPU performs a set of instructions that have been supplied to it. Each instruction is specified by an instruction code specified in a byte; this is known as an opcode.

An opcode may require a number of operands, which supply extra information to the opcode. In the case of the Z80 CPU, an opcode can have 0, 1 or 2 operands each of which are also a byte.

There is a lot more to emulating a CPU than just performing operations; things such as timing, interrupts and pin usage needs to be configured but I'm going to start with operations and work my way up.

To begin with, I need to define some classes.

Since all of the opcodes and operations are definable as bytes, I could use the built in byte class but I don't really want to do that. So instead, I am going to define my own ZByte class which is a collection of 8 bits.

So I need a Bit which I am going to define as an enum.

C#
public enum Bit
    {      
        Zero,
        One
    }

public class ZByte
{
      private Bit[] _bits = new Bit[8];

 public Bit this[ByteBitLocation location]
        {
            get
            {
                return _bits[(int)location];
            }
            set
            {
                _bits[(int)location] = value;
            }
        }

      /* Other methods */
}

With ByteBitLocation being defined as:

C#
public enum ByteBitLocation : int
   {
       Zero = 0,
       One = 1,
       Two = 2,
       Three = 3,
       Four = 4,
       Five = 5,
       Six = 6,
       Seven = 7
   }

There is an argument that this is more verbose than required and that using integers would be simpler and easier, but I want to take advantage of compile time checking as much as possible, so that means not using primitive types where possible.

Next week, we will start on our first operation.

 

This article was originally posted at http://www.jflanagan.co.uk/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Member 12485502
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
QuestionFinished Pin
jhuey6425-Jun-16 8:15
Memberjhuey6425-Jun-16 8:15 
AnswerRe: Finished Pin
James Flanagan28-Jun-16 11:08
MemberJames Flanagan28-Jun-16 11:08 
QuestionReally - Z80? Pin
Sean McPoland13-May-16 23:02
MemberSean McPoland13-May-16 23:02 
QuestionPerformance Pin
jpmik8-May-16 8:05
Memberjpmik8-May-16 8:05 
AnswerRe: Performance Pin
James Flanagan11-May-16 7:06
MemberJames Flanagan11-May-16 7:06 
Hi (I'm the author (I switched accounts)),

My main reasons for not using the built in types where

1. I wanted as much type safety as possible and using my own type enabled me to enforce that a bit easier (and requires me to access the class in ways that I define)
2. I wanted the ability to change how I was doing things quickly so encapsulating my byte class enables me to change the internal representation without affecting the rest of the code.

In response to your extremely good points.

1. I'm not particularly worried about performance the Z80 CPU is a 4MHz processor where as a lot of modern cpu's are in the 4GHz range so I'm not expecting it to be a problem. (This could be my own naivety though)

2. I do eventually change my implementation to a struct (I have posts written well in advance)

3. You are completely correct and I eventually change this as well to use an actual byte as an internal representation. So although I am still incurring the cost of having classes on top of the byte I get to keep my private internal implementation.
QuestionFun Pin
Herman Bakker27-Apr-16 23:55
MemberHerman Bakker27-Apr-16 23:55 
GeneralZ80 emulation Pin
Member 990203627-Apr-16 8:12
MemberMember 990203627-Apr-16 8:12 
PraiseZ80 Pin
SteveHolle26-Apr-16 10:43
MemberSteveHolle26-Apr-16 10:43 
QuestionNice Pin
CarelAgain26-Apr-16 6:24
professionalCarelAgain26-Apr-16 6:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.