Initialising the Machine

The first of the functions in the emulate.c file that we will discuss, is the initialise() function. It's job is to allocate some space in memory for a machine, to clear the memory that the machine uses and to initialise all the values of the registers of the machine as needed.

Since initialise() needs to return a pointer to the machine structure that it creates, the function starts off by defining a pointer to a machine, which we call mach. This is accomplished with the line:

static machine * mach;

Since we do not want any memory that we point to with this pointer to be deallocated when the initialise() function returns, we must tell C that we want whatever mach points to, to persist. This is done by prepending the reserved word static to the declaration of our pointer mach.

Basically, every time a function returns, C tries to clean up after it, by deallocating and invalidating any memory which that function allocated for use with its local variables. Thus if a programmer wishes the local variables and their contents to remain in memory until next time the function is called, then he/she needs to make use of the static reserved word. But more than that, C treats memory allocated by a function in a tree-like manner, so that if memory is allocated and then assigned to a pointer which happens to be a local variable of the function, on return, C not only invalidates the contents of the pointer itself, but any allocated memory that it points to. Placing the static key word on the declaration of the pointer, however, protects not only the pointer, but the allocated memory pointed to by it.

The next line of the initialise() function, is a simple for loop, which goes through the memory of the machine (which was defined as an array in the emulate.h file) and sets all its contents to zero. Since the initialise() function is called in main.c before we put the assembly language program into the emulated memory, this will not wipe the program from memory before it has a chance to be executed. The for loop, looks as follows-na:

for (int i = 0; i<65536; i++) mem[i] = 0;

Next, space for a new machine structure is allocated in memory, using the calloc function:

mach = calloc(sizeof(machine),1);

Note that the calloc function automatically zeroes all memory that it allocates. Therefore the contents of any fields within the machine structure will automatically be set to zero.

We simply tell calloc to allocate space for one machine, by sending it the size of a machine structure, and the parameter 1.

The only register that we don't want set to zero when the machine begins operation, is the stack pointer. We want the stack to start holding items from the last memory location before the screen memory starts, and down. This implies setting the inital value of the stack pointer to be the first screen memory location:

mach->SP = 0xA000;

Since mach is a pointer to a machine structure and not a machine structure itself, we first need to follow (dereference) the pointer, then set the value of the SP field. Thus we use the arrow notation instead of a dot when referring to the field SP.

Note that to specify the hexadecimal address A000 we use the notation 0xA000 in C. The leading 0x tells C that we are about to give a hexadecimal value, not a decimal one. We could have just given a decimal value, however we first would have had to determine what A000 represents in decimal.

That about covers the initialise() function. So, in summary, initialise() allocates some memory for the machine structure, zeroes everything in that structure except the stack pointer, which it sets to an appropriate address within our machine memory, zeroes the memory of our fictitious machine, then returns a pointer to the machine structure itself.