Saturday, September 24, 2016

It's all in the Modes & Mappings of the Recreated ZX Spectrum Keys

1 comment
As mentioned last post, the keyboard works perfectly in the standard PS2 mode, it's the emulator 'layer' that has usage issues. If you switch to mode A (the emulator layer) on the keyboard, the key presses register anything but what you'd expect. There seemed to be some rather odd mapping going on, leaving the emulator mode a little useless.

There would seem to be 3 ways in which to adjust the Recreated Spectrum for usage with Emulators, other than the designated but pulled Elite variants.
  1. Patch an Emulator, or wait for support to be added. Apparently the some patches exist for the Fuse Emulator, adding compatibility for the Recreated Spectrum. That's no guarantee that other emulators will support it; I'd wager many gradually will, though you never know.
  2. Rip out the existing control board and build up a new version.
  3. Come up with an external hardware solution to adjust the key codes sent back to the host computer.
I guess option 1 would be the easiest, at least from a general user perspective, though unless your favorite emulator is open source, this could take a while. Option 2 is the most problematic, as to replace the board in a non case destroying way would be difficult (not impossible) to achieve. Frankly I don't want to ruin the look of the Recreated Spectrum with a hatchet job. That leaves option 3 as a pretty good alternative.

The PS2 mode would be the logical mode to tap into for signal / code modification, we need to see what the Spectrum keyboard actually sends out across the USB cable. To do this easily I pulled out an Arduino USB host shield to read the key codes are being sent. The results where interesting. Firstly, the standard PS2 layer (Mode B), was sending exactly what would be expected. With all letters and combinations of 'shift' and 'Alt' key presses being sent in a seemingly standard manner. I found one glaring issue that puts a stop to tapping into the PS2 mode however; the keyboard does not send any codes for the combination of "CAPS SHIFT + 9". What this means to those who have not already guessed, is that you can't set the keyboard to graphics mode.

So this leaves us with Mode 'A', the emulator layer. This is where things get interesting. A PS2 style keyboard will normally send codes stating when a key is pressed, and a similar code indicating that a particular key has been released. The codes the Recreated Spectrum is sending in emulator mode do not follow that pattern. Instead, when you press 'q', for example the keyboard sends the code for 'u' being pressed, however on release the keyboard send the code for 'v' being released. There is not a single key that sends just the expected letter. I've mapped the keys in the table below.


The Recreated ZX Spectrums Mode 'A' Key Mapping

KEY 1 2 3 4 5 6 7 8 9 0
PRESS a c e g I k m o q s
RELEASE b d f h j l n p r t
KEY Q W E R T Y U I O P
PRESS u w y A C E G I K M
RELEASE v x z B D F H J L N
KEY A S D F G H J K L ENTER
PRESS O Q S U W Y 0 2 4 6
RELEASE P R T V X Z 1 3 5 7
KEY CAPS SHIFT Z X C V B N M SYM SHIFT SPACE
PRESS 8 < - [ ; , / { ! %
RELEASE 9 > = ] : . ? } $ ^

As can be seen from the table, the key code order is layed out in a very neat and predictable manner. Also crucially, all key presses are detected in emulator mode, there are no dead keys combination problems such as in the "CAPS SHIFT + 9" issue discovered in PS2 mode. This all makes adding a man in the middle hardware solution relatively easy to implement.

The next step is to write some Arduino code to see just what we can achieve.

Read More

Tuesday, September 20, 2016

Half Recreated ZX Spectrum

Leave a Comment
Curiosity got the better of me, with some help from continuous price drops and forced my hand into the procurement of a Recreated ZX Spectrum. The Elite Systems clone of the original Sinclair Spectrums keyboard was one of the inspirations behind the starting of this blog. Given these reasons (or excuses) it's not surprising that I felt the desire to try one out, a kind of celebration of the year since beginning the AZ15 project.


I'm not in much of a position to pass judgement on the overall look, feel or experiential replication embodied by the Recreated ZX, you see I've never owned a rubber keyed Spectrum (I had a +2a for a while quite recently), in fact I've only ever seen them in the wild twice. The most recent Spectrum encounter was with an extremely beaten up system found resting quietly in a computer store in Delfzijl, up in the north eastern Netherlands.

My only other brush with a rubber Spectrum was half a world away and decades in between, at the Sydney Personal Computer Show in 1983, where Sinclair had a very prominent and striking black pavilion right at the entrance to the exhibition. As a young teenager and ZX81 owner, this encounter was beyond exciting, though sadly owning one of the beasts on display was not in my near future.

Regardless of the above, we can still judge the Recreated on it's functionality as a keyboard. There are good and bad points to this device. The good points first. The keyboard is stunning, I mean really stunning, it does look to me (with my limited experience) look like a Spectrum. Secondly the keyboard works flawlessly, at least for a rubber keyed throwback to times past as a PC keyboard, though certainly not recommended for daily typing. Frankly is quite fun to use the keyboard, gaze at the keyboard and generally fiddle with it for a while.

Despite the attention to detail shown externally and in the immediate PC-keyboard compatibility, the real use for this keyboard is with Spectrum emulators. This is where functionality falls apart. For whatever reason Elite crippled the keyboard by limiting its emulation use to Elites own suite of applications. None of these Elite applications are supported, let alone available due to ongoing legal disputes. So unless Emulator writers decide to include support for the Recreated Spectrum, the device is functionally useless for emulation purposes. 

There is of course always an option another option: Rip out the internals, grab an Adruino or other micro-controller and retrofit for purpose. In fact retrofitting looks quite achievable, I haven't as yet opened the little box up to check it over, but Tero Heikkinen at the Old Machinery blog has and the possibilities are promising. So this is what I think I'll end up trying out, and if so, I'll of course post the details here.


Read More

Tuesday, September 13, 2016

The ZX81, Z88dk, Apps & Roman Numerals.

Leave a Comment
So what do you do with a Raspberry PI / Arduino ZX81 frankensteinian clone beast, that is other than play copious amounts of games?

In a world full of mobile phone apps, it's easy to forget that effectively computers of the ZX81s ilk only ever really ran what we would now consider apps. Refer to any listing in say, the magazine ZX-Computing, one that isn't a game of some dubious nature for examples. The case being, that really very serious software just wont fit into 16k, let alone 1k of RAM. (With all apologies to the masters of machine code and their associated assembly acolytes, who are at this very moment proving my point entirely incorrect.)

Of course all of the above being the case, the answer to the lead question is of to this post, is write an app.

Thanks to the wonders of the post-modern age, apps can quite easily be developed off on a PC some place, then cross complied for injection back into the plastic doorstop that is a ZX81. To give this all a good go, it was off to Z88dk, the C development tool of choice for targeting Z80 based machines.

I'm not about to bore the world with a run down on the inner most workings of Z88dk, not least because never really having used it before, my 2 cents of input here is not going to help anybody. Suffice to say that it's pretty easy to get to grips with, and really the hardest part about it is that you end up primarily programming in C.

Which leads to the point that there is only one really good reason that explains the existence of C++, and that is the annoyance that is C and specifically Cs' painful handling of Strings. The String and C problem being an extra annoyance as the App I ended up making was a conversion of a Roman Numeral Format checking applet, I'd originally written in Java and then moved to C++, an applet that I'd made the Strings do all the heavy lifting in.

Anyway, regardless of any pet C based grievances, Z88dk is brilliant, and in the end I produced a passable piece of ZX81 software.


The "ZX Roman Numeral-izer" is born.

The only real hard and fast rules to Roman Numeral conversion is this: Always add the numbers together from left to right, unless the numeral to the right is of a lower value, in that case subtract that numeral. That's it, see Wikipeadia for a better explanation.

Of course there is a correct, strict and socially acceptable way to format Roman Numerals, and this is precisely what my little ZX81 app is designed to do. It will check your dodgy formatting, make an informed guess at what you meant, spits out an Arabic Number and presents you with the Correct Roman formatting.

For the moment I've left the app a little bit on the gamey side, it's up to you to try and format your Roman Numeral correctly, there is no Arabic Numeral input option. The code behind the app would easily allow for it, I've just not implemented that extra code as yet, (and possibly wont).

You can download ZX Roman Numeral-izer and give it a go in your favourite ZX81 emulator.
Read More

Sunday, August 28, 2016

AZ15 Raspberry PI 3 Upgrade

Leave a Comment
I've taken the opportunity to upgrade the heart of the AZ15 to a Raspberry PI 3, up from a PI 2. The neat thing about the last few models of PIs' has been the unchanging form factor with increasing capabilities.

There has been a noticeable speed boost between the PI 2 and PI 3, this has been most evident when using the ZEsarUX emulator. Previously ZEsarUX has seemed somewhat sluggish on the PI 2, leaving SZ81 as my emulator of choice. With the performance improvements on the PI 3, the choice of emulator is now wide open, a nice change indeed.

Also  the PI 3s' addition of baked in Bluetooth and WIFI has meant that a number of the USB ports formerly dedicated to these tasks are suddenly free. With the PI 2, I had dedicated one of the internal (to the AZ15) USB ports to a WIFI dongle, with the advent of the PI 3 new found connectivity option, I've instead inserted a small in stature and capacity USB flash drive for ZX81 ''P" file storage. Additionally with Bluetooth now available, wireless mice in particular are easy to add.

AZ15 With Bluetooth Mouse and WIFI

AZ15 Concept Image

A What's in the Box Shot


All the nice additions to the PI 3 bring the whole AZ15 project pretty damn close to the original concept image; thanks to the addition of a Bluetoooth mouse and the ever unseen WIFI.

So now it's time for a new glory shot, a shot which I've taken at as close to the same angles and lighting conditions as manageable.

What do you think?


Read More

Sunday, August 21, 2016

Brand New Version ZX81 Arduino Keyboard Sketches

Leave a Comment
This week brings major changes to the Arduino sketch, so big I'm calling this latest modification version 2.

The last update still left me somewhat dissatisfied with the keyboards performance in some emulators. The deficiencies were particularly apparent when playing games, where the keyboard would not respond smoothly and in a timely fashion. To remedy the response time problems, I went back and re-examined how the code was first put together.


When Originally written, I'd relied on the Keyboard.print function to send key presses, which worked fine during initial testing. Unfortunately that didn't work so well when incorporate the shift, graphics and function modes into the keyboard. Using the Ardunio keyboard Keyboard.press functionality solved that issue and all seemed to be okay for a while. There were still some problems that become noticeable in various emulators, and these I addressed with some debouncing routines (which culminated in the last code release).

To cut it all short the debouning routines were the completely wrong solution to the problem and as it turned out I'd completely overlooked a decent Keyboard.release method. After a mild dose of head scratching in the effort to remedy past errors, I'm releasing what I'm calling version 2 of the sketches.

The Version 2 removes the kludge of keyboard debouncing, and now thankfully we have a keyboard that functions just as well as that on any self respecting ZX81.

The command line / serial switches have, thanks to the changes, slimmed back down. The need for extra commands to set extended emulation behavior have been removed.


Command Line, Mode and Options Selection
BELLSound the LeoStick Piezo. Could be used to forward audio system notifications etc. 
BEEP OFFTurn off Keyboard Sounds. Sounds are off by default.
BEEP ONTurn on Keyboard Sounds. Similar to the keyboard clicks made by ZX Spectrum when typing. The keyboard only emits clicks in Standard mode. In Emulation mode sound is always off.
DEVICEReturns message "ZX81_KEYS" to the console. Useful if unsure you have the correct serial port. You must be monitoring incoming streams to get the return message. eg cat /dev/ttyACM0
EMULATORSwitch the keyboard into emulator mode.
STANDARDSwitch the keyboard into standard mode.

All versions of the keyboard sketches are avaliable from the Project Files page.
Read More

Sunday, August 14, 2016

Arduino Sketch Updates for Keyboard Debounce Timimgs

Leave a Comment
I've made some minor changes to the Arduino sketches over the weekend. The alterations affect the debounce timings, where I've hopefully improved keyboard response while in EMULATOR modes. The latest Code can be downloaded from Project Files page.

A new switch DBEM ON / OFF, for piping to the Arduino serial console, has been added. The switch is designed to set the STANDARD mode debounce timimgs to those use in EMULATOR mode. This is particularly useful if the emulator frequently requires the keyboard to be switched to STANDARD mode. I found that in particular ZEsarUX requires STANDARD mode to be set quite often to load files or change options etc.

The below example  sets the keyboard to EMULATOR mode, sounds the BELL and turns DBEM ON.

echo emulator bell dbem on> /dev/ttyACM0

Setting DBEM ON will also negate the use of the BEEP ON option. For more extra information on switches see the earlier blog entry AZ15 and A Tale of Two Features.


Command Line, Mode and Options Selection
BELLSound the LeoStick Piezo. Could be used to forward audio system notifications etc. 
BEEP OFFTurn off Keyboard Sounds. Sounds are off by default.
BEEP ONTurn on Keyboard Sounds. Similar to the keyboard clicks made by ZX Spectrum when typing. The keyboard only emits clicks in Standard mode. In Emulation mode sound is always off.
DBEM OFFUse normal STANDARD mode debounce timings. This is the default option.
DBEM ONUse EMULATOR keyboard debounce timings in STANDARD mode. Good to set if switching to STANDARD mode frequently while using an Emulator. Switch was added with ZEsarUX in mind in particular. Default if off.
DEVICEReturns message "ZX81_KEYS" to the console. Useful if unsure you have the correct serial port. You must be monitoring incoming streams to get the return message. eg cat /dev/ttyACM0
EMULATORSwitch the keyboard into emulator mode.
STANDARDSwitch the keyboard into standard mode.


Read More

Saturday, August 13, 2016

ZX81 Kiosk Mode for Raspberry Pi / AZ15 (Part 2)

Leave a Comment

In Part 1, we setup the AZ15 to boot into a kiosk mode that relied on X11. This is all well and good, but why use an X11 windows manager when we don't really need to.

All the major ZX81 Emulators available for use on the Raspberry Pi have SDL versions available, and SDL dosn't require an X11 windows manager. Booting right into an emulator will speed up the startup process and get us "programming" our ZX81 in not time at all.

All the hard work such as installing the sz81 emulator was covered in Part 1. This time around we only need to make some minor alterations.

Auto Login the PI User to the CLI


First off, a couple of minor config changes from the last blog entry. We need to set auto login to the CLI instead of the Desktop. From the X11 desktop (startx if you need to), access the graphical config utility using the “Preferences” > “Raspberry Pi Configuration” menu. Set the options as below:


Auto Run the ZX81 Emulator at Login


Next up add the following Code to the end of your /home/pi/.bashrc file.


# Run if tty1
if [ $(tty) == /dev/tty1 ]; then
 # *** Configure and Run the ZX81 emulator ***
 # If you have ZX81 P files / Roms in a handy Dirctory, cd to it first.
 # This obviously makes life easier later on.
 cd ~/Files/emulation/zx81

 #Set az15 keyboard options, if you haven't built a az15 the comment this out.
 echo emulator bell beep off dbem on> /dev/ttyACM0

 # Run the sz81 emulator in fullscreen mode
 sz81 -f -1024x768

 #Set az15 keyboard options, if you haven't built a az15 the comment this out.
 echo standard bell beep on dbem off> /dev/ttyACM0
fi


That's it, we can now boot right on into the emulator after the next "reboot".

A Little Extra Visual Config Enhancement


Normally when the Pi boots up a whole load of logging and informational messages scroll down the screen. While this is all very useful information (depending on your perspective), it's not exactly helping generate that 80s mircro-computer vibe.

So let's hide the information overload by adding some extra switches into the Raspberries "cmdline.txt" file.

sudo nano /boot/cmdline.txt

All the configuration options will be on the first line of the file, change the following details.

Find:
console=tty1

Change to:
console=tty3

Next, add the following commands to the end of the line.

loglevel=3 logo.nologo

If you reboot now, having made the above changes in combination with Part 1's instructions, then you should see something very similar to the video clip below. (You'll probably also notice I changed the Splash Screen).



Now the AZ15 has booted up, we're ready to do some serious programming, or the somewhat more likely scenario, play the excellent "Crozxy Road" from Bobs Stuff.




Read More

Wednesday, August 03, 2016

ZX81 Kiosk Mode for Raspberry Pi / AZ15 (Part 1)

Leave a Comment

The final piece to the ZX81 keyboard puzzle is to get the Raspberry Pi / AZ15 to boot like it's 1981, arriving straight at the Sinclair "K" prompt after being switched on. Booting won't be measured in seconds (actually it comes in at about 20 seconds) as it was in 1981, after all 35 years of progress takes extra time. Though to be fair, the loading of software after booting up a ZX81 was measured in aeons.

There are many ways to boot a Pi into a Kiosk like mode, I've gone with one of the easiest, simply hijacking the pre-existing Openbox Xsession. The process outlined below is applied on top of a default Raspbian Jessie installation.

Installing the sz81 Emulator


Fist up you'll need a ZX81 emulator, I've been using various sz81 versions to test the AZ15, and have found the last official release, sz81-2.1.7,  the most stable for my purposes.

- Download the official sz81-2.1.7 release of sz81 from http://sz81.sourceforge.net/
- Alternatively, experiment with the unofficial updates provided at http://rullf2.xs4all.nl/sz81/

After downloading and decompressing the sz81-2.1.7-source.tar.gz file, edit the makefile in the source directory, and change the installation type to system wide. Full details can be found in the sz81 REAME file.


# Comment/uncomment these to choose an installation destination
# System wide installation
PREFIX?=/usr/local
BINDIR?=$(PREFIX)/bin
DOCDIR?=$(PREFIX)/share/doc/$(TARGET)
PACKAGE_DATA_DIR?=$(PREFIX)/share/$(TARGET)


Also, if not already installed grab, the SDL develpment libararies from the repositories, as these will be required before compiling the sz81 source.

sudo apt-get install libsdl1.2-dev

Then from the sz81 source directory, make and install sz81 itself.

make
sudo make install


Auto Login the PI User


Now that we have an emulator installed, we'll want it to execute on boot up.

If the Pi isn't already configured to Boot to the Desktop and / or Auto Login, you can access the graphical config utility using the “Preferences” > “Raspberry Pi Configuration” menu. Set the preferences as below:


If your Raspberry Pi wasn't previously configured to boot to the desktop, reboot it now before continuing, in order to test all is well so far.

Simple PI / ZX81 Emulator Kiosk


Raspbian Jessie ships with 3 pre-configured desktop environments:


  1. Default Xsession: An LDXE enironment using version 3 GTK+ of toolkit
  2. LDXE: An LDXE enironment using version 2 GTK+ of toolkit
  3. Openbox: Amazingly configurable Desktop


For our purposes we'll essentially hijack Openbox for auto logon and startup the sz81 emulator. Openbox is a very user configurable and we shall be ignoring most of that power co-opt it for our Kiosk style login.

Editing or create an OpenBox autostart file (using Geany or Nano from a console) in a sub-directory off the pi users home directory.

nano ~/.config/openbox/autostart


# *** Set some Openbox options ***
# Set a background colour to Black
BG=""
if which hsetroot >/dev/null; then
  BG=hsetroot
elif which esetroot >/dev/null; then
  BG=esetroot
elif which xsetroot >/dev/null; then
  BG=xsetroot
fi
test -z $BG || $BG -solid "#000000"

# *** Configure and Run the ZX81 emulator ***

# If you have ZX81 P files / Roms in a handy Dirctory, cd to it first.
# This obviously makes life easier later on.
cd ~/Files/emulation/zx81

#Set az15 keyboard options, if you haven't built a az15 the comment this out.
echo emulator bell beep off> /dev/ttyACM0

# Run the sz81 emulator in fullscreen mode
sz81 -f -1280x900

# *** On emulator Close exit Openbox ***

#Set az15 keyboard options, if you haven't built a az15 the comment this out.
echo standard bell beep on> /dev/ttyACM0

openbox --exit


Save the files and that's the basic kiosk like configuration completed.

Now log out of the default LXD environment. Once back to the logon screen, select Openbox from the drop down menu on the top left of the screen. If everything has gone to plan the sz81 emulator should startup.

If you now exit the sz81 emulator, you should once again be dropped back to the logon screen. This time select Restart from the power menu and the PI should boot directly into Openbox and open the emulator, as by default the last Desktop Environment will be selected on a system restart.

Retro Pixel Inducing Splash Screen

Setup a Splash Screen


Get into that 80s spirit with a Loading Screen. Technically there were no splash screens on a ZX81, unless you count the wavy lines that take over the screen when loading from tapes, but lets no spoil things. I've made up a rather retro and referential black and light grey image for the purpose, but use what ever image floats your boat.

Log onto the console and create a directory.

sudo mkdir /etc/images

Copy your chosen image into that directory, make sure your image is in the PNG format.

sudo cp /home/pi/"YOUR IMAGE".png /etc/images/az15-splash.png

Now we need a FrameBuffer Image viewer to run on boot.

sudo apt-get install fbi

Create a startup file and edit the contents.

sudo nano /etc/init.d/az15-splash-screen


#! /bin/sh
### BEGIN INIT INFO
# Provides:          az15-splash-screen
# Required-Start:
# Required-Stop:
# Should-Start:      
# Default-Start:     S
# Default-Stop:
# Short-Description: Show custom splashscreen
# Description:       Show custom splashscreen
### END INIT INFO

do_start () {
  /usr/bin/fbi -T 1 -noverbose -a /etc/images/az15-splash.png    
  exit 0
}

case "$1" in
  start|"")
    do_start
    ;;
  restart|reload|force-reload)
    echo "Error: argument '$1' not supported" >&2
    exit 3
    ;;
  stop)
    # No-op
    ;;
  status)
    exit 0
    ;;
  *)
    echo "Usage: az15-splash-screen [start|stop]" >&2
    exit 3
    ;;
esac

:


Now, make the file executable and get the system to recognise it as an init script.

sudo chmod a+x /etc/init.d/az15-splash-screen
sudo insserv /etc/init.d/az15-splash-screen

Reboot and you should have something very similar to the video clip below.


Credit Where It's Due Most


Much thanks to the following sites and blogs describing the exact or very similar processes, leading to an article that's boarding on plagiarism.

Run a ZX81 Emulator in "kiosk" mode on a Raspberry Pi
Building a Raspberry Pi Kiosk
Openbox Wiki Entry on Autostart


Read More

Thursday, December 31, 2015

Build Your Own AZ15

Leave a Comment
Why not round out the year be building your AZ15, the Raspberry Pi, Arduino and ZX81 keyboarded wonder of a mini computer.

There have been a number of requests asking where to get the case, all the parts etc, so after ironing out a couple of minor issues I've made the Case available on Shapeways, and below is detailed most of everything else you'll require to complete your own AZ15 project.

This little is adventure has always been about achieving a fun build in the spirit of  "just because it's possible I think I'll give it a go", so please  don't expect this thing to be a cheep enterprise (3D Printing the case is the largest single cost factor here). This project is a learning experience and one undertaken to just see what could be achieved with 3D printing, off the shelf Arduino components and some hard graft.

Before you rush of and purchase everything, keep in mind that this is also not a professional product and doesn't come with a warranty, though if you ask nicely I'll do my best to provide some help along the way, should you decide to give it a go.

Major Case Components List


These are the major components, the ones responsible for all the heavy lifting, style substance and the impress (or not) your friends bits at the heart of the AZ15. 

Major& Miscellaneous Parts Shopping List


Amount Part Type Properties
1 AZ15 Computer Case Main AZ15 Case to hold the Raspberry Pi2 and Keyboard Converter Board etc
1 AZ15 Computer Case Lid For a Complete case the lid component is also required
1 Raspberry Pi2 Specifically a Raspberry Pi2 is required to fit inside the AZ15 Case.
1 LeoStick Freetronics LeoStick (Arduino Compatible)
1 ZX81 Keyboard ZX8-KDLX - PCB replacement keyboard for ZX81. These can be purchase fully assembled or un-assembled depending on preference. There is also a ZX80 variant available, compatible with the AZ15 project, if you're feeling super retro. (some minor changes to Arduino code to match the layout may be required).
1 Rubber Feet Rubber Feet, Small Stick On, Size: 12 x 12mm- Height 6mm
1 Compact Right Angled USB Cable This goes inside the AZ15 case and connects the Pi to the Leostick. A 15cm length of cable should be plenty. I got one of these from Ebay.
1 Mini USB WIFI Dongle Optional, for plugging into the internal USB port.
1 Double Sided Tape Black Double sided tape for mounting the ZX81 Keyboard into the case keyboard tray.
1 Hot Glue Hot glue and glue gun, used to permanently attach LEDs to case.


Converter Board Components and Minor Case Furnishings


In this section is listed everything required to build the Converter Board. I've linked to the exact components I used in my original board for clarification. You should be able to match the linked components to you're local supplier if needed.

Shopping List


Amount Part Type Properties
1 Molex 22-02-3053 header - 5 pins hole size 1.0mm,0.508mm; row single; package THT; pins 5; form ♀ (female); variant variant 4; pin spacing 0.1in (2.54mm)
1 Molex 22-02-3083 header - 8 pins hole size 1.0mm,0.508mm; row single; package THT; pins 8; form ♀ (female); variant variant 5; pin spacing 0.1in (2.54mm)
4 Locking male header - 2 pins 2 Pin 0.1 Straight Locking Header - 2.54 pitch - Single; form ♂ (male); pin spacing 0.1in (2.54mm)
2 Generic male header - 14 pins hole size 1.0mm,0.508mm; row single; package THT; pins 14; form ♂ (male); pin spacing 0.1in (2.54mm)
4 Header with Crimp Pins - 2 pins 2 Pin 0.1 Header with Crimp Pins - 2.54 pitch (2.54mm). Connect LEDs and switch to Board
3 Red (633nm) LED color Red (633nm); package 5 mm [THT]; leg yes. Use hookup wire and Header to Connect to Board and Mounting in Case
1 LeoStick As above, don't panic, you don't require 2 of these. Assemble separately with female header at bottom. Plugs into J7 and J8
3 220Ω Resistor tolerance ±5%; package THT; bands 4; resistance 220Ω; pin spacing 400 mil
1 10kΩ Resistor tolerance ±5%; package THT; bands 4; resistance 10kΩ; pin spacing 400 mil
1 Round Pushbutton switching circuit SPST; default state Normally Open. Mounting hole 12mm
1 Hook Up Wire Various Colours, For connecting LEDs and Switch to Board via Headers
1 Heatshrink For isolating LEDs, prevent contact with Raspberry PI etc


Converter Board Assembly


ZX81 Keyboard Converter Board PCB Layout.
There is not a great deal to assemble on the
Converter Board, just a couple of resistors, pin headers and the Molex sockets, over all is a very basic solder job.

All the files required files for ordering a PCB from a fabrication house are contained in AZ15_PCB_layout.zip. Or do as I did, and use the same files to to create your own PCB. I outlined the basic process earlier in the blog. Extra details on construction of the Converter Board have also been documented previously.

Of course you'll nee the latest Arduino sketch to fuel the Leostick, and that can be found in the zx81usbkeyboard_20151.tar.gz file.

Components highlighted in bold green, under Properties, are not soldered / attached directly to the converter board. These components are for attaching via hookup wires and headers to the board, and are mounted in or on the AZ15 Case.

Assembly List


Label Part Type Properties
J1 Molex 22-02-3053 header - 5 pins hole size 1.0mm,0.508mm; row single; package THT; pins 5; form ♀ (female); variant variant 4; pin spacing 0.1in (2.54mm)
J2 Molex 22-02-3083 header - 8 pins hole size 1.0mm,0.508mm; row single; package THT; pins 8; form ♀ (female); variant variant 5; pin spacing 0.1in (2.54mm)
J3 Locking male header - 2 pins 2 Pin 0.1 Straight Locking Header - 2.54 pitch - Single; form ♂ (male); pin spacing 0.1in (2.54mm)
J4 Locking male header - 2 pins 2 Pin 0.1 Straight Locking Header - 2.54 pitch - Single; form ♂ (male); pin spacing 0.1in (2.54mm)
J5 Locking male header - 2 pins 2 Pin 0.1 Straight Locking Header - 2.54 pitch - Single; form ♂ (male); pin spacing 0.1in (2.54mm)
J6 Locking male header - 2 pins 2 Pin 0.1 Straight Locking Header - 2.54 pitch - Single; form ♂ (male); pin spacing 0.1in (2.54mm)
J7 Generic male header - 14 pins hole size 1.0mm,0.508mm; row single; package THT; pins 14; form ♂ (male); pin spacing 0.1in (2.54mm)
J8 Generic male header - 14 pins hole size 1.0mm,0.508mm; row single; package THT; pins 14; form ♂ (male); pin spacing 0.1in (2.54mm)
LED1 Red (633nm) LED color Red (633nm); package 5 mm [THT]; leg yes
LED2 Red (633nm) LED color Red (633nm); package 5 mm [THT]; leg yes
LED3 Red (633nm) LED color Red (633nm); package 5 mm [THT]; leg yes
LeoStick Arduino Assemble separately with female header at bottom. Plugs into J7 and J8
R1 220Ω Resistor tolerance ±5%; package THT; bands 4; resistance 220Ω; pin spacing 400 mil
R2 220Ω Resistor tolerance ±5%; package THT; bands 4; resistance 220Ω; pin spacing 400 mil
R3 220Ω Resistor tolerance ±5%; package THT; bands 4; resistance 220Ω; pin spacing 400 mil
R4 10kΩ Resistor tolerance ±5%; package THT; bands 4; resistance 10kΩ; pin spacing 400 mil
S1 Round Pushbutton switching circuit SPST; default state Normally Open. Mounting hole 12mm

Read More

Wednesday, December 09, 2015

AZ15 and a Tale of two Features

Leave a Comment

Feature One: As seen on the GuardianWitness


A big thanks to the The Guardian and Matthew Holmes in particular, for featuring this humble Raspberry Pi, Arduino and ZX81 keyboard project in the article Best reader Raspberry Pi projects – and some of the most pointless. There are loads of other interesting Pi related constructions to peruse through, the article is a fun sample of all the ways people are finding to enjoy the Pi. I particularly enjoyed the Raspberry Pi hacked into a Holga 120 Film Camera, and its taking of photos old school.

The AZ15, as seen in all the best online newspapers.


Feature Two: New Keyboard Functionality


The nice thing about making something yourself is that you can continue to work on it, even if to all external appearances the project may seem complete.

Having used the AZ15 for almost two weeks now I decided to add a little extra functionality, addressing some minor usability issues, the main one being my forgetting to switch between Emulator and Standard keyboard modes. When using a ZX81 emulator with the keyboard, the button on the right side of the case is pressed, this changes the keyboard mode, and the LEDs on top visually tell you what mode you're in. This is all fine, except I keep forgetting to press the button.

The solution is simple enough, have the keyboard change modes automatically. Nicely the Raspberry Pi can talk to the LeoStick via serial link and vice versa. A couple of commands directed at the serial interface before launching an Emulator automatically selecting the correct keyboard mode and things soon become more user friendly.

For example, emulator mode can be selected and a notification bell passed with the following redirection to the serial port the LeoStick / Keyboard is attached to.

echo emulator bell > /dev/ttyACM0

Putting the above in a start script that launches the emulator and then sets all back to normal after exiting solves my main issues.



#!/bin/bash
# Put keyboard in Emulator Mode
echo emulator bell > /dev/ttyACM0
# Launch the sz80 emulator
sz81
# Set keyboard back to Standard Mode
echo standard > /dev/ttyACM0

If the USB port assignment changes around, "dmesg" could always be used to parse for the correct device.


Command Line, Mode and Options Selection
BELLSound the LeoStick Piezo. Could be used to forward audio system notifications etc. 
BEEP OFFTurn off Keyboard Sounds. Sounds are off by default.
BEEP ONTurn on Keyboard Sounds. Similar to the keyboard clicks made by ZX Spectrum when typing. The keyboard only emits clicks in Standard mode. In Emulation mode sound is always off.
DEVICEReturns message "ZX81_KEYS" to the console. Useful if unsure you have the correct serial port. You must be monitoring incoming streams to get the return message. eg cat /dev/ttyACM0
EMULATORSwitch the keyboard into emulator mode.
STANDARDSwitch the keyboard into standard mode.


The latest Arduino sketch can be downloaded here: http://zx81.dasteph.com/files/zx81usbkeyboard_20151205.tar.gz

Read More

Friday, November 27, 2015

Presenting the AZ15, a not Actuall Clone of a ZX81 Assembled

Leave a Comment
I was confident it would look pretty cool, yet once the case arrived (after some timely industrial action at customs and excise) my expectations were exceeded by far. It does in fact look damn amazing, this 3D printing thing and by extension Shapeways ability to turn home design into reality is brilliant.


As expected the surface on the final product is lightly rough to touch and has a non-gloss finish. It kind of reminds me of suede, if suede assumed a plasticky form. You can still see the layers where the object has been built up but that certainly doesn't detract from the looks of the AZ15 case. Invariably I couldn't wait to put it all together, and thus the beginning of the end phase ensued.

Firstly I gathered all the disparate parts together. Internally the case had the following items to be installed, a Raspberry Pi 2, the LeoStick and Converter board, a right-angled usb cable to connect to the LeoStick, a WIFI dongle, LEDs and the mode selector switch. The keyboard would sit nicely on the tray, with it's cable sliding through a gap provided at the upper right corner much, like on the original ZX81.


The Pi, USB cable and WIFI dongle were installed first. I was relived that this all fit exactly as planned, being that the AZ15 case was designed specifically to hide one of the USB port banks and thus give the appearance of one complete unit to the casual observer.


Next the LEDs were hot glued into position, the mode switch installed and the keyboard converter board were inserted. Working in the confined space was a little challenging but everything so far went in without to much difficultly. As I'd made the converter myself and therefore drilled the mounting holes by hand, the mounting points were designed to allow a little slip and slide for easy adjustment. The one thing I hadn't counted on was not being able to affix the bolt heads due to access issues at the far right corners, luckily for me the drill holes in the converter board are nice and tight, so the bolts screwed in and held the board firmly enough.


Time to plug in the brains of the keyboard ie. the LeoStick. It's all a tight little fit, leaving just enough room to smuggle in the cables coming directly from the keyboard. The keyboard was mounted with some doubled sided tape on the keyboard tray.


Flipping the case over, some handy dandy rubber feet are slotted into position to provide much needed non slipping action, necessary when typing on a keyboard of diminutive weight and size.


Now it was a simple matter of plonking the lid on, except that the plonking didn't quite plonk as one might have expected. Unfortunately I'd made the little tabs on the side of the lid slight to small, meaning that the lid slides about a little bit to much. The immediate solution was to use some tiny strips of double sided tape to hold the movable lid in position. At a later date I might opt to get the lid reprinted and permanently fix this relatively minor issue.


So that's it, time for some sitting back a marveling at my creation. I'm very pleased with the final look of the AZ15 case, and hopefully I've managed to do the original ZX81 design justice and possibly at least slightly amuse Rick Dickinson the creator of the ZX81's iconic looks.


Read More

Monday, November 09, 2015

Final Case Design Shipped to Shapeways

Leave a Comment
Az15 Raspberry Pi Computer / LeosStick Computer with ZX81 Keyboard
AZ15 Deign Impression
The final AZ15 case design has been shipped off to Shapeways for printing and the nervous wait for a tangible object to arrive in the post has begun. All being well, the physical product will work as designed; meeting all expectations generated by the on screen version of reality.

The case was designed using the modeler AC3D, I've been using this tool for various projects over a number of years (though never for a 3d printed model before), so am pretty comfortable using it. A Raspberry PI 2 / B+ model was sourced from Thingiverse to construct the case around. I can't locate the exact model I used now, however there are a number to chose from including this one by jayftee. It's always a bonus when somebody else has done the hard work of modeling and exacting object for you.

AZ15 Case Design, Side View
Some decisions taken early on that dictated the shape and size of the AZ15 case. The choice not to de-solder the USB and Ethernet ports from Raspberry PI 2 lent extensively to the final design. The PI 2 has four USB ports, and I've designed the case such that two of these ports are only available internally. This layout allows the Leostick to connect internally and invisibly to one of these ports, giving the overall external appearance of one complete unit. The other internally USB port could be used to house a WIFI or Bluetooth adapter.

AZ15 Case Design, Rear View
The choice of configuration for the USB ports has given a rather unique cut-out appearance at the back of the computer, a nice little design touch that also helps maintain a compact and tidy feel when external USB devices are plugged in at the side.

From the outset I hadn't intended to clone a ZX81 case, the original being a design classic in its own right. What I'm after is something reminiscent of a classic 80s microcomputer but with a contemporary feel. A kind of modern clone. Hopefully within the next week or so I'll find out just how successful I've been.


Read More

Wednesday, November 04, 2015

Some More Arduino Code for the ZX81 Keyboard

4 comments
I've made  a fair number of changes to the ZX81 keyboard Arduino sketch. The most noticeable being that the code is now broken into multiple files / libraries; all feeling a little more C++ like. Of course real microcontroller programmers use C, but we wont discus that here.

In general the keyboard functions as earlier. The main physically tangible improvement being that the keyboard performs a whole lot better in ZX81 emulators. It's not perfect and it's definitely not ideal for playing real time games with, though It works as advertised when typing normally, ie. using the keyboard to program with.

Emulator comparability wise, the keyboard will work with  sz81 and ZEsarUX. I'd recommend using sz81, as the keyboard still functions best with that particular emulator. I've also had a go at using Fuse with the keyboard, and to the extent that a ZX81 keyboard can be used on ZX Spectrum it functions okay, though it is missing those couple of crucial extra keys for proper Spectrum emulation.

When using the keyboard in standard mode as a regular USB input device in Linux or with a Raspberry Pi there are no issues, unfortunately, as with the emulators, games that require SDL libraries suffer from the "keys not being registered when you'd like them to be" syndrome. This issue I'm afraid may be down to problems with the Arduino USB Keyboard library and beyond my immediate control.

Presented For Your Amusement, Code Caught in the Wild


Main Program (zx81usbkeyboard.ino)

As the name on the implies, here be the general program.


// **************************************************************************
// **** ZX81 USB Keyboard for Funtronics LeoStick (based on a Leonardo). ****
// **** zx81usbkeyboard.ino                                              ****
// **************************************************************************
// ** David Stephenson 2015-11-03  **
// **                              **
// ** Originally based on code by: **
// ** Dave Curran  2013-04-27      **
// ** Tony Smith 2014-02-15        **
// **********************************

 #include "Arduino.h"
 #include "zx81keyboard.h"
 #include "zx81modestate.h"
 
// ************************
// *** Global Variables ***
// ************************

// Setup Global Variables for keyboard.
ZxKeyBoard MyKeyboard;

// Setup LeoStick pins for mode switch and indicator LEDs.
ModeState MyModeState(A5,A0,A1,A2);

// Setup LeoStick pins for Keyboard rows and columns.
const byte bColPins[NUM_COLS] = {13,12,10,9,8};
const byte bRowPins[NUM_ROWS] = {7,6,5,4,3,2,1,0};


// ******************
// *** Main Setup ***
// ******************
void setup() {
  
 // Set all Keyboard pins as inputs and activate pull-ups.
 for (byte bColCount = 0 ; bColCount < NUM_COLS ; bColCount++)
 {
  pinMode(bColPins[bColCount], INPUT);
  digitalWrite(bColPins[bColCount], HIGH);
 }
 
 // Set all Keyboard pins as inputs.
 for (byte bRowCount = 0 ; bRowCount < NUM_ROWS ; bRowCount++)
 {
  pinMode(bRowPins[bRowCount], INPUT);
 }
 
 // initialize control over the keyboard.
 //Serial.begin(9600);
 Keyboard.begin();
 
}
 
// ************************
// *** Main loop        ***
// *** Lets get Busy-ah ***
//*************************
void loop() {

 bool boShifted = false;
 byte bKeyPressed = 0;
 
 // Set Keyboard Mode.
 KEYMODES eMyKeyMode = MyModeState.GetMode();
 KEYSTATES eMyKeyState = MyModeState.GetState();
 
 // Check for the Shift key being pressed.
 pinMode(bRowPins[SHIFT_ROW], OUTPUT);
 
 if (digitalRead(bColPins[SHIFT_COL]) == LOW) boShifted = true;
 
 pinMode(bRowPins[SHIFT_ROW], INPUT);
 
 for (byte bRow = 0 ; bRow < NUM_ROWS ; bRow++){
  // Run through the rows, turn them on.
  
  pinMode(bRowPins[bRow], OUTPUT);
  digitalWrite(bRowPins[bRow], LOW);
  
  for (byte bCol = 0 ; bCol < NUM_COLS ; bCol++){
   if (digitalRead(bColPins[bCol]) == LOW){
    if (boShifted && eMyKeyMode == STANDARD){
     // Select correct Keyboard layout for current state For STANDARD mode. 
     // Shift alters the Current state selection. eg. gets Red Shift symbols in Normal State. 
     switch (eMyKeyState) {
      case NORMAL:
       bKeyPressed = MyKeyboard.bKeyPress(bRow, bCol, NORMAL_SHIFTED, eMyKeyMode);
       if (bKeyPressed == KEY_RETURN) { 
        eMyKeyState = FUNCTION;
        bKeyPressed = 0;
        MyKeyboard.KeyDisable(bRow, bCol);
       }
       if (bKeyPressed == '9') {
        eMyKeyState = GRAPHICS;
        bKeyPressed = 0;
        MyKeyboard.KeyDisable(bRow, bCol);
       }
      break;
       
      case FUNCTION:
       bKeyPressed = MyKeyboard.bKeyPress(bRow, bCol, NORMAL_SHIFTED, eMyKeyMode);
       if (bKeyPressed == KEY_RETURN) { 
        eMyKeyState = NORMAL;
        bKeyPressed = 0;
        MyKeyboard.KeyDisable(bRow, bCol);
       }
       if (bKeyPressed == '9') {
        eMyKeyState = GRAPHICS;
        bKeyPressed = 0;
        MyKeyboard.KeyDisable(bRow, bCol);
       }
      break;
       
      case GRAPHICS:
       bKeyPressed = MyKeyboard.bKeyPress(bRow, bCol, GRAPHICS_SHIFTED, eMyKeyMode);
       if (bKeyPressed == KEY_RETURN) { 
        eMyKeyState = FUNCTION;
        bKeyPressed = 0;
        MyKeyboard.KeyDisable(bRow, bCol);
       }
       if (bKeyPressed == '9') {
        eMyKeyState = NORMAL;
        bKeyPressed = 0;
        MyKeyboard.KeyDisable(bRow, bCol);
       }
      break;
       
     }
    } else {
     // Emulator keyboard, the keyboard states are controlled by a ZX81 emulator.
     // Keyboard mimics unaltered PS2 Keyboard presses as expected by an emulator.
     bKeyPressed = MyKeyboard.bKeyPress(bRow, bCol, eMyKeyState, eMyKeyMode);
    }
    
    if (bKeyPressed > 0 ) {
     //Serial.write(bKeyPressed);
     if (eMyKeyMode == EMULATOR){
      if (bKeyPressed && boShifted) Keyboard.press(KEY_LEFT_SHIFT);
      Keyboard.press(bKeyPressed);
      // Many Emulators don't use standard OS keyboard routines and require a pause
      // for key to register. There is some variance, but 100ms seems to cover most.  
      delay(DEBOUNCE_DELAY/2);
     } else {
      if (eMyKeyState == GRAPHICS && bKeyPressed > 96 && bKeyPressed < 123){
       if (boShifted){
        Keyboard.press(KEY_LEFT_ALT);
       } else {
        Keyboard.press(KEY_LEFT_CTRL);
       }
      }
      Keyboard.press(bKeyPressed);
      // Some audio feedback if not in EMULATOR mode.
      // Kill the line if you hate beepy beep beeps.
      tone(11, 31, 20);
     }
     
     Keyboard.releaseAll();
    }
    
   } else {
    MyKeyboard.KeyPressReset(bRow, bCol);
   }
  }
  pinMode(bRowPins[bRow], INPUT);
 }
 
 digitalWrite(bRowPins[SHIFT_ROW], LOW);
 
 // Update LED panel and check for Mode change switch press.
 MyModeState.SetState(eMyKeyState);
 
 }

Keyboard Class (zx81keyboard.h)

Main guts of the keyboard setup and initial handling is in here.


// ***********************
// ** zx81keyboard.h    **
// ** Class Definitions **
// ** For ZX81 keyboard **
// ***********************

enum KEYMODES {EMULATOR, STANDARD};
enum KEYSTATES {NORMAL, NORMAL_SHIFTED, GRAPHICS, GRAPHICS_SHIFTED, FUNCTION};

#define NUM_ROWS 8
#define NUM_COLS 5 

#define SHIFT_COL 4
#define SHIFT_ROW 5
//#define FUNCTION_COL 4
//#define FUNCTION_ROW 6
//#define GRAPHICS_COL 3
//#define GRAPHICS_ROW 2

#define DEBOUNCE_DELAY 200 //debounce countdown value.
#define DEBOUNCE_DELAY_REPEAT 600

// Defines a single key and its 4 possible Major KEYSTATES: NORMAL, NORMAL_SHIFTED, GRAPHICS, GRAPHICS_SHIFTED
// Returns 5 KEYSTATES, adds FUNCTION: Caps Lock).
class ZxKey  {
 private:
  // Standard Keyboard Characters for Normal PC Use
  byte bNormal;   // Standard ZX keyboard only in lower case. EMULATOR KEYMODE should use bNormal only.
  // Extra Modes for using keyboard as a normal(ish) PS2 / USB device.
  byte bNormalShifted; // Red Symbols & Words (replaced by Symbols)  
  byte bGraphics;   // Standard ZX keyboard but should be used with CTL characters. Numbers = F1 - F10 etc
  byte bGraphicsShifted; // Standard ZX keyboard but should be used with ALT characters. Numbers = F11 - F12, 5 = home, 6 PGUP etc 
  
  // Monitor Keys last press / activity.
  short iDebounceCount = DEBOUNCE_DELAY;
  short iDebounceCountHighest = iDebounceCount;

  byte KeyValue(KEYSTATES eKeystate) {
   // Get Keyboard character for correct Key state.
   byte bKeyValue = 0;

   switch (eKeystate) {
    case FUNCTION:
     bKeyValue = bNormal;
     // Adjust for Capital Letters
     if (bKeyValue > 96 && bKeyValue < 123){
      bKeyValue = bKeyValue - 32;
     }
     break;
     
    case NORMAL_SHIFTED:
     bKeyValue = bNormalShifted;
     break;
     
    case GRAPHICS:
     bKeyValue = bGraphics;
     break;
     
    case GRAPHICS_SHIFTED:
     bKeyValue = bGraphicsShifted;
     break;
     
    default:
     // Standard normal and Emulator mode keyboard.
     // Shift key modifier used later to select functions etc in a ZX81 Emulator.
     bKeyValue = bNormal;
     break;
   }
   return bKeyValue;
  }
  
 public:
  ZxKey (byte, byte, byte, byte);
   
  byte KeyPressDetected(KEYSTATES eKeystate, KEYMODES eKeymode){
   byte bKeyValue = 0;
   iDebounceCount--;
   if (iDebounceCount == 0){
    switch (iDebounceCountHighest) {
     case DEBOUNCE_DELAY:
      iDebounceCount = DEBOUNCE_DELAY_REPEAT;
      iDebounceCountHighest = iDebounceCount;
     break;
     
     case DEBOUNCE_DELAY_REPEAT:
      if (eKeymode == EMULATOR){
       iDebounceCount = DEBOUNCE_DELAY;
      } else {
       iDebounceCount = DEBOUNCE_DELAY / 2;
      }
     break;
     
     default:
      iDebounceCount = DEBOUNCE_DELAY;
     break;
    }
    bKeyValue = KeyValue(eKeystate);
   }
   return bKeyValue;
  }
  
  void KeyPressReset(){
   iDebounceCount = DEBOUNCE_DELAY;
   iDebounceCountHighest = iDebounceCount;
  }
 
  void KeyDisable(){
   iDebounceCount = -1;
  }
};


// ZxKey constructor
ZxKey::ZxKey (byte Normal, byte NormalShifted, byte Graphics, byte GraphicsShifted){
 bNormal = Normal;
 bNormalShifted = NormalShifted;
 bGraphics = Graphics;
 bGraphicsShifted = GraphicsShifted;
}


// Defines entire keyboard, includes ZxKey class.
class ZxKeyBoard {
 private:
  // Setup 4 versions of keyboard states into keyboard.
  // Keyboard mapped for US, might need changing for other configurations eg. UK keyboard.
  ZxKey keyMap[NUM_ROWS][NUM_COLS] = 
  {
   {{'5',KEY_LEFT_ARROW,KEY_F5,KEY_HOME},{'4','%',KEY_F4,KEY_INSERT},{'3','#',KEY_F3,KEY_ESC},{'2','@',KEY_F2,KEY_F12},{'1','!',KEY_F1,KEY_F11}},
   {{'t','_','t','t'},{'r','&','r','r'},{'e','^','e','e'},{'w','`','w','w'},{'q','~','q','q'}},
   {{'6',KEY_DOWN_ARROW,KEY_F6,KEY_PAGE_DOWN},{'7',KEY_UP_ARROW,KEY_F7,KEY_PAGE_UP},{'8',KEY_RIGHT_ARROW,KEY_F8,KEY_END},{'9','9',KEY_F9,'9'},{'0',KEY_BACKSPACE,KEY_F10,'0'}},
   {{'g','\\','g','g'},{'f','}','f','f'},{'d','{','d','d'},{'s',']','s','s'},{'a','[','a','a'}},
   {{'y','|','y','y'},{'u','$','u','u'},{'i','(','i','i'},{'o',')','o','o'},{'p','"','p','p'}},
   {{'v','/','v','v'},{'c','?','c','c'},{'x',';','x','x'},{'z',':','z','z'},{0,0,0,0}},
   {{'h','\'','h','h'},{'j','-','j','j'},{'k','+','k','k'},{'l','=','l','l'},{KEY_RETURN,KEY_RETURN,KEY_RETURN,KEY_RETURN}},
   {{'b','*','b','b'},{'n','<','n','n'},{'m','>','m','m'},{'.',',','.','.'},{' ',KEY_TAB,'£',' '}}
  };
  
 public:
  // Return from ZxKey matching specified state.
  byte bKeyPress(byte bRow, byte bCol, KEYSTATES eKeystate, KEYMODES eKeymode){
   return keyMap[bRow][bCol].KeyPressDetected(eKeystate, eKeymode);
  }
  
  void KeyPressReset(byte bRow, byte bCol){;
   keyMap[bRow][bCol].KeyPressReset();
  }
  
  void KeyDisable(byte bRow, byte bCol){;
   keyMap[bRow][bCol].KeyDisable();
  }
};

Mode Switch & LED Class (zx81modestate.h)

This ones still a work in progress, I'm wanting to add some more functionality to the Mode selection button at some point. Works well enough for the moment.


// *****************************
// ** zx81modestate.h         **
// ** Class Definitions       **
// ** For Mode Switch  & LEDs **
// *****************************

// Defines LED / Mode switch panel and its behaviour.
// Three LEDs are configured to report on keyboard mode and states.
// 
// In STANDARD mode:
//  Left LED on = GRAPHICS state.
//  Middle LED on = FUNCTION state.
//  Right LED on = NORMAL state.
//
// In EMULATOR mode:
//  Left and Right LEDs = on.

class ModeState {
private:
 KEYMODES eKeyboardMode = STANDARD;
 KEYSTATES eKeyboardState = NORMAL;
 byte bModeSwitchPin;
 byte bGraphicsPin;
 byte bFunctionPin;
 byte bModePin;
 
 bool boDebounce = false;
 
 byte SetMode(){
  if (digitalRead(bModeSwitchPin) == HIGH && boDebounce == false) {
   //Serial.println("high ");
   if (eKeyboardMode == STANDARD){
    eKeyboardMode = EMULATOR;
   } else {
    eKeyboardMode = STANDARD;
   }
   
   delay(DEBOUNCE_DELAY_REPEAT);
   boDebounce = true;
  } else if (digitalRead(bModeSwitchPin) == LOW) {
   boDebounce = false;
  }
 }
 
public:
 ModeState (byte, byte, byte, byte);
 
 byte SetState(KEYSTATES eKeystate){
  
  eKeyboardState = eKeystate;
  
  // Check and set mode if Mode switch is pressed
  SetMode();
  
  if (eKeyboardMode != EMULATOR){
   switch (eKeyboardState) {
    
    case FUNCTION:
     digitalWrite(bGraphicsPin, LOW);
     digitalWrite(bFunctionPin, HIGH);
     digitalWrite(bModePin, LOW);
     break;
     
    case GRAPHICS:
     digitalWrite(bGraphicsPin, HIGH);
     digitalWrite(bFunctionPin, LOW);
     digitalWrite(bModePin, LOW);
     break;
     
    default:
     digitalWrite(bGraphicsPin, LOW);
     digitalWrite(bFunctionPin, LOW);
     digitalWrite(bModePin, HIGH);
     eKeyboardState = NORMAL;
     break;
   }
  } else {
   digitalWrite(bGraphicsPin, HIGH);
   digitalWrite(bFunctionPin, LOW);
   digitalWrite(bModePin, HIGH);
   eKeyboardState = NORMAL;
  }
 }
 
 KEYMODES GetMode(){
  return eKeyboardMode;
 }
 
 KEYSTATES GetState(){
  return eKeyboardState;
 }
};

// ModeState constructor.
ModeState::ModeState (byte ModeSwitchPin, byte GraphicsPin, byte FunctionPin, byte ModePin){
 
 bModeSwitchPin = ModeSwitchPin;
 bGraphicsPin = GraphicsPin;
 bFunctionPin = FunctionPin;
 bModePin = ModePin;
 
 pinMode(bModeSwitchPin, INPUT);
 pinMode(bGraphicsPin, OUTPUT);
 pinMode(bFunctionPin, OUTPUT);
 pinMode(bModePin, OUTPUT);
 
}
Read More

Wednesday, October 28, 2015

A Little Case With a Name

Leave a Comment
It's taken longer than I'd have liked, yet the case design is nearing completion. A couple more days and some oddly grabbed hours should see the final design ready for 3d printing at Shapeways.

The Computer finally has a name of sorts, AZ15, it's a little bit referential, and a little bit obscure. In line with the original ZX81, the naming convention is drawn from the CPU name, a futuristic sounding second letter and the year of (very limited) release.
  • A: Standing for the CPU names at the heart of both the Raspberry Pi2 and the Leostick, the ARMv7 and ATmega32U4 respectively.
  • Z: The futuristiclly optimistic last letter of the alphabet, which is also referential to the Z in ZX81
  • 15: The year of very limited release.

Concept Art for the (amazing) AZ15

Read More