NEWS, EDITORIALS, REFERENCE
Updates on C64 OS, Beta 0.8 and 0.9
Hello folks and welcome back to another blog post on C64 OS. I've got so much to talk about, and no time to talk about it.
How about the elephant in the room first? It's May of 2022, and I haven't made a blog post since December of 2021. What's more, I said the next blog posted would be the follow-up part 3 of my exposé of VIC-II timing for an FLI routine I disected, commented and figured out from Codebase64. But this blog post is not that post. Has C64 OS development stalled? What happened, where am I at? Why the silence?
The good news is that, it's basically all good news! I have been developing like a cross over between a cave troll and a 6502 code producing machine, that's powered by coffee beans. And whenever I'm not coding, I've been discussing things with my beta testers, designing a new logo, overhauling the /c64os/ subsite of c64os.com, and writing the online version of the C64 OS User's Guide. The only bad news is, I simply haven't had time to write the lengthy and detailed blog posts that I like to write. What's more, the last blog post I was working on, that is only maybe 25% written, is a long, detailed, technical piece that requires a lot of work. And every time I sat down to think about working on it, I realized that I've got a mountain of work in front of me to get C64 OS ready...
So this blog post—I don't know how long it'll end up being—is here to give you an update on all the stuff I've been working on, to make some announcements and to show off some things that are coming.
Get C64 OS Ready... for what?
If you're on Twitter then please follow me there, @gregnacu. Twitter is the opposite of my blog where I talk and talk, but its briefness makes it lightweight and easy to tweet out photos, short videos, and one sentence updates every few days.
My goal is to have a physical release of C64 OS version 1.0, ready for sale, this summer. I don't want to be more specific than that, but I can tell you that I'm busting my balls to get everything done that needs to get done and that I want to complete for the initial release.
Although it was mentioned on Twitter, because people have been asking, you can consider this blog post to be the official announcement that C64 OS is planned for release for summer 2022.
Updates to the website
I've got a ton of updates to C64OS.com that I've been working on. But I haven't uploaded those changes quite yet. I'd like to give a little peek into the changes I've been making before the big upload though.
When C64OS.com began it was a single page. The buyer's guide ran down the left sidebar, an explanation of why I was bothering to do this was at the top, and blog posts appeared, in their full text, in the middle. As the site grew, it got split into the sections it more or less has now. But it was worded around being "a project," and a hobby. Something I was working on, and learning from, and tinkering with, and a finished product was way off in the distance.
Since then, I've finally rounded the bend, and I think I have something that is quite nice, and with sufficient functionality that it can already be useful as it is. And that's not even taking into consideration what is available at a technical level to make this a great platform for developing new C64 software. The tinkering, hobby project has entered into the home stretch phase towards a product that can be shared with the world. There are a few things that this means.
For starters, I can't use the Commodore logo! It's probably fine for a fan website with a blog by some nerdy rando on the internet. But it's not fine for a commercial product. So I've come up with a new official C64 OS logo, that will replace the Commodore logo on this site, and in all the documentation, and other official stuff like print material.
I want to offer a huge thank you to Kroc Camen, whom I met on Twitter and who subsequently became a beta tester, and who offers me helpful design tips, both for visual things like logos and for bouncing technical ideas around. If it weren't for his input on this logo, mine would have ended up looking like a certain vulgar male body part, scrawled on the inside of a bathroom stall at a drunken Commodore demo party.
There is a vague recollection of the ol' chicken lips, and a mild similarity to the American flag. The main bits are in high res, but the 64 retains its pixel version that is proportionally identical to the full 8-bit version. In sum, I like it a lot. Here are some 8-bit versions of the logo, embedded in some "Made for C64 OS" badges. The new logo appears on the boot screen starting in beta 0.8.
Next, I've updated the heading font used throughout the site. I've switched from Blue Highway, which was, okay, but a bit too narrow for my tastes, to Outfit, which I'm really diggin'.
Where the welcome page's introduction text used to be about the project, and the blog and so on, the new welcome text introduces people to what C64 OS is, what it can do for you, and has some cool looking screenshots, and messaging that you can purchase a copy of C64 OS right here on C64OS.com. Here's a side-by-side of the two, old and new.
The headers of the inner pages are also cleaned up, using the new font, spaced better and with the new C64 OS logo. Here's a side-by-side of those, old and new.
The /c64os/ subsite of c64os.com has received the most attention.
- The main page has been spiced up, in prep for being able to take orders.
- The Getting Started guide has been made into its own page, like every other guide.
- The User's Guide has 9 chapters, plus an Appendix. (8 of those chapters have been written.)
- A new "legal" section in the sidebar replaces a one-liner that used to sit beneath the top menus.
- Sidebar links to 9 important user manuals for Commodore 64 storage devices.
- Lots of new marketing-style graphics have been added.
I particularly like this one:
Updates to C64 OS
I've been putting out betas to the beta testers, and each new beta release gets us closer and closer to a fully usable product.Beta 0.6, File Utilities Release
Beta 0.6 extended the capabilities of the File Manager with a suite of supporting Utilities: Scratch, Copy, and Move for recursively copying and moving whole directories and their contents between any two places on any two devices, simply by putting two tabs at different places, selecting some files and subdirectories in one tab and choosing "File → Copy To → Tab X" from the menus.
The File Info Utility was also included in beta 0.6, allowing the user to rename files, duplicate a file in the same directory with a new name, lock and unlock files on devices that support file locking, and view the date/time, file type and size metadata of a file. New classes and libraries were added to make these Utilities work.
Beta 0.7, TextView Release
Beta 0.7 was the first release where I knew that the end was in sight. The list of features I wanted to include in the version 1.0 release was finally becoming short, specific and manageable.
This release introduced the TextView Utility, a quick way to view text files, and other text-based data files, such as those used throughout C64 OS for settings and menus and more. TextView is backended by new libraries and the Toolkit class TKText, which together support a new lightweight text-markup language for C64 OS called MText. I demoed this version of C64 OS at World of Commodore 2021, and the last blog post was specifically about this, Text Rendering and MText.
Beta 0.7 also introduced the Clipboard Utility, for previewing the contents of the clipboard, and makes use of another Toolkit class, TKFileMeta. The TestGround Application was also completely overhauled—and I'm going to open-source this one—to showcase a bunch of Toolkit classes; show how they're created and wired up in code, etc. The App also includes the source code for a custom Toolkit class that is included in the TestGround's App bundle. This shows how to create a custom subclass, and how to source in and link custom classes that are stored in your Application's bundle.
Beta 0.8, Penultimate Beta Release
Shortly after World of Commodore, I went into a prolonged and highly productive full-bore development phase. Beta 0.8 was not released until mid March. But it was a doozy, bringing C64 OS significantly closer to the v1.0 release. I decided to call this the Penultimate Beta because I'm currently working on beta 0.9 but I believe that everything I'm going to fit into the v1.0 release will be written and released in the 0.9 Beta, the ultimate beta, making 0.8 the penultimate beta.
Beta 0.8 included 5 new Utilities, 3 new libraries, 3 new Toolkit classes and some major upgrades to a 4th Toolkit class. Let's briefly talk about some of these.The Mouse Utility
C64 OS includes a first-run configuration tool, a program written in BASIC to be run from the READY prompt shortly after installing C64 OS, before you boot for the first time. It offers options for configuring mouse settings, among other things necessary to make C64 OS work with the hardware you have. As you walk through the Configure tool, it writes your selections into a series text-based settings files stored in the system's settings directory (//os/settings/).
The Mouse Utility uses the Toolkit to present the options for configuring the mouse settings from within C64 OS. What's nice about this is that you see the changes in realtime. You can play with the mouse pointers, and their inner and outer colors, and get immediate feedback about how they look. You can adjust the tracking speed and double-click speed and test them out immediately. The Utility writes the settings out to the same settings file that the Configure tool does, but it feels a lot more real to have this within the OS itself.
The Time Utility
Beta 0.8 also added the Time Utility. It shows four tabs and makes use of 3 new Toolkit classes, TKDatePick, TKTimePick and TKTimer. TKTimer is the class that shows those double-high characters, and it can be put in two modes, either stopwatch or timer. They're similar. The stopwatch just counts up forever, and when reset it goes back to 00:00:00. The timer has a reset value, that can be adjusted by clicking the top and bottom halves of the components, and then it counts down to zero, and resets to its current reset value.
The Time Utility also lets you configure settings related to the clock and time throughout C64 OS. Just as with the Mouse Utility, these things can be set using the first-run Configure tool from BASIC, but it's a lot cooler to see them adjusting in realtime from within the OS itself.
In this release, setting the RTC from the clock tab was not yet working. And the timer counting down to zero was just doing a system alert, i.e., the screen border blinks twice.
The Opener Utility
The Opener Utility is, in my opinion, a pretty big piece of the puzzle. The Opener let's the File Manager open documents in another Application or in a Utility. Opener introduces the mechanism that assigns an Application or Utility to be the opener for a data type. A file's data type is identified by a combination of its CBM file type (PRG, SEQ, USR, REL) and its filename extension. An extension can be 1 to 6 characters long, and can be either postfix (following a dot at the end of a filename) of prefix (preceding a dot at the start of a filename).
If you double-click a file in File Manager, the Opener Utility opens first, but it doesn't necessarily show (or even build) its UI. It first analyzes the file and looks for an established assign. If there is such an assign, it runs that Application or Utility, passing it a reference to the file to be opened. If no such assign exists (or, for example, if the file has no filename extension,) then Opener presents its own UI, shown below.
You can then pick an App or a Util, and you can either open this file one-time only in the selected opener by clicking Open, OR, you can assign the selection to this file type to be used in the future by clicking Assign.
Opener can also be used, by opening it manually, for modifying existing assigns.The Places Utility
The Places Utility also made its debut in this beta release. In File Manager you can choose from the Go menu from a set of standard places to jump directly to: Documents, Games, Music, Pictures. These can also be triggered with the unmodified function keys: F1, F3, F5 and F7. Each one accesses a corresponding file in the system settings directory that holds a file reference defining where that place is.
Prior to the Places Utility it's been possible to manually set these files using commands in BASIC. Something like this:
open2,8,2,"@//os/settings/:music.path.t,s,w" print#2,"8:7:://hvsc/musicians/"; close2
But now you can copy and paste places from File Manager into these fields, and configure these standard places from within C64 OS.
The Date Utility
This beta also introduced a new Utility called, simply, "Date". Since I'd already written the TKDatePick and TKTimePick classes, I thought this would be a useful way to put them to work.
If you want, of course, your Application can make use of the date and time pickers directly. But that might be a bit overkill. If you just want to take a date or date-time, it requires a lot less code to open the Date Utility. It can be configured to show or hide the time picker and whether it should show a custom date or default to now.
Make an adjustment and hit the little arrow button. A message is sent to the Application with the specified date and time. The Application could then tell the Date Utility to close. As I said, it takes less code to procure a date/time using the Date Utility, but if you want to directly embed the date and time pickers to get more control, you can do that too.
The Date Utility is also integrated with the clipbooard. You can copy and paste dates (datatype text/date or text/datetime). I like this because it starts to extend functionality across different Apps and Utilities. Copy a date from the Date Utility, paste while the Today Utility is open to have Today jump the calendar straight to that date. Love it.
Oh, one other neat thing about the Date Utility. The TKTimePick class supports both 12 hour and 24 hour modes. The Date Utility pays attention the preferred 12/24H mode you've set using the Time Utility and configures the TKTimePick for the same mode.The Places Library and TKPlaces Class
Another major piece that got put into place in beta 0.8 is the sidebar of the File Manager.
The File Manager's UI is made up of a vertical split, with a left and right half. The right half has the 4 tabs, with an optional path bar above it and an optional info bar below. Then within each tab is a table with resizeable columns for the directory listing.
The left side of the split is taken up by a single custom class, called TKPlaces. TKPlaces shows the list of detected devices at the top. It pays attention to messages about changes to the detected devices table, and dynamically updates this list if you change the drive configuration using the Drives Utility.
This section can be folded or unfolded and integrates with the File Manager for navigation. As you switch tabs, the checkmark moves about to indicate which device the directory you're looking at comes from. Clicking on a device, meanwhile, opens the root of that device in the current tab.
All of this functionality has been working for a while now. But back when I gave the demo for Commodore Users Europe in June of 2021, and even at World of Commodore in December 2021, the bottom half was just a bunch of placeholder content.
As of beta 0.8, TKPlaces is now fully functional. There's a header on the bottom half, you click that header to toggle between a list of "favorites" and a list of "recents." Both lists can have up to 15 items. A menu option in File Manager lets you add the currently displaying directory to the bottom of the list of favorites. This can be to any device, partition and path, or even the partition directory of a device. Click that favorite at any time to navigate back to that place.
Recents are a little bit more advanced than favorites. Whenever you open a file either by double-clicking or by choosing File → Open, it pushes a file reference to that file to the TKPlaces class (which backends on the places library) to save as a recent. New recents get saved to the top of the list, and existing recents get bumped down the list. Anything that would end up in position 16 gets removed from the list. Clicking a recent takes the File Manager's current tab to that place, selects the file, and scrolls it into view if necessary.
All the under-the-hood file management for favorites and recents is handled for you. Favorites are global, common to all Applications, so the table of favorites is stored in the system settings directory. The file references associated with the favorites are stored in corresponding files in a favorites subdirectory of the system settings directory.
Recents, again, have something a bit more advanced. The table of recents is maintained on a per Application basis. So, if you open a file directly from File Manager, that file reference is added to the recents that are stored inside File Manager's own Application bundle.
But wait, what does it mean that favorites are global but recents are per Application, if it's File Manager that is used to open files? ...
What's being worked on for beta 0.9
That final question above, takes us to what's already been developed for beta 0.9. Beta 0.9 hasn't been released yet, because several things still need to be completed for it, but I'll mention a few things that have been completed.The Open Utility
The great beauty of an operating system, UI frameworks, Toolkit classes and shared libraries is how much of it can be reused in different contexts. It took some serious effort to get File Manager and all its various parts working. It took significantly less time to get the Open Utility written and working. Granted, the Open Utility is simpler than the File Manager, but it nonetheless benefited from being able to reuse tons of code, in neat modular ways.
To start with, the common Toolkit classes: The Open Utility has a vertical split. In the righthand side, there aren't four tabs, but there is path bar and a table. And the table itself is composed of numerous classes and subclasses of classes. The ability to load in the directory and sort it, depends on several shared libraries. And finally, there is the TKPlaces class to the left of the split.
TKPlaces was originally written as a custom class to provide device navigation for File Manager. It's quite complex; it resizes horizontally and vertically, it handles devices and the list of devices can vary in length. That section can be folded up. The devices show little icons, the device number, the name of the device type, a checkmark indicator and has custom hit-testing. The bottom section gets even crazier. It embeds a TKScroll view, which embeds a scroll bar and a TKList view. A dynamic header that can be used to toggle between lists. This then backends on the places shared library which TKPlaces dynamically loads and unloads. It gets messages about files being opened, and manipulates a table to hold the list contents, and also maintains a set of corresponding files with the file reference data for the items in the the lists. It does lazy loading on the list content to conserve memory. And it remembers its state. So if you were showing favorites last time, it loads favorites when it reopens, and doesn't load in recents unless and until it needs them.
To get all of this functionality, the Open Utility needs just a few lines of code to load and link the class, to instantiate an instance of the class and append it to the split view. It then needs a few more lines to integrate its behaviors into the Utility's main logic by calling some of the TKPlaces' methods, and supporting a few callbacks. Reusing the TKPlaces class is orders of magnitude easier than it was to write it and its supporting libraries in the first place.
I haven't got any good screenshots of this yet, because I haven't installed the latest beta on my Ultimate64 (which is freakin' fantastic for screenshots, by the way, with VIC Streaming over ethernet in pristine digital quality.) But I recently posted this brief video to Twitter showing the Open Utility in action.
Here’s a little video showing the Open Utility is now fully functional. And it’s integrated into App Launcher to let us change backdrops and add new alias to the desktops. #c64 Recents and Favorites are working now too! pic.twitter.com/An7s528Xbd— Gregorio Naçu (@gregnacu) May 13, 2022
SIDPlay library and Time Utility
Recall that in beta 0.8 the Time Utility made its appearence. It's pretty cool; it's got lots of features. But when the Timer struck zero, it did something rather short, simple and easy to miss. It just called a system alert, which blinks the border twice. If you're not looking at the screen it goes by in about half a second. What's more, there are many other things that can trigger an alert. For example, if you press a key combo that propagates through the layers but never gets handled by anything, the default behavior is to trigger an alert.
When I sent out beta 0.8, it wasn't my intention that doing a system alert was what the timer timing out should do, I just hadn't had the time to figure out how to do something better. But when beta 0.9 comes out, and in the version 1.0 release, it does something quite a bit cooler. It now plays a SID tune, and you can supply your own.
Playing SIDs is not like playing a PCM Wave file. A SID is not just data, it's code. Each SID tune contains within it the data plus the player program. You can't just have a generic player, because the players enable support for effects that are only possible by manipulating the SID registers in unique ways. I'm no artist, but my understanding is that the great SID musicians of the past wrote their own playing routines in order to accomplish the sound effects they wanted, which they were dreaming up out of pure creativity.
SID music typically accompanies the piece of software for which it was written. For example, a tune like the Commando theme song by Rob Hubbard was written to be played while the Commando game is in memory. The game developer and the musician could simply talk to each other and negotiate the details; how many songs are needed, how much memory will be available, how much raster time is the tune allowed to steal, what zero page addresses may be used, whether an NMI may be generated for playing embedded digi samples, and so on. But if you simply rip and collect a pile of SID tunes from random sources, different games, different demos, etc. you get SIDs that were written to all use different machine resources. This is, in short, what the High Voltage Sid Collection is. It's over 55,000 SID tunes, from 55,000 different sources!
Inside the context of an operating system, this makes supporting SIDs problematic. Zero Page is at an extreme premium. There is a dynamic memory allocator, and most things (drivers, classes, libraries) strive to be relocatable, specifically so that they can get plugged in wherever the allocator can find some space, on the fly, without knowing in advance what else is going to be in memory.
The SID Relocator "sidreloc," by the extremely talented Swedish programmer LFT, is essential to being able to play SIDs in C64 OS at all. It's not perfect, it doesn't work for every single SID, especially given the constraints that C64 OS imposes, and even relocated tunes sometimes can't be loaded. But it's pretty good, and I'm not complaining. I'm super stoked that it all works out as well as it does.
C64 OS reserves 4 consecutive zero page addresses, just for SID music, which is enough for 2 pointers. Some SIDs require more than 4 ZP addresses, but a great many don't need more than this. SIDs must be relocated to use these and only these ZP addresses, otherwise the tune risks trampling on Zero Page used by other parts of the OS and it will surely result in a crash of beautiful colors. Where in main memory the SID gets relocated to, and how long the SID is, are somewhat flexible, but some address ranges are better than others.
The essential C64 OS memory map reserves $0000 to $08FF as workspace memory for variables, tables, buffers, and so on. $0900 to somewhere way up high like $8100 (it varies slightly depending on the hardware you're using) is heap memory. The C64 OS KERNAL runs from the end of heap memory to $CFFF. $D000 to $DFFF is used both for I/O and for VIC-II screen and buffers and some other stuff. Then $E000 to $FFFF is used for Utilities, bitmap graphics and mouse pointers, as well as the C64 KERNAL in ROM of course.
An Application's main binary is hard-assembled to $0900 and up. A Utility's main binary from $E000 and up. When an Application's main binary is loaded in, the space it took at the bottom of heap gets marked so the allocator knows it's not free. Once these main binaries are running, they make dynamic allocations and load in numerous relocatable components from remaining heap memory. Heap allocations are made from the top down. That is, if an Application loads in a 2-page library, the allocator finds the first 2 consecutive pages of memory, starting from $8100 (or thereabouts) and searching downwards towards $0900. In practice, this means the last memory ever to be allocated, and the memory most likely to be available at any given moment is that which immediately follows the Application's main binary.
We don't know precisely how big the main binary will be, it varies. However, if a SID starts at $2000, that leaves $0900 to $1FFF, which is $16FF or just shy of 6KB for the Application's main binary. 6KB is a lot. And because everything in C64 OS (so far) has been developed natively using Turbo Macro Pro, it's been my experience that it can't really handle the quantity of code necessary to assemble a binary that large. Even the File Manager, which is quite featureful, does not have a 6KB main binary. The reason is because large swaths of its functionality have been carved off into reusable shared libraries, toolkit classes, and other dynamically loadable/relocatable components. Therefore, while not strictly necessary, in my opinion, the best place to relocate a SID to (for use in C64 OS) is $2000.
The SIDPlay library supports one SID tune being loaded at a time. If one is already loaded when a call is made to load another, it stops the first from playing, and unloads it. Then proceeds to load in the next. It starts by loading in the PSID headers (the format used by HVSC and sidreloc). The headers specify where the tune will start in memory, combined with the length of the file, tells the library exactly what block of memory the SID needs to occupy. It then refers to the memory allocation table directly to see if that block is free. If any part of that block is not free, there is nothing it can do but return a failure code. But if that block is available, it uses the pgmark KERNAL call to mark it as taken, and then proceeds to load the rest of the SID data into that area.
The SIDPlay library hooks itself into the standard IRQ service routine, and calls to play, pause, stop playback, and select which song to play of multi-song SIDs, is done by making calls to the SIDPlay library. There are other calls that can be made to the SIDPlay library to get pointers to the song title, author and copyright information, although these are not used by the Time Utility.
The Time Utility lazy loads both the SIDPlay library and a SID file, called timer.sid, from the system settings directory. Lazy load means, it doesn't load those things immediately upon opening the Utility. It waits until what you're doing with the Utility necessitates loading in those extra resources.
Here's a video of this that I posted to Twitter a little while ago.
OMG, this never happens. I wrote a pile of a code in 6502, a new library, and debugged in the assembler only. Then I put it to use in the Time Utility, again, debugged in the assembler only. I just ran it for the very first time, and it’s working on the first try! #C64 🤯🤗 pic.twitter.com/Lzxt1CTlqb— Gregorio Naçu (@gregnacu) May 7, 2022
RTC Drivers and Time Utility
Speaking of adding new things that flesh out the Time Utility, in beta 0.8, although the Time Utility had the Clock tab, it wasn't functional. The Clock tab embeds a TKDatePick and a TKTimePick object, which it configures for the current system date and time as of the moment when the Utility is opened. These don't tick in realtime as it would be awkward if they were changing while you were attempting to set them.
You make some adjustments and hit the Set button. But what does it set, and how?
It refers back to the drivers settings file, //os/settings/:drivers.t, which is used to configure all of the drivers that C64 OS supports. The RTC driver is loaded during boot, used to read a hardware RTC and set the systsem date and time, but the driver is not left in memory. Once it's done its job, C64 OS doesn't need to have continual access to the RTC hardware, os the driver gets expunged to free up memory.
The Time Utility, when you try to set the date and time, needs access to the hardware RTC again. So it parses drivers.t to find what RTC driver you have configured, loads it in on-the-fly, and calls its settime routine, passing a pointer to a 5-byte datetime value extracted from the two picker objects. The RTC drivers in beta 0.8 had only placeholder routines for settime.
As of this writing, the "rtc.iec device" driver has implemented settime, which works to set the RTC of a CMD HD, CMD FD or CMD RamLink, or an IDE64 or an SD2IEC (if it has an embedded RTC). So that covers pretty much the full gamut of RTCs in storage devices.
The "rtc.ultimate" driver has implemented settime now too, which works to set the RTC of the 1541 Ultimate and the Ultimate 64. Both of these are set the same way via the Ultimate Command Interface, which has to be enabled in the menu systems. There is also a custom setting in the menu systems to allow or prevent software from changing the RTC, this obviously also must be set to allow.
C64 OS also provides a manual RTC driver (rtc.manual), which is used if you don't have RTC hardware. The manual driver reads a static date/time from the settings file //os/settings/:time.manual.t. If you are using this driver, and you set the date/time using the Time Utility, it writes the new date/time into the static settings file. It doesn't stay up-to-date but it's nice that you can change the manual value.
I still need to implement settime in the DS3231 I2C driver. But that's next on the list.
So that's the big update on most of what's been developed in C64 OS and on c64os.com over the last few months. Version 1.0 is planned for physical release in Summer 2022. You'll be able to purchase a copy right here on C64OS.com/c64os when it becomes available.
I apologize that I haven't had the time to sink into the blog post Part 3 of the VIC-II timing and FLI routine, it will get finished and posted eventually, but for now, C64 OS development, updates to the website itself, and writing the User's Guide and supporting material has to take precedence.
Once again, if you're not following me on Twitter, please do: @gregnacu.
And I also have a couple of YouTube channels, please check them out:
C64 OS Progress and Updates, and
C64 and C64 OS Native Coding Sessions
Do you like what you see?
You've just read one of my high-quality, long-form, weblog posts, for free! First, thank you for your interest, it makes producing this content feel worthwhile. I love to hear your input and feedback in the forums below. And I do my best to answer every question.
I'm creating C64 OS and documenting my progress along the way, to give something to you and contribute to the Commodore community. Please consider purchasing one of the items I am currently offering or making a small donation, to help me continue to bring you updates, in-depth technical discussions and programming reference. Your generous support is greatly appreciated.
Greg Naçu — C64OS.com