Live demo: Building in (2023)

Building BeebIt

Script and notes


I found a repository in GitHub for the BeebIt BBC emulator. I took a brief look at what it contained and decided that it would probably build with the RISC OS build system. Initially, I thought I would create a video about creating a video which would demonstrate how to make the repository build under the build system.

However, I realised it would be interesting to try out a 'live' recording of my making it work - whatever that might mean. I had never done that, so it seemed like a good experiment.

As a consequence, this is a little more rough than the usual videos, but it shows how I investigated the repository and made it build. It also provides demonstrates changing RISC OS Pyromaniac's configuration on the fly, and debugging a simple hang.

The following is an edited transcription from the video. Interspersed, there will be notes about the video which I didn't explain as I was recording it.

Transcription and notes

Browser open at the GitHub repository

I found this GitHub repository, by Michael Foot, which is the BeebIt emulator. And looking at it, it looks like a regular RISC OS build system.

Clicks on the Makefile and scrolls through

And if I have a look at the Makefile very quickly, it just looks like a standard one, it's built 32 bit. It uses stubs, which I can change.

You can see the -apcs 3/32bit which indicates that it's 32bit. The use of Stubs restricts its usefulness, and I don't ever build things without StubsG.

But otherwise, it looks like it's just a regular build system. So I'm going to try and build it. So let's try to do that with the shell system.

Opens up the site

So we create a working directory and let us... directory into it, not CD.

I got confused about the command to change directory on RISC OS

And git clone copy-paste the URL.

The git repository was quicker to copy and paste rather than type, so I used the shell's paste function to paste the text in.

dir BeebIt-for-RISC-OS

Let's make a small change to the Makefile for StubsG, ok StubsG. Save that out and exit.

I used the *Edit command to edit the Makefile, changed C:o.stubs to C:o.stubsG, and then saved the file.

And then let's try and build it.

*Run the amu command to build and almost immediately we fail with an error writing the object file.`

Ah. That's because we haven't got an o directory.

cdir o

That's created a o directory and build...

amu again and we then see that the RipROMs source built and invoked the linker just fine.

And that's built it. The C compilers run and the linker, so that means we've actually got a executable out of it. Now it's building some more things.

We see a few more files getting built by the compiler

There's quite a few files in this if I remember rightly. So this could mean it takes a while. This might mean it's a smidge boring.

We see an error from the compiler - out of store

Ah! Okay. We've run out of disks space ... no not disc space, out of memory. So help dynamic areas.

Type *help DynamicAreas to see how much space is available - Application space is visible as area -1

Okay, so the application space is 100,000 hex. Let's just give it 10 megabytes, I think you have to measure it in K.

Use *AppSize 10000K to change the application space - we're not in the desktop and have no WindowManager, so cannot use the more commonly seen WimpSlot.

Help dynamicareas. That's a bigger number. Right. Build it again.

We can see the much bigger number from the help. *amu to build some more

Hopefully this will build with that. I mean, there are quite a few files here, so it would be unsurprising if it failed. Yeah. Okay, so that extra memory has worked. We've got that file built.

We watch some more files build, reaching the video system

Video system. It is a bit slower as it's being emulated, but still should work.

Cool, and now we're building Sheila. Sheila is one of the memory mapped I/O space. I don't remember what it controls. My memory of BBC systems is a little bit outdated. Now I'm lying. It's completely gone pretty much.

*More files build.

Keyboard system. ADC. Analogue. I wonder if that calls to the INKEY system for doing analogue, so we'll just pass through to the analogue system. Let's go and have a look at that as well whilst waiting.

Returns to the Github repository and navigates the source to the adc source file

Where is ADC? Analogue to digital converters, it's faking a D7002C whatever one of those is.

The header of the file is nicely showing us what it's for and the chip that it uses - quite nice really. Now skim the code for the implementation

Right, so it can be configured to emulate things to a joystick - no, a mouse to be emulated through joysticks. So if that is the case, then it will go and translate this presumably as a position on the screen and the button, it comes from the mouse. And if it's not configured to use the mouse simulation, it just returns a zero. So it doesn't actually go through the INKEY system. Which is a pity. But oh well.

Jump around the function adcpoll pointing out what I'm seeing

All right, see where we're up to...

Back to the compilation tab

It's getting somewhere 6522. User VIA. Okay. Honestly couldn't have told you what that does. System VIA

How many files have we got? Can we see how far we're getting through? We're on assembler files. 65c12. Ah, wasn't that the one that was in the master. Or was it in the master compact? I can't remember.

Oh, we got crash! "Instruction inadvisable in 32 bit". Yeah, fair enough.

We see a message pop up that says (truncated) "Warning: TSTP inadvisable in 32-bit. Unable to start throwback session, error 0x1e6 'SWI not known'"

"Unable to start throwback session". Something must be up with the DDEUtils system. So I'm going to just restart it and see if it's just not initialised properly.

Reinitialise DDEUtils and try the amu again

Let's try again. Nope, that failed as well. It's probable that there's a bug in how the throwback system is set up. I'll fix that, but in the meantime, let's just change the configuration throwback.implementation=Console. I'm guessing that the null system actually just returns errors, which probably isn't right.

Used *PyromaniacConfig to change the setting throwback.implementation to console.

So if we just go and show the settings now? Yeah, we've changed that to console. And we should just be able to reinitialise DDEUtils to pick up a new config and then build this again.

DDEUtils was reinitialised, and we ran the amu again.

That's probably also a bug in my implementation of objasm. Because it shouldn't crash. If it gets an error back from that SWI it should just simply ignore it.

In DDEutils, the null implementation just reported that it couldn't handle the throwback which was turned into a SWI not found error. By reconfiguring the module on the fly to use a different implementation - console this does understand the call and all was well. RISC OS Pyromaniac was updated to be silent when null was used, and objasm was updated to not fail fatally if we didn't have DDEUtils.

But you can see the yellow printout saying it's doing throwback.

The console implementation prints messages to the console to show the effect of the throwback calls in different colours.

*More files are assembled by objasm - there are a bunch of 6512cpu files from 00 to F0.

There are quite a few of these I'm assuming there is one file per instruction block. Right and now we've got the .... that was 6512, now 6502... We're back into doing C code now. How many files do we have?

Flips back to the Makefile to see how far we're going, and tries to match up the file with those in the list of objects - we were compiling o.beepit and in the definition of the files to compile, the first 2 are o.main and o.beepit and it goes backwards through the list

Oh ... missed it scrolls back Oh we're nearly. flips back and forth No can't see it... oh there's c.beepit, so it's nearly done.

Wait a bit more for the last two files to compile

This almost certainly won't be able to be run, because it'll be a desktop application. But with no changes, it's looking like - well, I did change some I didn't know I modified it to use StubsG... We're building the main file.

I'm guessing this is a big file, or bigger than the others.

Just waiting for c.main to finish

One of the advantages of just trying these things out is that I find little bugs like the one I just found, and I can refine things a bit.

The compile completed, and we're back at a prompt - we can list the files

Right. So out of that we've got a, we've linked something called !RunImage. So if I just have a list of what's in there ... we've got the RIProms tool.

Run the RipROMs binary, and it prints a message about not having !65Host but doesn't return to start of the line.

Okay, so that's interesting, it printed out a message, but it didn't put a new line on the end of part of it. So that's a little bit odd. Might mean I've implemented something wrong, or it might be a bug in the actual RipRoms code, because this is an error path.

It was a bug in the code - the reason I mention that it's the error path is that often people don't check the error case, and so there can be untidy or bad effects when things go wrong. And of course this isn't an important error case either

In any case, it's really not that interesting.

Either way, I don't actually have !65Host, so I can't do that.

Lists the files again

If you have a look, we also got the !RunImage. Let's try running.

Run it as !RunImage, and we see it outputs a message saying 'Unable to save configuration' and a prompt

That pops up an error box, this is the presentation you get if you would normally use Wimp_ReportError. It's saying you can press O or return to just accept it. Ok, That was error.

Accepted that by pressing return, and it finishes the error back and ... nothing happens - cursor just sits there

Now it's just sitting there. I'm guessing that it probably has tried to start up some Wimp operations and isn't actually able to start up properly. Not really sure what else to do there. Might be... yeah it might be dead.

Press escape and we exit the application back to the command line

Okay, so let's press escape. And we'll have a see. Okay, so what's the best thing to try here? Not sure. *PyromaniacDebug traceswiargs. This is going to list all of the SWI calls are made as they happen. It's going to be a bit noisy. It may not be at all useful.

Entered the debug command to turn on SWI arguments and then ran !RunImage again. Lots of traced SWI calls are printed, together with the address of the call, and the argument descriptions. Soon we get to the Wimp_ReportError and we pause.

Right, so here, we can see that it's failed to do things. And one of the things we can see is it's got an error Cannot create $..BeebIt.Choices, which probably means... yes, if we have a look up here, and look at the parameters, it was actually requesting <Choices$Write>, which isn't set in this environment.

The trace above the Wimp_ReportError is saying that it has an Inappropriate operation on filesystem for an OS_File 11 call. And in the entry parameters the <Choices$Write> use is very clear

So let's press Escape again. And let it shut down.

Pressing escape will shut down the application, so it calls lots more SWIs to restore the environment back for the command line.

Set Choices$Write $

This will just ensure that we don't get the error - it will be able to write a file. It shouldn't be writing anything to Choices during startup, but that's a separate bug. Then we run the application again.

Let's see what happens. !RunImage

I point out the left part of the display which shows a set of characters like [||||) which are indications of the stack depth. If on a call, the stack is deeper than before, it gets a new symbol from the right, if it returns to the old level, then it drops a symbol from the right. If the stack is more shallow than before but still deeper than the prior stack position, the symbol changes. So this shows an indication of how nested the execution of the program is.

So the bit you can see here on the left-hand side is the stack depth as it's executing things.

The system is just reporting XWimp_Poll calls repeatedly now, and each one is returning an error SWI not known.

Right, here we are. So essentially, it's calling a whole bunch of Wimp_Poll and Wimp operations, but ignoring the errors. So it's not noticed the fact that we haven't got a WindowManager. That's strictly a bug. It should have reported a failure when it got to Wimp_Initialise and the call returned an error. And because it hasn't, we're left in this limbo state where the system is trying to just continue to polling and nothing's coming back.

Presses Escape to return to the prompt and shows again that we have built binaries.

There we go. But what we've actually got out of this is - we built something, and we didn't need to do very much at all. Yeah, I think that was pretty successful, to be honest.

There we go!