8-bit BASIC virtual machine?

Speaking of “squeezing” stuff in … an article going around lately is about the “impossible” Elite, fitting in 32K of RAM.

But there’s another “impossible” game which blows my mind more than that - The Hobbit. That was a single loader tape game, but it was no ordinary text adventure. It had complex emergent behavior gameplay due to the NPCs behaving and interacting with each other independently of the player.

I can wrap my head around Elite, but I think I’ll never get a handle on The Hobbit.

@spacehobo Unfortunately, support for tape-based computers doesn’t seem to be a high priority for PunyInform or Ozmoo.

Even the Puny (previously Puddle) BuildTools seem to be more disk-oriented these days.

I’m a bit confused.
Is it mainly about a new universal audio tape format (on modern media) for old and new computers?
And /or a general new universal BASIC version?
And both with and without GFX for all computers?

Much already exist.
But everything together is maybe not possible.
And I wonder who really needs this. (OK maybe just a programming task).

If you want to include existing games
these maybe have to be all rewritten to work on all machines.
Or for new games you could create an own format.
But with GFX it’s very hard.

It would require some clever programming to create a universal audio tape format for multiple platforms as besides anything else there was no universal baud rate.

A universal BASIC version is closer to the idea, only it would be based on existing ANSI standards for Minimal and Full BASIC, so not new. The ANSI Full BASIC standard has an optional graphics module.

As the system would rely on using a virtual machine for each physical machine, having 3 options would allow users to choose the smallest one that would fit their needs.

It might even be possible to reduce the number of options to 2, depending on how much the byte code would need to vary for Minimal and Full BASIC.

I doubt it would be practical to have the graphics version available for every machine, as they varied too much in that area.

There are a number of existing options that support multiple retro machines, but these tend to be aimed at C programmers.

Yes, existing BASIC games would need some conversion, but it would only need to be done once to run on multiple machines.

An 8-bit graphic adventure game I was really impressed with was “Robot Odyssey,” partly because of something similar to what you talk about with The Hobbit. There were versions for the Apple II (which may have had to be 48K, since it loaded from disk), IBM PC, and the CoCo.

I had played 8-bit graphic adventure games before, and what I always saw was that action only took place in the room where you entered. If there were other characters in it, they were randomly placed. Sometimes they might be there, but maybe not. If you killed them off, you could leave the room, come back, and there might be more off them (with no other way to enter the room than where you entered, that sort of thing). I found it annoying. RO was different in that objects and characters were not randomly placed. They had consistent behavior. So, you could see them doing something in a room, leave, come back, and where they were was consistent with what they were doing earlier. In a way, it had to do this, because you could set your own robots off doing a task, you could leave the room, come back later, and see how much progress they made. If you did something that changed in a room, it stayed changed. So, the game was tracking everything that was happening in the world, with a bunch of potentially moving objects that could change anything in it. There were also important inter-character interactions that would take place while you weren’t looking, particularly as you got near the end of the game.

In my experience, that was very unusual.

2 Likes

And yet BASICODE (previously) managed, somehow.

I’ve hesistated to contribute to this thread as I think you’ve over-constrained your goals:

  • must be able to run on more obscure home computers (“Sharp MZ-700, Enterprise 64/128 and Dragon 32 …”). The more obscure the target, the less general help you can receive. Fewer people will be interested in the end result because they don’t know about the systems, too.

  • must support tape. I don’t know anyone who limits themselves to tape-based retrocomputing these days. It was a bit crap when we had to do it, and now it’s stultifying minutes we’ll never get back again. There are now faster ways to load program on tape-based systems for a reason.

2 Likes

Adding to @scruss’ concerns, and with regard to a compatible BASIC subset (as outlined previously): Mind that BASIC comes with significant overhead, especially, if we were to abstract any complex operations, like string matching, in subroutines. Also, this will become pretty slow, and, if we were to constrain ourselves to single-letter variable names and single-dimensional arrays, we may run out of variables pretty soon. Then, if we really want to run this on popular machines out of the box, we will also run out of memory pretty soon, especially with a kind of application that requires significant data sections, like a text adventure. E.g., consider the VIC-20, which comes with just 5K of RAM stock (not to speak of the ZX-80 with just a single K, including video RAM.) How much of this is already required just for a viable parser?

I guess, it’s much a question of matching a range of target machines and a specific architecture, which may realistically support this. – I’d really advice towards pushing any headless code, which has to go through some degree of abstraction anyway, to byte-code or machine code routines, which may also allow for compression of any data sections involved. (I do see the charm and the sweetness of the challenge of implementing this in BASIC, but I don’t think that this can be done for anything that suits modern taste, as in minimal complexity.) And, I guess, if you want to implement anything more supportive of modern taste, a lower memory limit of 32K may also be advisible, which reduces the list of possible platforms already quite a bit.

1 Like

100R — uxn might be something to play with, you can use ~rabbits/tiny-basic - Tiny BASIC, written in Tal - sourcehut git on it.

1 Like

Yes, the BASICODE programers were able to do it. I didn’t say it was impossible.

However, I believe it was limited to a 300 baud rate and would have limited use for this project.

As far as text-based programs are concerned, the differences between machines are not that great. Most of the Sharp MZ series were compatible with other machines in the same series and the Dragon 32 was very similar to the Tandy CoCo 1.

If I only wanted to support popular, disk-based machines, I could choose from several existing tools.

@NoLand The Enterprise 64 and 128 had an IS-BASIC interpreter which was very similar to ANSI Full BASIC (with optional graphics module) and used about 16Kb of memory.

Decimal BASIC is an ANSI Full BASIC interpreter for modern machines with the option to translate to FreePascal for compilation.

ANSI Minimal BASIC is similar to Microsoft’s BASIC-80 aka MBASIC. I’m guessing an interpreter would fit in 8Kb or so.

I don’t have any plans to support machines with less than 32Kb as Minimal BASIC would probably use half the memory of a 16Kb computer, but others could try if they needed that option.

1 Like

I wonder if it’s useful to look at this as being about a single-load game image - not necessarily for tape-base systems, but ruling out any overlays, paging, or swapping which might be practical with disk but impractical with tape.

So, a single-load image which can run on a 32k machine - that is quite a constraint, but not an unrealistic one. It does feel to me that a well-designed domain specific language will be the way to go, and quite probably it would run on a suitable virtual machine with an appropriate instruction set. That would be a way of trading speed for density.

But you have to start somewhere - you might start by trying to design something universal and then implement it. Or you might start by designing and implementing something fairly specific, and learning from that, to make a revised design which can target more platforms.

One thing about analytical people, is that they will always be able to find ways in which things might not work, or ways in which things might do slightly more. You’ll always get criticism that your idea doesn’t do enough, or doesn’t do it the right way. I think getting started is the way to go, and not to worry about a big audience or a commercial success. Those things can come later, once you’ve got an approach that works. And similarly, for attracting collaborators and testers.

2 Likes

Being too analytical is probably a good way of not starting at all. Also, a first go with more specific requirements may give you a better idea of what may be actually needed for a more general approach – and, on the other hand, what may be things that you thought to be show stoppers, but are actually not much of a worry.

(On the other hand, if it’s about authenticity, the analytical approach is the way to go. I’m under the impression that a typical home computer project consisted of a variety of detailed, still dreamed up and mocked up screens and states, but not that much of code to make this actually work… Of course, we knew how we would implement it (sort of), but, at the end of the day, it may have been more the heyday of UX design than that of programming. :slight_smile: – The lesson learned may be that it may be more important to come up with a system that actually allows you to implement some, rather than devising the perfect system.)

1 Like

With this in mind, I’d like to return to my BASIC to BASIC suggestion. I just feel like it could be easier to “get started”.

Starting with BASIC skips a lot of language design decisions. The source code language could be, for example, a slightly modified BASIC V2 (replace line numbers with freeform labels, support long variable names, and trim away some of the less needed commands).

For me, starting with BASIC V2 is natural since I know that one like the back of my hand. But whatever you’re most familiar with will work just the same.

To start off with, the process of saving to a target BASIC might be simplified by using copy/paste to emulators. Most (?) emulators support copy/paste of text to keyboard input. So, your BASIC to BASIC translator doesn’t need all the details of how the target system saves program files. You just copy/paste into the target system emulator, and then save the program from there.

My point is - you get something working, without having to work out all the details of saving the program file.

Obviously BASIC to BASIC gives up on the idea of obtaining higher performance than the default installed BASIC. But I think it’s fine for portability. And I think it’s good for ease of “getting started”.

It depends. E.g., if Will Crowther’s Colossal Cave is your preferred starting point, porting the original FORTRAN code to C is actually easy (and C versions are readily available). And you have already a rooms & interactions engine ready to start with…

Porting FORTRAN to C using a pattern like the following is quite straight forward…
(I actually did this once in JS. To be fair, the dwarves are a different story.)

int label = 0;
while (label >= 0)  {
   switch(label) {
      case 0: /*code until next label, if, goto, etc */
           label = xxx; break;
      case xy: …
   }
}

and this already compiles to native code. Now you’ve only to tag on any code for character translation and I/O… (Of course, for any I/O, you’d have to leave the loop and take note of the reentry label, but this should be straight forward, as well.)

Recreating this code in a minimal BASIC subset may be a lot more of a challenge.

1 Like

I’m not entirely sure what you mean by this. PunyInform and Ozmoo are absolutely working to make themselves as small as possible, and each advance in this helps your resulting z3 file fit on tape. And Ozmoo online will let you easily build a C64 tape image from your z3 file that you can load onto a real CBM machine and play.

The “Puny Build Tools” you’re referring to are a third-party project by the author of some PunyInform games. He personally targets disk-based systems, and ships media for a wide variety as collector editions mimicking the grey-box Infocom releases. But that’s not PunyInform itself, and you don’t need to use his support infrastructure to write PunyInform games.

I think it still would be some sort of emulator. No need for BASIC at all.
You “just” have to write an emulator for every computer and define a standard including i/o, then you’ve got it.

A tape-based style would be good to load another room. So you can even include the computers with very few RAM.

Interesting would be a DUAL version to choose an original game (with original colors and fonts) and a compatible, versatile game. Or a converter for existing games.
But it’s a lot of work.

One thing about Minimal BASIC that makes it less than ideal for interactive fiction: it has no string functions. At least, the version described in ECMA-55 has no string functions.

Looking across your three machines’ BASIC interpreters:

  • Dragon BASIC is a fairly typical Microsoft offering with the expected string functions. (This is just as well, as a few of my friends wrote and sold BASIC text adventures for the Dragon while we were at school);
  • Sharp MZ BASIC, though not from Microsoft, looks a lot like Microsoft BASIC and does the MID$() etc. thing. (Just look at this glorious manual, though: SHARP MZ-80 SERIES BASIC - a work of art from the front cover on);
  • Enterprise BASIC uses string-slicing, because ANSI/ECMA-116: BASIC does. Compatibility functions could be written. (Props to the manual authors for including my favourite un-limerick).

Maybe you could get quite far with a common or translatable subset of BASIC? For all the newer computers, the code could run under the very portable PC-BASIC.

1 Like

@EdS The need for a single load game image is one restriction, yes. There also has to be the option to load and save data via tape, so that players can use save and restore their progress.

I wouldn’t use BASIC on a tape-based machine that didn’t have that option.

A DSL was my first idea. I had doubts about creating yet another new one though, so I started looking into A-code (the Platt/Arnautov version) with the idea of using it with an existing 8-bit C cross-compiler.

After consulting with Mike Arnautov, we found that due to the current implementation’s dynamic nature, it would not work on 8-bit systems in its current state.

He suggested trying to convert Platt’s original version - which was written in Fortran - as it was designed for older computers and used a virtual machine system (not unlike Level 9’s A-code system).

Whilst looking into that option, I had the idea of adding a BASIC front end to make the system more useful for other text-based programs.

@IsaacKuo I considered a BASIC to BASIC converter - possibly converting the BASIC tokens between machines - but abandoned the idea after finding existing software like ugBASIC and ACK that produce compiled programs for 8-bit computers.

@spacehobo Unless I’m missing something, Ozmoo only works for the CBM64 and similar computers. There seems to be an Acorn port written by someone else, but that’s it as far as I could see.

The reason I mentioned the Puny BuildTools is that they used to work with multiple 8-bit systems, but they seemed to have dropped support for some of them when the name was changed.

Either way, it seems to me that it would require a lot more effort to add new tape-based targets to a system that was originally designed to work with a disk drive than it would be to add them to something like DAAD.

Level 9’s A-machine is much closer to what I need than Infocom’s Z-machine.

@mainframetom An emulator is basically a virtual machine that is based on a real computer.

@scruss Yes, Minimal BASIC seems a little too minimal, but it is a starting point.

It could potentially be expanded using features from Full BASIC to make it closer to what was available on early 8-bit home computers rather than restricted to what was available when Dartmouth BASIC was first devised.

My main criteria for creating both versions would be that they are based on some existing standard (that is tried and tested) and that they would seem familiar to anyone who has used an 8-bit home computer.

I guess the main differences between the two versions would be that one is structured and one is not.

1 Like

However, there are other incompatibilities lurking, e.g., Sharp MZ BASIC uses addition and multiplication for logical OR and AND. So

IF (E=1) AND (F=2) THEN …

is in MZ BASIC:

IF (E=1) * (F=2) THEN …

Meaning, you’d have to do without any locgical conjunctions and disjunctions, yet another burder for any parser.

After considering the posts here and the results of my own research, I have come up with a possible route to take:-

  • Install ACK and experiment with it for a while
  • Add a couple of new Z80 computers
  • Add the Dragon 32 as a 6809 computer
  • Add a structured version of BASIC to the existing languages
  • Add a DSL to the existing languages
  • Add a standalone VM for a Z80 computer to the back end
  • Compare that VM against compiled programs for that platform
  • Add new VMs if there is an advantage to doing so

The first two steps need to be done in that order, but I can probably take a “suck it and see” approach to the rest.

The main reasons I decided to use ACK is that it already does a lot of what I want, and it’s a tried and tested toolchain with an existing (simple) BASIC front end.

It is also already used by programs such as CROSS-LIB, so any additions to ACK could benefit those too.

David Given (the maintainer of ACK) is currently working on a ZX Spectrum compiler configuration, so that should be a good reference.

He also implemented most of a code generator and interpreter for a p-code system a while back, so that might also help if he can find the code again.

Can anyone see any obvious flaws in my outline or suggest any additions to it?

1 Like

I had never seen that MZ-80 BASIC manual before, well never owned a MZ-80, but I had MZ-700s and MZ-800s, and yes indeed the manual is glorious – and now I understand the Greek ship present in many of the demos!