SkoolKit 1.0.6 (2010-02-04)

1 What is SkoolKit?
1.1 Licence
2 Installing and using SkoolKit
2.1 Requirements
2.2 Linux/*BSD v. Windows command line
2.3 Generating the HTML disassemblies
2.4 Generating ASM files
3 Parsing, rendering, and modes
3.1 Parsing
3.1.1 HTML mode
3.1.2 ASM mode
3.2 Rendering
3.2.1 HTML mode
3.2.2 ASM mode
4 Data files
4.1 sd.skool
4.2 sd.ref
4.3 bts.skool
4.4 bts.ref
4.5 skool.ref
4.6 start.skool
4.7 load.skool
4.8 save.skool
4.9 changelog.ref
4.10 Skool file format
4.11 Ref file format
5 Ref file macros
5.1 ::
5.2 ${bts:}, ${sd:}
5.3 ${f:}
5.4 ${v:}
6 Skool directives
6.1 !bts+begin, !bts+end, !sd+begin, !sd+end
6.2 !defb
6.3 !refs
7 Skool macros
7.1 #AS (Animatory State)
7.2 #ASIMG (Animatory State IMaGe)
7.3 #ASM
7.4 #ASTILE (Animatory State TILE)
7.5 #BOX
7.6 #BUG
7.7 #C (Copyright)
7.8 #CBUF (Character BUFfer)
7.9 #D (Description)
7.10 #EREFS (Entry point REFerences)
7.11 #FACT
7.12 #FONT
7.13 #GBUF (Game status BUFfer)
7.14 #KEYTABLE
7.15 #LESSON
7.16 #LOAD
7.17 #MSG
7.18 #MUTABLE
7.19 #NAME
7.20 #P (Paragraph)
7.21 #PATILE (Play Area TILE)
7.22 #POKE
7.23 #POKES (POKE Snapshot)
7.24 #POPS (POP Snapshot)
7.25 #PT (Personal Timetable)
7.26 #PUSHS (PUSH Snapshot)
7.27 #R (Reference)
7.28 #REFS (REFerenceS)
7.29 #REG (REGister)
7.30 #SAVE
7.31 #SCR (SCReenshot)
7.32 #SKOOL
7.33 #SPACE
7.34 #START
7.35 #TABLE
7.36 #TAP
7.37 #TAPS
7.38 #TIME
7.39 #UDG
7.40 #UDGTABLE
8 ASM modes and directives
8.1 Substitution modes
8.1.1 @isub mode
8.1.2 @ssub mode
8.1.3 @rsub mode
8.2 Bugfix modes
8.2.1 @ofix mode
8.2.2 @bfix mode
8.2.3 @rfix mode
8.3 ASM directives
8.3.1 @bfix
8.3.2 @bfix block directives
8.3.3 @ignoremrcua
8.3.4 @ignoreua
8.3.5 @isub
8.3.6 @isub block directives
8.3.7 @keep
8.3.8 @label
8.3.9 @nolabel
8.3.10 @nowarn
8.3.11 @ofix
8.3.12 @ofix block directives
8.3.13 @org
8.3.14 @rem
8.3.15 @rfix block directives
8.3.16 @rlabel
8.3.17 @rsub
8.3.18 @rsub block directives
8.3.19 @ssub
8.3.20 @start
9 Disassembly DIY
9.1 sna2skool.py
9.2 The control file
9.3 A skeleton skool disassembly
9.4 Generating a control file
9.5 Other disassembly options
9.6 Adding pokes, bugs, trivia and a glossary
9.7 skool v. ASM
10 Changelog
10.1 SkoolKit 1.0.6 (2010-02-04)
10.2 SkoolKit 1.0.5 (2010-02-03)
10.3 SkoolKit 1.0.4 (2010-02-02)
10.4 SkoolKit 1.0.3 (2010-02-01)
10.5 SkoolKit 1.0.2 (2010-01-31)
10.6 SkoolKit 1.0.1 (2010-01-30)
10.7 SkoolKit 1.0 (2010-01-28)
11 Bugs

1 What is SkoolKit?

SkoolKit is the bunch of data files, libraries and scripts that are used to generate the Skool Disassemblies (both the HTML versions and the ASM versions). You could think of SkoolKit as one (or more) of the following:

SkoolKit also provides some support for creating disassemblies of games other than Skool Daze and Back to Skool.

The latest version of SkoolKit can always be obtained from pyskool.ca.

1.1 Licence

SkoolKit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

See the file 'COPYING' for the full text of the licence.

2 Installing and using SkoolKit

2.1 Requirements

SkoolKit requires Python 2.x, version 2.5 or later. (SkoolKit has not been tested with Python 3.x; it almost certainly will not work.) If you're running Linux or *BSD, you probably already have Python installed. If you're running Windows, you can get Python here.

In addition to the stock Python distribution, SkoolKit also requires one of the following image-processing libraries:

Either one will do. gdmodule seems to be slower than PIL, but it creates smaller image files. gdmodule is available in Debian, Ubuntu, openSUSE and Mandriva as python-gd; it is apparently not packaged for Fedora. It is also available in FreeBSD and NetBSD as graphics/py-gd, and in OpenBSD as py-gd. PIL is available in Debian, Ubuntu, openSUSE, Mandriva and Fedora as python-imaging. It is also available in FreeBSD and NetBSD as graphics/py-imaging, and in OpenBSD as py-Imaging. Windows users will probably want to use PIL, since it has downloads readily available.

SkoolKit will use gdmodule in preference to PIL if it is available.

2.2 Linux/*BSD v. Windows command line

Throughout this document, commands that must be entered in a terminal window ('Command Prompt' in Windows) are shown on a line beginning with a dollar sign ($), like this:

$ ./some-script.py some arguments

On Linux/*BSD, the commands may be entered exactly as they are shown (without the dollar sign, of course). On Windows, the dot-slash (./) prefix should be omitted. (The dot-slash prefix may also be omitted on Linux/*BSD if you have the current working directory in your PATH, but that is not the norm.)

2.3 Generating the HTML disassemblies

To generate the HTML version of the Skool Disassemblies, use the skool2html.py script. Open a terminal window, change to the directory containing SkoolKit, and enter this command:

$ ./skool2html.py skool-disassemblies

A few seconds later (or minutes, depending on the speed of your machine), the HTML version of the Skool Disassemblies will be ready in the skool-disassemblies subdirectory (which will have been created if it didn't already exist).

skool2html.py supports many options; run it with no arguments to see a list:

-q Be quiet -s Write Skool Daze files only -b Write Back to Skool files only -f FILE Use FILE instead of sd.skool or bts.skool -wX Write only these files, where X is one or more of: b = Bugs C = Changelog c = Character buffers d = Disassembly files G = Game status buffer g = Graphics files h = Home page I = Disassembly index (minimal) i = Disassembly index (full) k = Keypress table L = Lessons and personal timetable index l = Load code m = Memory maps p = Pokes S = Startup code s = Save code t = Trivia y = Glossary

So, to write only the disassembly files and memory maps for Skool Daze:

$ ./skool2html.py -s -wdm skool-disassemblies

2.4 Generating ASM files

To generate ASM files for Skool Daze or Back to Skool, use the skool2asm.py script. Open a terminal window, change to the directory containing SkoolKit, and enter this command:

$ ./skool2asm.py sd.skool > sd.asm

A few seconds later, an ASM file for Skool Daze will be ready: sd.asm.

To create an ASM file for Back to Skool:

$ ./skool2asm.py bts.skool > bts.asm

skool2asm.py supports many options; run it with no arguments to see a list:

-q Be quiet (don't show timings) -v Be verbose (show instruction substitutions) -w Suppress warnings -e Write processed lines to stderr (implies -w) -d Use CR+LF to end lines (default line terminator is LF) -t Use tab to indent instructions (default indentation is 2 spaces) -l Use lower case (default is upper case, e.g. 'LD A,(HL)') -iN Set instruction field width to N (default=23) -fN Apply fixes: N=0: None (default) N=1: @ofix only N=2: @ofix and @bfix N=3: @ofix, @bfix and @rfix (implies -r) -s Use safe substitutions (@ssub) -r Use relocatability substitutions too (@rsub) (implies -f1)

See ASM modes and directives for a description of the @ssub and @rsub substitution modes, and the @ofix, @bfix and @rfix bugfix modes.

3 Parsing, rendering, and modes

The following subsections explain at a high level the two phases involved in transforming a skool file (and its related ref files) into HTML or ASM format: parsing and rendering. These subsections also introduce some terminology that will be used in later sections.

3.1 Parsing

In the first phase, the skool file is parsed. Parsing a skool file entails reading each line of the file, and processing any relevant skool directives and ASM directives that are found along the way.

After a skool directive or ASM directive has been processed, it is discarded, so that it cannot be 'seen' during the rendering phase. The purpose of the skool directives and ASM directives is to transform the skool file into something suitable for rendering (in either HTML or ASM format) later on.

Whether a particular skool directive or ASM directive is processed depends on the mode in which the parsing is being done: HTML mode or ASM mode.

3.1.1 HTML mode

HTML mode is used when the target output format is HTML (as opposed to ASM). In HTML mode, all skool directives are processed, but most ASM directives are ignored (because they are irrelevant to the purpose of creating the HTML disassemblies). The only ASM directives that are processed in HTML mode are those that introduce two different versions of a section of code or data: one that applies for HTML output, and another that applies for ASM output.

3.1.2 ASM mode

ASM mode is used when the target output format is ASM (as opposed to HTML). In ASM mode, all skool directives and ASM directives are processed.

3.2 Rendering

In the second phase, the skool file (stripped of all its skool directives and ASM directives during the parsing phase) is 'rendered' - as either HTML or ASM, depending on the mode.

3.2.1 HTML mode

HTML mode is used to render the skool file (and its related ref files) as a bunch of HTML files. During rendering, any skool macros found along the way are 'expanded' to the required HTML markup.

3.2.2 ASM mode

ASM mode is used to render the skool file as a single, assembler-ready ASM file. During rendering, any skool macros found along the way are 'reduced' to some appropriate plain text.

4 Data files

SkoolKit contains several data files. The following subsections describe those files, their purpose, and their format.

4.1 sd.skool

sd.skool contains all the assembly language instructions for the main routines and data blocks in Skool Daze.

4.2 sd.ref

sd.ref contains all the data required to generate the non-code parts of the HTML version of the Skool Daze disassembly, including:

4.3 bts.skool

bts.skool contains all the assembly language instructions for the main routines and data blocks in Back to Skool.

4.4 bts.ref

bts.ref contains all the data required to generate the non-code parts of the HTML version of the Back to Skool disassembly, including:

4.5 skool.ref

skool.ref contains data required to generate the non-code parts of the HTML versions of the disassemblies that are either common to both games or not game-specific, such as the glossary.

4.6 start.skool

start.skool contains the assembly language instructions for the startup routines for both Skool Daze and Back to Skool. They are placed here because they don't really fit in the main skool files (sd.skool and bts.skool).

4.7 load.skool

load.skool contains the assembly language instructions for the tape loader routines for both Skool Daze and Back to Skool.

4.8 save.skool

save.skool contains the assembly language instructions for the tape saver routines for both Skool Daze and Back to Skool.

4.9 changelog.ref

changelog.ref contains the changelog entries.

4.10 Skool file format

The skool files (sd.skool, bts.skool and the others) must be in a certain format to ensure that they are processed correctly by skool2html.py and skool2asm.py. The rules are as follows:

1. Entries (an 'entry' being a routine or data block) must be separated by blank lines, and an entry must not contain any blank lines.

2. Lines in an entry may start with one of ';*!bcgituwz ', where:

If a non-comment line starts with any other character (e.g. 'a' in load.skool), it is to distinguish it from another non-comment line with the same address.

The format of a non-comment line is:

C##### INSTRUCTION ; comment

where:

The comment for a single instruction may span multiple lines thus:

c24296 CALL 57935 ; Give up right now if the catapult pellet's buffer is ; already in use

A comment may also be associated with more than one instruction by the use of braces ('{' and '}') to indicate the start and end points, thus:

*24372 SUB D ; {Jump if ERIC's y-coordinate does not match HAYLEY's, or 24373 JR NZ,24378 ; ERIC has used up all his kisses}

Lines that start with '*' or '!' will have their addresses shown in bold in the HTML versions of the disassemblies, and will have labels generated for them in the ASM versions. '!' is used only in load.skool to distinguish one entry point from another with '*' and the same address.

3. Tables (grids) have their own markup syntax. See #TABLE for details.

4. Entry headers are a sequence of comment lines broken into three sections:

The sections are separated by an empty comment line. For example:

; This is the entry title ; ; This is the entry description ; ; A An important parameter ; B Another important parameter

4.11 Ref file format

The ref files (sd.ref, bts.ref, skool.ref and changelog.ref) are formatted into sections separated by section names inside square brackets, like this:

[SectionName]

The contents of each section follow no particular format. They may be parsed as free text, a list of key-value pairs, or something else depending on the context.

5 Ref file macros

Sections in the ref files may contain macros that will be expanded before rendering. The ref file macros recognised by SkoolKit are described in the following subsections.

5.1 ::

The :: macro is used to include the contents of another section in the current section.

For example (in sd.ref and bts.ref):

[Bug:waitingForEinstein:Waiting for EINSTEIN] ::Bug-WaitingForEinstein

This will copy the contents of the section named Bug-WaitingForEinstein (defined in skool.ref) into the current section.

5.2 ${bts:}, ${sd:}

The bts: macro is expanded only in Back to Skool mode; in Skool Daze mode it is replaced with an empty string. Conversely, the sd: macro is expanded only in Skool Daze mode; in Back to Skool mode it is replaced with an empty string.

For example (in skool.ref):

A character will be moved if bit 7 of byte ${sd:122}${bts:29} of his buffer is ${sd:re}set

In Skool Daze mode, this expands to:

A character will be moved if bit 7 of byte 122 of his buffer is reset

But in Back to Skool mode, it expands to:

A character will be moved if bit 7 of byte 29 of his buffer is set

5.3 ${f:}

The f: macro expands to a filename path computed from the names of variables in the FileInfo object (defined in skoolhtml.py).

For example (in changelog.ref):

<a class="link" href="${f:sd_dir/playarea_tiles}">Skool Daze</a>

Here, ${f:sd_dir/playarea_tiles} expands to the path of the 'Play area tiles' page in the Skool Daze disassembly, defined by the sd_dir and playarea_tiles variables of the FileInfo object.

The f: macro can also be used to call methods of the FileInfo object. For example (in changelog.ref):

...see Skool Daze command list <a class="link" href="${f:sd_dir/asm_path/asm_fname(64939)}">202</a>

Here, ${f:sd_dir/asm_path/asm_fname(64939)} expands to the path of the file containing the disassembly of the data block at 64939 in the Skool Daze disassembly; that path is defined by the following elements:

5.4 ${v:}

The v: macro expands to the value of a game variable (defined in the [Game] section of sd.ref or bts.ref).

For example (in skool.ref):

[Glossary:SRB] Screen refresh buffer at #R${v:SRBAddress}

Here, ${v:SRBAddress} expands to the value of the game variable SRBAddress (defined as '32524' in the [Game] section in sd.ref, and as '32512' in the [Game] section in bts.ref).

6 Skool directives

The skool files (sd.skool, bts.skool and the others) contain some directives that are processed during the parsing phase. These 'skool directives' are described in the following subsections.

6.1 !bts+begin, !bts+end, !sd+begin, !sd+end

These directives are used to define a section of a skool file that should be parsed in Back to Skool mode but ignored in Skool Daze mode (!bts+begin, !bts+end), or vice versa (!sd+begin, !sd+end).

For example (in load.skool):

; !sd+begin 23809 LD HL,23551 ; {INK 6: PAPER 2 *23812 LD (HL),22 ; ; !sd+end ; !bts+begin 23809 LD HL,23551 ; {INK 1: PAPER 1 *23812 LD (HL),9 ; ; !bts+end

The result here is that in Skool Daze mode only these lines are processed:

23809 LD HL,23551 ; {INK 6: PAPER 2 *23812 LD (HL),22 ;

whereas in Back to Skool mode only these lines are processed:

23809 LD HL,23551 ; {INK 1: PAPER 1 *23812 LD (HL),9 ;

6.2 !defb

The !defb directive defines bytes to be inserted into the memory snapshot for the skool file being parsed. This is used in sd.skool to define the bytes for the routines that occupy the space for the unused animatory states 104-126 and 232-254, so that those animatory states will not appear blank on the 'Animatory states' page.

For example:

c44919 LD DE,46572 ; 44922 CP 200 ; Reset the carry flag if the animatory state is >= #AS200 ; (i.e. if we're dealing with a teacher) 44924 JP 45429 ; ; !defb=44919:17,236,181,254,200,195,117,177

The !defb directive is required here because the parser (in skoolparser.py) will only convert the DEFB, DEFW, DEFM and DEFS assembler directives into a sequence of bytes; it does not convert assembly language instructions into the equivalent byte values (it is not a Z80 assembler).

6.3 !refs

The !refs directive is used to define empty entries that will not appear in the memory map for the skool file being parsed, but which JR/JP/CALL instructions should be hyperlinked to (because they are defined in some other skool file).

For example (in start.skool):

!refs=26880

This defines an empty entry for the routine at 26880 in Skool Daze, so that any JR/JP/CALL instruction with 26880 as the operand can be hyperlinked to the entry for that routine (which is defined in sd.skool). Further down in start.skool we see:

!refs=20709,21746,21920

which defines empty entries for the routines at 20709, 21746 and 21920 in Back to Skool.

7 Skool macros

The skool files (sd.skool, bts.skool and the others) and the ref files (sd.ref, bts.ref and skool.ref) contain some macros that are either 'expanded' to an appropriate piece of HTML markup (when rendering in HTML mode), or 'reduced' to an appropriate piece of plain text (when rendering in ASM mode). The skool macros recognised by SkoolKit are described in the following subsections.

7.1 #AS (Animatory State)

In HTML mode, the #AS macro expands to a hyperlink (<a> element) to an image on the 'Animatory states' page.

#AS[state][(link text)]

In ASM mode, the #AS macro reduces to the link text.

For example (from sd.skool):

56081 DEFB 16 ; #AS16=EINSTEIN

In HTML mode, this instance of the #AS macro expands to a hyperlink to the image of animatory state 16 (EINSTEIN standing/walking, phase 1) on the 'Animatory states' page.

In ASM mode, this instance of the #AS macro reduces to '16'.

7.2 #ASIMG (Animatory State IMaGe)

In HTML mode, the #ASIMG macro expands to an <img> element for the image of an animatory state.

#ASIMGnum[,scale[,mask[,attribute]]]

The #ASIMG macro is not supported in ASM mode.

If an image file matching the required properties doesn't already exist, it will be created.

For example (from bts.ref):

When BOY WANDER is sitting on the floor, there is a blank line above his head: #UDGTABLE(gglitch) { #ASIMG21,4 } UDGTABLE#

In HTML mode, this instance of the #ASIMG macro expands to an <img> element for the image for animatory state 21 (BOY WANDER sitting on the floor) at 4 times the original size.

7.3 #ASM

In HTML mode, the #ASM macro expands to a hyperlink (<a> element) to the disassembly page for a routine or data block. The routine or data block need not exist in the current skool file.

#ASMaddress[#anchor][(link text)]

In ASM mode, the #ASM macro reduces to the link text.

For example (from the entry at 58144 in bts.skool):

; The 8 bytes here are skool graphic data that is copied into page 128 by the ; #ASM33204(startup routine) after the game has loaded...

In HTML mode, this instance of the #ASM macro expands to a hyperlink to the disassembly page for the startup routine at 33204 for Back to Skool (which is defined in start.skool), with 'startup routine' as the link text.

In ASM mode, this instance of the #ASM macro reduces to 'startup routine'.

See also #R.

7.4 #ASTILE (Animatory State TILE)

In HTML mode, the #ASTILE macro expands to an HTML <img> element for the image of an animatory state tile.

#ASTILEstate,row,col[,attr[,mask[,scale]]]

The #ASTILE macro is not supported in ASM mode.

If an image file matching the required properties doesn't already exist, it will be created.

7.5 #BOX

In HTML mode, the #BOX macro expands to an <img> element for the image of a box graphic (such as the game logo or the score box, which are 64x24 pixels).

#BOXaddress[,scale[,attribute]]

The #BOX macro is not supported in ASM mode.

If an image file matching the required properties doesn't already exist, it will be created.

For example (from sd.skool):

; 'Score - 0 Lines - 0 Hi-Sc - 0' box graphic ; ; Used by the routine at #R27406. ; #UDGTABLE(udgs) ; { #BOX60928 } ; TABLE#

In HTML mode, this instance of the #BOX macro expands to an <img> element for the image of the Skool Daze score box.

7.6 #BUG

In HTML mode, the #BUG macro expands to a hyperlink (<a> element) to the 'Bugs' page, or to a specific entry on that page.

#BUG[#name][(link text)]

In ASM mode, the #BUG macro reduces to the link text.

For example (from sd.skool):

42726 DEFB 130 ; Lesson #LESSON230 (REVISION LIBRARY): #TAP130 (Reading Room) ; (this is a #BUG#emptyClass)

In HTML mode, this instance of the #BUG macro expands to a hyperlink to the entry for 'MR CREAK and the empty class' on the 'Bugs' page for Skool Daze.

In ASM mode, this instance of the #BUG macro reduces to 'bug'.

See also #FACT and #POKE.

7.7 #C (Copyright)

In HTML mode, the #C macro expands to the HTML entity reference for the copyright symbol (&#169;).

#C

In ASM mode, the #C macro reduces to '(c)'.

For example (from sd.skool):

26751 DEFB 0 ; '#C': Unused

7.8 #CBUF (Character BUFfer)

In HTML mode, the #CBUF macro expands to a hyperlink (<a> element) to the character buffer documentation page, or to a specific entry on that page.

#CBUF[#name][(link text)]

In ASM mode, the #CBUF macro reduces to the link text.

For example (in sd.skool):

; Character buffer for little boy no. 1 (152) ; ; See the #CBUF(character buffer documentation) for details of how the buffer is ; used.

In HTML mode, this instance of the #CBUF macro expands to a hyperlink to the character buffer documentation page with the link text 'character buffer documentation'.

In ASM mode, this instance of the #CBUF macro reduces to 'character buffer documentation'.

7.9 #D (Description)

In HTML mode, the #D macro expands to the title of an entry (a routine or data block) in the memory map.

#Daddress

In ASM mode, the #D macro reduces to the title of the entry.

For example (in sd.skool):

; The address of one of the following continual subcommand routines will be ; present in bytes 124 and 125 of a character's buffer: ; #TABLE(data,centre) ; { =h Address | =h Description } ; { #R25247 | RET (do nothing) } ; { #R27126 | #D27126 }

In HTML mode, this instance of the #D macro (in the last line) expands to the title of the routine at 27126 in Skool Daze.

In ASM mode, this instance of the #D macro reduces to the title of the routine at 27126 in Skool Daze.

7.10 #EREFS (Entry point REFerences)

In HTML mode, the #EREFS macro expands to a comma-separated sequence of hyperlinks (<a> elements) to the disassembly pages for the routines that jump to or call a given address.

#EREFSaddress

The #EREFS macro is not supported in ASM mode.

The #EREFS macro is not used in any of the stock SkoolKit data files, but it was used while the Skool Disassemblies were under development.

See also #REFS and #TAPS.

7.11 #FACT

In HTML mode, the #FACT macro expands to a hyperlink (<a> element) to the 'Trivia' page, or to a specific entry on that page.

#FACT[#name][(link text)]

The #FACT macro is not supported in ASM mode.

See also #BUG and #POKE.

7.12 #FONT

In HTML mode, the #FONT macro expands to an <img> element for the image of the skool font (as used on the 'Other graphics' page).

#FONT

The #FONT macro is not supported in ASM mode.

The image of the skool font will be created if it doesn't already exist.

7.13 #GBUF (Game status BUFfer)

In HTML mode, the #GBUF macro expands to a hyperlink (<a> element) to the 'Game status buffer' page, or to a specific entry on that page.

#GBUF[address][(link text)]

In ASM mode, the #GBUF macro reduces to the link text.

For example (from bts.skool):

; Next, clear the first 222 bytes of the #GBUF(game status buffer).

7.14 #KEYTABLE

In HTML mode, the #KEYTABLE macro expands to a hyperlink (<a> element) to the 'Keypress table' page, or to a specific entry on that page.

#KEYTABLE[#name][(link text)]

In ASM mode, the #KEYTABLE macro reduces to 'keypress table documentation'.

For example (from sd.skool):

; Used by the routine at #R26471. The entries in this table are pointed to by ; the the entries in the keypress offset table at #R26656. Another table of ; ASCII codes and routine addresses can be found at #R26752. For more details, ; see the #KEYTABLE.

7.15 #LESSON

In HTML mode, the #LESSON macro expands to a hyperlink (<a> element) to the page for a lesson.

#LESSONnum

In ASM mode, the #LESSON macro reduces to the lesson number.

For example (from sd.skool):

; Personal timetable for little boy no. 1 (152) ; ; Used by the routine at #R26342. b39136 DEFB 170 ; Lesson #LESSON224 (DINNER (MR WITHIT)): #TAP170 (Dinner)

In HTML mode, this instance of the #LESSON macro (in the last line) expands to a hyperlink to the page for lesson 224.

In ASM mode, this instance of the #LESSON macro reduces to '224'.

7.16 #LOAD

In HTML mode, the #LOAD macro expands to a hyperlink (<a> element) to the disassembly page for one of the tape loading routines.

#LOADaddress[#name][(link text)]

In ASM mode, the #LOAD macro reduces to the link text.

For example (from save.skool):

; The last 5 bytes of the first group (16384 to 32956) saved make important ; changes to the #LOAD32815(load routine) when the game is being loaded:

In HTML mode, this instance of the #LOAD macro expands to a hyperlink to the disassembly page for the tape loading routine at 32815 with link text 'load routine'.

In ASM mode, this instance of the #LOAD macro reduces to 'load routine'.

7.17 #MSG

In HTML mode, the #MSG macro expands to a hyperlink (<a> element) to the disassembly page for the data block containing a specific message.

#MSGnum[(link text)]

or

#MSGaddress[(link text)]

In ASM mode, the #MSG macro reduces to the link text.

For example (from bts.skool):

c21152 LD A,21 ; Message #MSG21: 'MR WACKER'

In HTML mode, this instance of the #MSG macro expands to a hyperlink to the disassembly page for the data block containing message 21 (at 61267).

In ASM mode, this instance of the #MSG macro reduces to '21'.

7.18 #MUTABLE

In HTML mode, the #MUTABLE macro expands to an <img> element for the image of a mutable object in Back to Skool (i.e. a door, a window, a cup, or the spot on the tree where the bike is chained).

#MUTABLEaddress[,padding]

The #MUTABLE macro is not supported in ASM mode.

If an image file matching the required properties doesn't already exist, it will be created.

For example (from bts.skool):

; UDG reference table for the top-floor window when shut ; ; Used by the routine at #R27672. The UDG reference table for the top-floor ; window when open is at #R55296. ; #UDGTABLE(udgs) ; { #MUTABLE55040 } ; TABLE#

In HTML mode, this instance of the #MUTABLE macro expands to an <img> element for the image of the top-floor window when shut (with no padding).

7.19 #NAME

In HTML mode, the #NAME macro expands to an anchor (<a>) element with a given name.

#NAMEname

In ASM mode, the #NAME macro reduces to an empty string.

For example (from bts.skool):

; #NAMEstaircaseMatrix ; The staircase endpoint identifiers are arranged in bytes 60-67 (corresponding ; to the destination) of pages 189-196 (corresponding to the current location) ; as follows:

In HTML mode, this instance of the #NAME macro expands to an anchor element named 'staircaseMatrix'.

In ASM mode, this instance of the #NAME macro reduces to an empty string.

7.20 #P (Paragraph)

In HTML mode, the #P macro expands to two adjacent br elements: <br /><br />.

#P

In ASM mode, the #P macro reduces to an empty string.

For example (from bts.skool):

; Print a tile ; ; Used by the routines at #R25026, #R25080 and #R25248. Copies a tile of the ; play area into the back buffer at #R57712, superimposes character sprite tiles ; as appropriate, and then copies the resultant tile to the screen. Also sets ; the corresponding attribute byte. ; #P ; The play area graphic data is laid out across pages 128 to 181:

In HTML mode, this instance of the #P macro, along with the others in the entry for the routine at 24684 in Back to Skool, is used to separate the (long) description into paragraphs.

In ASM mode, this instance of the #P macro, along with the others, is reduced to an empty string.

7.21 #PATILE (Play Area TILE)

In HTML mode, the #PATILE macro expands to an <img> element for the image of a play area tile.

#PATILEx,y[,scale]

The #PATILE macro is not supported in ASM mode.

If an image with the required properties doesn't already exist, it will be created.

7.22 #POKE

In HTML mode, the #POKE macro expands to a hyperlink (<a> element) to the 'Pokes' page, or to a specific entry on that page.

#POKE[#name][(link text)]

The #POKE macro is not supported in ASM mode.

For example (from bts.ref):

If you want to check this for yourself but can't bear to wait for playtime to come, try the POKEs that enable ERIC to #POKE#ringBell(ring the bell).

In HTML mode, this instance of the #POKE macro expands to a hyperlink to the entry for 'Ring the bell' on the 'Pokes' page for Back to Skool, with link text 'ring the bell'.

See also #BUG and #FACT.

7.23 #POKES (POKE Snapshot)

In HTML mode, the #POKES macro is used to POKE values into the current memory snapshot.

#POKESaddress,byte[,length[,step]]

The #POKES macro is not supported in ASM mode.

For example (in bts.ref):

To make the line transparent: #PUSHSeh2 #POKES47254,255 #UDGTABLE(gglitch) { #ASIMG54,4 } { POKE 47254,255 } UDGTABLE# #POPS

In HTML mode, this instance of the #POKES macro does POKE 47254,255, which fixes the graphic glitch in the animatory state of EINSTEIN lying down. The #ASIMG macro (see #ASIMG) further down then expands to an img element for the image of the fixed animatory state.

See also #PUSHS and #POPS.

7.24 #POPS (POP Snapshot)

In HTML mode, the #POPS macro removes the current memory snapshot and replaces it with the one that was previously saved by a #PUSHS macro.

#POPS

The #POPS macro is not supported in ASM mode.

See also #PUSHS and #POKES.

7.25 #PT (Personal Timetable)

In HTML mode, the #PT macro expands to a hyperlink (<a> element) to the disassembly page containing a character's personal timetable.

#PTnum[(link text)]

The #PT macro is not supported in ASM mode.

For example (from sd.ref):

MR ROCKITT never teaches in the Map Room. See his #PT164(personal timetable).

In HTML mode, this instance of the #PT macro expands to a hyperlink to the disassembly page containing the personal timetable for MR ROCKITT (whose character number is 164), with the link text 'personal timetable'.

7.26 #PUSHS (PUSH Snapshot)

As a skool file is being parsed, a memory snapshot is built up from all the DEFB, DEFW, DEFM and DEFS instructions, and also any !defb directives (see !defb). After the file has been parsed, the memory snapshot is used to build images of the skool graphic elements (animatory states, score box etc.) for the HTML disassemblies.

In HTML mode, the #PUSHS macro saves the current snapshot, and replaces it with an identical copy with a given name.

#PUSHSname

The #PUSHS macro is not supported in ASM mode.

The new snapshot may then be modified by using the #POKES macro. The snapshot name is used to indicate that the current snapshot is a modified version of the original (which has no name).

For example (in bts.ref):

To make the line transparent: #PUSHSeh2 #POKES47254,255 #UDGTABLE(gglitch) { #ASIMG54,4 } { POKE 47254,255 } UDGTABLE# #POPS

In HTML mode, this instance of the #PUSHS macro creates a new snapshot (copied from the original) named 'eh2'. This snapshot is then modified with a #POKES macro. Further on, the #ASIMG macro (see #ASIMG) will expand to an <img> element for the image of animatory state 54 (scaled up by a factor of 4) built from the current snapshot ('eh2').

See also #POKES and #POPS.

7.27 #R (Reference)

In HTML mode, the #R macro expands to a hyperlink (<a> element) to the disassembly page for a routine or data block, or to a line at a given address within that page. The routine or data block being referred to must exist in the skool file.

#Raddress[#name][(link text)]

In ASM mode, the #R macro reduces to the label for address, or to address if no label is found.

For example (from sd.skool):

; Scroll the screen left one column ; ; Used by the routine at #R25820.

In HTML mode, this instance of the #R macro expands to a hyperlink to the disassembly page for the routine at 25820 in Skool Daze.

In ASM mode, this instance of the #R macro reduces to 'LSCROLL8' (the label for the routine at 25820).

See also #ASM.

7.28 #REFS (REFerenceS)

In HTML mode, the #REFS macro expands to a comma-separated sequence of hyperlinks (<a> elements) to the disassembly pages for the routines that jump to or call a given routine, or jump to or call any entry point within that routine.

#REFSaddress[(prefix)]

If there are no references, the macro expands to the following text:

Not used directly by any other routines

The #REFS macro is not supported in ASM mode.

The #REFS macro is not used in any of the stock SkoolKit data files, but it was used while the Skool Disassemblies were under development.

See also #EREFS and #TAPS.

7.29 #REG (REGister)

In HTML mode, the #REG macro expands to a styled <span> element containing a register name.

#REGreg

In ASM mode, the #REG macro reduces to the name of the register.

The register name must contain 1, 2 or 3 of the following characters:

abcdefhlirspxy'

For example (from sd.skool):

24623 LD C,31 ; #REGbc'=31

7.30 #SAVE

In HTML mode, the #SAVE macro expands to a hyperlink (<a> element) to the disassembly page for the tape saver routine.

#SAVE[#name][(link text)]

In ASM mode, the #SAVE macro reduces to the link text.

For example (from sd.skool):

32494 JP 33024 ; Jump into the #SAVE(save routine)

In HTML mode, this instance of the #SAVE macro expands to a hyperlink to the disassembly page for the tape saver routine with link text 'save routine'.

In ASM mode, this instance of the #SAVE macro reduces to 'save routine'.

7.31 #SCR (SCReenshot)

In HTML mode, the #SCR macro expands to an <img> element for the image constructed from the display file and attribute bytes of the current memory snapshot (in turn constructed from the contents of the skool file).

#SCR

The #SCR macro is not supported in ASM mode.

The screenshot image will be created if it doesn't already exist.

For example (from save.skool):

; #TABLE(scr,,scrDesc) ; { #SCR | This is the program used to save the fast code block for Skool Daze. } ; TABLE#

7.32 #SKOOL

In HTML mode, the #SKOOL macro expands to an <img> element for an image of the play area (or a portion of the play area).

#SKOOLx,y,w,h[,scale[,showChars[,showX]]]

The #SKOOL macro is not supported in ASM mode.

If an image of the play area matching the requirements doesn't already exist, it will be created.

For example (from bts.ref):

#UDGTABLE(udgs) { #SKOOL0,0,96,21,1,0,8 } { #SKOOL96,0,96,21,1,0,8 } UDGTABLE#

In HTML mode, the first instance of the #SKOOL macro here expands to an <img> element for an image of the left half of the play area of Back to Skool, with scale 1, no game characters displayed, and x-coordinates shown at 0, 8, 16, 24 and so on.

7.33 #SPACE

In HTML mode, the #SPACE macro expands to one or more '&nbsp;' expressions.

#SPACE[num]

In ASM mode, the #SPACE macro reduces to num spaces.

For example (from sd.skool):

t56832 DEFM "TAKE 2000 LINES YOU NASTY BOY" 56861 DEFB 3 ; #R55830: '#SPACE8' (8 spaces)

In HTML mode, this instance of the #SPACE macro expands to:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

In ASM mode, this instance of the #SPACE macro reduces to a string containing 8 spaces.

7.34 #START

In HTML mode, the #START macro expands to a hyperlink (<a> element) to the disassembly page for the startup routine.

#START[#name][(link text)]

The #START macro is not supported in ASM mode.

For example (from load.skool):

a32906 RET ; To (23833)=#START

In HTML mode, this instance of the #START macro expands to a hyperlink to the disassembly page for the startup routine (24288 in Skool Daze, 33204 in Back to Skool), with the address of that routine as the link text.

7.35 #TABLE

The #TABLE macro marks the beginning of a table; TABLE# is used to mark the end. Between these markers, the rows of the table are defined.

#TABLE[(class[,class1[:w][,class2[:w]...]])]<rows>TABLE#

The rows in a table must start with '{ ' and end with ' }'. The cells in a row must be separated by ' | '.

For example (from the routine at 29052 in bts.skool):

; And then the action identifier: ; #TABLE(data) ; { 0 | Close it } ; { 1 | Open it } ; TABLE#

This table has two rows and two columns, and will have the CSS class 'data'.

By default, cells will be rendered as <td> elements. To specify that a <th> element should be used instead, use the =h indicator before the cell contents:

; #TABLE ; { =h Header 1 | =h Header 2 } ; { Regular cell | Another one } ; TABLE#

It is also possible to specify colspan and rowspan attributes using the =c and =r indicators:

; #TABLE ; { =r2 2 rows | X | Y } ; { =c2 2 columns } ; TABLE#

Finally, the =t indicator specifies that a cell should be transparent (i.e. inherit its parent element's background colour).

If a cell requires more than one indicator, the indicators should be separated by commas:

; #TABLE ; { =h,c2 Wide header } ; { Column 1 | Column 2 } ; TABLE#

In ASM mode, tables are rendered as plain text, using dashes (-) and pipes (|) for the borders, and plus signs (+) where a horizontal border meets a vertical border.

ASM mode also supports the :w indicator in the #TABLE macro's arguments. The :w indicator marks a column as a candidate for having its width reduced (by wrapping the text it contains) so that the table will be no more than 79 characters wide when rendered. For example:

; #TABLE(data,centre,:w) ; { =h X | =h Description } ; { 0 | Text in this column will be wrapped in ASM mode to make the table less than 80 characters wide } ; TABLE#

See also #UDGTABLE.

7.36 #TAP

In HTML mode, the #TAP macro expands to a hyperlink (<a> element) to the disassembly page for a command list.

#TAPnum

In ASM mode, the #TAP macro reduces to the command list number.

For example (from sd.skool):

; Make a little boy find and follow little boy no. 1 ; ; Used by command list #TAP206 (which is used by little boys 2-11).

In HTML mode, this instance of the #TAP macro expands to a hyperlink to the disassembly page for command list 206 in Skool Daze.

In ASM mode, this instance of the #TAP macro reduces to '206'.

7.37 #TAPS

In HTML mode, the #TAPS macro expands to a comma-separated list of hyperlinks (<a> elements) to the disassembly pages for the command lists that contain a given routine address.

#TAPSaddress

The #TAPS macro is not supported in ASM mode.

The #TAPS macro is not used in any of the stock SkoolKit data files, but it was used while the Skool Disassemblies were under development.

See also #EREFS and #REFS.

7.38 #TIME

In ASM mode, the #TIME macro expands to the following string:

Generated by skool2asm on Mon 18 Jan 2010 14:48:56 AST

(with the timestamp replaced by the current time).

#TIME

The #TIME macro is not supported in HTML mode.

7.39 #UDG

In HTML mode, the #UDG macro expands to an <img> element for the image of a UDG (an 8x8 block of pixels).

#UDGaddress,attribute[,scale[,step[,increment]]]

The #UDG macro is not supported in ASM mode.

If an image of the UDG matching the required properties doesn't already exist, it will be created.

For example (from bts.skool):

; Safe key UDG ; ; Used by the routine at #R31746. ; #UDGTABLE(udgs) ; { #UDG39144,6 } ; TABLE#

In HTML mode, this instance of the #UDG macro expands to an <img> element for the image of the safe key UDG, with attribute byte 6 (INK 6: PAPER 0).

7.40 #UDGTABLE

The #UDGTABLE macro is used to mark the beginning of a table that will contain images. It is used instead of the #TABLE macro to indicate up-front that the table should not be rendered in ASM mode.

See #TABLE.

8 ASM modes and directives

The two main skool files (sd.skool and bts.skool) contain directives that are processed when parsing in ASM mode. Exactly how a directive is processed (and whether it is executed) depends on the 'substitution mode' and 'bugfix mode' in which the skool file is being parsed.

8.1 Substitution modes

There are three substitution modes: @isub, @ssub, and @rsub. These modes are described in the following subsections.

8.1.1 @isub mode

In @isub mode, @isub directives are executed, but @ssub, and @rsub directives are not. The main purpose of @isub mode is to make the minimum number of instruction substitutions necessary to produce an ASM file that assembles.

For example (from sd.skool):

; @isub=LD A,(32512) 25396 LD A,(m) ; Pick up the byte holding the signal flag for this event

This @isub directive ensures that 'LD A,(m)' is replaced by the valid instruction 'LD A,(32512)'.

@isub mode is invoked by default when running skool2asm.py.

8.1.2 @ssub mode

In @ssub mode, @isub and @ssub directives are executed, but @rsub directives are not. The main purpose of @ssub mode is to replace LSBs, MSBs and full addresses in the operands of instructions with labels, to make the code amenable to some degree of relocation, but without actually removing or inserting any code.

For example (from sd.skool):

; @ssub=LD (27015+1),A *25091 LD (27016),A ; Change the instruction at #R27015 from SET n,(HL) to ; SET n+1,(HL) or SET 0,(HL)

This @ssub directive replaces 'LD (27016),A' with 'LD (27015+1),A'; the '27015' will be replaced by the label for that address before rendering. (27016 cannot be replaced by a label, since it is not the address of an instruction.)

@ssub mode is invoked by passing the '-s' option to skool2asm.py.

8.1.3 @rsub mode

In @rsub mode, @isub, @ssub and @rsub directives are executed. The main purpose of @rsub mode is to make code unconditionally relocatable, even if that requires the removal of existing code or the insertion of new code.

For example (from sd.skool):

25313 LD L,99 ; {Change the address in bytes 99 and 100 of the ; @ssub=LD (HL),25317%256 25315 LD (HL),229 ; character's buffer from #R25303 to #R25317 (below) ; @rsub+begin INC L LD (HL),25317/256 ; @rsub+end ; }

This @rsub block directive inserts two instructions that ensure that the address in bytes 99 and 100 of the character's buffer has the correct MSB as well as the correct LSB, regardless of where the code originally at 25317 now lives.

@rsub mode is invoked by passing the '-r' option to skool2asm.py. @rsub mode also implies @ofix mode; see below for a description of @ofix mode and the other bugfix modes.

8.2 Bugfix modes

There are three bugfix modes: @ofix, @bfix and @rfix. These modes are described in the following subsections.

8.2.1 @ofix mode

In @ofix mode, @ofix directives are executed, but @bfix and @rfix directives are not. The main purpose of @ofix mode is to fix instructions that have faulty operands.

For example (from sd.skool):

; @ofix-begin ; @nowarn 27872 CALL 27633 ; This should be CALL #R27634 - is ERIC beside a chair? ; @ofix+else CALL 27634 ; Is ERIC beside a chair? ; @ofix+end

These @ofix block directives fix the faulty operand of the CALL instruction at 27872.

@ofix mode is invoked by passing the '-f1' option to skool2asm.py.

8.2.2 @bfix mode

In @bfix mode, @ofix and @bfix directives are executed, but @rfix directives are not. The main purpose of @bfix mode is to fix bugs by replacing instructions, but without changing the start address of any routines, routine entry points, or data blocks.

For example (from bts.skool):

32203 BIT 2,(HL) ; Is ERIC sitting (facing left) or lying down? ; @bfix-begin 32205 JR Z,32232 ; Tell ERIC to sit facing the stage if not (this is a ; #BUG#assemblySit) ; @bfix+else JR NZ,32232 ; Tell ERIC to sit facing the stage if so ; @bfix+end

@bfix mode is invoked by passing the '-f2' option to skool2asm.py.

8.2.3 @rfix mode

In @rfix mode, @ofix, @bfix and @rfix directives are executed. The purpose of @rfix mode is to fix bugs that cannot be fixed without moving code around (to make space for the fix).

For example (from sd.skool):

; @rfix-begin ; ERIC has been hit by the pellet. Knock him over. ; @rfix+else ; ERIC is in the same location as the pellet. Can he be knocked over? 28017 LD A,(44128) ; #REGa=ERIC's animatory state AND 15 ; Keep only the 'action' bits (bits 0-3) CP 6 ; Is ERIC standing, midstride, or sitting in a chair? RET NC ; Return if not (he can't be knocked over) ; @rfix+end

These @rfix block directives insert some instructions to fix the bug in Skool Daze where ERIC can be hit by BOY WANDER's pellet even when he's sitting on the floor or lying down.

@rfix mode is invoked by passing the '-f3' option to skool2asm.py. @rfix mode implies @rsub mode (see @rsub mode).

8.3 ASM directives

The ASM directives recognised by SkoolKit are described in the following subsections.

8.3.1 @bfix

The @bfix directive is used to make an instruction substitution in @bfix mode.

; @bfix=INSTRUCTION

For example (from sd.skool):

; @bfix=DEFM "Phosphorus" t57532 DEFM "Phosphorous"

8.3.2 @bfix block directives

The @bfix block directives are used to define a block of lines that will be inserted or removed in @bfix mode.

The syntax for defining a block that will be inserted in @bfix mode is:

; @bfix+begin ... ; Lines to be inserted ; @bfix+end

The syntax for defining a block that will be removed in @bfix mode is:

; @bfix-begin ... ; Lines to be removed ; @bfix-end

Typically, though, it is desirable to define a block that will be removed in @bfix mode right next to the block that should be inserted in its place. That may be done thus:

; @bfix-begin ... ; Instructions to be removed ; @bfix+else ... ; Instructions to be inserted ; @bfix+end

which is equivalent to:

; @bfix-begin ... ; Instructions to be removed ; @bfix-end ; @bfix+begin ... ; Instructions to be inserted ; @bfix+end

For example (from bts.skool):

; @bfix-begin 26211 SET 7,(HL) ; Set bit 7 of ERIC's primary status flags, indicating that ; he's been knocked to the floor; however, bit 7 is ignored ; by the routine at #R63405 (because bit 2 is also set), so ; ERIC actually stays in his seat (which is a #BUG#seat) ; @bfix+else LD (HL),128 ; Set bit 7 of ERIC's primary status flags, indicating that ; he's been knocked to the floor ; @bfix+end

These @bfix block directives fix the bug where ERIC cannot be pushed out of his seat by changing the instruction at 26211 from 'SET 7,(HL)' to 'LD (HL),128'.

8.3.3 @ignoremrcua

The @ignoremrcua directive is used to suppress any warnings that would otherwise be reported concerning addresses not converted to labels in the mid-routine comment above the next instruction.

; @ignoremrcua

For example (from bts.skool):

; @ignoremrcua ; R=5, 6 or 7. The next section of code is intended to set the x-coordinate for ; the new free mouse to 10 provided that X>=56, or try again with a new random ; number (R) if X<56. However, as noted above, #REGhl may now hold 32522 or ; 32600 instead of #R32767, and so the contents of 32522 or 32600 (instead of X) ; may be compared with 56. Thus it is possible for the new free mouse to appear ; at x-coordinate 10 even when X<56, which means it could appear on-screen. This ; is a #BUG#rematerialisingMouse.

If the @ignoremrcua directive were not present, warnings would be printed (during the rendering phase) about the comment containing addresses (32522, 32600) that cannot be converted to labels.

8.3.4 @ignoreua

The @ignoreua directive is used to suppress any warnings that would otherwise be reported concerning addresses not converted to labels in the comment for the next instruction.

; @ignoreua

For example (from sd.skool):

; @ignoreua c60139 LD HL,784 ; {These parameters were meant for the routine at #R65122; 60142 LD DE,12896 ; however, the CALL below is to 62818 (98,245) instead of 60145 LD A,1 ; #R65122 (98,254), which is a #BUG#jumpSound}

If the @ignoreua directive were not present, a warning would be printed (during the rendering phase) about the comment containing an address (62818) that cannot be converted to a label.

8.3.5 @isub

The @isub directive is used to make an instruction substitution in @isub mode.

; @isub=INSTRUCTION

For example (in sd.skool):

; @isub=LD A,(32512) 25396 LD A,(m) ; Pick up the byte holding the signal flag for this event

8.3.6 @isub block directives

The @isub block directives are used to define a block of lines that will be inserted or removed in @isub mode.

The syntax is equivalent to that for the @bfix block directives.

8.3.7 @keep

The @keep directive is used to prevent the substitution of a label for the operand in the next instruction (but only when the instruction has not been replaced using an @isub or @ssub directive).

; @keep

For example (in sd.skool):

; @keep 28328 LD BC,24576 ; #REGb=96, #REGc=0 (maximum and minimum bounds)

If the @keep directive were not present, the operand (24576) of the 'LD BC' instruction would be replaced with a label (because there is a routine at 24576); however, the operand is meant to be a pure data value, not a variable or routine address.

8.3.8 @label

The @label directive sets the label for the next instruction.

; @label=LABEL

For example (from sd.skool):

; @label=RSCROLL c24576 EXX

This sets the label for the routine at 24576 to 'RSCROLL'.

See also @rlabel.

8.3.9 @nolabel

The @nolabel directive is used to prevent the next instruction from having a label automatically generated.

; @nolabel

For example (from bts.skool):

; Determine where to release another mouse. ; @bfix+begin ; @label=NEXTR ; @bfix+end 31607 LD HL,32767 ; #R32767 holds the column of the play area at the far left ; of the screen ; @bfix+begin ; @nolabel ; @bfix+end *31610 CALL 25233 ; {#REGa=R, a random number from 0 to 7; we'll use this to 31613 AND 7 ; determine where the new free mouse will be placed}

The @nolabel directive here prevents the instruction at 31610 from being labelled in @bfix mode (because no label is required; instead, the previous instruction at 31607 will be labelled).

The output from this section of bts.skool in @bfix mode will be:

; Determine where to release another mouse. NEXTR: LD HL,LEFTCOL ; LEFTCOL holds the column of the play area at the ; far left of the screen CALL GETRANDOM ; A=R, a random number from 0 to 7; we'll use this to AND 7 ; determine where the new free mouse will be placed

And the output when not in @bfix mode will be:

; Determine where to release another mouse. LD HL,LEFTCOL ; LEFTCOL holds the column of the play area at the ; far left of the screen CATCHMORF_0: CALL GETRANDOM ; A=R, a random number from 0 to 7; we'll use this to AND 7 ; determine where the new free mouse will be placed

8.3.10 @nowarn

The @nowarn directive is used to suppress any warnings that would otherwise be reported for the next instruction concerning:

; @nowarn

For example (from sd.skool):

; @nowarn 25560 LD BC,25404 ; Point #REGbc at #R25404 (guide character to intermediate ; destination)

If this @nowarn directive were not present, a warning would be printed (during the parsing phase) about the operand (25404) being replaced with a routine label (which would be inappropriate if 25404 were intended to be a pure data value).

For another example (also from sd.skool):

; @ofix-begin ; @nowarn 27872 CALL 27633 ; This should be CALL #R27634 - is ERIC beside a chair? ; @ofix+else CALL 27634 ; Is ERIC beside a chair? ; @ofix+end

If this @nowarn directive were not present, a warning would be printed (during the parsing phase, if not in @ofix mode) about the operand (27633) not being replaced with a label (usually you would want the operand of a CALL instruction to be replaced with a label, but not in this case).

8.3.11 @ofix

The @ofix directive is used to make an instruction substitution in @ofix mode.

; @ofix=INSTRUCTION

The stock skool files distributed with SkoolKit do not make use of this directive; instead they use the @ofix block directives.

Anyway, an example usage would be:

; @ofix=JR NZ,26067 25989 JR NZ,26068

which would replace the operand of the 'JR NZ' instruction with 26067.

8.3.12 @ofix block directives

The @ofix block directives are used to define a block of lines that will be inserted or removed in @ofix mode.

The syntax is equivalent to that for the @bfix block directives.

8.3.13 @org

The @org directive inserts an ORG assembler directive.

; @org=ADDRESS

8.3.14 @rem

The @rem directive is used to make an illuminating comment about a nearby section or other ASM directive in a skool file. The directive is ignored by the parser.

; @rem COMMENT

For example (from bts.skool):

; @rem This table must be 256 bytes after the table for the skool gate when shut ; @org=64000 ; UDG reference table for the skool gate when open

If this @rem directive were not present, I might one day be tempted to remove the @org directive that follows, having forgotten why it's actually extremely important.

8.3.15 @rfix block directives

The @rfix block directives are used to define a block of lines that will be inserted or removed in @rfix mode.

The syntax is equivalent to that for the @bfix block directives.

8.3.16 @rlabel

The @rlabel directive sets the label for the next instruction, but only when parsing in @rsub mode.

; @rlabel=LABEL

For example (from sd.skool):

; @rsub+begin INC L LD (HL),31861/256 LD A,E CP 62 JR Z,31892 LD (HL),31895/256 ; @rsub+end ; } ; @rlabel=DINSTEP 31892 JP 25404 ; Proceed to the other end of the dinner hall

This sets the label for the instruction at 31892 to 'DINSTEP', so that the operand of the 'JR Z,31892' instruction (which is included only in @rsub mode) a few lines up can be converted to that label.

See also @label.

8.3.17 @rsub

The @rsub directive is used to make an instruction substitution in @rsub mode.

; @rsub=INSTRUCTION

For example (from sd.skool):

; @rsub=INC BC 30143 INC C ; Move #REGbc along in the graphic data table

8.3.18 @rsub block directives

The @rsub block directives are used to define a block of lines that will be inserted or removed in @rsub mode.

The syntax is equivalent to that for the @bfix block directives.

8.3.19 @ssub

The @ssub directive is used to make an instruction substitution in @ssub mode.

; @ssub=INSTRUCTION

For example (from sd.skool):

; @ssub=LD HL,44128+3 25864 LD HL,44131 ; Point #REGhl at byte 99 of ERIC's buffer

8.3.20 @start

The @start directive indicates where to start parsing the skool file for the purpose of generating ASM output. Everything before the @start directive is ignored.

; @start

9 Disassembly DIY

9.1 sna2skool.py

SkoolKit includes a utility script called sna2skool.py that can be used to convert a 48K SNA or Z80 snapshot into a skool file. To try it out, copy a Z80 snapshot of Skool Daze (call it skool_daze.z80) to the directory containing SkoolKit, and then run the following command from that directory:

$ ./sna2skool.py skool_daze.z80 > sd-blank.skool

Now take a look at sd-blank.skool. As you can see, by default, sna2skool.py disassembles everything from 16384 to 65535, treating it all as code. Needless to say, this is not particularly useful - unless you have no idea where the code and data blocks are yet, and want to use this disassembly to find out.

Once you have figured out where the code and data blocks are, it would be handy if you could supply sna2skool.py with this information, so that it can disassemble the blocks accordingly. That is where the control file comes in.

9.2 The control file

A control file contains a list of start addresses of code and data blocks. Each address is marked with a 'control directive', which is a single letter that indicates what the block contains:

(If these letters remind you of the valid characters that may appear in the first column of each line of a skool file, that is no coincidence.)

For example:

c 24576 b 32768 t 49152 u 64000

This control file declares that:

9.3 A skeleton skool disassembly

So if we had a control file for Skool Daze, we could produce a much more useful skool file. As it happens, SkoolKit includes one: sd.ctl. You can use it with sna2skool.py thus:

$ ./sna2skool.py -c sd.ctl skool_daze.z80 > sd-blank.skool

This time, sd-blank.skool is split up into meaningful blocks, with code as code, data as data (DEFBs), and text as text (DEFMs). Much nicer.

The next step is to create an HTML disassembly from this skool file:

$ ./skool2html.py -f sd-blank.skool html

Now open html/sd-blank/index.html in a web browser. There's not much there, but it's a base from which you can start adding comments to sd-blank.skool (remembering to use skool macros where appropriate to insert hyperlinks and images) and create your own Skool Daze disassembly.

To replace the word 'sd-blank' in the page titles, we need to give the game a name. This can be done by creating a ref file called sd-blank.ref that contains the following lines:

[Game] Game=Skool Daze

Then run skool2html.py again to re-generate the HTML. Alternatively, you could create a game logo image (in PNG format) and copy it to html/sd-blank/images/logo.png; the image will be used instead of the game name if it is present.

To create a skeleton skool disassembly for Back to Skool too, use the supplied bts.ctl file with a snapshot of the game (call it back_to_skool.z80):

$ ./sna2skool.py -c bts.ctl back_to_skool.z80 > bts-blank.skool $ ./skool2html.py -f bts-blank.skool html

Open html/bts-blank/index.html to start browsing this newborn disassembly.

9.4 Generating a control file

If you are planning to create a disassembly of some game other than Skool Daze or Back to Skool, you will need to create your own control file. To get started, you can use the '-g' option with sna2skool.py to perform a rudimentary static code analysis of the snapshot file and generate a corresponding control file:

$ ./sna2skool.py -g game.ctl game.z80 > game.skool

This will do a reasonable job of splitting the snapshot into blocks, but you will need to examine the resultant skool file (game.skool in this case) to see which blocks should be marked as text or data instead of code, and then edit the generated control file (game.ctl) accordingly.

Blocks whose contents resemble text are given a title like this:

Routine/text? at 26836

Blocks whose contents resemble neither code nor text are given a title like this:

Routine/data? at 26624

Any other blocks are assumed to contain code and are given a title like this:

Routine at 24576

9.5 Other disassembly options

If you know that there is nothing of interest in the snapshot before address 24576 (for example), you can tell sna2skool.py to start disassembling from that address (instead of 16384) by using the '-s' option:

$ ./sna2skool.py -s 24576 -g game.ctl game.z80 > game.skool

To make it easier to find messages (strings) in the snapshot, use the '-t' option:

$ ./sna2skool.py -t -g game.ctl game.z80 > game.skool

This will add to the comment field, for each line of the disassembly, the ASCII equivalent of the disassembled bytes.

9.6 Adding pokes, bugs, trivia and a glossary

Adding 'Pokes', 'Bugs', 'Trivia' and 'Glossary' pages to a disassembly is done by adding Poke, Bug, Fact and Glossary sections to the ref file. For any such sections that are present, skool2html.py will add links to the disassembly index page.

For example, let's add a poke. Add the following lines to sd-blank.ref (or bts-blank.ref if you're playing with the skeleton Back to Skool disassembly):

[Poke:greatPoke:Great POKE] The following POKE is great: POKE 45678,9

Now run skool2html.py again:

$ ./skool2html.py -f sd-blank.skool html

Open html/sd-blank/index.html and you should see a link to the 'Pokes' page in the 'Reference' section.

The format of a Poke section is:

[Poke:anchor:Title] First paragraph. Second paragraph. ...

where:

Paragraphs should be separated by blank lines.

The format of a Bug or Fact section is the same, except that the section name prefix is Bug: or Fact: (instead of Poke:) as appropriate.

One Poke, Bug or Fact section should be added for each poke, bug or trivia item to be documented. Entries will appear on the 'Pokes', 'Bugs' or 'Trivia' page in the same order as the sections appear in the ref file.

The format of a Glossary section is slightly different:

[Glossary:term] Description

The description should be a single paragraph. For example:

[Glossary:Chuntable] Likely to be affected by a disturbance in the chuntey (q.v.)

9.7 skool v. ASM

If, instead of a skool file, you'd rather create an assembler-ready ASM file from a snapshot, sna2skool.py can do that with the '-a' option:

$ ./sna2skool.py -c sd.ctl -a skool_daze.z80 > sd-blank.asm

10 Changelog

10.1 SkoolKit 1.0.6 (2010-02-04)

Above each entry point in a code block, sna2skool.py will insert a comment containing a list of the routines that call or jump to that entry point.

10.2 SkoolKit 1.0.5 (2010-02-03)

Made the following changes to sna2skool.py:

10.3 SkoolKit 1.0.4 (2010-02-02)

Made the following changes to sna2skool.py:

10.4 SkoolKit 1.0.3 (2010-02-01)

10.5 SkoolKit 1.0.2 (2010-01-31)

Modified sna2skool.py so that it:

10.6 SkoolKit 1.0.1 (2010-01-30)

Fixed the following bugs in sna2skool.py:

10.7 SkoolKit 1.0 (2010-01-28)

Initial public release.

11 Bugs

The following bugs in SkoolKit do not (currently) affect the HTML or ASM rendering, so there is no pressing need to fix them.

1. If the last entry in a skool file has an end comment (i.e. a comment after the last instruction), it is not picked up in the parsing phase, and so will not be rendered.

2. If a table (defined between #TABLE and TABLE# markers) contains a cell with rowspan > 1 and its contents are wrapped, adjacent cells with rowspan = 1 are rendered incorrectly in ASM mode.

3. In verbose ('-v') mode, skool2asm.py does not show lines inserted or removed by the @isub, @rsub, @ofix, @bfix and @rfix block directives.

4. This documentation does not describe the sections in the ref files.