tags:

views:

225

answers:

2

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:

  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.

+3  A: 

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:

http://stackoverflow.com/questions/1120709/emulator-framework

Carl Smotricz
Or at least make it seperate projects.
ziggystar
Carl:You are right in saying i am looking for IDE type of environment. However, intent is to have not much fancy GUI features like syntax highlighting etc.To make it very simple, i could use small editbox in the main window, user can type few instructions and run the code. More interested how instructions will actually be emulated/simulated on a PC.
Kavitesh Singh
I've added some more details. Those should help you with that aspect of your question.
Carl Smotricz
Thanks Carl:One more doubt, Since you indicate main task is to create or work on assembler which would have all the features mentioned by me.Any info regarding that?Thing is i want to start in a systematic way of learning this. So be it top down or bottom up approach. It should be like that i realize mid-way, oh i should have done this before i did this.So wanted to take a simple processor and gain some in-roads before heading for bigger ones.
Kavitesh Singh
Writing an assembler is a pretty serious project. I tackled a similar project for the 6502 back in my university days. My personal approach is to jump right in, start coding, fail and then give up. However, I can't recommend this approach. You'll probably want to look at some existing project from the links in this post or Google, and then work out a variation on that.
Carl Smotricz
+4  A: 

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.

Greg Hewgill
Greg:Thanks for the link. Can it be compiled under visual studio 2005/2008? Any additional documentation which may help me understand your work easily. Also details about the chip you emulated?
Kavitesh Singh
is this the chip http://www.atmel.com/products/AVR/
Kavitesh Singh
I've only built it under OS X, but it should be reasonably portable. No guarantees there, though (patches accepted!). The chip it emulates is the ATmega168P, you can get the datasheet from: http://www.atmel.com/dyn/products/datasheets.asp?family_id=607
Greg Hewgill
Comments in the code :(
Kavitesh Singh