开发者

How to make 8051 emulator

For learning purpose i intend to start building a 8051 microcontroller emulator. I am comfortable programming in C/C++/C#. This is no class project etc but a learning initiative from my side.

I did found quite a lot of questions discussing this. However, I wanted to break it bit more on a granular level so that I can know which areas I need to focus before i actually start writing the code.

My initial requirements are:

    开发者_如何学Go
  1. text editor(can use editbox control) where the user can write assembly code

  2. Validate if the syntax is correct

  3. Have small window which shows the register values at run time.

  4. when user starts the program, the instructions should be step by step updating the register windows.

More than the GUI element i am more interested to know how to emulate the microcontroller.

The way I understand I can further break it down:

  1. I need to have a look up table for instructions or some other way to store available instructions and validate the syntax. Any pointers how to implement this, please let me know.

  2. How do I emulate each instruction for 8051?

  3. For registers, i can have the use un/signed integers based on the type and update the table.

  4. Since microcontroller has limited RAM memory, how do I keep a check of the code length or rather the code which is executing in the memory to avoid and buffer overflow or other issues.

If there are some opensource projects which detail how an emulator is built ground-up, would appreciate.


I think you're a little unclear on the scope of this project, at least as related to the title.

An emulator executes binary code, and nothing else. The emulator doesn't include an editor (that's a development tool) nor an assembler (ditto). It's the assembler's responsibility to do the syntax check and translation, that way the emulator has only the relatively easy job of executing pre-validated, legal code.

It sounds like you want to build a complete IDE. This would wrap a lot of GUI around the editor, assembler and emulator. I would leave that step as the last one.


As for your questions regarding the emulator itself:

You can use an array of up to (e.g.) 64K bytes as the emulator's working memory. You use variables in your program to emulate the registers. I'd use an unsigned char * to emulate the program counter, and ints for most other stuff...

The operation is pretty simple: Start the program counter at 0 (or a pre-determined boot location), and start a loop which fetches instructions via that pointer, and apply to registers and memory whatever operation is associated with the instruction. A simple implementation would center around a huge switch statement that includes all possible instruction codes.

As I said, your emulator shouldn't need to worry about illegal instructions, because the assembler shouldn't produce any. You could have your program (i.e. the main loop) halt if it hits an illegal operation.

Similarly, your emulator doesn't have to worry about range, index or size overruns... that's also the assembler's problem, or maybe the linker's, if you have one.


Update: A few pointers from right here in SO:

Emulator Framework


Recently I put together an emulator for the AVR chip, which is also a small 8-bit microcontroller. The source is on GitHub as ghewgill/emulino. The most interesting file is cpu.c which contains the implementations for each CPU instruction. The key lines are in cpu_run() (omitting some details):

while (state == CPU_RUN) {
    u16 instr = Program[PC++];
    Instr[instr](instr);
}

This loads a 16-bit word from the program memory pointed to by the PC register, then uses that as in index into an instruction jump table (which is a 64k array of function pointers - the actual table is generated by a script at compile time). This function will be one of the do_XXX() functions in that source file, and may do further instruction decoding before executing the actual instruction. For example, the do_ADD() function:

static void do_ADD(u16 instr)
{
    trace(__FUNCTION__);
    // ------rdddddrrrr
    u16 r = (instr & 0xf) | ((instr >> 5) & 0x10);
    u16 d = ((instr >> 4) & 0x1f);
    u8 x = Data.Reg[d] + Data.Reg[r];
    Data.SREG.H = (((Data.Reg[d] & Data.Reg[r]) | (Data.Reg[r] & ~x) | (~x & Data.Reg[d])) & 0x08) != 0;
    Data.SREG.V = (((Data.Reg[d] & Data.Reg[r] & ~x) | (~Data.Reg[d] & ~Data.Reg[r] & x)) & 0x80) != 0;
    Data.SREG.N = (x & 0x80) != 0;
    Data.SREG.S = Data.SREG.N ^ Data.SREG.V;
    Data.SREG.Z = x == 0;
    Data.SREG.C = (((Data.Reg[d] & Data.Reg[r]) | (Data.Reg[r] & ~x) | (~x & Data.Reg[d])) & 0x80) != 0;
    Data.Reg[d] = x;
    Cycle++;
}

This does the actual addition operation (Data.Reg[d] + Data.Reg[r]), then sets all the various condition flags based on the result.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜