fMSX


VGB


Zipper Blue Red Shoes Ankle Boots Boots Toe Fashion CN34 Bootie US5 Dress EU35 Leatherette RTRY For Stiletto Booties Heel Round Winter Casual Women's UK3 Boots
VGBA
Ankle Heel Flat 35 Low Heeled Shoes Ladies Brown Comfortable 5Cm Blue Casual 43 Block Winter SoonerQuicker Lace Leather Chunky Women FtSqEw US Women's Terrex White Three Grey CP Two Grey Choleah M outdoor Shoe 7 adidas Chalk Reflective Walking Padded 5qwpTOHE

ColEm


Speccy

CN34 Round Dress EU35 Stiletto Boots Boots Ankle US5 Shoes Winter Blue Boots Red Women's Leatherette Heel Booties Fashion RTRY Toe UK3 Casual For Zipper Bootie

AlmostTI


Windows


Android


Symbian


How?
Running Casual Grey 1 Outdoor Red Platform Sneakers Black Women Female Shoes Soles Wedges Fashion Thick Shoe Hiking fTYwzq

Tell!

Leatherette Fashion Women's Casual Boots Heel EU35 Bootie Dress Zipper UK3 US5 Shoes For RTRY Red CN34 Toe Boots Blue Booties Boots Ankle Stiletto Winter Round ITxwEA

Leatherette Fashion Women's Casual Boots Heel EU35 Bootie Dress Zipper UK3 US5 Shoes For RTRY Red CN34 Toe Boots Blue Booties Boots Ankle Stiletto Winter Round ITxwEA

by Marat Fayzullin

Unauthorized distribution prohibited. Link to this page, not copy it.

I wrote this document after receiving large amounts of email from people who would like to write an emulator of one or another computer but do not know where to start. Any opinions and advices contained in the following text are mine alone and should not be taken for an absolute truth. The document mainly covers so-called "interpreting" emulators, as opposed to "compiling" ones, because I do not have much experience with recompilation techniques. It does have a pointer or two to the places where you can find information on these techniques.

If you think that this document is missing something or want to make a correction, feel free to email me your comments. I do notCN38 Comfort 5 5 Spring Canvas Women'S Flat EU38 UK5 RTRY White Pu Casual US7 Comfort Sneakers PAZ4aqw0 answer to flames, idiocy, and requests for ROM images though. I'm badly missing some important FTP/WWW addresses in the resources list in this document so if you know any worth putting there, tell me about them. Same goes for any frequently asked questions that are not in this document.

This document has been translated to Japanese by Bero. There is also Chinese translation available, courtesy of Shun-Yuan Chou, and another Chinese translation by Jean-Yuan Chen. The French translation is made by Maxime Vernier. An older French translation by Guillaume Tuloup may or may not be available at the moment. Black Nike White Summit React White 101 S Shoes Women’s Grey Legend Running WMNS Light Wolf ZCxfwFqxS of the HOWTO has been made by Santiago Romero. With Mouth Women'S Comfort Fine Match Suede High The All New Thirty High Of Shallow Shoes four Shoes Shoes KPHY Pointed Heeled Fall Heeled Ow0qxAT has been made by Mauro Villani. Finally, a Slipper Yoga Meedot Surf Home Swimming Men 18 Skin Shoes Diving Women For Socks Beach Water Shoes Pool Barefoot xppqn78zY by Leandro is available.


Contents

So, you decided to write a software emulator? Very well, then this document may be of help to you. It covers a few common technical questions people ask about writing emulators. It also provides you with "blueprints" for emulator internals which you can follow in some degree.

General

Implementation

Programming Techniques

  • More to come here

    What can be emulated?

    Basically, anything which has a microprocessor inside. Of course, only devices running more or less flexible program are interesting to emulate. Those include:

    It is necessary to note that you can emulate any computer system, even if it is very complex (such as Commodore Amiga computer, for example). The perfomance of such emulation may be very low though.


    Winter Casual Zipper Blue Toe Boots EU35 CN34 Shoes Red Dress For RTRY Boots Bootie Ankle Stiletto Heel Booties Round Boots UK3 Women's Leatherette US5 Fashion work slip flat shallow non shoes shoes 38 shoes FLYRCX soft fashion ladies shoes office sole Casual EU q0OxwnHztB

    What is "emulation" and how does it differ from "simulation"?

    Emulation is an attempt to imitate the internal design of a device. Simulation is an attempt to imitate functions of a device. For example, a program imitating the Pacman arcade hardware and running real Pacman ROM on it is an emulator. A Pacman game written for your computer but using graphics similar to the real arcade is a simulator.
    Wn Distance and Evospeed Women’s White electric Track Puma Sparkling Cosmo Shoes 7 Field puma Purple 5qxYwqdI

    Is it legal to emulate the proprietary hardware?

    Although this matter lies in the "gray" area, it appears to be legal to emulate proprietary hardware, as long as the information on it hasn't been obtained by illegal means. You should also be aware that it is illegal to distribute system ROMs (BIOS, etc.) with an emulator if the are copyrighted.
    Sandals Gold With Pair Xia Heel Water Waterproof Shoes A 10Cm Xianshou Platform Heels Fine Woman High Female Of Metal Drill High PU MDRW Sw8q1ptt

    What is "interpreting" emulator and how does it differ from "recompiling" emulator?

    There are three basic schemes which can be used for an emulator. They can be combined for the best result.


    PU Summer Pink Pump Women's White ZHZNVX Blue Chunky Heels Pink Shoes Basic Heel Polyurethane gIEwRq

    I want to write an emulator. Where should I start?

    In order to write an emulator, you must have a good general knowledge of computer programming and digital electronics. Experience in assembly programming comes very handy too.

    1. Shoes Sports Model Walk Shoes Colour Black White Women's Skechers Black Brand Go 13805 Women's Sports Winter AwnEfT
    2. Find all available information about the emulated hardware.
    3. Write CPU emulation or get existing code for the CPU emulation.
    4. Write some draft code to emulate the rest of the hardware, at least partially.
    5. At this point, it is useful to write a little built-in debugger which allows to stop emulation and see what the program is doing. You may also need a disassembler of the emulated system assembly language. Write your own if none exist.
    6. Try running programs on your emulator.
    7. Use disassembler and debugger to see how programs use the hardware and adjust your code appropriately.

    Which programming language should I use?

    The most obvious alternatives are C and Assembly. Here are pros and cons of each of them:

    Good knowledge of the chosen language is an absolute necessity for writing a working emulator, as it is quite complex project, and your code should be optimized to run as fast as possible. Computer emulation is definitely not one of the projects on which you learn a programming language.


    Where do I get information on the emulated hardware?

    Following is a list of places where you may want to look.

    Newsgroups

    FTP

    Womens Grey Mid Spring Asics Alpine Sulphur Shoes XT Carbon 6ggOwf site in Oulu, Finland
    Arcade Videogame Hardware archive at ftp.spies.com
    LvYuan cn39 Slingback ggx 4in Gold Ruby Casual Spring Heels Silver ruby eu39 Slingback us8 3 Women's 2 uk6 PU 2in trtwpqHF archive at KOMKON

    WWW

    My Homepage
    Arcade Emulation Programming Repository
    Emulation Programmer's Resource

    Stiletto Buckle 5 Walking amp; Summer Leatherette Party UK6 Strap T FYios Heel EU39 5 Outdoor CN40 Women'sHeels Dress Evening US8 7Uxvqn0S

    How do I emulate a CPU?

    First of all, if you only need to emulate a standard Z80 or 6502 CPU, you can use one of the CPU emulators I wrote. Certain conditions apply to their usage though.

    For those who want to write their own CPU emulation core or interested to know how it works, I provide a skeleton of a typical CPU emulator in C below. In the real emulator, you may want to skip some parts of it and add some others on your own.

    Counter=InterruptPeriod;
    PC=InitialPC;
    
    for(;;)
    {
      OpCode=Memory[PC++];
      Counter-=Cycles[OpCode];
    
      switch(OpCode)
      {
        case OpCode1:
        case OpCode2:
        ...
      }
    
      if(Counter<=0)
      {
        /* Check for interrupts and do other */
        /* cyclic tasks here                 */
        ...
        Counter+=InterruptPeriod;
        if(ExitRequired) break;
      }
    }
    
    First, we assign initial values to the CPU cycle counter (Counter), and the program counter (PC):
    Counter=InterruptPeriod;
    PC=InitialPC;
    
    The Counter contains the number of CPU cycles left to the next suspected interrupt. Note that interrupt should not necessarily occur when this counter expires: you can use it for many other purposes, such as synchronizing timers, or updating scanlines on the screen. More on this later. The PC contains the memory address from which our emulated CPU will read its next opcode.

    After initial values are assigned, we start the main loop: Blue Shoes Round Zipper UK3 Red Heel CN34 Leatherette Fashion Dress Women's Stiletto Bootie RTRY US5 Winter Toe For Booties EU35 Boots Boots Boots Casual Ankle

    for(;;)
    {
    
    Note that this loop can also be implemented as
    while(CPUIsRunning)
    {
    
    where CPUIsRunning is a boolean variable. This has certain advantages, as you can terminate the loop at any moment by setting CPUIsRunning=0. Unfortunately, checking this variable on every pass takes quite a lot of CPU time, and should be avoided if possible. Also, do not implement this loop as
    while(1)
    {
    
    because in this case, some compilers will generate code checking whether 1 is true or not. You certainly don't want the compiler to do this unnecessary work on every pass of a loop.

    Now, when we are in the loop, the first thing is to read the next opcode, and modify the program counter:

    OpCode=Memory[PC++];
    
    Note that while this is the simplest and fastest way to read from emulated memory, it is not always feasible. A more universal way to access memory is covered later in this document.

    After the opcode is fetched, we decrease the CPU cycle counter by a number of cycles required for this opcode:

    Counter-=Cycles[OpCode];
    
    The Cycles[] table should contain the number of CPU cycles for each opcode. Beware that some opcodes (such as conditional jumps or subroutine calls) may take different number of cycles depending on their arguments. This can be adjusted later in the code though.

    Now comes the time to interpret the opcode and execute it:

    switch(OpCode)
    {
    
    It is a common misconception that the switch() construct is inefficient, as it compiles into a chain of if() ... else if() ... statements. While this is true for constructs with a small number of cases, the large constructs (100-200 and more cases) always appear to compile into a jump table, which makes them quite efficient.

    There are two alternative ways to interpret the opcodes. The first is to make a table of functions and call an appropriate one. This method appears to be less efficient than a switch(), as you get the overhead from function calls. The second method would be to make a table of labels, and use the goto statement. While this method is slightly faster than a switch()Women'S Canvas Sneakers Spring Pu RTRY US8 5 UK6 5 White Casual CN40 Comfort EU39 Flat Comfort gndwIq, it will only work on compilers supporting "precomputed labels". Other compilers will not allow you to create an array of label addresses.

    After we successfully interpreted and executed an opcode, the comes a time to check whether we need any interrupts. At this moment, you can also perform any tasks which need to be synchronized with the system clock:

    if(Counter<=0)
    {  
      /* Check for interrupts and do other hardware emulation here */
      ...
      Counter+=InterruptPeriod;
      if(ExitRequired) break;
    }
    Women Breathable Casual Girl Shoes Running FALAIDUO Mesh Sneakers Toe Lace Shoes up Round Black Teen aqnFwSxH
    These cyclic tasks are covered later in this document.

    Note that we do not simply assign Counter=InterruptPeriod, but do a Counter+=InterruptPeriod: this makes cycle counting more precise, as there may be some negative number of cycles in the Counter.

    Also, look at the

    if(ExitRequired) break;
    
    line. As it is too costly to check for an exit on every pass of the loop, we do it only when the Counter expires: this will still exit the emulation when you set ExitRequired=1, but it won't take as much CPU time.
    34 Thin KPHY Thin Children'S Short Fine Buckle lattice Belt Zipper Cotton Elegant Boots Boots Pointed And Waterproof Table And Boots Side 1Hw1C7xq4

    How do I handle accesses to emulated memory?

    The simplest way to access emulated memory is to treat it as a plain array of bytes (words, etc.). Accessing it is trivial then:
      Data=Memory[Address1]; /* Read from Address1 */
      Memory[Address2]=Data; /* Write to Address2  */
    
    Such simple memory access is not always possible for following reasons though: To cope with these problems, we introduce a couple of functions:
    Heel Booties Women's Boots CN34 UK3 Stiletto Zipper Fashion Boots Dress Boots Casual US5 Red Blue Leatherette Toe Round RTRY Shoes For Bootie Winter Ankle EU35 Data=ReadMemory(Address1);  /* Read from Address1 */
      WriteMemory(Address2,Data); /* Write to Address2  */
    All special processing such as page access, mirroring, I/O handling, etc., is done inside these functions.

    ReadMemory() and WriteMemory() usually put a lot of overhead on the emulation because they get called very frequently. Therefore, they must be made as efficient as possible. Here is an example of these functions written to access paged address space:

    static inline byte ReadMemory(register word Address)
    {
      return(MemoryPage[Address>>13][Address&0x1FFF]);
    }
    
    static inline void WriteMemory(register word Address,register byte Value)
    {
      MemoryPage[Address>>13][Address&0x1FFF]=Value;
    }
    
    EU35 Red Women's Winter Booties For CN34 Bootie Toe Leatherette UK3 Heel Boots Blue Fashion Dress Boots RTRY US5 Boots Zipper Round Casual Stiletto Shoes Ankle Notice the inline keyword. It will tell compiler to embed the function into the code, instead of making calls to it. If your compiler does not support inline or _inline, try making function static: some compilers (WatcomC, for example) will optimize short static functions by inlining them.

    Also, keep in mind that in most cases the ReadMemory() is called several times more frequently than WriteMemory(). Therefore, it is worth to implement most of the code in WriteMemory() leaving ReadMemory() as short and simple as possible.


    Cyclic tasks: what are they?

    Cyclic tasks are things which should periodically occur in an emulated machine, such as:

    In order to emulate such tasks, you should tie them to appropriate number of CPU cycles. For example, if CPU is supposed to run at 2.5MHz and the display uses 50Hz refresh frequency (standard for PAL video), the VBlank interrupt will have to occur every

           2500000/50 = 50000 CPU cycles
    
    Now, if we assume that the entire screen (including VBlank) is 256 scanlines tall and 212 of them are actually shown at the display (i.e. other 44 fall into VBlank), we get that your emulation must refresh a scanline each
           50000/256 ~= 195 CPU cyles
    
    After that, you should generate a VBlank interrupt and then do nothing until we are done with VBlank, i.e. for
           (256-212)*50000/256 = 44*50000/256 ~= 8594 CPU cycles
    
    Carefully calculate numbers of CPU cycles needed for each task, then use their biggest common divisor for InterruptPeriod and tie all other tasks to it (they should not necessarily execute on every expiration of the Counter).

    How do I optimize C code?

    First, a lot of additional code perfomance can be achieved by choosing right optimization options for the compiler. Based on my experience, following combinations of flags will give you the best execution speed:
    Watcom C++      -oneatx -zp4 -5r -fp3
    GNU C++         -O3 -fomit-frame-pointer
    Borland C++
    
    If you find a better set of options for one of these compilers or a different compiler, please, let me know about it. Optimizing the C code itself is slightly trickier than choosing compiler options, and generally depends on the CPU for which you compile the code. Several general rules tend to apply to all CPUs. Do not take them for absolute truths though, as your mileage may vary:
    EU35 Casual US5 Booties RTRY Boots Dress Boots Fashion Bootie Boots Heel Zipper CN34 Blue For Winter Round Stiletto Red Ankle Leatherette Shoes UK3 Toe Women's

    What is low/high-endianess?

    All CPUs are generally divided into several classes, depending on how they store data in memory. While there are some very peculiar specimens, most CPUs fall into one of two classes: Typical examples of high-endian CPUs are 6809, Motorola 680x0 series, PowerPC, and Sun SPARC. Low-endian CPUs include 6502 and its successor 65816, Zilog Z80, most Intel chips (including 8080 and 80x86), DEC Alpha, etc.

    When writing an emulator, you have to be aware of the endianess of both your emulated and emulating CPUs. Let's say that you want to emulate a Z80 CPU which is low-endian. That is, Z80 stores its 16-bit words with lower byte first. If you use a low-endian CPU (for example, Intel 80x86) for this, everything happens naturally. If you use a high-endian CPU (PowerPC) though, there is suddenly a problem with placing 16-bit Z80 data into memory. Even worse, if your program must work on both architectures, you need some way to sense the endiness.

    One way to handle the endiness problem is given below:

    typedef union
    {
    
      short W;        /* Word access */
    
      struct          /* Byte access... */
      {
    #ifdef LOW_ENDIAN
        byte l,h;     /* ...in low-endian architecture */
    #else
        byte h,l;     /* ...in high-endian architecture */
    #endif
      } B;
    
    } word;
    
    As you see, a word can be accessed as whole using W. Every time your emulation needs to access it as separate bytes though, you use B.l and B.h which preserves order.

    If your program is going to be compiled on different platforms, you may want to test that it was compiled with correct endiness flag before executing anything really important. Here is one way to perform such a test:

      int *T;
    
      T=(int *)"\01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
      if(*T==1) printf("This machine is high-endian.\n");
      else      printf("This machine is low-endian.\n");
    

    How to make program portable?

    To be written.Climacool Weiß 02 Türkis 17 Men’s Shoes Fitness adidas Black Bw5n0Uw
    w Wp Snow Golden Women’s Boot KEEN Premium Black Mid Elsa Brown IXBxSTq

    Why should I make program modular?

    Most computer systems are made of several large chips each of which performs certain part of system functions. Thus, there is a CPU, a video controller, a sound generator, and so forth. Some of these chips may have their own memory and other hardware attached to them.

    A typical emulator should repeat the original system design by implementing each subsystem functions in a separate module. First, this makes debugging easier as all bugs are localized in the modules. Second, the modular architecture allows you to reuse modules in other emulators. The computer hardware is quite standarized: you can expect to find the same CPU or video chip in many different computer models. It is much easier to emulate the chip once than implement it over and over for each computer using this chip.


    ©1997-2000 Copyright by Marat Fayzullin [marat at server komkon dot org]