Friday, 21 August 2020

OpenROMs Update

Howdy folks,

Feral Child has been working through the European summer heat on the OpenROMs (our free and open-source C64/C65 ROM project), and has the following update for our reading and viewing pleasure:

---

Hi there! It's been a while since the previous Open ROMs update, time for a new one!

I'll start from not-so-good news - I'm running out of ROM space. On the stock C64 the Kernal + BASIC has to fit within 16 KB total; with the original C64 ROM set there are very few bytes left, and the code is already space-optimized most of the time. That means, if you reimplement the firmware (or mod the original one), it is very hard (or even impossible) to add any significant feature without removing something else. This is already clearly visible - for unexpanded ROM it is no longer possible to enable all the features the Kernal replacement offers, also there is not that much BASIC ROM area left. For example, I had to disable the built-in tape head alignment tool for the default build:

https://vimeo.com/425935795

Fortunately, lack of space is not a problem on the MEGA65 - it has an abundance of extra ROM, which can be mapped anywhere in the C64 address space with 8KB granularity. Also, the Ultimate64 community started an interesting effort - additional Kernal ROM banks. Although the concept is quite different from what MEGA65 does, it should still be possible to take advantage of this extra space in the future.

So, what takes so much space? The official Kernal API is nearly complete at this moment, but feature-wise... it is now able to utilize two most popular drive mods: DolphinDOS and JiffyDOS (but the latter protocol is not fully implemented yet, LOADing is not as fast as it could be - but still much faster than with standard IEC transfer). Additionally, there is tape support - limited to loading programs, but can read both the standard format and TurboTape64. The turbo-saved files can be up to 250 blocks long (not all the implementations can read such a large chunks of data), and there are raster and sound effects (with normal format only raster effects are available - it uses such a long pulses, that for now every attempt to add SFX resulted in a very low buzzing sound, probably dangerous to the speakers in the long run). And that's not all - normal/turbo formats can be autodetected, you don't have to worry about special syntax to select the proper loading routine. No turbo implementation I know is able to do this!

BASIC also saw some work, although it still needs more effort before it is really usable. Besides various reworks and speed improvements, at last we have some variable support. For now only strings (including TI$, string arrays are mostly functional too!) - although some floating point routines are already written, they still need more testing, and are not exposed as variables yet. The expression parser (code that interprets mathematical expressions, including brackets and operator precedence) is already written too - for now it can be used to concatenate strings.

Our string handling is a little bit different than C64 one. Microsoft BASIC interpreter has a mechanism called garbage collector, which is triggered once there is so much garbage (obsolete strings - replaced with different ones, but still kept in memory), that it isn't possible to allocate any more memory - the original mechanism (used in PETs, VIC-20, and C64) is very ineffective (square computational complexity), the C64 can freeze for half a minute before the process is complete. Starting from CBM-II and C16/C116/C+4, an improved algorithm was implemented - much faster, but requires additional 2 bytes per each string, a so-called back-pointer. Open ROMs contains a similar mechanism, although it differs in details (there is no magic value to denote a temporary string). You can read more about these algorithms here:

https://www.c64-wiki.com/wiki/Garbage_Collection

Open ROMs has one more improvement over the original memory handling - the Commodore C64 ROM displays '38911 BASIC BYTES FREE' message on the startup banner, despite the machine having 64KB of RAM (not including the colour memory). 38911 is much less than 64KB - but this was done for a reason. First, the ROM needs some memory for itself, to store screen content and some other stuff - this takes away 2KB. Second, some of the RAM cannot be easily accessed by C64 BASIC, as it is hidden 'below' the ROM or I/O area. Old builds of Open ROMs displayed '61438 BASIC BYTES FREE', as they contained a specialized code (helper routines, which has to be copied to RAM) to access nearly all the C64 memory. But this code has two drawbacks: it is much slower, and utilizes some RAM which normally can be used by applications or games - which might easily lead to compatibility problems. Therefore, at some point I have disabled this mechanism (but it is still there, and can be enabled on custom builds) and implemented the C64-like behaviour. But now the default Open ROMs build displays '51199 BYTES FREE':

because we have another 'memory model', which is able to use RAM hidden below the $A000-$BFFF BASIC ROM - which can be accessed relatively cheaply if the memory access routines are placed in a high ROM area, $E000 or above. It does not use RAM below the I/O or the $E000-$FFFF ROM - it is harder to access safely, as one has to redirect the interrupt handlers back to the ROM. I hope this will remain as a default memory model for MEGA65 build - I'm not sure about the generic C64 one, as the required memory access routines need some extra ROM space.

That's all for now - let's hope not much will be found broken once I start testing the Open ROMs with the upcoming DevKit!

3 comments:

  1. I thought that the C64 ROM and Kernal was 16K and 4K was for the character ROM? Meaning 20K in total? Or have I read that incorrectly.

    ReplyDelete
    Replies
    1. On the C64, that is the case. The C65 and MEGA65 uses a 128KB ROM.

      Delete