The obsolescence of IFFL

So what is IFFL?

IFFL is the technique to link disk data. Since the drive allocates a full sector as a minimum, the last sector is statistically only half full. So if you merge several files into a bigger one, you statistically win half a block per file you add to the merged file.


It’s also fair to say that IFFL exists in two versions;

Version 1: This one is merely merging the files of a level into one bigger, where they are always meant to be loaded all at the same time. Here it is not possible to load only one of the segments without loading (and possible discarding) the segments preceding the one you are after, but if you package segments to be loaded at the same time, this is no restriction. A merit of this type is also that it doesn’t need any code in the drive and you can hence use standard Kernal load and save routines in parallel. So this is simple and straight forward, has no constraints on the compatibility.

Version 2: The concept matured and people added a routine to scan the IFFL file, to generate a table containing track, sector and offset of the different segments (this as the file can be copied and the track/sector part can be different every time the game is run). Using this technique, it’s possible to load an arbitrary segment. This is really handy, but it comes with a price; there must be code in the drive that handles the tables. And not all drive units have any drive RAM (SD2IEC for starters). And supporting a plethora of units, you need drive code that works in as many as possible. (Having said this, Uload does have the tables in computer RAM but I’d say it’s not really common to have memory enough to store the scan tables in computer RAM).


The term was to the best of my knowledge coined by Snacky when he released Another World in 1989 (or by OMG if you read the interview with Snacky). This was a version of IFFL version 1. It’s quite interesting that Gollum had used the same technique before, but just not given it any special name – see RoadBlasters from 1988. So Snacky didnt invent it – GP just coined the term.

Why should we use IFFL?


Cracking games on the c64 has always involved two types of competitions – speed (first release) and quality when the size and number of files have been a key aspects. Triad’s magazine Gamer’s Guide was the leading force, driving people to perfect the release in the size and number of files aspect. Today GG doesn’t exist, and the only thing we have is the release rules maintained by Jazzcat. In these rules, the competition is all about speed and all the rules does to address quality is to set a minimum standard for when the release is counted. So striving for shaving off a few blocks is a dead craft, and this is today a really weak argument.

Disk search

A directory spanning multiple sectors will cause the drive to search for the file it wants to load. Even if you have a fastloader, this aspect is typically not any faster. So loading a file in a later part of the directory using a fastloader, will still be a bit slow even if the speedloader makes the load rather fast.

Why shouldn’t we use IFFL?


The key aspect is that it breaks compatibility with a number of devices. We want the crack to have a working fallback to standard Kernal if possible, and this basically rules out IFFL.

Save becomes really complex

If you have the IFFL routine in the drive, and then also the scan tables, then you have filled drive ram. Any feature you add will eat the available ram, and that will restrict the number of files you can have in your tables. Save is such a feature. This is why the save functions in the IFFL context are quite restrictive. Some allow you to save an exact size file inside the actual IFFL. Some allow you to save exact size file(s) outside of the IFFL itself. There are none that support proper save or save with replace. Being clearly in favour of plain and unrestricted save, this is a real disadvantage.


Balancing the pros and cons, my clear conclusion is that IFFL is obsoleted. The priority should be on compatibility. Fewer blocks is nice, but people putting this forward and having 50 block intros have lost their sense of direction in the argument. You can’t argue in favour of killing compatibility in exchange for fewer blocks, and then wasting the same amount of blocks and more on something else. It doesn’t compute.

The only valid argument today is the search time for files in the latter part of the directory, but balancing this against compatibility – then compatibility wins for me.

Fibaro – two triggers and time interval

I wanted to implement a scenario with two different motion sensors triggering a single lamp. But I wanted to ensure that this behavior was only applicable during a special time interval. The solution looks like this (and please mind that the references to the devices are of course applicable only to my system).

This is the trigger section; The important learning here is the structure of the operators and conditions. “All” basically means AND whereas “Any” means OR.


    operator = "all",
    conditions = {{
        operator = "all",
        conditions = {{
            type = "date",
            property = "cron",
            operator = "match>=",
            value = {"15", "0", "*", "*", "*", "*"}
        }, {
            type = "date",
            property = "cron",
            operator = "match<",
            value = {"59", "6", "*", "*", "*", "*"}
    }, {
        operator = "any",
        conditions = {{
            id = 364,
            isTrigger = true,
            operator = "==",
            property = "value",
            type = "device",
            value = true
        }, {
            id = 232,
            isTrigger = true,
            operator = "==",
            property = "value",
            type = "device",
            value = true

This is the action section:

local motion1 = 364; -- ID for PIR Motion Sensor - Livingroom
local motion2 = 232; -- ID for PIR Motion Sensor - Hallway
local starttimer = 120; -- Time for light to be on in seconds
local horntimer = (starttimer); -- timer
fibaro.call(switch, "turnOn");

fibaro.debug("green", "Start: Light on");

------------------ Starting loop ----------------------------------------

-- if movement then restart timer------------------
      local value movement = fibaro.get(motion1, "value");
      if movement == true then
            fibaro.debug("grey", "I see movement. Timer reset");
      local value movement = fibaro.get(motion2, "value");
      if movement == true then
            fibaro.debug("grey", "I see movement. Timer reset");

until (horntimer<1)

fibaro.call(switch, "turnOff");
fibaro.debug("red", "End: Light off");

Some rarely used 6502 aspects

I am by no means any professional programmer, but I have coded 6502 since the late 80s and can safely say that I have a lot of experience. My main focus throughout all these years has been to reverse other peoples work, so I have also seen a lot of examples of how others use it.

I will take this time to look at two rather nice, but rather underutilised ways to do things.

The BIT operation

The most used aspect of BIT is seems to be to allow different entry values in a set of code, like you see here:

It’s a very handy way to achieve a result that is difficult to get good in other ways. The $2C (BIT of a word) is used as a way to have the CPU skip the following two bytes. (Basically like the illegal opcode $0C, that is a three byte NOP)

But have you used BIT for what is actually there to do? In a situation where you have data in all three registers (A, X, and Y) and you still need to make a compare, BIT might be your friend.

When you do a BIT operation, bit 7 from the argument is copied to the N flag and bit 6 is copied to the V flag which means that you can now use BPL/BMI to branch based on bit 7 and use BVS/BVC to branch based on bit 6.

The command also sets the Z flag but that is a lot trickier to use, as the flag is set as a result of an AND between the A and the memory location given as an argument. So it’s not independent of the registers as the N and V flags are.

Decimal mode

“Hexadecimal is the humanly readable form of binary” (Pontus Berg, 2021). Whereas hex is logical and easy to manage, many people in the real world tend to prefer decimal. Given our number of fingers, it does make sense to use that. And no 6502 programmer can get around the problem that you need to bridge the two paradigms from time to time. Be it counting lives and other resources in a game to printing line numbers in a wordprocessor, presentation of decimal values is sometimes requested.

So how do you convert between the two? Well, have you ever considered that you don’t have to? Store the value in decimal form and let the 6502 do its work, using decimal when accessing these values. Looking at the example on the right, what is the value of the A register when you read it from $1000?

Normally incrementing 09 with one would be 0A. But if you set decimal mode (SED), increasing 09 with one results in 10. It handles the nibbels in the byte as only being able to hold values up to 9. Very handy indeed.

Just remember to close decimal mode again (CLD) or your code will for sure turn haywire.

C64 Disk drive access

(Seems my theme shows Code as black text on black background – will fix that eventually 😉

There are always aspects of c64 programming that you haven’t tested and exploring it is also a new learning. Assuming things that turn out to be wrong is always a nice learning and then you are expected to remember and next time around you are expected to navigate better.

Normally when loading, I use fastloaders which means that the entire area of how IO works, is sort of delegated. But in order to load and save status files, it is always an option to revert to having DOS handle that.

The standard way of handling this would be like this:

	lda #loadname_end-loadname
	ldx #<loadname
	ldy #>loadname
	jsr setnam

	lda #$02
        // Logical file
	ldx $ba 	// last used device number
	bne !+
	ldx #$08     	// default to device 8
!:	ldy #$02	// Secondary address
	jsr setlfs 	// call SETLFS - OK with no vectors

	jsr open
	bcs Error

And this is where I ran into the same issue I had experienced before, but seemingly didn’t learn from.

When executing Open as per the above, the Carry flag is signalling that an error has occurred. The error is typically that the communication channel couldn’t be established – most importantly as the drive didn’t respond or if you have too many files already open. Please mind that the error is NOT including the scenario that the file in question doesn’t exist.

So if you want to detect if the file exists, you must ask the drive to prepare for reading by calling chkin with the current logical file number in X, and then fetch a byte. The Error label hear is reached when your read failed, and a common reason is that the file didn’t exist.

	ldx #$02
 // Logical file
	jsr chkin

	jsr chrin
	// Store away the A if you need this

	jsr readst
	beq !+

Error:	// Handle an error 

!:	// Reading was ok

Some references:

C64 graphics – a quick reference

The VIC is the chip in a c64 that handle all graphics.

Whereas the CPU sees all of the memory, the VIC only sees 1/4. We call that a VIC bank or graphics bank. Default is $0000 to $3fff – you need to actively change it using the two bits in $dd00 if you want something else. Any of the indexes talked about below are relative to the start of the bank.

Depending on the graphics mode (character and bitmap), the VIC registers define different things. (These registers are located at the addresses $d000 to $d02f). Default is character mode.

If so;

The screen and font are set by the same register ($d018 – screen is bit 4-7 and font is bit 1-3):

  • Screen is a $03e8 byte big area that can be set to any of the $0400 aligned indexes in the current VIC bank (so 0 is $0000, 1 is $0400, 2 is $0800 and so on – in the lowest bank $0000 is rather theoretical). Default is 1, ie $0400.
  • Font is a $0800 area that can be set to any $0800 aligned address. Default is $1000 (which is a shadow of the char ROM that really resides at $d000)The last 8 address of the area allocated to screen is used for pointers to the sprite memory.

A sprite is an independently movable object that is 24*21 pixels, which means 3 * 21 = 63 bytes of memory, and they hence fit nicely inside a 64/$40 byte block. A sprite data shall hence be located at an even 64/$40 location.

With bank set to 0 and screen to $0400, this means that you find the sprite pointers at $07f8. A sprite pointer is the index of the “slot” containing the content that is to be interpreted as sprites; 0 is $0000, 1 is $0040 and so on.

I’d say it’s bad practice to set the pointer and the address hard and not calculate one of them. Use something like “LDA #spritemem/64” where “spritemem” is the address where the sprite data is stored.

One thing to understand is that if you change VIC bank, all data for all graphics change and point to new places. But also, if you change the pointer to the current screen, the pointers to sprites also change and hence both screen and sprite content changes.

It’s a bit complex to learn, but it’s super powerful once you get a hang of it

C64 character encoding

The commodore 64 has two character encoding schemes; Petscii and screencode. Petscii is what you use when you print using the standard $ffd2 charout print routine and screencodes is what you use when you poke the values directly to the screen.

In addition to this, you can toggle between upper/lower and upper/gfx by pressing Commodore + Shift

Printing $8e will take you to upper/gfx and printing $0e will take you to lower. You can block this by printing $08 and you can enable it again using $09.

Simple enough, and most of the times it is apparent if it’s done right as it will show up on the screen. However, one distinguishable difference is if you work with the drive. Filenames and disk commands must be in the proper format, or it won’t work. After AGAIN spending hours in a ghost chasing bug hunt, which was caused by setting a string to petscii upper/lower I got fed up and decided to have this blog post for my own reference. 🙂



.encoding "screencode_mixed" 	//default

smix:	.text "abcdefgh"
	.text "ABCDEFGH"

.encoding "screencode_upper"

supper:	.text "abcdefgh"
	.text "ABCDEFGH"

.encoding "petscii_mixed"

pmix:	.text "abcdefgh"
	.text "ABCDEFGH"

.encoding "petscii_upper"

pupper:	.text "abcdefgh"
	.text "ABCDEFGH"

/* Result:

>C:1000  01 02 03 04  05 06 07 08   ........
>C:1008  41 42 43 44  45 46 47 48   ABCDEFGH

>C:1010  61 62 63 64  65 66 67 68   abcdefgh
>C:1018  01 02 03 04  05 06 07 08   ........

>C:1020  41 42 43 44  45 46 47 48   ABCDEFGH
>C:1028  c1 c2 c3 c4  c5 c6 c7 c8   ........

>C:1030  61 62 63 64  65 66 67 68   abcdefgh
>C:1038  41 42 43 44  45 46 47 48   ABCDEFGH

If using Screencode_mixed, disk commands and filenames should be in UPPER CASE.
If using petscii_mixed, disk commands and filenames should be in lower case.

Brands and right

Many people are loyal to certain brands and trademarks, and associated themselves with certain brands. Buying all the stuff in the categories that the brand is active. But what if the brand is an old one, and no longer really active? What if the original company has been through multiple bankruptcies? The example at hand is Commodore.

Let me just say that I will base this on Swedish legislation as that is what I know, but much IPR (Intelectual Property Right) is globally applicable. Most of the same rules apply in most countries given that the foundation is based on international agreements, such as the Bern convention from 1886.

Copyright needs no registration. It just happens and the protection is 70 years from public release or 70 years from the death of the author.

Brands/Trademarks require registration as a default. There is a rather complex structure of registration, so depending on where you register it could have a varied regional reach. You can for example register in Sweden but also make a universal EU registration for this region.
We also acknowledge registrations in states connected to the Parisconvention of 1883. We also acknowledge trademarks from countries that acknowledge rights of Swedish trademarks (reciprocity). We also acknowledge registrations by WIPO.

However if a sufficient number of people in the target audience recognises a brand/trademark, it can be seen as held even without registration.

The right means that no one is allowed to use the brand can use it for the purpose of what’s defined in law. Basically you can’t use it, or anything that is close enough so that there is a risk for mixing up another product with the original one.

There are a few exceptions where similar brands can be used in parallel, but these are really slim exceptions. In principle, you need to show a reasonable level of activity to defend your brand, or you could be seen as accepting the other brand, and brands can coexist. (here and here)

Duration of the right is normally ten years.

You can still lose the right for a number of reasons. The most interesting reason might be that if you haven’t used the brand on the Swedish market for the last five years for no legit reason.

Penalty for abuse of someone else’s trademarks is listed here.

SO, NO you cannot legally correct sell a mug with a Commodore or Amiga logo on it unless you have obtained the rights from the legal holder of the brand/trademark. It doesn’t matter if you sell it at no profit or for charity. It doesn’t matter. You are using the rights of someone else and that you are not entitled to – zero tolerance.

Is this reasonable, is the risk of getting caught big? Well these are other questions. This text only aimed to establish the legal foundation of trademarks. It IS a breach to use brands and is pickpocketing and speeding. Still doing them, calculating the risk of getting caught in these different cases will be between you and your moral.

VICE logging

Yes, yes, yes …

One of the features I missed the most is not in VICE, as per one of the most recent builds (one of the last builds before 3.3 becomes 3.4). Logging to file. Quite often when I make a version of a game, I need to record values. Especially games where the loader is fed with data that is not in a consistent table, you need to set a trap at each call of the loader and record the values. That’s tedious and error-prone.

The new commands are logname and log on/off.

Logname is quite obvious – it sets the name of the textfile. I guess one could wish for an option to overwrite or append if the file already exists, but here I think it always overwrites.

The next command is log on/off and if it’s on, it simply copies the same content as sent to the screen also to the file set by the logname.

So how to use this? Well, it’s here quite handy to also know a few other commands:

Break – triggers a break to the monitor window where the breakpoint address is executed.

Watch – triggers a break to the monitor where the address is read/written to.

These are basically the same command but break defaults to trigger on execution and watch defaults to read/write, but if you give the arguments they can be the same. “Watch exec” is the same as break with no argument.

Trace – triggers a break on all of the exec/load/store but doesn’t open the monitor window on the hit. It merely prints it to the console. With the new log, it can also print to file.

Command – The break/watch/trace points are allocated an index. Issuing Command <index> and a string, the command in the string is issued when the breakpoint latches. The index is incremented with every new one, but the counter is reset to 1 when you issue a delete to clear all points defined. I issue the delete in order to ensure that the index reference in the trace command is correct.

As you can see in my example you can also stack commands using a semicolon, so a command can issue multiple commands.


logname "my_log.txt"
trace exec cb00
command 1 "m ce44 ce45;m ce47 ce48;m cb20 cb21;m cb49 cb4a;m 67 68;chis 5"
log on

The above silently triggers an execution on cb00 and then issues a stack of commands.

Please mind that the file is written to, but you OS might buffer the writes so that the file isn’t updated until it’s closed. Opening the monitor, you might need to do a “log off” to make that happen, or it might not happen before you close VICE.

As a bonus, I could also add that in case you don’t feel like typing the commands multiple times, you can create command files. This is done using the record “<filename>” command. To execute it, you playback using pb”<filename>”.

Fibaro controlling Hue

I just covered the topic in a group on Facebook, and might as well cover it here as well so it’s public also to non-swedes.

The question was how to control the Hue lights from scripts. There is a requirement to use a magic Id number to do this. In fact, there are actually two.

Instaling the Hue function in HC2

First you need to install the Hue plugin to have the HC2 even talk to Hue. This guide is very straight forward so no point repeating the same content again.

1.Enable Hue devices in scenes using blocks

What is enormously annoying is that the Hue plugin cannot be used in scenes that you build using blocks. For this, you need to create a Virtual Device.

There is one that looks very competent, but which was developed way after I installed my setup. Feel free to test it- HERE.

My picture is from the version I have installed but in any case you need to find the hueLightID as per my picture below:

That Id is actually rather straight forward. It’s the index number found in the Hue mobile app. Chose the cogwheel (settings) and scroll down to the About option.

2. Addressing the Hue lamps from own LUA code

In your own LUA scripts, you use the Id of the Hue plugin per lamp and not the Id of the lamp a per the Hue index. Hoover the wrench with the mouse and then you see in the URL in the bottom left cornet the Id. In this case 74.

I might just as well provide you with a small piece of LUA that I used to create a Scene for a Walk In Closet. I have installed a door sensor on the door and there is a Hue lamp in there. I want the lamp to turn on when the door is opened, and turn off as soon as the door is closed. You already know that the lamp is Fibaro device Id 74. The Door sensor is device 236.

Script called “Turn ON WiC light”

%% properties
236 value
%% weather
%% events
%% globals

local startSource = fibaro:getSourceTrigger();
if (
( tonumber(fibaro:getValue(236, “value”)) > 0 )
startSource[“type”] == “other”
fibaro:call(74, “turnOn”);
fibaro:call(74, “changeBightness,216”);
fibaro:call(74, “changeHue,45853”);
fibaro:call(74, “changeSaturation,61”);

Script called “Turn OFF WiC light”

%% properties
236 value
%% weather
%% events
%% globals

local startSource = fibaro:getSourceTrigger();
if (
( tonumber(fibaro:getValue(236, “value”)) == 0 )
startSource[“type”] == “other”
fibaro:call(74, “turnOff”);

Come to think of it, I guess these could be merged to one and the same, right?

Building Vice emulator – NO black magic needed!

Being rather tech savvy but still not working with software, the entire field of source repos and management of them has been a field where I felt my competence was really blurry. Adding to this, I hear from many sources that building VICE from source seemed like it included elements of black magic to pull off. So I didn’t even try. Then Pokefinder nightly build stopped working at new year 2018/19 (and much to my surprise it seems up again since a few days). So in short, if I wanted to keep up, I had to learn to build myself.

So I was ready to dig deep and start learning black magic. I’m not really sure if I was disappointed, surprised or happy when I realised that all it took was following a guide and then I was done. There was absolutely nothing strange about it. Nothing.

There is a guide in the source package so the only part one can have views on is that you need to download the package just to get the guide. It would be a lot easier if the guide was online directly. Below you will find the guide as provided in the source package, after my rather extensive modifications.


ALSO: the switches in “$ ./configure -C –enable-native-tools –enable-native-gtk3ui” begins with double minus characters. It seems copy + paste can fail … (Thankx to tNG for this)

VICE (GTK) on Windows

Setup MSYS2

These are some instructions about getting VICE with the GTK3 GUI
compiled on Windows under MinGW.

  1. Get MSys2 (includes mingw):
    Install as per that webpage. You can skip the GIT part if you don’t want that.
  2. Install the stuff that you actually need to build VICE:
    Launch either the MSYS2 MinGW 64-bit shell or the MSYS2 MinGW 32-bit shell (use the one that matches the version of MSYS2 that you installed).

You first need to install a number of libraries, and here things changed since the original text I wrote. (Please mind that I have identified no libs that will handle the pdf generation so in the following I will disable the pdf docs). If you don’t, the later building will fail as it depends on them being in place.

$ pacman -Syu
$ pacman -S base-devel
$ pacman -S mingw-w64-x86_64-{toolchain,libvorbis,flac,mpg123,icoutils}

And optionally also (skip if you don’t want Git or already installed in in the earlier step)

$ pacman -S git

Quit the shell and start it again. Now issue the string:

$ pacboy sync base-devel: pkg-config gcc ntldd zip: subversion: gtk3 glew

Setup XA6502

  1. Then you need the xa 6502 cross-assembler, which is used to assemble the “driver” program for vsid (the SID player that comes with VICE). It can be found here:

    Check this link for a reference to the most recent version. Below URL to the download assumes 2.3.11 which was current at the time of writing this.

    Download to where you want it by placing yourself in a directory of your choice – here I make one in the Home where you should be now.
$ mkdir -p Download
$ cd Download
$ wget http://www.floodgap.com/retrotech/xa/dists/xa-2.3.11.tar.gz

Make the directory “/usr/local/src/”.
Use tar to unpack xa (use the MSys2 path to where you downloaded it):

$ cd /usr/local
$ mkdir -p src
$ cd src
$ tar -xzf ~/Download/xa-2.3.11.tar.gz

Then, build and install it:

$ cd xa-2.3.11
$ make mingw install
$ mv ../../bin/xa.exe ../../bin/xa65.exe

Download the VICE source

  1. Get VICE’s source code.
    To checkout the source with Subversion (to “~/vice/”, for example),
    you could type:
$ cd ~
$ svn checkout http://svn.code.sf.net/p/vice-emu/code/trunk/vice

Build VICE

Now, you can try to build VICE (Basic set-up):

$ cd ~/vice 
$ ./autogen.sh
$ ./configure -C --enable-native-tools --enable-native-gtk3ui --enable-cpuhistory --disable-catweasel --disable-lame --disable-rs232 --disable-hardsid --disable-parsid --enable-ethernet --enable-x64 --disable-debug --disable-pdf-docs --without-ogg-vorbis --without-flac 
$ make all bindist

Also, the parameters might look a bit different than in other examples you find. This is due to recent changes. Docs suddenly built as PDF (but there is no TeX that would work for me on windows) and they also recently fiddled with the supported codecs, so I had to disable ogg-vorbis, flac and lame support to make it build.

There are aspects of VICE I really want (CPU history being the main one) and there are a number of features I can live without, that only risk slowing down the emulator and making the payload bigger. The general recommendation is to disable anything you don’t need. So my first build looks like this:

$ cd ~/vice
$ ./autogen.sh
$ ./configure -C --enable-cpuhistory --disable-catweasel --disable-lame --disable-rs232 --disable-hardsid --disable-parsid --disable-ethernet --enable-x64 --disable-debug --disable-pdf-docs --disable-platformdox --without-flac --enable-hwscale --with-png --disable-libieee1284 --disable-realdevice --disable-ffmpeg
$ make all bindist
  1. If it got through all those steps, you should have some executables to play
    with in “GTK3VICE-3.?-win??-*/” (the “win??” part of that name tells you which
    type [32-bit or 64-bit] you built).
  2. You can build the 32-bit version of VICE and/or the 64-bit version. You
    make the choice by choosing to run a particular one of the MSYS2 MinGW shells
    (its environment variables control VICE’s configuration).

If you build one version, then want to build the other version, you must clean away some object files first. Then, you must configure VICE again.

$ make clean
$ rm config.cache
$ ./configure -C --enable-native-tools --enable-native-gtk3ui
$ make all bindist

NOTE: The above alternative configure lines should be used if you want the alternative configurations.

  1. If you want the distribution in a ZIP archive instead of a subdirectory,
    then use the command
$ make bindistzip

instead of

$ make bindist

Pontus: Updating VICE is then easy. Open the MSYS2 shell and write:

$ cd vice 
$ svn update
$ make all bindist

One thing I haven’t tried, but which was confirmed on the bug reporting mailing list recently was that if you don’t want to build the entire package (and that takes a lot of time), you can build just one of the emulators by using for example:

make x64sc

Also, if the build fails as there has been changes to the build process, or you had to install new components required, the process for refreshing the ability to build is this:

rm config.cache
./config.status --recheck
make -s all bindist