Retro Challenge 2017/10 – Returning to Zork

After what felt like a lot of aimless bumbling around and poor progress on the first streamed game of Zork, I decided to take a peek at a walkthrough solution before playing this.

The last live stream finished off with me getting frustrated with not being able to undo a bolt at the Dam, despite having a wrench.  A peek at the walkthrough mentioned pushing a yellow button in the control room first.  Really?  Like, how was I supposed to know that?  Ok, I’ll admit that I hadn’t spotted any of the buttons in the control room (there was a lot of text bombarding me as I arrived in there), but if I had, I would have probably pushed all the buttons.  I don’t know if you must push only the yellow one, or if pushing them all would render the bolt still unturnable, but if this is the level of puzzle I’m supposed to solve, then it’s unlikely that I’m going to make too much progress after this part.

So, instead, I decided to print off the first couple of pages of the walkthrough, and planned to just follow along with it.

The live stream started at 7pm on Thursday evening, and the set up was the same as the previous one.  The only difference was that I’ve now upgraded from the free version of Wirecast to a licence one with no interruptions.  There was 5 viewers on YouTube and 4 on the text stream, although towards the end I spotted a tweet from a viewer that was unable to connect to the text stream (Sorry!), but I never found out if it was a problem at my end or his.

The first thing I wanted to do was test out the instructions on pushing the yellow button before undoing the bolt.  Sure enough, this worked!  However, there were a few other things that I’d missed out between the start and the dam.  I could have possibly caught up with those in a different order, but decided to quit this game and start afresh.

Progress went well, and within an hour I had completed around 50% of the game.  Some of the walkthrough was invaluable.  I can imagine I’d have ended up stuck in the maze for ever, and probably unable to map it too, but when the walkthrough tells you to just go northwest, south, west, up, west, southwest, and northeast, it is much more enjoyable.  Even following along on the map this was hard to work out.

I feel like I’ve successfully completed the Retro Challenge I set myself, and I’m happy that things went pretty well.  As I’ve mentioned before, I’m not much of a text adventurer, and I don’t think this experience has changed that.  Zork was actually better than I thought it would be, and at some point I’ll play through the 2nd half of the walkthrough.  The best part for me, however, was the technical side of things, and hooking up an ESP8266 as a wifi link for the RC2014.  There seems to be a few different bits of ESP8266 software that will add value to the RC2014, so I’ll be developing a proper ESP8266 Module soon.

A big thanks to those that have followed along with this blog, via Twitter, and, of course, via YouTube and the text stream.

Transcript of this adventure here;

If you need to watch the YouTube stream, it can be found here https://youtu.be/K-Kv5saIHyE

Retro Challenge 2017

Ok, with 5 days of October already gone, I know it’s cutting things a bit fine for putting my entry in for this seasons Retro Challenge – particularly as it started 5 days ago… but, better late than never, right?

So, what have I planned to do that is both retro and challenging? Simple, I’m going to play games! More specifically, I’m going to play Zork, on a CP/M enabled RC2014 that is connected to the internet so it can be streamed live to an audience of anybody that cares to watch me get eaten by a grue.

The first challenge is going to be hooking up the RC2014 to the internet, such that it can stream text. Kind of like Twitch, but in ASCII. Luckily, I’ve got a bunch of ESP8266 modules that have been sitting in a drawer, and I think these are likely to be ideal for converting serial data in to web pages.  I should be able to hook up something on breadboard, and find a bit of code that does the job – although it would be nice if I can get some real PCBs made up for the job.  With just over 3 weeks to go, though, that might be pushing it timewise.

Then there is the challenge of Zork itself.  I often use it as a test game to show people what the RC2014 can do, however, I’ve never done more than a bit of random North, North, East, Look, Get Lamp etc.  I’ve never really played many text adventures either, so this will be a big learning experience for me.  I can’t promise that I won’t use the odd cheat/clue here and there, but if there are actually people watching along online, I’ll happily take suggestions over Twitter.  If things happen to go really well, and I complete it in good time, then I will add Adventure as a stretch goal.

Decoding ROM labels

Back in the earliest days of the RC2014, it came with a pre-programmed 64k ROM, with Microsoft BASIC on it in the first 8k, and it would work with 32k of RAM and a 68B50 ACIA.  One set up, one ROM, life was simple!

As time has gone on, and more options have become available, other ROM images, such as Microsoft BASIC for 56k RAM, or CP/M Monitor have been introduced.

Future possibilities, such as other UARTs, different CPUs or other variations will inevitably lead to more ROM images being needed.  So, in order to keep track of what is programmed where, ROMs are now being shipped out with a label on them.

Every ROM now has an 8 digit code on it.  Each digit, from left to right, refers to an 8k bank from 0x0000 to 0xD000.  This bank can be selected with the A13, A14, A15 jumpers;

Address A15 A14 A13 ROM Label
0000 0 0 0  Xooooooo
2000 0 0 1  oXoooooo
4000 0 1 0  ooXooooo
6000 0 1 1  oooXoooo
8000 1 0 0  ooooXooo
A000 1 0 1  oooooXoo
C000 1 1 0  ooooooXo
E000 1 1 1  oooooooX

 

The value of the digit represents the ROM image that sits in that particular 8k bank.  Currently, it will be one of the following;

0 – Empty bank, available for user to program

R – Microsoft BASIC, for 32k RAM, 68B50 ACIA, with origin 0x0000

K – Microsoft BASIC, for 56k RAM, 68B50 ACIA, with origin 0x0000

1 – CP/M Monitor, for pageable ROM, 64k RAM, 68B50 ACIA, CF Module at 0x10, with origin at 0x0000

2 – Microsoft BASIC, for 32k RAM, SIO/2, with origin 0x0000

4 – Microsoft BASIC, for 56k RAM, SIO/2, with origin 0x0000

5 – Microsoft BASIC, for CP/M installation,64k RAM, 68B50 ACIA, CF Module at 0x10, with origin at 0x2000

6 – CP/M Monitor, for pageable ROM, 64k RAM, SIO/2, CF Module at 0x10, with origin at 0x0000

 

As more ROM images are added, this list will be updated.

 

Standard factory ROM images can be downloaded from Github https://github.com/RC2014Z80/RC2014/tree/master/ROMs/Factory

The RC2014 currently uses a very simple, although inefficient method of addressing peripherals.  Most of the expansion modules feature a 74HCT138 used to provide up to 8 enable lines from 3 address signals.  For the purposes of this document, I will mainly refer to the Digital I/O Module, but the principals apply to all modules with a 74HCT138 (generally referred to simply as ‘138)

It is worth noting that the Z80 CPU can address up to 255 Input or 155 output addresses.  These are selected by the first 8 address lines (A0 – A7), IORQ going low and either WR or RD going low.

The ’138 has 3 enable pins, G1, G2B, G2A, all of which need to be true (G1 needs to be high, and both G2B and G2A need to be low) for the ‘138 to be enabled.  When it is enabled, the 3 address lines, A0, A1, A2 are read.  These 3 addresses have 8 possible combinations (000, 001, 010, 011, 100, 101, 110, 111), which will activate one of the 8 outputs Y0 to Y7.

In the Digital I/O Module, the ‘138 is activated when M1 is high, IORQ is low and A7 is low.  This corresponds to any port from 0 to 127 (IORQ being low indicates the address bus represents port, and A7 being low indicates the address bus is lower than 127).  [Side note – Serial I/O Module uses addresses 128 and 129, which are indicated by A7 being high].

The Z80 address pins A0 and A1, along with WR are connected to the address pins A0, A1, A2 on the ‘138.  This gives 4 addresses (00, 01, 10, 11) with the write bit high, and 4 with it low.

In normal use, the ports are addressed as 0 (In 0 or Out 0) on the Digital I/O Module.  (Or port 0, 1, 2 on the Digital Input module, for example).  However, any address that has A0, A1 and A7 low will work; 0—–00.  So echoes of this will appear on 4, 8, 12… 124.  So, whilst this works, and is fine for a small system without much I/O requirements, it quickly becomes inefficient as you need more ports.  In particular, it will clash with the Compact Flash Storage Module, which can have an impact on running CP/M.

In an ideal world, every peripheral should have a unique address, and with a lot of digital logic, this is certainly possible to do.  However, it will add both complexity and cost as well as needing more board space.

The easy solution, however, involves just 6 diodes and a resistor.  By connecting address lines A2 – A7 to the anode of each diode and the cathode of each diode to the G2A enable pin on the ‘138, any address above 00000011 will prevent the ‘138 from being enabled.  Effectively all the diodes are acting as a very simple OR gate.  A 10k resistor will bias the output low.

So with this set up, it will give just 4 unique addresses; 00000000, 00000001, 00000010, 00000011 (ie 0, 1, 2, 3) which for the Digital I/O Module, or the Digital Input or Digital Output is ideal.

Other addresses can be selected by changing which address pin the diodes are connected to.  So, for example, if A1 was connected to a diode instead of A3, and A3 went to the ‘138, the addresses would be 00000000, 00000001, 00001000, 00001001 (ie 0, 1, 8, 9).  Whilst it cuts down on the echoes at higher addresses, it’s still not perfect – but much better and still very cheap with minimal extra board space needed.

The Digital I/O Module has now been updated to reflect this change.  As PCB stocks run low on other modules, they too will have similar updates.  If you already have a non-diode selectable module, and wish to implement this, it is actually very simple to do as shown below.