A control file contains a list of start addresses of code and data blocks. This information can be used by sna2skool.py to organise a skool file into corresponding code and data blocks.
Each address in a control file 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 Do stuff
b 24832 Important data
t 25088 Interesting messages
u 25344 Unused
This control file declares that:
Addresses may be written as hexadecimal numbers, too; the equivalent example control file using hexadecimal notation would be:
c $6000 Do stuff
b $6100 Important data
t $6200 Interesting messages
u $6300 Unused
Besides the declaration of block types, addresses and titles, the control file syntax also supports the declaration of the following things:
The syntax for declaring these things is described in the following sections.
To provide a description for a code block at 24576 (for example), use the D directive thus:
c 24576 This is the title of the routine at 24576
D 24576 This is the description of the routine at 24576.
If the description consists of two or more paragraphs, each one should be declared with a separate D directive:
D 24576 This is the first paragraph of the description of the routine at 24576.
D 24576 This is the second paragraph of the description of the routine at 24576.
To declare the values of the registers upon entry to the routine at 24576, add one line per register with the R directive thus:
R 24576 A An important value in the accumulator
R 24576 DE Display file address
To declare a mid-block comment that will appear above the instruction at 24592, use the D directive thus:
D 24592 The next section of code does something really important.
If the mid-block comment consists of two or more paragraphs, each one should be declared with a separate D directive:
D 24592 This is the first paragraph of the mid-block comment.
D 24592 This is the second paragraph of the mid-block comment.
To declare a comment that will appear at the end of the routine at 24576, use the E directive thus:
E 24576 And so the work of this routine is done.
If the block end comment consists of two or more paragraphs, each one should be declared with a separate E directive:
E 24576 This is the first paragraph of the end comment for the routine at 24576.
E 24576 This is the second paragraph of the end comment for the routine at 24576.
Sometimes a block marked as one type (code, data, text, or whatever) may contain instructions or statements of another type. For example, a word (w) block may contain the odd non-word here and there. To declare such sub-blocks whose type does not match that of the containing block, use the following syntax:
w 32768 A block containing mostly words
B 32800,3 But here's a sub-block of 3 bytes at 32800
T 32809,8 And an 8-byte text string at 32809
C 32821,10 And 10 bytes of code at 32821 too?
The directives (B, T and C) used here to mark the sub-blocks are the upper case equivalents of the directives used to mark top-level blocks (b, t and c). The comments at the end of these sub-block declarations are taken as instruction-level comments and will appear as such in the resultant skool file.
If an instruction-level comment spans a group of two or more sub-blocks of different types, it must be declared with an M directive:
M 40000,21 This comment covers the following 3 sub-blocks
B 40000,3
W 40003,10
T 40013,8
If the length parameter is omitted from an M directive, the comment is assumed to cover all sub-blocks from the given start address to the end of the top-level block.
Three bits of sub-block syntax left. First, the blank sub-block directive:
c 24576 A great routine
24580,11 A great section of code at 24580
This is equivalent to:
c 24576 A great routine
C 24580,11 A great section of code at 24580
That is, the the type of a blank sub-block directive is taken to be the same as that of the parent block.
Next, the address range:
c 24576 A great routine
24580-24590 A great section of code at 24580
This is equivalent to:
c 24576 A great routine
24580,11 A great section of code at 24580
That is, you can specify the extent of a sub-block using either an address range, or an address and a length.
Finally, the implicit sub-block extent:
c 24576 A great routine
24580 A great section of code at 24580
24588,10 Another great section of code at 24590
This is equivalent to:
c 24576 A great routine
24580,8 A great section of code at 24580
24588,10 Another great section of code at 24588
But the declaration of the length (8) of the sub-block at 24580 is redundant, because the sub-block is implicitly terminated by the declaration of the sub-block at 24588 that follows. This is exactly how top-level block declarations work: each top-level block is implicitly terminated by the declaration of the next one.
Normally, a B sub-block declared thus:
B 24580,12 Interesting data
would result in something like this in the corresponding skool file:
24580 DEFB 1,2,3,4,5,6,7,8 ; {Interesting data
24588 DEFB 9,10,11,12 ; }
But what if you wanted to split the data in this sub-block into groups of 3 bytes each? That can be achieved with:
B 24580,12,3 Interesting data
which would give:
24580 DEFB 1,2,3 ; {Interesting data
24583 DEFB 4,5,6
24586 DEFB 7,8,9
24589 DEFB 10,11,12 ; }
That is, in a B directive, the desired DEFB statement lengths may be given as a comma-separated list of numbers following the sub-block length parameter, and the final number in the list is used for all remaining data in the block. So, for example:
B 24580,12,1,2,3 Interesting data
would give:
24580 DEFB 1 ; {Interesting data
24581 DEFB 2,3
24583 DEFB 4,5,6
24586 DEFB 7,8,9
24589 DEFB 10,11,12 ; }
If the statement length list contains sequences of two or more identical lengths, as in:
B 24580,21,2,2,2,2,2,2,1,1,1,3
then it may be abbreviated thus:
B 24580,21,2*6,1*3,3
The same syntax can be used for T, W and Z sub-blocks too. For example:
Z 32768,100,25 Four 25-byte chunks of zeroes
would give:
32768 DEFS 25 ; {Four 25-byte chunks of zeroes
32793 DEFS 25
32818 DEFS 25
32843 DEFS 25 ; }
To declare an ASM directive for a block or an individual instruction, use the following syntax:
; @directive:address[=value]
where:
For example, to declare a @label directive for the instruction at 32768:
; @label:32768=LOOP
Note that neither ASM block directives (such as the @bfix block directives) nor the exact location of the block-level ASM directives @org, @start and @end can be preserved using this syntax.
A control file can be useful in the early stages of developing a skool file for reorganising code and data blocks, but it cannot preserve the following elements:
Skool file templates, however, can preserve all of these elements, and so may be a better choice for skool files that contain any of them.