By downloading the software package including source code, any user can change how the emulator works to make it behave in a different way for their personal interest, as stated in the license terms for the software package.
Some hints are given on the source code to make it easier to advanced people to modify the program. They should be specially useful for people that wants to contribute to the project by making their contributions public by patching the upstream source code via a Pull Request.
|• Basic source code guidelines:||The most easy rules to follow.|
|• Style guides:||Style guides when writing code for this project.|
|• Opcodes table:||Clarification on how the opcodes table is made.|
This program is made using the C programming language. Although any port to a different programming language is good to have as a side project, this is the official language for this project. Therefore, any patch that attempts to change that is not welcome. The project is good using C; I don’t want to change to C++, Python or whatever funky language is the trendiest at this moment.
This program uses GNU Autotools for the build tool. Although GNU Autotools is not loved by everyone, this is the official tool for this project. So, any attempt to change the build tool to CMake, Gradle or regular Makefiles is not welcome.
Although this is not an official GNU project, I make use of most of their style guidelines. Any contributor that wants to make public changes to the project must keep the following rules in mind.
Kfor variables related to an opcode, because these are the names given to the opcode structures. Long names when they are not required is not pretty.
In order to implement the opcodes, the following structure has been made.
There is a common definition for every opcode function in the code, declared
as a type named
opcode_table_t, located as a private typedef
in the file cpu.c at the lib8 subproject.
After that, 16 functions are declared, every one compatible with that typedef.
Their names are
functions have been declared as private functions using the same parameters:
static void nibble_0(struct machine_t* cpu, word opcode); static void nibble_1(struct machine_t* cpu, word opcode); static void nibble_2(struct machine_t* cpu, word opcode);
Every one of these functions executes opcodes with a P value matching the one
in the function name. As an example, the opcode
6104 would be executed
nibble_6, since P(6104) = 6.
Then, there is an array pointing to every opcode function named
nibbles. These functions are sorted by P value, so that
nibbles will return a pointer to the function
nibbles[0xB] will return a pointer to the function
Thanks to this indirection, the processing logic for an opcode is easier
since no big switch is required on code. Using this indirection, it is
more straightforward to know which function should process each opcode.
Although, some functions such as
nibble_6 will make use of switch
anyway since there are multiple opcodes sharing the same P value.