A-code on 8-bit machines

Continuing the discussion from A-code documentation:

A misunderstanding, I think. Internally, as currently implemented, an A-code game’s data structure consist of of just two large arrays. One is a byte array, holding all texts and descriptions, which are referenced by offsets into that array. The other is an int array, holding all information on game entities, which are referenced by offsets into that array. Entity descriptions are stored in the data array simply as offsets into the text one.

Yes, the A-code engine does cater for memory saves with SAVE MEMORY and RESTORE MEMORY commands. Using it creates yet another copy of the data array, of course. So there are up to three copies of that array. The current game one. The one created by RESTORE FILE for checking the integrity of the game dump. And the one used by SAVE MEMORY, if that is used.

Not knowing anything about z88dk, I am in no position to argues. Nevertheless, I would like to implement any necessary 8 bit tweaks into the main engine, if at all possible.

As I understand it, the main barrier to using the existing A-code system to produce code for 8-bit systems using modern cross compilers is the lack of memory on the target platforms.

Storing the same data in multiple arrays is not an issue for modern computers, but it would severely reduce the potential size of games on machines with 64Kb RAM or less.

Loading data from a separate file would help, but that would not be possible on some machines, due to a lack of support for file i/o in some compilers for those machines.

I’m not sure how practical it would be, but it could potentially save a lot of memory if even the location description data was converted to C switch statements which assigned the text to a single reusable string instead of an array.

It has been more than a few years since I used C, but something like this:-

switch (room_number)
{
  case 1:
    room_description = "You are outside a small brick building."
    break
  case 2:
    room_description = "You are by a stream."
    break
  default:
    room_description = "You are in limbo. Something has gone wrong."
}

I probably have the syntax wrong, but hopefully you get the general idea.

Sorry, your switch example makes no sense for A-code. Rooms in A-code are not and cannot be identified by numbers. They have arbitrary names. These names are converted into numbers by the translator and it is the derived C code that uses numbers as entity identifiers. You seem to be conflating A-code source and the derived C source. So e.g.

place building.front
  You are outside a small brick building.
place by.stream
  You are by a stream.
place limbo
  You are in limbo.

The A-code source refers to these places by their names or via named variables currently referencing relevant places. The translator assigns numbers to all such names names and spits out C code where places (and other entities, such as objects, variables or texts) are referenced by numbers. The descriptions are all placed as consecutive byte sequences into the byte text array, which is either dumped into a file or pre-loaded into the executable (together with all other bits of game texts). The C code knows the relevant offsets and accesses those description by their offsets into the text array. If the text array is written off into a .dat file, the C code will either read those descriptions from the file as required, or will implement a requested number (up to 32) of 1KB buffers to use for paging the file contents.

The example was meant to be for the resulting C code, not the A-code that produces it.

How the A-code is written shouldn’t matter to the target machine, so it could stay as-is. I was suggesting that the output C code be adjusted so that there is less duplicated data stored in memory.

Now I am thoroughly confused. I thought you were asking me whether A-code implemented a SWITCH statement, so why give me an example of using switch in the derived C code? It makes no sense anyway. The acdc translator organises entities (such as locations) and their corresponding texts into text and data arrays, as I’d explained – ready for use. There is nothing for the C code to initialise.

Initially I was asking about a switch type statement in A-code, assuming that would be translated by acdc to an actual switch statement in the C code.

You then replied there was no switch equivalent in A-code and that data was stored in arrays in the C code. My example was to illustrate how the A-code data could be translated to switch statements in the C code instead of using arrays.

It has been around 30 years since I wrote any C code, but my understanding of how arrays work is that memory space is allocated for the data in the array and there is also additional code to assign values to that memory space.

This means that the data is in memory twice (once in the array and again as assignment code). Loading the data from a separate file would solve this problem, but as I mentioned before file i/o is not currently available for every 8-bit platform that modern cross-compilers support.

Creating a single variable large enough to hold the longest string you intend to use, then adding a switch block with a case to assign each value as needed, would use just over half the memory space of an array.

Unless I’m misunderstanding how C arrays and switch statements work after being compiled to machine code.

The acdc translator already has the complete contents of the texts array, so spits out a static declaration of it. Thus the array contents is already there, written into the compiled/linked executive file and ready to be read from the file into memory. Just how a loader deals with the resulting executive, is up to the loader on the target system. Can’t help with that.

I’ll have to do a little experimenting and research, when I can find the time.

C has never been my favourite language, but if acdc can be modified to work with z88dk it should be able to produce games for over 100 Z80-family machines.

If it could produce code compatible with Cross-Lib it should work on even more.