A Project with Source Code: Hexadecimal Little Man Computer Simulator

Author’s Note: This is just the result of a little experiment I was doing recently. This simulator uses a modified version of the Little Man educational computer instruction set, using hexadecimal byte encoding rather than binary-coded decimal, and as such is not particularly sophisticated or useful. As this code was written in a short period of time, it is not the cleanest, and there are several elements where the performance is sub-optimal; these include the switches, which flick on and off far too quickly when a key is pressed.

The simulator uses the Allegro library – much of what I was doing was simply for the purpose of getting to grips with the graphical functions, and it made some sense to adapt a previously tested program to test these out.

The key layout is as follows:

P – toggle simulator power

Q, W, E, R, T, Y, U, I – toggle address counter bits 0 to 7

A, S, D, F, G, H, J, K, Z, X, C, F – toggle address content bits 0 to 11

Enter – Execute instructions

Space – Enter input (only operational when Awaiting Input light is on)

Delete – Clear memory

ESC – Quit

The Little Man instruction set has nine operation codes as standard, with some additional instructions added as placeholders in the hexadecimal system. They are described below (where xx is a hexadecimal number):

1xx – Add the contents of memory address xx to the accumulator

2xx – Subtract the contents of memory address xx from the accumulator

3xx – Store the contents of the accumulator in memory address xx

5xx – Retrieve the contents of memory address xx and place them in the accumulator

6xx – Unconditional branch to memory address xx

7xx – Branch to memory address xx if the contents of the accumulator equal zero

8xx – Branch to memory address xx if the contents of the accumulator equal or are greater than zero

901 – Accept input, which will be placed in the accumulator (the user will be prompted to enter a number via the address contents switches)

902 – Output the contents of the accumulator (these will be printed using fprintf() to a file whose name by default is lmc_output, and is placed in the same directory as the executable file)

0xx – End program

4xx, 9xx (where xx >= 03), Axx, Bxx, Cxx, Dxx, Exx, Fxx – NOP (no operation)

Note: The layout of this blog format doesn’t extend to the 80 columns required to show all of the source code appropriately. You can circumvent this restriction by dragging the mouse over all of the source code and copying it to a text editor; the hidden code will show up.

/* lmc_gui: A graphical simulator for the Little Man educational instruction
   set, modified for hexadecimal operation.
   Copyright (C) 2012  Richard Kiernan

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#include <allegro.h>
#include <stdio.h>

/* Hexadecimal LMC instruction set has 255 "mailboxes" */
#define MAILBOXES 0x100
#define INSTRUCTION_MAX 0xFFF /* Highest value of LMC instructions/data */
#define OP_SPLIT 0xFF /* Denotes the split between opcodes and operands */
#define INSTRUCTION_REST 15 /* The pause time between executed instructions
			     * in milliseconds */

/* Colour definitions */
#define OFF_RED makecol(148,64,64)
#define ON_RED makecol(225,64,64)
#define BG_BLUE makecol(78,191,89)
#define TOGGLE_YELLOW makecol(186,255,0)

/* Memory address structure */
struct memory_address {
    int address;
    int contents;
} mailbox[MAILBOXES];

/* Function prototypes */
void setup_screen(void);
void setup_components(void);
void setup_accumulator(void);
void setup_memory_addresses(void);
void setup_memory_contents(void);
void setup_power_switch(void);
void setup_clear_switch(void);
void setup_execute_switch(void);
void setup_input_light(void);
void initialise_memory(void);
void get_input(void);
void print_status(void);
void toggle_power(int setting);
void toggle_address_switch(int toggle, int setting);
void set_contents(void);
void toggle_contents_switch(int toggle, int setting, char mode);
void toggle_clear_switch(void);
void toggle_execute_switch(void);
void execute_instructions(void);
void set_accumulator(void);
void display_op_status(int opcode, int operand);
void get_program_input(void);

/* Program variables */
int pc = 0; /* Program counter */
int power = 0; /* Power status */
int accumulator = 0; /* Accumulator contents */
int input_temp = 0; /* Temporary storage for user input */

/* lmc_gui: A graphical simulator for the Little Man educational instruction
   set, modified for hexadecimal operation.
   Copyright (C) 2012  Richard Kiernan

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#include "lmc_gui.h"

int main(void)
{
    /* Initialise program */
    allegro_init();
    setup_screen();
    install_keyboard();
    initialise_memory();

    while (!key[KEY_ESC]) {
	/* Wait for a keypress */
	if (keypressed()) {
	    get_input();
	    rest(150);
	}
    }

    /* Clean up */
    allegro_exit();
    return 0;
}

/* setup_screen: Sets graphics mode, then calls the setup_components() function
   to draw the screen. */
void setup_screen() {
    /* Change video mode to 640x250 windowed */
    int ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 250, 0, 0);
    if (ret != 0) {
	allegro_message(allegro_error);
	return;
    }

    setup_components();
}

/* setup_components: Sets up all the individual graphical elements of the
   simulator. */
void setup_components(void)
{
    rectfill(screen, 0, 0, SCREEN_W, SCREEN_H, 0); /* Clear screen */
    setup_accumulator();
    setup_memory_addresses();
    setup_memory_contents();
    setup_power_switch();
    setup_execute_switch();
    setup_clear_switch();
    setup_input_light();
}

/* setup_accumulator: Draws the accumulator lights in their default "off"
   state */
void setup_accumulator(void)
{
    int i;

    for (i = 0; i < 12; i++)
	circlefill(screen, 100 + i * 25, 50, 5, OFF_RED);

    textout_ex(screen, font, "ACCUMULATOR", 200, 60, 15, 0);
}

/* setup_memory_addresses: Draws the memory address lights and switches in their
   default "off" state */
void setup_memory_addresses(void)
{
    int i;

    textout_ex(screen, font, "MEMORY ADDRESS", 200, 85, 15, 0);
    for (i = 0; i < 8; i++)
	circlefill(screen, 200 + i * 25, 100, 5, OFF_RED);
    for (i = 0; i < 8; i++)
	rectfill(screen, 195 + i * 25, 120, 205 + i * 25, 140, BG_BLUE);
    for (i = 0; i < 8; i++)
	rectfill(screen, 195 + i * 25, 120, 205 + i * 25, 125, TOGGLE_YELLOW);
}

/* setup_memory_contents: Draws the address contents lights and switches in
   their default "off" state */
void setup_memory_contents(void)
{
    int i;

    textout_ex(screen, font, "ADDRESS CONTENTS", 200, 150, 15, 0);
    for (i = 0; i < 12; i++)
	circlefill(screen, 100 + i * 25, 165, 5, OFF_RED);
    for (i = 0; i < 12; i++)
	rectfill(screen, 95 + i * 25, 185, 105 + i * 25, 205, BG_BLUE);
    for (i = 0; i < 12; i++)
	rectfill(screen, 95 + i * 25, 185, 105 + i * 25, 190, TOGGLE_YELLOW);
}

/* setup_power_switch: Draws the power toggle light and switch in their default
   "off" state */
void setup_power_switch(void)
{
    circlefill(screen, 490, 50, 5, OFF_RED);
    rectfill(screen, 485, 65, 495, 85, BG_BLUE);
    rectfill(screen, 485, 65, 495, 70, TOGGLE_YELLOW);
    textout_ex(screen, font, "POWER", 500, 65, 15, 0);
}

/* setup_clear_switch: Draws the clear memory light and switch in their default
   "off" state */
void setup_clear_switch(void)
{
    circlefill(screen, 490, 100, 5, OFF_RED);
    rectfill(screen, 485, 120, 495, 140, BG_BLUE);
    rectfill(screen, 485, 120, 495, 125, TOGGLE_YELLOW);
    textout_ex(screen, font, "CLEAR", 500, 120, 15, 0);
    textout_ex(screen, font, "MEMORY", 500, 130, 15, 0);
}

/* setup_execute_switch: Draws the execute instructions light and switch in
   their default "off" state */
void setup_execute_switch(void)
{
    circlefill(screen, 490, 165, 5, OFF_RED);
    rectfill(screen, 485, 185, 495, 205, BG_BLUE);
    rectfill(screen, 485, 185, 495, 190, TOGGLE_YELLOW);
    textout_ex(screen, font, "EXECUTE", 500, 185, 15, 0);
    textout_ex(screen, font, "INSTRUCTIONS", 500, 195, 15, 0);
}

/* setup_input_light: Draws the input light in its default "off" state */
void setup_input_light(void)
{
    circlefill(screen, 425, 50, 5, OFF_RED);
    textout_ex(screen, font, "AWAITING", 400, 65, 15, 0);
    textout_ex(screen, font, "INPUT", 400, 75, 15, 0);
}

/* initialise_memory: zeroes the contents of all mailboxes and the
   accumulator */
void initialise_memory(void)
{
    int i;

    /* Set mailbox addresses appropriately, clear memory */
    for (i = 0; i < MAILBOXES; i++) {
	mailbox[i].address = i;
	mailbox[i].contents = 0;
    }

    /* Clear accumulator contents */
    accumulator = 0;
}

/* get_input: receives and resolves user input from the keyboard */
void get_input(void)
{
    /* Toggle power switch */
    if (key[KEY_P]) {
	if (!power)
	    toggle_power(1);
	else {
	    toggle_power(0);
	    initialise_memory();
	    setup_components();
	    pc = 0;
	}
    }

    /* Toggle address switches */
    if (key[KEY_Q] && power) {
	if (pc & (1 << 7))
	    toggle_address_switch(0, 0);
	else
	    toggle_address_switch(0, 1);
    }

    if (key[KEY_W] && power) {
	if (pc & (1 << 6))
	    toggle_address_switch(1, 0);
	else
	    toggle_address_switch(1, 1);
    }

    if (key[KEY_E] && power) {
	if (pc & (1 << 5))
	    toggle_address_switch(2, 0);
	else
	    toggle_address_switch(2, 1);
    }

    if (key[KEY_R] && power) {
	if (pc & (1 << 4))
	    toggle_address_switch(3, 0);
	else
	    toggle_address_switch(3, 1);
    }

    if (key[KEY_T] && power) {
	if (pc & (1 << 3))
	    toggle_address_switch(4, 0);
	else
	    toggle_address_switch(4, 1);
    }

    if (key[KEY_Y] && power) {
	if (pc & (1 << 2))
	    toggle_address_switch(5, 0);
	else
	    toggle_address_switch(5, 1);
    }

    if (key[KEY_U] && power) {
	if (pc & (1 << 1))
	    toggle_address_switch(6, 0);
	else
	    toggle_address_switch(6, 1);
    }

    if (key[KEY_I] && power) {
	if (pc & (1 << 0))
	    toggle_address_switch(7, 0);
	else
	    toggle_address_switch(7, 1);
    }

    /* Toggle contents switches */
    if (key[KEY_A] && power) {
	if (mailbox[pc].contents & (1 << 11))
	    toggle_contents_switch(0, 0, 't');
	else
	    toggle_contents_switch(0, 1, 't');
    }

    if (key[KEY_S] && power) {
	if (mailbox[pc].contents & (1 << 10))
	    toggle_contents_switch(1, 0, 't');
	else
	    toggle_contents_switch(1, 1, 't');
    }

    if (key[KEY_D] && power) {
	if (mailbox[pc].contents & (1 << 9))
	    toggle_contents_switch(2, 0, 't');
	else
	    toggle_contents_switch(2, 1, 't');
    }

    if (key[KEY_F] && power) {
	if (mailbox[pc].contents & (1 << 8))
	    toggle_contents_switch(3, 0, 't');
	else
	    toggle_contents_switch(3, 1, 't');
    }

    if (key[KEY_G] && power) {
	if (mailbox[pc].contents & (1 << 7))
	    toggle_contents_switch(4, 0, 't');
	else
	    toggle_contents_switch(4, 1, 't');
    }

    if (key[KEY_H] && power) {
	if (mailbox[pc].contents & (1 << 6))
	    toggle_contents_switch(5, 0, 't');
	else
	    toggle_contents_switch(5, 1, 't');
    }

    if (key[KEY_J] && power) {
	if (mailbox[pc].contents & (1 << 5))
	    toggle_contents_switch(6, 0, 't');
	else
	    toggle_contents_switch(6, 1, 't');
    }

    if (key[KEY_K] && power) {
	if (mailbox[pc].contents & (1 << 4))
	    toggle_contents_switch(7, 0, 't');
	else
	    toggle_contents_switch(7, 1, 't');
    }

    if (key[KEY_Z] && power) {
	if (mailbox[pc].contents & (1 << 3))
	    toggle_contents_switch(8, 0, 't');
	else
	    toggle_contents_switch(8, 1, 't');
    }

    if (key[KEY_X] && power) {
	if (mailbox[pc].contents & (1 << 2))
	    toggle_contents_switch(9, 0, 't');
	else
	    toggle_contents_switch(9, 1, 't');
    }

    if (key[KEY_C] && power) {
	if (mailbox[pc].contents & (1 << 1))
	    toggle_contents_switch(10, 0, 't');
	else
	    toggle_contents_switch(10, 1, 't');
    }

    if (key[KEY_V] && power) {
	if (mailbox[pc].contents & (1 << 0))
	    toggle_contents_switch(11, 0, 't');
	else
	    toggle_contents_switch(11, 1, 't');
    }

    /* Toggle clear memory switch */
    if (key[KEY_DEL] && power) {
	toggle_clear_switch();
    }

    /* Toggle execute instructions switch */
    if (key[KEY_ENTER] && power) {
	toggle_execute_switch();
    }
}

/* toggle_power: toggles power from on to off and vice versa; flips the switch
   and light status appropriately. */
void toggle_power(int setting)
{
    if (setting == 1) {
	power = 1;
	/* Turn on light, flip switch down */
	circlefill(screen, 490, 50, 5, ON_RED);
	rectfill(screen, 485, 65, 495, 85, BG_BLUE);
	rectfill(screen, 485, 80, 495, 85, TOGGLE_YELLOW);
    } else if (setting == 0) {
	power = 0;
	/* Turn off light, flip switch up */
	circlefill(screen, 490, 50, 5, OFF_RED);
	rectfill(screen, 485, 65, 495, 85, BG_BLUE);
	rectfill(screen, 485, 65, 495, 70, TOGGLE_YELLOW);
    }
}

/* toggle_address_switch: toggles the bit in the current address addressed by
 the switch from on to off and vice versa; flips the switch and light status
 appropriately. */
void toggle_address_switch(int toggle, int setting)
{
    /* Flip the bit of the program counter corresponding to the big-endian
       position of the address switch */
    pc ^= 1 << (7 - toggle);

    /* Change light setting, flip switch */
    if (setting == 1) {
	circlefill(screen, 200 + toggle * 25, 100, 5, ON_RED);
    	rectfill(screen, 195 + toggle * 25, 120, 205 + toggle * 25, 140,
		 BG_BLUE);
    	rectfill(screen, 195 + toggle * 25, 135, 205 + toggle * 25, 140,
		 TOGGLE_YELLOW);
    } else if (setting == 0) {
	circlefill(screen, 200 + toggle * 25, 100, 5, OFF_RED);
    	rectfill(screen, 195 + toggle * 25, 120, 205 + toggle * 25, 140,
		 BG_BLUE);
    	rectfill(screen, 195 + toggle * 25, 120, 205 + toggle * 25, 125,
		 TOGGLE_YELLOW);
    }

    set_contents();
}

/* set_contents: Sets the positions of the memory contents switches correctly
   based on the current memory address */
void set_contents(void)
{
    int i;

    /* Toggle switches and lights depending on contents of memory address */
    for (i = 0; i < 12; i++) {
	toggle_contents_switch(i, (mailbox[pc].contents
				   & (1 << (11 - i))) >> (11 - i), 's');
    }
}

/* toggle_contents_switch: Flips the switch and light status of the switch
 appropriately; depending on the mode, it may also toggle the bit in either
 the current memory address's contents or the temporary input storage buffer
 based on the switch. */
void toggle_contents_switch(int toggle, int setting, char mode)
{
    /* If mode is 't', flip the bit in the address contents corresponding to
       the big-endian position of the switch.
       If mode is 'a', do this for the bit in the temporary input store. */
    if (mode == 't')
	mailbox[pc].contents ^= 1 << (11 - toggle);
    if (mode == 'a')
	input_temp ^= 1 << (11 - toggle);

    /* Change light settings, flip switch */
    if (setting == 1) {
	circlefill(screen, 100 + toggle * 25, 165, 5, ON_RED);
	rectfill(screen, 95 + toggle * 25, 185, 105 + toggle * 25, 205,
		 BG_BLUE);
	rectfill(screen, 95 + toggle * 25, 200, 105 + toggle * 25, 205,
		 TOGGLE_YELLOW);
    } else if (setting == 0) {
	circlefill(screen, 100 + toggle * 25, 165, 5, OFF_RED);
	rectfill(screen, 95 + toggle * 25, 185, 105 + toggle * 25, 205,
		 BG_BLUE);
	rectfill(screen, 95 + toggle * 25, 185, 105 + toggle * 25, 190,
		 TOGGLE_YELLOW);
    }
}

/* toggle_clear_switch: Clears the contents of the mailbox contents; flips the
   clear switch up and down and turns the light on and off. */
void toggle_clear_switch(void)
{
    int i;

    /* Turn on light, flip switch down. Pause for effect */
    circlefill(screen, 490, 100, 5, ON_RED);
    rectfill(screen, 485, 120, 495, 140, BG_BLUE);
    rectfill(screen, 485, 135, 495, 140, TOGGLE_YELLOW);
    rest(100);

    /* Clear contents of all mailboxes */
    for (i = 0; i < MAILBOXES; i++) { 	
        mailbox[i].contents = 0;
    }

    /* Change positions of address contents switches */
    set_contents(); 
    /* Turn off light, flip switch up */
    circlefill(screen, 490, 100, 5, OFF_RED);
    rectfill(screen, 485, 120, 495, 140, BG_BLUE);
    rectfill(screen, 485, 120, 495, 125, TOGGLE_YELLOW); 
} 

/* toggle_execute_switch: Calls the execute_instructions() function; keeps the
   switch flipped down and the light turned on until that function has
   finished. */ 
void toggle_execute_switch(void)
{
    /* Turn on light, flip switch down. Pause for effect */
    circlefill(screen, 490, 165, 5, ON_RED);
    rectfill(screen, 485, 185, 495, 205, BG_BLUE);
    rectfill(screen, 485, 200, 495, 205, TOGGLE_YELLOW);
    rest(100);
    execute_instructions();

    /* Turn off light, flip switch up. */
    circlefill(screen, 490, 165, 5, OFF_RED);
    rectfill(screen, 485, 185, 495, 205, BG_BLUE);
    rectfill(screen, 485, 185, 495, 190, TOGGLE_YELLOW);
} 

/* execute_instructions: Splits instructions into op codes and operands, then
   executes those instructions in accordance with the modified hexadecimal LMC
   rules of execution. */ 
void execute_instructions(void) 
{
    int opcode = 0, operand = 0;
    int counter = 0;
    int i;
    FILE *ofp = fopen("lmc_output", "a");
    accumulator = 0;

    do {
        opcode = mailbox[counter].contents / (OP_SPLIT + 1);
        operand = mailbox[counter].contents & OP_SPLIT;
        switch(opcode) {
        case 0x1:
            accumulator += mailbox[operand].contents;
            break;
        case 0x2:
            accumulator -= mailbox[operand].contents;
            break;
        case 0x3:
            mailbox[operand].contents = accumulator;
            break;
        case 0x4:
            break; /* Treat as NOP */
        case 0x5:
            accumulator = mailbox[operand].contents;
            break;
        case 0x6:
            counter = operand;
            break;
        case 0x7:
        /* If accumulator is zero, branch; otherwise, progress to next
        instruction - treat as NOP. */
            if (accumulator == 0)
                counter = operand;
            else
                ++counter;
            break;
        case 0x8:
        /* If accumulator is greater than or equal to zero, branch;
           otherwise, progress to next instruction - treat as NOP. */
            if (accumulator >= 0)
                counter = operand;
	    else
		++counter;
	    break;
	case 0x9:
	    if (operand == 0x1) {
		/* Clear all contents switches */
		for (i = 0; i < 12; i++)
		    toggle_contents_switch(i, 0, 's');
		/* Turn on input light */
		circlefill(screen, 425, 50, 5, ON_RED);
		get_program_input();
		/* Turn off input light */
		circlefill(screen, 425, 50, 5, OFF_RED);
		set_contents(); /* Restore memory contents switch settings */
		accumulator = input_temp;
	    } else if (operand == 0x2) {
		fprintf(ofp, "%3hx\n", accumulator);
	    }
	    break;
	case 0x0:
	    set_accumulator(); /* Display accumulator contents */
	    fprintf(ofp, "----- INSTRUCTIONS COMPLETE -----\n");
	    fclose(ofp);
	    return;
	default:
	    break; /* All op codes outside of 0 - 9 are undefined.
		    * Treat as NOP. */
	}
	/* If not a jump instruction, increment the counter */
	if (opcode != 0x6 && opcode != 0x7 && opcode != 0x8)
	    ++counter;

	set_accumulator(); /* Display accumulator contents */

	/* Pause for effect, to enable accumulator lights to be seen in action.
	   May be changed or removed for a faster or slower simulation. */
	rest(INSTRUCTION_REST);

	if (key[KEY_ESC])
	    return; /* Allow the user to exit, e.g. from an infinite loop */
    } while (opcode != 0);
}

/* set_accumulator: Set the status of the accumulator lights based on the
   active bits in the accumulator "register" */
void set_accumulator(void)
{
    int i;

    /* Set accumulator lights based on the active bits in the accumulator */
    for (i = 0; i < 12; i++) {
	if (accumulator & 1 << (11 - i))
	    circlefill(screen, 100 + i * 25, 50, 5, ON_RED);
	else
	    circlefill(screen, 100 + i * 25, 50, 5, OFF_RED);
    }
}

/* get_program_input: Allows entry of data into the temporary input storage
   buffer using the memory contents switches. */
void get_program_input(void)
{
    /* Clear temporary input storage buffer */
    input_temp = 0;
    while (!key[KEY_SPACE]) {
	/* Toggle contents switches */
	if (key[KEY_A]) {
	    if (input_temp & (1 << 11))
		toggle_contents_switch(0, 0, 'a');
	    else
		toggle_contents_switch(0, 1, 'a');
	}

	if (key[KEY_S]) {
	    if (input_temp & (1 << 10))
		toggle_contents_switch(1, 0, 'a');
	    else
		toggle_contents_switch(1, 1, 'a');
	}

	if (key[KEY_D]) {
	    if (input_temp & (1 << 9))
		toggle_contents_switch(2, 0, 'a');
	    else
		toggle_contents_switch(2, 1, 'a');
	}

	if (key[KEY_F]) {
	    if (input_temp & (1 << 8))
		toggle_contents_switch(3, 0, 'a');
	    else
		toggle_contents_switch(3, 1, 'a');
	}

	if (key[KEY_G]) {
	    if (input_temp & (1 << 7))
		toggle_contents_switch(4, 0, 'a');
	    else
		toggle_contents_switch(4, 1, 'a');
	}

	if (key[KEY_H]) {
	    if (input_temp & (1 << 6))
		toggle_contents_switch(5, 0, 'a');
	    else
		toggle_contents_switch(5, 1, 'a');
	}

	if (key[KEY_J]) {
	    if (input_temp & (1 << 5))
		toggle_contents_switch(6, 0, 'a');
	    else
		toggle_contents_switch(6, 1, 'a');
	}

	if (key[KEY_K]) {
	    if (input_temp & (1 << 4))
		toggle_contents_switch(7, 0, 'a');
	    else
		toggle_contents_switch(7, 1, 'a');
	}

	if (key[KEY_Z]) {
	    if (input_temp & (1 << 3))
		toggle_contents_switch(8, 0, 'a');
	    else
		toggle_contents_switch(8, 1, 'a');
	}

	if (key[KEY_X]) {
	    if (input_temp & (1 << 2))
		toggle_contents_switch(9, 0, 'a');
	    else
		toggle_contents_switch(9, 1, 'a');
	}

	if (key[KEY_C]) {
	    if (input_temp & (1 << 1))
		toggle_contents_switch(10, 0, 'a');
	    else
		toggle_contents_switch(10, 1, 'a');
	}

	if (key[KEY_V]) {
	    if (input_temp & (1 << 0))
		toggle_contents_switch(11, 0, 'a');
	    else
		toggle_contents_switch(11, 1, 'a');
	}
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: