Reinvent the wheel! It's great fun...
- me?
Hey, why not try to make an emulator for a CPU, that does not exist? - thats what I asked myself in late 1999 while attending the course 49116 Digitalteknik and 50250 Mikrodatamatsystemer on DTU, so I started. Now, just making an emulator isn't that hard - it contains of a lot of switch-case sentences - but I wanted more, so I dediced to design the instruction-set myself after what I thought would be the best compromises between speed, complexity and flexibility. This resulted in the instruction set for the R1-emulator. The documentation for the R1-emulator is avaliable for online reading or download here.
On this page, I'll try to keep you posted on the development of the R1-emulator.
The entire source-code for the emulator (in ANSI C++) is available for download under the GPL-license. The code is currently only tested under DJGPP and is definitly not bug-free.
The R1 is designed around a register unit with 24 general purpose registers and 8 reserved. I have chosen 32 registers, since I know with the simple instructions available for memory-access, one would like a large number of registers. Some of the registers are reserved for special use. One of the other considerations are access to the registers. I did not want to restrict the use of any of the registers, so I dediced that all instructions using registers should be able to address all of the 32 registers.
Since the CPU is designed to be a load/store type computer (only load and store instructions access memory - the rest is register-register instructions). This has the effect, that you can only use immediates in conjunction with move-instructions and jumps. The reason for choosing this approach is again to simplify the internal architecture of the CPU. Of course, it is the intention to protect some of the registers against writing directly to them with a move-instruction (in particular IP).
One of the major differences between this cpu and other cpu's are the fact that this cpu is based on bytes 16-bit long!. WHY?!? you scream, but there is a good reason. First of all, instructions are all 16-bit long, second - today, everybody wastes memory on unicode-characters, so the smallest relevant addressing unit - besides single bits - are 16-bit units. This again, means that a word is 32 bit long and consists of two bytes.
Documentation
The documentation describes all instructions and the syntax of the assembler.
Source
Download this archive and compile the source using an ANSI-C++ compiler and the included makefile
(just "make" it). If you are using a compiler different from DJGPP, please make sure that the four types BYTE, SHORTINT, WORD and INT in r1emu.h is of correct sizes - if they don't match, the entire emulator will fail!
A wordfile for R1-assembler for UltraEdit is included.
Two sort-algoritms are implemented in R1-assembler and included in the archive plus a test-file for the assembler (to test that compilation is correct).
A compiled version is included in the archive - assembler.exe
and emulator.exe
. The function of these two exe's should be straight forward. When emulating, a command-prompt will appear - use r
to execute the program, a
to run it slowly and s
to single-step the instructions.
2000-08-31: Interrupt system now working - use command "int <no>" to raise an interrupt
2000-08-31: New source structure (CPU and ui separated). Took a lot of rewriting, but it was worth it
2000-06-14: I still need to figure out how to make Borland's free C++ compiler compile this!
2000-05-01: Strings can now be used to initialise labels
2000-04-29: Significantly better support for expressions in constants etc.
2000-04-20: Created a makefile
2000-04-20: Errors are now defined as constant instead of magic numbers
2000-04-20: Improved support for algebraic constant expressions
2000-03-28: First public release - 0.5