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:
text editor(can use editbox control) where the user can write assembly code
Validate if the syntax is correct
Have small window which shows the register values at run time.
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:
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.
How do I emulate each instruction for 8051?
For registers, i can have the use un/signed integers based on the type and update the table.
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.
The industry-standard Keil C compilers, macro assemblers, debuggers, and real-time kernels support all 8051 derivatives and help you get your projects completed on schedule. The Keil 8051 development tools are designed to solve the complex problems facing embedded software developers.
Arduino boards are present in logic 5 volts and 3.3 volts. This makes arduino more versatile than 8051. We can interface 5 volt logic devices with 5 volt logic boards and 3.3 volt sensors with 3.3 volts boards. We don't need to have a level converter.
There are also development IDE like Arduino IDE for programming 8051 derivatives like the AT89s52, STC89c82 and others. In order to be useful any microcontroller will to be programmed for the target domain.
8051 is the original name by Intel with 4 KB ROM and 128 byte RAM. Variants starting with 87 have a user programmable EPROM, sometimes UV erasable. Variants with a C as the third character are some kind of CMOS. 8031 and 8032 are ROM-less versions, with 128 and 256 bytes RAM.
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 int
s 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With