April 2022

30Apr22

Pupdate

April started off cold and wet, but the back half has been a great improvement, with some T-shirt weather days, and a chance for the boys to meet their sausagey friends.

Milo, Martha and Max

Motorcyle

The fair weather has also meant some opportunities to get out on my bike.

Tyres

At its MOT a few weeks back the bike got advisories for both tyres being close to the legal limit, and the front valve perishing. My first thought was that I could probably get another season out of the tyres, but once I started looking for new ones I was persuaded to change sooner. One factor was learning about tyre manufacture dates. The rear was a little long in the tooth at 7y old, but the front was positively geriatric at almost 14y old. Also much as I love the bike, I can’t say that it’s ever felt sure footed with the Bridgestone BT23s I got it with.

The only trouble is that the rear tyre is an obscure fitting. A quick search online suggested that Dunlop Roadsmart IV was the only show in town, and when I emailed my local place they came back with “are you sure about 160/70ZR18? We can’t find them anywhere”. Of course by that point Murphy’s Law meant that they’d gone out of stock at the place I’d found them online. I resolved to buy wherever I could find stock, and a last minute search of eBay struck gold with Sticky Stuff offering a matched pair for my bike at a very reasonable price.

Once fitted I then had a tenuous 100 miles to do of ‘scrubbing in’, and it must be the first time I’ve done that in 25y. They immediately felt at least as good as the old Bridgestone’s, and now that they are scrubbed in the bike is great. I wouldn’t quite use ‘transformed’, but the handling is certainly more confidence inspiring.

Fuel additive

While ‘scrubbing in’ I noticed that the bike was running super smoothly. Nothing really to do with the tyres, but rather the engine being able to pull better at low revs. I’d previously had to drop a gear to ride smoothly at 30mph, but now – not so much.

I then remembered that I’d put some Techron into the tank in Autumn after reading some recommendations for it on Quora. I’ve generally been sceptical about fuel additives, but this one really does seem to have worked well. Not only is the engine running much more smoothly, but I can see the difference in economy/range too.

QCon

QCon London 2020 was the last event I attended before lockdown, so returning to QCon 2022 felt like a watershed. I’d love to say that it marked post Covid life, but the pandemic clearly isn’t over. It was great to catch up with friends, and do some ‘hallway track’ again.

Vineyard tour

To make up for the tour of Chapel Down my wife missed in February we gave Bolney Wine a go with their ‘Ultimate Wine and Food Tasting Tour‘. It was a fabulous day out, and we really enjoyed the wine, though it was the nibbles we brought home with us, along with a bottle of their amazing ‘Sussex Rosso Vermouth‘.

I can see us returning to their shop just for more Charlie’s Smoked Trout, though there are a bunch more local vineyards to try out for their tours.

Bungee

We use a bungee cord to hold the back door open, and it was getting a bit frayed. Also the cord we used to hold the mini greenhouse against the wall had snapped. So I bought a reel of cord from Amazon, along with some hog rings (and hog ring pliers) to fix them up. For sure I could have just bought some more bungee cords with hooks etc. already on, but the replacement cord does seem better quality, so hopefully it lasts better.


Dear Mims Davies,

It’s been three months since I last wrote to you about Alexander Boris de Pfeffel Johnson’s unsuitability, and nothing has happened in that time to exculpate him.

In fact it is clearer than ever that he broke the law, repeatedly lied about it to parliament, and has declared no intention to resign (as he should to comply with his own ministerial code).

It now falls upon you and your colleagues to act as the last line of defence for our democracy and push him out. You have a choice: do you actually stand for the rule of law, or are you willing to go along with ‘might is right’ with the democratic fig leaf of the 2019 election?

I would hope that despite conflicting loyalties it should be a simple choice. That you chose to became a lawmaker because you believe that people abiding by better laws will make for a better country. As Margaret Thatcher once said, “the first duty of government is to uphold the law – if it tries to bob and weave and duck around that duty when it is inconvenient then so will the governed”. Allowing the present situation to continue will further destroy trust in government and public institutions on which a functioning society depends.

Of course you might be thinking you can toe the party line, and maybe grab some of that might for yourself, and use it for purposes that seem right. But there lies the road to ruin, as you will make yourself a co-conspirator in a corrupt and criminal enterprise; and no good can come from that.

“But what about the war?” I see already trotted out as a talking point. There are far more capable, competent, and seemingly honest people within the ranks of The Conservative Party who can deal with us providing support to Ukraine. Tom Tungendhat immediately comes to mind.

It’s time to act. Don’t let us down. History will not be kind to those who appease and equivocate over this mortal hazard to the integrity of our nation.

Yours sincerely,

Chris Swan


March 2022

31Mar22

Pupdate

Although it’s looking ready to snow outside as I type, we’ve had some glorious summery weather in March, which means plenty of time outside running around for the boys.

But the picture that grabbed most attention was this one:

People thought we’d got another sausage dog, but it was just the boys hanging out with their friend Amber at the dog sitter’s.

On the Road Again

The dogs were at the dog sitter’s because I was in Barcelona for Mobile World Congress (MWC) showing off a demo of end-end encrypted Internet of Things IoT. It’s my first overseas trip since Jan 2020, and the first EU stamp in my passport since Brexit (after queueing in the ‘other passports’ lane when I’d have previously whisked through the automated gates) :(

eSIM

Three no longer do their ‘Feel at Home’ roaming, which mostly doesn’t matter to me as I’ve ditched them for the family mobiles. But I still have a Three data SIM in my iPad Mini. So I got a GigSky eSIM for the trip, which was £7.19 for ‘Data Plan Europe 1024 MB 15 Days’. The provisioning process was super easy. It worked right away in the UK (so I could leave the Three SIM behind and avoid any possibility of costly mistakes), and service was great in Spain. I kept it running for the remaining days once home, and it seemed good. Recommended – will use again.

Carry on speedy boarding

While we’ve all been not travelling it seems that all the short haul airlines (whether they claim to be ‘budget’ carriers or not) have changed their carry on policies. Where before you could carry on something that would reasonably hold a few days clothes and essentials, the cheapest sticker price now gets you a carry on that’s approximately a medium sized ladies handbag. I consider myself a master of travelling light, but I wouldn’t attempt anything more than a day trip with the reduced bag allowance.

To get an actual carry on bag included you have to buy a premium ticket (or just pony up for a bag, which oddly costs even more). The net effect is that the ‘speedy boarding’ line is now almost everybody.

MAME stuff

The RC2014 Mini pull request I wrote about at the end of Feb eventually got merged, and I’m thankful for the patience of the dev team shepherding me through the process. I’ve subsequently had two more PRs merged, one for TMS9995 and another for a C64 ‘turbo’ ROM. They should all appear in MAME 0.242, which I hope will be in the next few days..

As promised I wrote some posts about Decoding the MAME Rosetta Stone and my Journey to the RC2014 Mini Driver for MAME.

I’ve got more RC2014 related things planned, but some boards for TMS9995 just dropped through the letterbox from Alan Cox (@EtchedPixels), so they might come first (if I can find all the bits I need).


My original attempt at an RC2014 Mini driver started out as pretty much a copy of the gsz80 driver, with a find/replace of ‘gsz80’ with ‘rc2014mini’. But as the MAME team reviewed my pull request, they surfaced a bunch of problems.

Firstly I didn’t have the correct memory map. The RC2014 Mini only has 32K RAM (and of course it needs the corresponding 32K BASIC).

// RC2014 Mini only has 32K RAM
void rc2014mini_state::rc2014mini_mem(address_map &map)
{
	map(0x0000, 0x1fff).rom();
	map(0x8000, 0xffff).ram();
}

Then there was some discussion about how to handle ROMs. Initially I went for the MAME BIOS selection method:

// from https://github.com/RC2014Z80/RC2014/tree/master/ROMs/Factory
// `dd skip=56 count=8 if=R0000009.BIN of=rc2014mini_scm.bin bs=1024`
// `dd count=8 if=R0000009.BIN of=rc2014mini_32k.bin bs=1024`
ROM_START(rc2014mini)
	ROM_REGION(0x2000, "maincpu",0)
	ROM_SYSTEM_BIOS( 0, "scm", "Small Computer Monitor")
	ROMX_LOAD("rc2014mini_scm.bin",  0x0000, 0x2000, CRC(e8745176) SHA1(d71afa985c4dcc25536b6597a099dabc815a8eb2), ROM_BIOS(0))
	ROM_SYSTEM_BIOS( 1, "32k", "32K BASIC")
	ROMX_LOAD("rc2014mini_32k.bin",  0x0000, 0x2000, CRC(850e3ec7) SHA1(7c9613e160b324ee1ed42fc48d98bbc215791e81), ROM_BIOS(1))
ROM_END

But I was persuaded that it was better to implement jumpers for the ROMs, as that’s more authentic to the original hardware:

void rc2014mini_state::machine_start()
{
	m_rombank->configure_entries(0, 8, memregion("maincpu")->base(), 0x2000);
}

// Set ROM bank from machine CONF at Reset
void rc2014mini_state::machine_reset()
{
	m_rombank->set_entry(m_jump_rom->read() & 7);
}

//...

static INPUT_PORTS_START( rc2014mini )
	PORT_START("A13-15")   /* jumpers to select ROM region */
	PORT_CONFNAME( 0x7, 0x0, "ROM Bank" )
	PORT_CONFSETTING( 0x0, "BASIC" )
	PORT_CONFSETTING( 0x1, "EMPTY1" )
	PORT_CONFSETTING( 0x2, "EMPTY2" )
	PORT_CONFSETTING( 0x3, "EMPTY3" )
	PORT_CONFSETTING( 0x4, "EMPTY4" )
	PORT_CONFSETTING( 0x5, "EMPTY5" )
	PORT_CONFSETTING( 0x6, "EMPTY6" )
	PORT_CONFSETTING( 0x7, "SCM" )
INPUT_PORTS_END

//...

ROM_START(rc2014mini)
	ROM_REGION( 0x10000, "maincpu",0 )
	ROM_LOAD( "r0000009.bin",    0x0000, 0x10000, CRC(3fb1ced7) SHA1(40a030b931ebe6cca654ce056c228297f245b057))
ROM_END

Of course that now means defining an INPUT at the end block:

//    YEAR  NAME            PARENT    COMPAT    MACHINE        INPUT          CLASS             INIT           COMPANY           FULLNAME                FLAGS
COMP( 2007, gsz80,          0,        0,        gsz80,         0,             gsz80_state,      empty_init,    "Grant Searle",   "Simple Z-80 Machine",  MACHINE_NO_SOUND_HW )
COMP( 2015, rc2014mini,     gsz80,    0,        rc2014mini,    rc2014mini,    rc2014mini_state, empty_init,    "Z80Kits",        "RC2014 Mini",          MACHINE_NO_SOUND_HW )

Along the way the RC2014 Mini stuff was folded back into the gsz80.cpp driver rather than duplicating it. So it gets its own class:

class rc2014mini_state : public gsz80_state
{
public:
	rc2014mini_state(const machine_config &mconfig, device_type type, const char *tag)
		: gsz80_state(mconfig, type, tag)
		, m_rombank(*this, "rombank")
		, m_jump_rom(*this, "A13-15")
	{ }

	// Different machine config due to different RAM
	void rc2014mini(machine_config &config);

protected:
	// RC2014 Mini only has 32K RAM, so memory map is different
	void rc2014mini_mem(address_map &map);

	virtual void machine_start() override;
	virtual void machine_reset() override;

	required_memory_bank m_rombank;
	required_ioport m_jump_rom;
};

and that needs the implementation for state to make use of the different memory map and the ROM switched into it:

void rc2014mini_state::rc2014mini(machine_config &config)
{
	gsz80(config);
	m_maincpu->set_addrmap(AS_PROGRAM, &rc2014mini_state::rc2014mini_mem);
}

All of this rather stretched my very limited C++ knowledge. I did a Computer Based Training (CBT) course on C++ back in the mid nineties where absolutely nothing sank in (maybe because it spent too much time recapitulating C stuff that I though I already knew). When I started doing Java Enterprise stuff in 2000 classes and objects and inheritance and polymorphism were all new to me. To try to claw things back I ran through the W3 schools C++ Tutorial, which does a good job of covering the basics. If you’re new to C++ but want to try stuff in MAME then it’s probably a good enough place to start. Beyond that, Learn C++ looks pretty comprehensive.


I mentioned in my previous post Grant Searle Simple Z-80 Machine on MAME that the gsz80.cpp driver was like finding a Rosetta Stone for MAME. In this post I’m going to go through it block by block to explain how I parsed it, and how it enabled me to figure out how to write a driver for the RC2014 (Mini).

// license:BSD-3-Clause
// copyright-holders:Frank Palazzolo

Thanks Frank :)

// MAME Reference driver for Grant Searle's Simple Z80 Computer
// http://www.searle.wales/

And thanks Grant. A key point here is that I was familiar with Grant’s design from my RC2014 tinkering. It’s just about as simple as making a computer can get, using just 7 chips. I’d previously looked at drivers like the Imsai, but couldn’t figure it out. But Grant’s design is clean and simple, and Frank’s code is clean and simple.

For a hardware person (like me) it should be possible to relate the blocks of code to the blocks of hardware. So here goes…

We start off with the includes, which are like a bill of materials for the pieces being used.

// All the common emulator stuff is here
#include "emu.h"

This is the key include, providing all the stuff underlying the other parts. If I was making a Grant Searle system on a breadboard, then this is the bit that would give me the breadboard (and the laws of physics).

// Two member devices referenced in state class, a Z80 and a UART
#include "cpu/z80/z80.h"
#include "machine/6850acia.h"

This gives us two of the main chips, the Z80 CPU and the 6850 UART. The other two main chips are RAM and ROM, which we’ll get to later, and there are also 3 ‘glue’ chips, which we don’t actually need when doing things in software.

// Two more devices needed, a clock device for the UART, and RS-232 devices
#include "machine/clock.h"
#include "bus/rs232/rs232.h"

The system has a clock using a crystal and one of the glue chips, and input/output happens with a terminal attached to an RS232 port.

// State class - derives from driver_device
class gsz80_state : public driver_device

We’re creating a driver, which is done by creating a class based on driver_device (coming from that emu.h include earlier).

{
public:
	gsz80_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")   // Tag name for Z80 is "maincpu"
		, m_acia(*this, "acia")         // Tag name for UART is "acia"
	{ }

	// This function sets up the machine configuration
	void gsz80(machine_config &config);

The public methods for the class are essentially plugging the CPU and UART into the emulation ‘breadboard’.

private:
	// address maps for program memory and io memory
	void gsz80_mem(address_map &map);
	void gsz80_io(address_map &map);

	// two member devices required here
	required_device<cpu_device> m_maincpu;
	required_device<acia6850_device> m_acia;
};

and with the private methods we’re declaring that there will be a memory map, an I/O map and getting specific about the CPU and UART that are being used.

// Trivial memory map for program memory
void gsz80_state::gsz80_mem(address_map &map)
{
	map(0x0000, 0x1fff).rom();
	map(0x2000, 0xffff).ram();
}

The memory map uses the first 8K for ROM and the remaining 56K for RAM.

void gsz80_state::gsz80_io(address_map &map)
{
	map.global_mask(0xff);  // use 8-bit ports
	map.unmap_value_high(); // unmapped addresses return 0xff
	map(0x80, 0xbf).rw("acia", FUNC(acia6850_device::read), FUNC(acia6850_device::write));
}

The 6850 is mapped into an I/O address (which in hardware would be done by those ‘glue’ chips).

// This is here only to configure our terminal for interactive use
static DEVICE_INPUT_DEFAULTS_START( terminal )
	DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_115200 )
	DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_115200 )
	DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 )
	DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE )
	DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 )
DEVICE_INPUT_DEFAULTS_END

Connection parameters for the emulated terminal being connected to the RS232 interface provided by the 6850 UART to give input and output.

Now we wire the parts together:

void gsz80_state::gsz80(machine_config &config)
{
	/* basic machine hardware */

	// Configure member Z80 (via m_maincpu)
	Z80(config, m_maincpu, XTAL(7'372'800));
	m_maincpu->set_addrmap(AS_PROGRAM, &gsz80_state::gsz80_mem);
	m_maincpu->set_addrmap(AS_IO, &gsz80_state::gsz80_io);

The clock speed is set for the Z80 CPU, and it’s connected to the address map, where it will find the ROM and RAM, and the I/O map, where it will find the 6850 UART.

	// Configure UART (via m_acia)
	ACIA6850(config, m_acia, 0);
	m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
	m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts));
	m_acia->irq_handler().set_inputline("maincpu", INPUT_LINE_IRQ0); // Connect interrupt pin to our Z80 INT line

The UART is wired up to the CPU and RS232 interface.

	// Create a clock device to connect to the transmit and receive clock on the 6850
	clock_device &acia_clock(CLOCK(config, "acia_clock", 7'372'800));
	acia_clock.signal_handler().set("acia", FUNC(acia6850_device::write_txc));
	acia_clock.signal_handler().append("acia", FUNC(acia6850_device::write_rxc));

The UART is also connected to a clock (at the same frequency as the CPU, because in hardware they’d use the same clock signal).

	// Configure a "default terminal" to connect to the 6850, so we have a console
	rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal"));
	rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
	rs232.dcd_handler().set(m_acia, FUNC(acia6850_device::write_dcd));
	rs232.cts_handler().set(m_acia, FUNC(acia6850_device::write_cts));
	rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); // must be below the DEVICE_INPUT_DEFAULTS_START block
}

Finally the terminal is connected to the RS232 interface.

// ROM mapping is trivial, this binary was created from the HEX file on Grant's website
ROM_START(gsz80)
	ROM_REGION(0x2000, "maincpu",0)
	ROM_LOAD("gsz80.bin",   0x0000, 0x2000, CRC(6f4bc7e5) SHA1(9008fe3b9754ec5537b3ad90f748096602ba008e))
ROM_END

We said earlier that there would be 8K of ROM at the start of the memory map, here’s where we describe which ROM will be plugged in.

// This ties everything together
//    YEAR  NAME         PARENT    COMPAT  MACHINE   INPUT    CLASS        INIT           COMPANY           FULLNAME                FLAGS
COMP( 201?, gsz80,       0,        0,      gsz80,    0,       gsz80_state, empty_init,    "Grant Searle",   "Simple Z-80 Machine",  MACHINE_NO_SOUND_HW )

The driver definition concludes with a line describing the machine being emulated in terms of its ROMs, machine definition, input (not used), state class, and initialisation along with some biographical details.

And that’s it. The 4 main ICs, and how they’re wired together can be fairly easily picked out of the code. In a follow up post I’ll run through what changed to make an RC2014 driver.


Black Sea ’93

12Mar22

The last few weeks have had me reflecting a lot on my time in Russia and Ukraine almost 30y ago…

When I joined the Royal Navy in ’89 we were definitely living in ‘interesting times’. The defence studies lecturers at Britannia Royal Naval College (BRNC) Dartmouth were tearing up talks they’d used for decades as the Iron Curtain fell, the Berlin Wall came down, and we shifted into a brave new world of after the Cold War.

As I finished my degree I found myself spending a few weeks with the Polish Navy on their sail training ship ORP Iskra, giving me my first experience of a former Warsaw Pact country. A week or so later I joined HMS Avenger to complete my ‘fleet’ training, and found myself heading back East for the first Royal Navy deployment to the Black Sea since the end of WW2.

Novorossiysk

After transiting the Bosphorus into the Black Sea our first port of call was Novorossiysk, a large naval port city[1]. We stayed there about a week, and it was quite an experience. My time ended up split between hosting people on the ship, and attending the variety of receptions we were invited to.

For me, the highlight was visiting the ‘Champanski’ factory at Abrau Durso. They had a proud tradition of making high quality ‘traditional method‘ wine going back to the time of the Tsars, which had somehow survived the Bolshevik revolution, the ‘Great Patriotic War’ and subsequent Stalinism.

We were hosted for dinners on Russian warships, giving the opportunity for a good look around, and leaving the impression of ‘what were we ever scared of?’ – yes they were armed to the teeth, but all the kit was garbage. A visit to a Sovremenny-class destroyer revealed an operations room with command and control capability that looked like a WW2 time capsule [and some of those ships are still in service]. Of course the real problem was strength of numbers rather than quality of equipment. We faced wave after wave of vodka toasts saturating our livers, just like in conflict we’d have faced wave after wave saturating our defences.

I had my first encounter with the Klept. The local mayor (or maybe it was his ‘fixer’) was a former KGB Colonel. His kids had Nike trainers and satellite TV. The ‘McMafia’ was taking root and tapping itself into the cashflows as commerce opened up.

One peculiarity was money. Normally we’d get local currency, but for this visit we got dollars, and it soon became clear that the locals preferred pristine notes rather than worn ones, as they had more life left in them. The corruption and petty crime were insane. People expected $bribes to be paid for all sorts of things, and many of our sailors were robbed (some at gun point) for the $ in their wallets. We had to shut off access to the ops room during ship open to visitors as people were pinching the button caps from the Computer Assisted Action Information System (CAAIS) consoles to take home as souvenirs.

The visit was a BIG DEAL for the locals, and to an extent we were treated like rock stars. People would grab anybody in uniform to have their photo taken with a visitor from the West. I met some Brits who were starting up an import/export business, and amongst younger people there was much excitement and enthusiasm for the opportunities that were opening up. But the older folk were more skeptical, with many morning the demise of the Communism, the USSR, and the certainty it had given them.

Another memorable moment was meeting some of the teachers from a local school. We’d stuffed the ship with donated clothes and books and medical equipment that had all been donated to local charities. But they still wanted more English language books, so I gave one teacher my copy of Terry Pratchet’s ‘The Colour of Magic’, which I’d read on the way.

I also recall a soldier proudly showing off to me his AK-74. I was a little bemused that he didn’t remove the magazine as part of showing me the weapon was safe, until it transpired that nobody had any bullets. There were soldiers with guns all over the place, but none of them were actually armed.

A pause in the action

Our next port of call was supposed to be to Georgia, but they were rather inconveniently having a civil war, so we spent a few extra days at sea. For me it was a welcome break. I’d got food poisoning or a stomach bug in Novorossiysk that led to me losing a stone of weight, the constant entertaining and receptions had led to borderline alcohol poisoning, and the busy schedule hadn’t been at all conducive to progressing through the ‘task book’ that officers under training needed to complete.

Odesa

Next up was Odesa, Ukraine’s third largest city, and a major port. We weren’t there long, so I didn’t get to see very much of the place. As usual we hosted a cocktail party on arrival for local dignitaries, but this one was different. The Minister for Defence Malcolm Rifkind[2] was guest of honour, and he brought with him an entourage of the great and the good from Kyiv. I remember speaking to a young lady who spoke remarkably good English, and was in the process of setting up DHL’s operations in the Ukraine.

I got to spend an hour or two ashore sightseeing the wonderful architecture, but there wasn’t much to do. Though street traders were sprouting up, mostly selling Matryoshka dolls in a mix of traditional styles and modern ones representing Gorbachev and Yeltsin.

From my conversations with Ukrainians they were not bemoaning the end of the USSR. They were relishing the opportunities of independence, and all the potential that it brought.

And thus the divergent paths that bring us back to the present were embarked upon – Russia mourning its decline of empire, and Ukraine embracing an independent future. I’ve seen observations that Putin just doesn’t get this, but rather has a mental model forged in the 70s and 80s, and is now so insulated by surrounding kiss-ups that there’s no opportunity for the truth to break through.

Contstanta

I didn’t get to see anything of Constanta, as I was assistant liaison officer for the visit, which tied me down in admin work all day every day. At least the young officer from the Romanian Navy assigned to work with us was a great chap[3]. I did however get to see some other parts of Romania by helping to organise a trip to Transylvania, which included sites like the former Royal Palace at Peles Castle, and Bran Castle.

Bucharest was still showing the scars of the revolution that had deposed Ceaușescu, though we were treated to some amazing food there before the journey home. At least the back row of seats on the plane didn’t fall off their mountings on the way back like they had on the way out.

Varna

Varna in ’93 felt very different to the other Black Sea ports. It was busy and vibrant and fun in the ways that a city used to tourists should be. It wasn’t just a commercial port, looking after sailors for the short time there bringing trade in and out; it was a place where people came to eat, drink and be merry. We were almost back in the West, and it showed.

Update

16 Mar 2022 – my former colleague Igor Ilyinsky wrote about Odesa as his birthplace, and his mixed sense of identity, which reminded me of conversations about (Ukrainian) language whilst I was there.

Notes

[1] As Putin annexed the Crimea in 2014 I recall seeing an argument that Russia needed to secure Sevastapol as their only viable Black Sea port. This is of course nonsense, they always had Novorossiysk as well (and Sevastapol had continued to serve as a port for the Russian Navy).
[2] It can’t go without saying that I’ve never met a more ill mannered, pompous twat in all my life than Malcolm Rifkind. It says a lot about our political system that such awful people find their way into ‘safe seats’ where they get voted for despite everything, and of course this only emboldens their behaviour.
[3] His English was of course much better than my Romanian, but he very much desired the little Collins Romanian-English Dictionary we had on board. It wasn’t mine to give him, so I took his address and picked one up for him at W H Smiths once back home.


In my RC2014 Mini on MAME post this was one of the things I was planning to try next, and once again there was an existing driver that had most of the pieces in place – evmbug.cpp implementing the TMS 9995 Evaluation Module (aka TMAM 6095).

My first job was getting the existing driver working, which meant getting the ROMs sorted out. I found that the ROM config didn’t quite match the board, so I made some changes and got myself a working EVMBUG monitor. From there it was a short step to HELLO WORLD:

For the TMS 9995 Breadboard System (which I’ve previously made using RC2014 modules) I needed to add a revised memory map for the larger RAM, and the selection of ROMs for EVMBUG, BASIC, Forth etc. My pull request for tms9995bb has been merged, so it will be in the next release of MAME.

At this stage the one thing I’d like to change is the serial driver support. At the moment the driver isn’t using the TMS9902 UART (because it doesn’t support the broader rs232 system in MAME), meaning that the terminal is directly connected into an I/O port. The consequence of that is that it’s not possible to run the emulation headless and connect another terminal emulator, which turns out to be essential if you want to paste code in – something I’ve been trying out getting CP/M working with the gscpm driver. But more on that in another post.


February 2022

27Feb22

Pupdate

As we neared the end of the month it was finally warm enough for the boys to walk without their coats, and whilst they might look cute and snuggly in the coats they seem more energetic and free without them.

Pi Stuff – MWC Demo

All of that time spent playing with Raspberry Pis over the past decade is now being put to good use at work. The @ Company has been working with Internet of Things (IoT) connectivity specialist ZARIOT to provide end-to-end encryption for things, and we’ve been putting together a demo for Mobile World Congress (MWC). The demo system is a Pi 4, SSD, 4G/LTE HAT, TFT HAT and MAX30101 sensor. It lets us read heart rate and O2 saturation from somebody’s finger, and send the data to @ Platform apps. At the IoT end the @ sign private key can be stored on the SIM card (since there’s no secure element like we’d usually use on a phone/tablet). If you want to see it without making the trip to Barcelona, I did a quick preview on Flutter Hump Day.

MAME stuff

I already wrote a couple of posts about the Grant Searle Simple Z-80 Machine on MAME and RC2014 Mini on MAME, but things have moved on quite a bit since then. My upstream pull request has led to a lot of changes, and a lot of learning. I’m now planning to do a series of posts on that process, so hopefully it’s easier for others to find their way into MAME development.


TL;DR

Getting an RC2014 Mini working based on the Grant Searle Simple Z-80 Machine driver was pretty trivial, but it’s been enough to get me going with MAME development and persuade me to try some other things.

Background

I know there are already emulators out there already for the RC2014, I’ve used EtchedPixels/RC2014 a bit in the past. But I’ve seen people doing cool projects with MAME, which already has a broad range of hardware emulated, and I thought RC2014 would provide an easy on ramp. I chose the Mini version, because that’s the first RC2014 I made, and it’s pretty self contained.

VERY similar to gsz80

As I mentioned in Grant Searle Simple Z-80 Machine on MAME there’s already a ‘driver’ in MAME for a machine that looks much like the RC2014, because Grant’s Simple Z-80 provided inspiration for the RC2014.

What I hadn’t realised is that (for 56k BASIC at least) the RC2014 uses the same ROM as Grant’s machine. So from a MAME perspective there’s really no difference.

I created a revised rc2014mini.cpp driver, but it’s pretty much a search/replace of gsz80 with rc2014mini.

It did at least give me a chance to try out the tooling chain….

Building

I installed the Windows combined 32-bit/64-bit tools from mamedev.org/tools and followed the installation instructions there.

Phill recommended the following changes, which I also put in place:

set ARCHOPTS=-march=native -fuse-ld=lld
set OVERRIDE_AR=llvm-ar
set IGNORE_GIT=1
set PROMPT=

With my fork of MAME cloned (takes a while) and my driver file created I was ready to build it:

make -j 4 SOURCES=src\mame\drivers\rc2014mini.cpp SUBTARGET=rc2014mini

This created an rc2014mini.exe for me, which didn’t work because I’d forgotten to add anything to mame.lst. Once I added this:

@source:rc2014mini.cpp
rc2014mini                      // RC2014 Mini

I had an executable that worked:

ROM

As the ROM is just the same as gsz80.zip I could just rename that (and gsz80.bin) inside it. Though I went through the motions of downloading K0000000.hex from the RC2014 Factory ROMs page on GitHub, then converting it as before:

objcopy --input-target=ihex --output-target=binary K0000000.hex rc2014mini.bin
zip rc2014mini.zip rc2014mini.bin

Next…

I’d like to try getting RC2014 boards hooked up, particularly the TMS9918A Video Card for RC2014.

But I’d also like to get a TMS9995 system working in MAME. There’s already an eval module (evmbug.cpp) driver, which should give a good starting point for a breadboard system, though I’m a little worried that the TMS9902 serial driver isn’t in the shape it needs to be.

So far I haven’t done a pull request to upstream MAME for the RC2014 Mini driver, but I might do that soon.

Update

23 Feb 2022 – I did an upstream pull request, which led to me being asked to fold the changes into gsz80.cpp rather than having a standalone driver for RC2014. I also realised that the Mini should only have 32K RAM, and the corresponding BASIC, and I’ve added the Small Computer Monitor (SCM) ROM.


TL;DR

I’ve been wanting to try emulating some RC2014 stuff using MAME for some time, and I think I’ve found my way into it with the MAME driver for Grant Searle’s Simple Z-80 Machine.

Background

Back when I was making my TMS9995 on RC2014 system part of my adventure into the lands of TI-99/4A fans took me to the Multi Emulator Super System (MESS). But MESS has been folded into MAME (once Multiple Arcade Machine Emulator) since 2015. I thought it would be cool to emulate some RC2014 stuff on MAME, but I found the project impenetrable and just couldn’t figure out how to get started (not helped by the fact that my C++ skills are almost non existent).

But then the London Retro Computing Meetup held a Using MAME as a development tool event, which showed how to get started.

Almost by accident, I noticed that Grant Searle’s Simple Z-80 Machine is now part of MAME (thanks to Frank Palazzolo). For me this was like finding the Rosetta Stone. Grant’s system is the basis for Spencer Owen’s RC2014. So if I can get the Simple Z-80 Machine going then I can probably hack together something RC2014ish.

Also Phill did a great job in the meetup of showing how to get started with MAME development, using a previous meetup project – Tom Storey’s Z-80 clock.

ROMs

MAME doesn’t come with the ROMs needed to run the machines it emulates. That’s just too much trouble from a Copyright perspective.

The source file for gsz80 notes:

ROM mapping is trivial, this binary was created from the HEX file on Grant’s website

So I grabbed Grant’s bundle, which includes ROM.HEX

At first I extracted the binary via my MiniPro EPROM programmer app. But then I thought there must be an easier way than that, and there is. On my WSL2 Ubuntu command line I used:

objcopy --input-target=ihex --output-target=binary ROM.HEX gsz80.bin

Then confirmed that the file was correct:

$ sha1sum gsz80.bin
e843e597ca6c319002dbf191528998e654656736 gsz80.bin
$ crc32 gsz80.bin
6f4bc7e5

The binary then needs to be put into a zip file for MAME to find it properly:

zip gsz80.zip gsz80.bin

Running it

With gsz80.zip copied to my roms directory I ran:

mame gsz80

And the system sprang to life:

Next…

I’m going to have a go at hacking something together to use one of Spencer’s RC2014 ROMs.

And after that I may have a go at doing an emulation of Stuart Conner’s TMS 9995 Breadboard or PCB System.