• Please review our updated Terms and Rules here

How Emulators Work....

ziloo

Veteran Member
Joined
Feb 7, 2006
Messages
990
Location
in the basement
Before I go get myself 5000 lines of program that emulates an
8 bit computer, can someone guide me in the right direction as to
how an emulator works?

Thank you for your support

ziloo
 
An emulator is a program that tries to mimic another computer in as close detail as possible. It will have a CPU emulation where each instruction is handled like the original hardware did. It will have a video emulation where a video signal and in many cases also display of the video signal will be carried out in the same steps as the computer it emulates. It will handle input and output through virtual devices, images of various file formats that try to be an exact duplicate of how data was stored on the actual floppy disks, tapes etc. It often even remaps your PC keyboard so keys are laid out in the same order as on the original computer.

This should be put in perspective to a simulator, which to most part would only settle for presenting an end result that looks and behaves like the original, without necessarily taking all the steps required to get to that result. Take for example a computer which has an official graphic display of 320x200 pixels. An emulator would try to mimic the video chips to closest detail, while an simulator would just generate a 320x200 pixel image. If there were unofficial ways to address the video chip, the emulator might be able to catch them while the simulator would need to be adopted for special cases outside of normal use.
 
Thank you Carlsson!

Now....in order to mimic some aspect of that 8-bit computer,
do you define some kind of an "Object" or "Structure" whose
components correspond to the components of that emulated
entity?

ziloo
 
Hm, are you about to develop a new emulator rather than simply use an existing one? I suppose it depends on the programming team, how modular the emulator is made to be. If you want to look at source code, possibly something like MESS would be useful, as I imagine it consists of many small modules for emulation of various CPUs, generic video chips, keyboard input and so on, glued together with system specifics that make up every emulated machine within the multi-emulator.
 
So....what I understand now (to get a mental image of what is involved)
is that an emulator goes along the same style of programming as a
Computer Game does..... with its own bells and whistles.

ziloo
 
It used to be the case that emulation involved hardware assistance, such as an IBM 360/40 with the 1401 emulation feature and that "simulation" referred to a software-only approach.

Unfortunately, the distinction has become blurred and confused over the years. So my answer to the original question is "no practical difference".
 
I've had a bit of experience using the Z80 emulator on the Propeller chip, (though I didn't write the code and I still don't understand all of it).

The Z80 has 64k of ram and runs at around 6Mhz. The Propeller has 8 cores running at about 80Mhz and 2k of ram per core, plus 32k of common memory.

So the propeller is faster than a Z80 but has less memory. The emulation has to work around these limitations. The most obvious limitation is data storage so on the Propeller the first thing to add is an external ram chip.

In simplistic terms, you might start with some variables that represent the registers, eg A and BC etc. You might also start by filling up the memory with a program, say CP/M.

Then start by reading in the first byte - which I happen to know is the byte value for a JMP in Z80. So, take that byte value and use a lookup table to work out where to go in the emulation. Then call the "jump" routine. This reads the next two bytes from external memory and that gives the location to jump to. Then change the PC register in your emulation to point to this new location, and continue on.

Some opcodes are easy to emulate on another processor, eg MOV/LD instructions. Some get quite complex (DAA was the hardest on the Z80).

Once you have emulated the CPU, then you can emulate other things. For instance, instead of a floppy disk, you might have a disk image on an SD card. For the CP/M emulation, this starts off life as an 8mb file filled (I think) with E5. CP/M might want to write n bytes to a particular block, so you write code to talk to an SD card. At the low level, this is bit banging a pin high and low. At a higher more abstract level, there are routines to open an sd file, write a number of bytes to a particular location and close the file. This corresponds well with low level CP/M routines.

Then you might do the display. For the Propeller, much of this code is already written and so what you end up doing is grabbing a library for keyboard, a library for an 80 column display and a library for SD card access, plus a library for a serial port, and plugging them together with often only a few lines of code.

So this makes the job much simpler.

It is particularly easy on the propeller because of those cores running in parallel. So one core might be doing the keyboard, and it scans the keyboard and stores the bytes in a 16 byte buffer. Put the buffer in common memory.

Then if CP/M does a request via an IN for the port associated with the keyboard, it can just read from that buffer.

I hope this helps. Keep the questions coming!
 
Back to my point. If writing a program to function as another CPU is emulation, what's programming an FPGA to operate as the same CPU?

In general, it's very difficult to make a software program exhibit exactly the timing as a hardwired CPU and peripherals. That's generally where serious simulation/emulation falls apart.

My first software simulator was for a PDP-8; the second was for an 8008 (waiting for silicon to become available) running on a CDC 6600.

I'd still like to see some simulations/emulations of some of the larger mainframe systems. For example, the Burroughs BSP, the ETA GF-10, the Connection Machine, etc.
 
Emulation is hard.... really hard in some cases. Its one of the more advanced topics in computer science.
 
I think of John Carpenter of the Perambulator as being more of an emulator in his approach and Ives (my personal favourite) as the simulator. Don't know about cinema.
 
.......

In simplistic terms, you might start with some variables that represent the registers, eg A and BC etc. ...

.....Some opcodes are easy to emulate on another processor, eg MOV/LD instructions. Some get quite complex (DAA was the hardest on the Z80).

Once you have emulated the CPU.....


Thank you Doc for your prompt response! Now, would you please explain a bit
more about emulating the instruction set?

Ziloo
 
Still depends what you're trying to do and what method you want to go about. If you're just doing a simple software emulator then you might need to learn all of the machine language/opcodes that the other system has (or get a list) then figure out how to write a routine for the system you actually ARE on to convert all the codes from the program you're emulating to be able to run on your current hardware.

So if I was say trying to emulate a 6502 processor system I would want to get a list of all the valid opcodes, you would end up reading whatever image (cartridge or disk) in hex and you would then need to parse it correctly to read each hex byte or bytes and figure out what command they're doing. Then you need to convert it to what command would be valid or write code to get it the expected result. Kinda tricky when you're dealing with video and sound and not just processing. Plus you need to figure out if the commands running are based on just the processor or if they're also using codes that the operating system provided which would be a whole separate set of commands you'd need to figure out.

Think of it like the folks at Compaq originally trying to make a IBM compatible computer. You'd get sued if you just used IBMs code to say, print the character "A" on the screen on the 4th line down and 5th line over. So instead they had developers who were told "I need a function that will print A at x,y." They wrote that from their own mind on how it would work and then called it the same interrupt as the IBM software would call, and now if the software said "IBM computer, print Y at x,y" their code could interpret that and give the program the right result. It was legal since now it's compatible and not using copy protected code. Anyway similar stuff sorta.
 
Hi Ziloo,

There are lots of things to cover when writing an emulator. What system are you trying to emulate? There are many open source projects that you can either use as a starting point, or at least to get an overview of what is required.

On the emulator I'm working on (http://heathkit.garlanger.com/emulator/), I took the Z80Pack source code, started converting it into C++ and including specific H89 ports, memory layout, etc. Added code to implement Heathkit specific behavior, verify correct timings, and handle the floppy disk controller.

An emulator, maps very well to an object-oriented language, like C++. Things like the CPU, the memory system, disk controller, or serial port, can all be encapsulated in their own object, and have very well defined interactions between all of them.

You will want some type of event-driven loop to run the CPU. Each iteration of the loop will check for any pending interrupts, then reads the next memory location at the PC (program counter), and then executes that instruction.

Lots of things to handle, but starting with a working system, helps you stay on track, and quickly see the results of the enhancements you make.

Mark
 
you basically need to keep an array of variables to represent the CPU's registers, have an array to serve as the memory the CPU can access, and emulate it's ability to do port I/O. then to do a standard, straight-forward interpreting emulator you simply follow the program counter register through memory, reading instructions and parsing them accordingly to simulate their operations/results in memory and registers. you need to set CPU flags based on the results of most instructions. you'll also need algorithms to calculate effective memory addresses using the various addressing modes the chip can use.

it seems like something thats extremely complicated, but once you understand the CPU's internal operations well it's more time-consuming than hard. i'm in class at college right now, but when i get home i will post my code for emulating an 8086 CPU in C. (alone, not with the rest of the emulator)

have a look at it, and it should make sense.
 
Last edited:
If you're emulating something like an 8080, you can do so on an x86 so that it runs very, very fast.

Use the x86's registers as the emulated system's registers. If you've got a lot of space, allocate 8 bytes to the code to emulate each opcode, fetch the opcode, shift it 3 bits left and then jump to that value+the location of opcode 00 code. Since the "fetch next opcode" will always be the same, three's no point in doing a call of each opcode's emulation.

If you don't have that much space, make a table of addresses of each opcode's emulation code and do an indirect jump, indexed by the opcode.

The nice thing about using x86 to emulate x80 is that there are very few adjustments to the flags that are needed.

On a 286, the emulation will run like the wind, but even on an 8088, the emulation can turn in a respectable speed.

But you have to be a hard-bitten cycle-counting assembly geek to do this. :)
 
If you're emulating something like an 8080, you can do so on an x86 so that it runs very, very fast.

Use the x86's registers as the emulated system's registers. If you've got a lot of space, allocate 8 bytes to the code to emulate each opcode, fetch the opcode, shift it 3 bits left and then jump to that value+the location of opcode 00 code. Since the "fetch next opcode" will always be the same, three's no point in doing a call of each opcode's emulation.

If you don't have that much space, make a table of addresses of each opcode's emulation code and do an indirect jump, indexed by the opcode.

The nice thing about using x86 to emulate x80 is that there are very few adjustments to the flags that are needed.

On a 286, the emulation will run like the wind, but even on an 8088, the emulation can turn in a respectable speed.

But you have to be a hard-bitten cycle-counting assembly geek to do this. :)

yep, that is a very convenient case though. i don't know much about the 8080 myself, but that would be interesting to see implemented on an 8088. in most cases the host CPU is going to be very different from the emulated CPU, say a 6502 emulated on x86 in a NES emu or something like the motorola 68000 on a powerpc host as part of a Genesis emulator. :)
 
Back
Top