Programming the Gakken GMC-4 Microcomputer
Gakken publishes the line of Otona no Kagaku (Adult Science) build-it kits. The GMC-4 is a 4-bit microcomputer based on their F-Maikon R-165 kit. The GMC-4 hit the streets on June 30, 2009, with a street price of 2500 yen if purchased in Japan.
12/04/09: Added link to the full Tandy MCT English manual.
07/02/09: Wrote this knol.
The Gakken GMC-4 4-bit microcomputer kit shares the same basic instruction set as their F-Maikon (microcomputer) R-165 model. Kocharin wrote an R-165 simulator, and you can find a GMC-4 assembler here. The R-165 user manual in Japanese is here.
The GMC-4 is apparently based on the earlier Tandy Microcomputer Trainer. You can find the full English manual for the MCT here.
The GMC-4 consists of a hex keypad (with A SET, INCR, RUN and RESET keys), a speaker, one 7-segment LED and seven regular 2-pin LEDs.
Memory is laid out as follows:
|00 – 4F Program Memory|
|50 – 5F Data Memory|
|6F A Register||69 A’ Register|
|6C B Register||67 B’ Register|
|6E Y Register||68 Y’ Register|
|6D Z Register||66 Z’ Register|
The registers are all 4 bits wide. A’ – Z’ are auxiliary registers.
A register is used for most calculations.
Y register is used as an offset to point into data memory. The calculated address value is Y register + 0×50.
There are 7 pre-loaded programs, which are activated by pressing RESET, the program number, RUN. Some of the programs need data to be loaded starting from address 50 first before running. Refer to the program description in the mook for details.
|B||Sound Hit Game|
|F||Morse Code Generator|
Instructions for the Morse code generator are only found on the Otona no Kagaku site.
The GMC-4 keys are as follows:
|A SET||When you enter a 2-byte address value and then press A SET, the address pointer will change to the value entered. The 2-pin LEDs will light to represent the binary value of the current address, and the 7-segment readout will then show the value of the data at that address.|
|INCR||Increments the address pointer. If you entered a hex number for code or data, that value will be stored to memory before incrementing the address pointer.|
|RUN||Execute. If you want to run a pre-loaded program, enter the program number and then press RUN (as given in the table above). Otherwise, select the execute mode (see table below) and then press RUN. The program will start at the current address. Normally, the sequence is:
RESET 1 RUN
|RESET||Resets the address pointer to 0 0. Does not affect the contents of the code or data memory|
|Hard Reset||This is the unmarked button located beside the CPU. A hard reset sets the address pointer to 0 0 and sets memory from 00 to 6F to hex F.|
Entering code to write your own program consists of pressing the RESET key, pressing the single-byte hex character to enter, then INCR. The 2-pin LEDs will light up to show in binary the address you have advanced to, and the 7-segment readout will show the character you entered (prior to pressing INCR). Continue entering the program and pressing INCR as needed. Note that there’s no real end condition for programs. Gakken’s examples always use infinite loops, either jumping to the beginning of the program, or to the address of the JUMP instruction itself.
To review your program, press RESET, then INCR. This will advance you to the next address and the current code value will be displayed on the 7-segment readout. Entering a new code value and pressing INCR will overwrite the existing code. You can jump to a specific address by entering the 2-byte address and then pressing A SET. (I.e. –  [E] A SET to point to address 1E.)
Some programs require data to be loaded into the data memory. To get to the data memory, enter   and then press A SET. You can then enter data just as you added code, by pressing the single byte hex value of the data followed by INCR. You can verify the data values by entering   A SET, and then pressing INCR to advance through the memory addresses.
To execute your program, press RESET, the execute mode, RUN.
Program code table:
|0||KA||K->Ar||0, 1||The pressed key from the hex keypad is saved to the A register. If a key is not pressed, the Flag is set to 1, otherwise it is 0.|
|1||AO||Ar->Op||1||The 7-segment readout displays the value currently contained in the A register.|
|1||Exchange the contents of the A and B registers, and the Y and Z registers.|
|3||CY||Ar<=>Yr||1||Exchange the contents of the A and Y registers.|
|4||AM||Ar->M||1||Write the contents of the A register to data memory (memory address is 50 + Y register).|
|5||MA||M->Ar||1||Write the contents of data memory (50 + Y register) to the A register.|
|6||M+||M+Ar->Ar||0, 1||Add the contents of data memory (50 + Y register) to the A register. If there is overflow, the Flag is set to 1, otherwise 0.|
|7||M-||M-Ar->Ar||0, 1||Subtract the contents of data memory (50 + Y register) from the A register. If the result is negative, the Flag is set to 1, otherwise 0.|
|8||TIA [ ]||[ ] -> Ar||1||Transfer immediate to the A register.|
|9||AIA [ ]||Ar + [ ] -> Ar||0, 1||Add immediate to the A register. If there is overflow, the Flag is set to 1, otherwise 0.|
|A||TIY [ ]||[ ] -> Yr||1||Transfer immediate to the Y register.|
|B||AIY [ ]||Yr + [ ] -> Yr||0, 1||Add immediate to the Y register. If there is overflow, the Flag is set to 1, otherwise 0.|
|C||CIA [ ]||Ar != [ ] ?||0, 1||Compare immediate to the A register. If equal, Flag reset to 0, otherwise set to 1.|
|D||CIY [ ]||Yr != [ ] ?||0, 1||Compare immediate to the Y register. If equal, Flag reset to 0, otherwise set to 1.|
|E||—||—||—||Extended code. See table below.|
|F||JUMP [ ] [ ]||1||Jump to the immediate address if the Flag is 1, otherwise just increment the program counter. The Flag is then set to 1. Note that this is an absolute address. That is, JUMP   will change the address pointer to hex address 0×02. You can jump both forward and backward in program space.|
Extended code table.:
|E0||CAL RSTO||1||Clear the 7-segment readout.|
|E1||CAL SETR||1||Turn on the 2-pin LED using the Y register (Y register takes the value of 0-6).|
|E2||CAL RSTR||1||Turn off the 2-pin LED using the Y register (Y register takes the value of 0-6).|
|E4||CAL CMPL||1||Complement the A register (1 <=> 0).|
|E5||CAL CHNG||1||Swap the A/B/Y/Z registers with A’/B’/Y’/Z’|
|E6||CAL SIFT||0, 1||Shift the A register right 1 bit. If the starting value is even (bit 0 = 0), set the Flag to 1, otherwise 0.|
|E7||CAL ENDS||1||Play the End sound.|
|E8||CAL ERRS||1||Play the Error sound.|
|E9||CAL SHTS||1||Play a short “pi” sound.|
|EA||CAL LONS||1||Play a longer “pi-” sound.|
|EB||CAL SUND||1||Play a note based on the value of the A register (allowed values are 1 – E).|
|EC||CAL TIMR||1||Pause for the time calculated by (value of A register +1) * 0.1 seconds.|
|ED||CAL DSPR||1||Set the 2-pin LEDs with the value from data memory. The data to display is as follows: the upper three bits come from memory address 5F (bits 0-2), and the lower four from memory address 5E (bits 0-3).|
|EE||CAL DEM-||1||Subtract the value of the A register from the value in data memory. The new value is stored in data memory as a decimal. Afterwards, the Y register is decremented by 1.|
|EF||CAL DEM+||1||Add the value of the A register to the value in data memory. The new value is stored in memory as a decimal. If the result is overflow, data memory will be automatically adjusted. Afterwards, the Y register is decremented.|