Luckily for all who want to have their own CP/M computer, there is an Arduino based solution, which is quite cheap and very simple to build. All you need is Arduino Due or its clone and an SD shield (like this one), which you have to fit on top of your Arduino board. Now you need to download Marcelo Dantas' RunCPM, which is a multiplatform CP/M emulator, and upload it to the board with Arduino IDE. I managed to build RunCPM without problems on Ubuntu 12.04 using version 1.6.7 for Linux 64bits, just remember to install support for Arduino Due with Boards Manager under Tools menu. Next, connect the board to your computer with a micro USB cable inserted into the programming port of Arduino, and then select "Arduino Due (Programming Port)" for the Board and the Port (remember: Arduino must be connected to the computer). Open RunCPM.ino project, select "Verify/Compile" under the Sketch menu to produce the binary image, and then select "Upload" to flash the board with it.
Now, when you have a fully fledged Z80 board, all you need is the CP/M operating system. RunCPM comes with the most popular version 2.2 of CP/M. To run it, format an SD card as FAT32, and put the CPM22.BIN from RunCPM repository in the main folder of the card. Also create folders "A" and "B" - these will be your disk drives, everything you put in there will appear to the system as located on disks "A:" and "B:" respectively. You can create folders from A up to P (as this is the limit of CP/M itself). Now turn off the Arduino, put the card into the SD card shield, and connect it back. You now have the smallest CP/M computer in the world up and running.
Ok, the system has started, but how do you talk to it? Well, you need a terminal, just like for a real CP/M machine! Depending on your operating system, you will need a terminal software. For Windows I recommend PuTTY, in Linux you can install minicom package. Set serial transmission parameters to 8N1, speed to 9600 bauds, and select a serial port to which your CP/M machine is connected. In Ubuntu it's:
minicom -b 9600 -o -D /dev/ttyACM0With MacOSX it's even simpler, just start typing "screen /dev/tty.usb" from the terminal and press TAB to unfold the device full name. In my case the full command looks as follows:
screen /dev/tty.usbmodem1421If you configured the connection correctly, you will now be able to work on your Arduino board like on a real CP/M computer. Just remember to disconnect when leaving the terminal session (ctrl+a and then z in minicom or ctrl+a and then ctrl+\ in OSX) otherwise you may get some strange errors when trying to reconnect.
I did some speed tests with prime sieve Basic benchmark by John Metcalf in Microsoft Basic-80 and Z80 Instruction Exerciser and compared them with results achieved by z80pack simulations at different CPU clocks. As far as I can tell Arduino Due with RunCPM runs very close to a 5MHz Z80 computer, which makes it even more realistic.
RunCPM allows you to have your own, modern, inexpensive CP/M computer, running at the speed of original Z80 based hardware, and use all the huge library of CP/M software with it. At the same time, you can connect to it with USB instead of a serial cable, you can easily exchange software with an SD card, it takes very little power, and last but not least - it easily fits in a pocket.
3 comments:
Thank you for this post.
I did build it like you after reading your post :)
And I did wrote today also a blog-entry about this, but in german.
https://lehwalder.wordpress.com/2017/04/17/cpm-auf-dem-arduino-due-mit-runcpm-bzw-cpmdunino/
for RunCPM v3.7 with this SDCard-Hat see the information at the following page:
https://github.com/MockbaTheBorg/RunCPM/issues/72
for v4.5 of RunCPM which is using the newer SDFat-Lib v2.0.2 you need to change in the first tab of the RunCPM.ino also this for using this SDCard-Shield:
==================================
FROM:
==================================
#else
_puts("Initializing SD card.\r\n");
if (SD.begin(SDINIT)) {
#endif
==================================
TO:
==================================
#else
_puts("Initializing SD card.\r\n");
if (SD.begin(SDINIT, SD_SCK_MHZ(40))) {
#endif
Post a Comment