Thursday, April 16, 2009

Getting BBC BASIC to run on ROLF

I'm trying to get the BASIC105 module from ROOL to run using the compatibility library and ARM emulator.

Downloaded the module from:
http://www.riscosopen.org/content/downloads/module-zipfiles

Next, a program to load a single Relocatable Module:


#include <stdlib.h>

#include "rolf/compatibility/compatibility.h"
#include "rolf/compatibility/arm_emulator.h"

int main( int argc, const char *argv[] )
{
uint32_t regs[16];
uint32_t flags;

setenv( "RISCOS_MODULES", "BASIC105", 0 );

// Any old SWI, the first call to riscos_swi loads and
// initialises all the modules in RISCOS_MODULES (a
// colon-separated list of filenames)

riscos_swi( 0x0, regs, &flags );

return 0;
}


First problems:

1. I haven't implemented arguments to be passed to the module on initialisation (in r10). I can fake that in gdb, for the time being.

2. The module expects to be decompressed by the operating system (the init code has bit 31 set). What algorithm does it use?

[Update]
The decompression algorithm appears to be private, so I've ripped a decompressed version from my Risc PC.

The start code assumes it has memory to use at 0x8000, so I've given it some to be going on with.

The code makes use of multiple load and store instructions which load or store the base register, which I hadn't implemented.

I believe I've fixed that, now, and with the (quick and dirty) implementation of a few OS_ SWIs (WriteS, Write0, WriteI+... and ReadLine) I've got to the point where it prompts for input, but segfaults at a strange address that's exactly 0x20000000 lower than the return address in r14. I suspect that the module requires loading in the lowest 512MB, or even lower.

[Update 2]
Yes, allocating memory around the 64MB mark means that the code runs a lot longer.

A whole lot longer; it's time to disable logging the register contents on each ARM instruction!

[Update 3]
OK, the underlying problem is that the BASIC I have is 26-bit, and I'm not implementing that (yet). The 0x20000000 offset was due to the code clearing the C flag.

On the plus side, I found a bug in the emulator where loading a byte didn't clear the top 24 bits of the register. I'll go back to trying to get AWRender to work, now that's fixed.