Information wants to be free...

Z80 CP/M 2.2 Emulator

After finishing a prototype of a MOS 6502 emulator I almost immediately started working on another one. This time a Zilog Z80 based one that runs CP/M 2.2 with inspiration taken from the Kaypro II computer, so I named the emulator "Kaytil".

Despite taking inspiration from the Kaypro II, it does not actually emulate any of the Kaypro II specific hardware, with the exception of the Lear Siegler ADM-3A compatible terminal emulation. But I think most Kaypro II software should work as long as it is not hardware specific and only expects the CP/M OS functionality. ADM-3A escape codes are converted directly to ANSI counterparts without going through (n)curses, which should be good enough.

To be able to run CP/M I adapted the skeletal CBIOS from Digital Research's manual to the emulator code, which is using IN/OUT instructions to communicate with each other. This, together with the reverse engineered CP/M 2.2 source from Clark A. Calkins is assembled using Digital Research's MAC macro assembler. Since the assembler is itself a CP/M program, I have run this in YAZE, which is another popular Z80 CP/M emulator.

Note that the Z80 emulation is not complete, but simply good enough, so some functionality is missing. I have made sure that it passes all the ZEXDOC tests for documented instruction flags, but I have made no effort so support the undocumented flags required to pass the ZEXALL tests. I also think the emulator is quite slow compared to others, probably due to ineffective O(n) instruction lookup and passing of data through functions instead of using global variables. In order for some games to run correctly, the speed is also artificially slowed down by using an interval timer, so it kind of matches that of a real Kaypro II. Some of these things can be adjusted by compile time defines though.

For storage, the emulator operates around on IBM 3740 8-inch floppy disk images. These can easily be managed with the Cpmtools package, which can create new images (mkfs.cpm) or copy files to and from them (cpmcp) from the host system. A total of 4 floppy drives (A, B, C & D) are emulated and can each contain its own image. By default the images are "read only" so any changes are not written back to the disk image file, but this can be overridden with the command line arguments.

Here are some games I have been able to run:
* Ladder (Yahoo Software, Kaypro II Version)
* Aliens (Yahoo Software, Kaypro II Version)
* CatChum (Yahoo Software, Kaypro II Version)
* Colossal Cave Adventure (Michael Goetz, Kaypro II Version)
* Sargon Chess (Hayden Books, CP/M Version)
* Deadline (Infocom, CP/M Version)
* Zork I (Infocom, CP/M Version)
* Zork II (Infocom, CP/M Version)
* Zork III (Infocom, CP/M Version)
* Nemesis (SuperSoft, CP/M Version)

The initial version can be gotten here but I have also put the source code on here for possible further development.

Finally, some screenshots of different games:

Aliens

CatChum

Deadline

Ladder

Sargon Chess


Topic: Open Source, by Kjetil @ 04/07-2021, Article Link

Terminal Mode Commodore 64 Emulator

Just for fun I have made a primitive Commodore 64 emulator, or more correctly mostly a 6502 CPU emulator that happens to run the Commodore 64 ROMs with just a few tweaks. It was mostly to learn about the 6502 CPU itself, so if you actually need a proper emulator, then use VICE instead! The goal was to be able to load and run the Commodore BASIC ROM, which it does, in a Linux terminal.

Anyway, I am releasing the source code under the MIT license and it can be downloaded here.

The 6502 CPU is fully emulated and even supports decimal mode, although only with NMOS (not CMOS) compatibility, so the N, V and Z flags are not set correctly. Nevertheless it passes the excellent test suite made by Klaus Dormann, and even some of the tests made by Wolfgang Lorenz.

To support the C64 architecture, some simple memory bank switching support has been implemented, and hooks are placed when reading and writing to certain memory locations to capture the user input and output. The emulator blocks on input when waiting for a keyboard press, which is hugely beneficial to CPU load. I thought about using curses, but this makes things more complicated so the emulator sets the terminal into canonical mode (with no echo) for the BASIC editor to work instead.

To find the ROMs the emulator assumes that you have VICE installed from before, which puts these at "/usr/lib64/vice/C64/". The location can be changed by editing a #define if they happen to be elsewhere.

Here is what it looks like running in XTerm, and you can also see the CPU disassembly/trace and memory dump functionality embedded into the emulator:

Terminal Mode Commodore 64 Emulator


Topic: Open Source, by Kjetil @ 01/06-2021, Article Link

FreeRTOS support for GR-SAKURA

I have managed to get FreeRTOS running on the GR-SAKURA board. Currently it's just a demo that blinks the LEDs, but maybe I will improve on that later. Anyway, this makes it possible to do multitasking. It is based code from the other FreeRTOS demos and some of the stuff from my earlier GR-SAKURA projects.

I started on this a while ago so the code is built around version 10.0.0 of FreeRTOS, but maybe it will work on newer versions as well.

Download the code from here and unpack the "GR-SAKURA" directory alongside the others into the "Demos" directory of FreeRTOS. Compile it by running "make" from that directory, but you will need the GCC toolchain for the Renesas RX CPU installed first.

I also finally got hold of the excellent Segger J-Link debug probe which makes it possible to use GDB ("rx-elf-gdb" from the RX GCC toolchain) to connect to the GR-SAKURA JTAG port, which I have soldered on:

GR-SAKURA with JTAG connector.


Topic: Open Source, by Kjetil @ 08/05-2021, Article Link

Multiplayer Tank Game

Here is another game project I have had lying around for many years but never finished, until now that is. The idea was to make a graphical multiplayer game and the result is this game which lets up to 6 players drive a tank and shoot at each other. No emphasis on any advanced functionality, I just wanted to get this done and released. Note that a lot of trust is placed on the client here, which makes things simpler, but also makes it pretty easy to cheat by modifying the code.

The game is written in C and uses version 2 of the SDL library for graphics and sound. To make the networked multiplayer portion work, it uses the ENet reliable UDP networking library. It was created to be used on Linux, and I have not tried compiling and running it on other platforms. It probably works best on a local LAN, but I did test it through the Internet as well.

A screenshot:

Tank game screenshot


The map data is stored as a text file that looks like this, easily edited:

################################################################
#      #                                                       #
#      #                                                       #
#      #                                                       #
#   T  #                                                    T  #
#      #                                                       #
#      #                             T                         #
#      #      #########                                 ########
#                                                              #
#                                                              #
#                                                              #
#                                                              #
#             #                                                #
#             #                                                #
#             #                T                               #
#             #                              ###########       #
#             #                              #                 #
#             #                              #                 #
#             #                              #                 #
#             #                              #                 #
#             #            #########                           #
#             #            #########                           #
#             #            #########                           #
#     T       #            #########                           #
#             #            #########              T            #
#             #                                                #
#             #                                                #
#             #                                                #
#             #                                                #
#             #                                                #
#             #                                                #
#             #                T     #                         #
#             #                      #                         #
#             #                      #                         #
#             #                      ###################       #
#             #                                                #
#             #        #######                                 #
#                                                              #
#                                                              #
#                                                              #
########                                                #      #
#                                        T              #      #
#                                                       #      #
#                                                       #      #
#   T                                                   #   T  #
#                                                       #      #
#                                                       #      #
################################################################
          


The source code is released under the MIT license and can be downloaded here.

Topic: Open Source, by Kjetil @ 17/04-2021, Article Link

Strawman

This is a game project I have had lying around for many years, which I finally made into something usable. The initial idea was to make a side-scroller using the SDL library, and the project codename was "Strawman", so that just became the title as well.

The end result is a highly configurable yet simple game. The map data is stored in a text file and can be easily changed. The "game engine" itself is configured through a bunch of #define macros.

Here's a screenshot:

Strawman screenshot


And the corresponding part of the map data, rotated by 90 degrees on purpose, so adding more lines makes the map longer horizontally:

#
# P
#
###
###  #  CCC
###  #E CCC
###  #  CCC
###
#
#E
#
#
#
##

        # CC
#       # CC
##      # CC
###
####
          


The source code is released under the MIT license and can be downloaded here.

Topic: Open Source, by Kjetil @ 01/01-2020, Article Link

uIP support for GR-SAKURA

I have now managed to get the uIP TCP/IP network stack running on the GR-SAKURA board. I'm using the Renesas PHY driver, but my own heavily modified (and simplified) implementation of the Ethernet driver.

The Renesas Ethernet controller has a "Zero Copy" mechanism that uses DMA transfer on incoming and outgoing packets. This is nice and all, but it comes into conflict with the uIP architecture with a single buffer. So I ended up with the separate single uIP buffer and two separate ethernet buffers instead, doing CPU based (memcpy) copying between them. Even though this is not as efficient, it prevents the need for any modifications to the core uIP source code.

One limitation with this initial implementation is that there is no handling of link up or down. The code expects the Ethernet plug to be plugged in at boot and remain connected.

To start using it, get the code from here and unpack it in the uIP source folder. (The "sakura" directory should be alongside the "unix" directory.) Then run "make" inside the "sakura" directory to create the "uip.bin" binary that may be uploaded the GR-SAKURA board.

I have also forked the original uIP repository and made the necessary changes on GitHub.

Topic: Open Source, by Kjetil @ 01/01-2019, Article Link

Joystick Mouse on GR-SAKURA

Here is another project based on the GR-SAKURA board. It translates joystick movement into mouse movement, so it can be used on a PC. This is done reading three analog inputs from the joystick and forwarding data over an UART using the simple Microsoft Serial Mouse format.

The software is based heavily on the 30JH joystick that I happen to have. This is a 3-axis joystick, and the last axis is used to simulate the button presses.

This command in Linux can be used to get it connected:

sudo inputattach -bare /dev/ttyUSB0
          


Here's a photo of the setup:

GR-SAKURA wth Joystick


Here is the main part of the code, which implements the serial mouse protocol:

#include "uart.h"
#include "adc.h"

/* Raw ADC reference values: */
#define JOYSTICK_POS_MAX 2464
#define JOYSTICK_POS_MIN 2080 /* JOYSTICK_POS_MAX - (128 * 3) */
#define JOYSTICK_CENTER  2048
#define JOYSTICK_NEG_MIN 2016 /* JOYSTICK_NEG_MAX + (128 * 3) */
#define JOYSTICK_NEG_MAX 1632

static unsigned char prev_buttons = 0;

static unsigned char convert_adc_to_move_value(short value)
{
  /* Scaling and manual conversion to two's complement. */
  if (value > JOYSTICK_POS_MIN) {
    if (value > JOYSTICK_POS_MAX) {
      value = JOYSTICK_POS_MAX;
    }
    return (value - (JOYSTICK_POS_MIN + 1)) / 3;

  } else if (value < JOYSTICK_NEG_MIN) {
    if (value < JOYSTICK_NEG_MAX) {
      value = JOYSTICK_NEG_MAX;
    }
    return ((value - (JOYSTICK_NEG_MAX + 1)) / 3) + 128;

  } else {
    return 0; /* Filtered. */
  }
}

static unsigned char convert_adc_to_button_value(short value)
{
  if (value > JOYSTICK_POS_MIN) {
    return 0b10; /* Left button pressed. */

  } else if (value < JOYSTICK_NEG_MIN) {
    return 0b01; /* Right button pressed. */

  } else {
    return 0b00; /* No buttons pressed. */
  }
}

static short invert_adc_value(short value)
{
  if (value > JOYSTICK_CENTER) {
    return JOYSTICK_CENTER - (value - JOYSTICK_CENTER);
  } else {
    return JOYSTICK_CENTER + (JOYSTICK_CENTER - value);
  } 
}

static int mouse_format(short x_move_adc, short y_move_adc,
                        short button_adc, unsigned char *data)
{
  unsigned char x_move, y_move, buttons;

  x_move = convert_adc_to_move_value(x_move_adc);
  y_move = convert_adc_to_move_value(invert_adc_value(y_move_adc));
  buttons = convert_adc_to_button_value(button_adc);

  data[0] = 0b11000000;
  data[1] = 0b10000000;
  data[2] = 0b10000000;

  data[0] |= (buttons << 4);
  data[0] |= ((y_move >> 4) & 0b00001100);
  data[0] |= ((x_move >> 6) & 0b00000011);
  data[1] |= (x_move & 0b00111111);
  data[2] |= (y_move & 0b00111111);

  if (y_move > 0 || x_move > 0 || buttons != prev_buttons) {
    prev_buttons = buttons;
    return 1; /* Activity */
  } else {
    return 0; /* No activity */
  }
}

void mouse_loop(void)
{
  unsigned char data[3];

  while(1) {
    asm("wait");
    if (mouse_format(adc_get(0), adc_get(1), adc_get(2), data)) {
      uart0_send(data, 3);
    }
  }
}
          


Get the complete code under the MIT License here, which requires the RX GCC toolchain to compile.

Topic: Open Source, by Kjetil @ 12/12-2018, Article Link

eLua support for GR-SAKURA

I have managed to get eLua running on the GR-SAKURA board. It's an embedded version of version of The Programming Language Lua that can be run on bare-metal.

I forked the original eLua repository and made the necessary changes here on my own copy. Note however that this initial support is very basic; only limited versions of the "tmr", "uart" and "pio" modules are supported at the moment.

Here is an example Lua script that can be run on the board. Name it "autorun.lua" and put it in the "romfs/" directory to run it automatically on startup:

require "pio"
require "pd"
require "tmr"

print("Running LEDs on " .. pd.board())
print("Hold blue button to stop.")

while pio.pin.getval(7) == 1 do
  pio.pin.sethigh(0)
  tmr.delay(0,200000)
  pio.pin.sethigh(1)
  tmr.delay(0,200000)
  pio.pin.sethigh(2)
  tmr.delay(0,200000)
  pio.pin.sethigh(6)
  tmr.delay(0,200000)

  pio.pin.setlow(0)
  tmr.delay(0,200000)
  pio.pin.setlow(1)
  tmr.delay(0,200000)
  pio.pin.setlow(2)
  tmr.delay(0,200000)
  pio.pin.setlow(6)
  tmr.delay(0,200000)
end

print("Finished.")
          


Topic: Open Source, by Kjetil @ 09/11-2018, Article Link

GR-SAKURA Shell Update

I have added two new commands to the GR-SAKURA Shell. One is just a "button" command to print the state of the blue push button, known as SW2. The other "adc" command prints the binary value of the 12-bit A/D converter connected to analog inputs AN0 to AN5.

ADC command:

sakura> adc
AN0: 101111011010
AN1: 110000101110
AN2: 110001111111
AN3: 100000001000
AN4: 000000000001
AN5: 110000110001
sakura> adc
AN0: 101110111011
AN1: 110000000010
AN2: 110001010111
AN3: 110001000001
AN4: 011111000010
AN5: 000000000011
          


Button command:

sakura> button
released
sakura> button
pressed
          


Get the source code here or from my GitLab or GitHub pages.

Also consider using my updated instructions on to build the cross compilation toolchain for the Renesas RX CPU.

Topic: Open Source, by Kjetil @ 11/10-2018, Article Link

GR-SAKURA Shell

Renesas has more microcontroller reference boards. On another trip to Japan I picked up the GR-SAKURA board, which uses the Renesas RX63N microcontroller.

Like the GR-KURUMI, I have made a command shell interface for the GR-SAKURA as well, based on much of the same code, to control its LED and timer functions.

The shell is spawned as the UART on "SCI0", which has the RxD pin at P21 (aka IO0) and the TxD pin at P20 (aka IO1) on the board. The code and build environment also assumes that the pre-flashed USB mass-storage based bootloader is in use, so the binary may be transferred using that USB interface.

Get the source code here and follow this advice on how to setup the toolchain for compiling Renesas RX binaries. I have created custom C-runtime stubs and a linker script to work specifically with the pre-flashed bootloader. These are included in the source code tarball as well.

Here is a similar Python script that can be used to load script files remotely:

#!/usr/bin/python

import serial

class Sakura(object):
    def __init__(self, port):
        self.s = serial.Serial()
        self.s.port = port
        self.s.baudrate = 9600
        self.s.bytesize = serial.EIGHTBITS
        self.s.parity = serial.PARITY_NONE
        self.s.stopbits = serial.STOPBITS_ONE
        self.s.xonxoff = False
        self.s.rtscts = False
        self.s.dsrdtr = False

        self.s.open()
        self.s.flushInput()
        self.s.flushOutput()
    
    def __del__(self):
        self.s.close()

    def _command(self, cmd):
        print ">", cmd
        for char in cmd:
            self.s.write(char) # Write one character at a time...
            self.s.read(1)     # ...and read the echo.
        self.s.write("\r") # Finish command...
        self.s.read(10)    # ...and read the prompt.

    def script(self, filename):
        self._command("stop")
        self._command("d1 off")
        self._command("d2 off")
        self._command("d3 off")
        self._command("d4 off")
        self._command("clear")
        with open(filename) as fh:
            for line_no, line in enumerate(fh):
                self._command("%s %s" % (line_no, line.strip()))
        self._command("run")

if __name__ == "__main__":
    import sys
    s = Sakura("/dev/ttyUSB0")

    if len(sys.argv) > 1:
        s.script(sys.argv[1])
    else:
        print "Usage: %s <script file>" % (sys.argv[0])
          


One difference compared to the GR-KURUMI is that the LEDs on GR-SAKURA are all blue and named D1 to D4 instead. Here is a sample script:

d1 on
sleep 50
d1 off
sleep 50
d2 on
d3 on
sleep 100
d2 off
sleep 100
d3 off
sleep 500
d4 toggle
          


Topic: Open Source, by Kjetil @ 04/02-2018, Article Link

Older articles