SkoolKit 8.6 has been released. To get a copy, please head over to the download page, the Python Package Index, the Ubuntu PPA, or the Fedora copr repo.

So far, the 8.x series of SkoolKit has been a big one for new macros - eight since 8.0 - and version 8.6 continues that theme by bringing along no fewer than three in the shape of #UDGS, #WHILE and #STR.

First up, #UDGS. This macro is an alternative to the venerable #UDGARRAY for creating an image of a rectangular array of UDGs. How is it different from #UDGARRAY? Well, where #UDGARRAY expects a sequence of UDG specifications (including UDG base address, attribute byte etc.) in its parameter string, #UDGS instead expects a single expression that takes a pair of coordinates (the coordinates of the UDG within the rectangular array) and expands to the name of a frame. This makes the typical #UDGS macro much shorter and more readable than the equivalent #UDGARRAY macro. For example:

#UDGS3,4(thing)(#UDGAT($x,$y))

This creates an image (thing.png) three UDGs wide and four high, where the UDG at (x,y) is produced by the #UDGAT macro (which you might have defined with #DEF).

Second up, #WHILE. In the interests of making skool macros more usable as a programming language, this one, as its name suggests, repeatedly expands other macros while a conditional expression is true. So, for example, if you wanted to translate a sequence of character codes starting at address 32768 until a zero-byte is reached, you could do something like this:

#LET(a=32768)
#WHILE(#PEEK({a})>0)(
  #CHR(#PEEK({a}))
  #LET(a={a}+1)
)

Third up, #STR. This one rather undermines the #WHILE example just given, because it expands to the text string at a specific address, by default terminating either just before the first byte that is zero or on the first byte that has bit 7 set. So the example above could be reduced to:

#STR32768

But never mind: #WHILE can no doubt be put to other uses. Meanwhile, #STR can also strip leading and trailing whitespace from strings, and handle strings that terminate somewhere other than the first byte whose value is 0 or 128+.

By now you’re probably feeling some macro fatigue, so let’s move on to a couple of other features. The first one, while not a macro itself, could be described as macro-related, but bear with me. Ever used the @expand directive and liked it, but wondered if there was an alternative that is specific to HTML mode? Wonder no more. The value of the Expand parameter in the [Config] section is expanded before anything else, and thus enables all your macro definitions to be placed in their own section, e.g. [Macros]:

[Config]
Expand=#INCLUDE(Macros)

[Macros]
...macro definitions here instead of in @expand directives...

Finally, a new feature that genuinely has nothing to do with macros. The --ram option of tap2sna.py now supports ‘call’ operations, which call an arbitrary Python function to perform arbitrary modification of the memory snapshot. This will come in handy when the stock ‘move’ and ‘poke’ operations just don’t quite cut it, for example if the RAM needs to be descrambled before it can be disassembled.

Of course, this is not an exhaustive account of all the new features in 8.6. For details on the others, I suggest heading over to the changelog. There you will find details on such things as defining dictionary variables with the #LET macro, and how the #CHR macro is now more friendly towards the ‘special’ members of the ZX Spectrum character set: ‘↑’, ‘£’ and ‘©’. When you’re done there, why not grab a copy of 8.6 and see whether #UDGS can reignite your passion for image macros?