SkoolKit components — SkoolKit 9.6 documentation (original) (raw)

SkoolKit relies on several components in order to function:

The objects that are used for these components can be specified in the[skoolkit] section of skoolkit.ini.

[skoolkit]

Global configuration for SkoolKit can be specified in the [skoolkit]section of a file named skoolkit.ini either in the current working directory or in ~/.skoolkit. The default contents of this section are as follows:

[skoolkit] Assembler=skoolkit.z80.Assembler AudioWriter=skoolkit.audio.AudioWriter CodeMapReader=skoolkit.snactl CommentGenerator=skoolkit.comment.CommentGenerator ControlDirectiveComposer=skoolkit.skoolctl.ControlDirectiveComposer ControlFileGenerator=skoolkit.snactl DefaultDisassemblyStartAddress=16384 Disassembler=skoolkit.disassembler.Disassembler HtmlTemplateFormatter=skoolkit.skoolhtml.TemplateFormatter ImageWriter=skoolkit.image.ImageWriter InstructionUtility=skoolkit.skoolparser.InstructionUtility OperandEvaluator=skoolkit.z80 OperandFormatter=skoolkit.disassembler.OperandFormatter RSTHandler=skoolkit.rst.RSTHandler RSTHandlerConfig=8:B SnapshotReader=skoolkit.snapshot SnapshotReferenceCalculator=skoolkit.snaskool SnapshotReferenceOperations=DJ,JR,JP,CA,RS

Most of the parameters in the [skoolkit] section specify the objects to use for SkoolKit’s pluggable components. The other recognised parameters are:

Assembler

This object is responsible for converting assembly language instructions and DEFB/DEFM/DEFS/DEFW statements into byte values, or computing their size. It must supply the following API functions, in common with skoolkit.z80.Assembler:

class skoolkit.z80.Assembler

assemble(operation, address)

Convert an assembly language instruction or DEFB/DEFM/DEFS/DEFW statement into a sequence of byte values.

Parameters:

Returns:

A sequence of byte values (empty if the instruction cannot be assembled).

get_size(operation, address)

Compute the size (in bytes) of an assembly language instruction or DEFB/DEFM/DEFS/DEFW statement.

Parameters:

Returns:

The instruction size, or 0 if the instruction cannot be assembled.

Audio writer

This class is responsible for writing audio files. It must supply the following API methods, in common with skoolkit.audio.AudioWriter:

class skoolkit.audio.AudioWriter(config=None)

Initialise the audio writer.

Parameters:

config – A dictionary constructed from the contents of the[AudioWriter] section of the ref file.

formats()

Return a sequence of filename extensions (including the ‘.’) corresponding to the audio formats supported by this writer.

write_audio(audio_file, delays, contention=False, interrupts=False, offset=0, ma_filter=False, is128k=False)

Write an audio file.

Parameters:

Code map reader

This object is reponsible for generating a list of code block start addresses and lengths from a code map file and corresponding snapshot. The code map reader object must supply the following API function, in common with skoolkit.snactl:

skoolkit.snactl.read_map(fname, snapshot, start, end)

Read a code map.

Parameters:

Returns:

A list of 2-element sequences of the form (address, length)corresponding to the code blocks in snapshot.

If read_map() encounters an error while reading a code map file, it should raise a CodeMapError:

class skoolkit.snactl.CodeMapError

Raised when an error occurs while reading a code map file.

Control directive composer

This class is responsible for computing the type, length and sublengths of a DEFB/DEFM/DEFS/DEFW statement, or the operand bases of a regular instruction, for the purpose of composing a control directive. It must supply the following API methods, in common with skoolkit.skoolctl.ControlDirectiveComposer:

class skoolkit.skoolctl.ControlDirectiveComposer(preserve_base)

Initialise the control directive composer.

Parameters:

preserve_base – Whether to preserve the base of decimal and hexadecimal values with explicit ‘d’ and ‘h’ base indicators.

compose(operation)

Compute the type, length and sublengths of a DEFB/DEFM/DEFS/DEFW statement, or the operand bases of a regular instruction.

Parameters:

operation – The operation (e.g. ‘LD A,0’ or ‘DEFB 0’).

Returns:

A 3-element tuple, (ctl, length, sublengths), where:

If compose() encounters an error while parsing an operation and cannot recover, it should raise a SkoolParsingError:

class skoolkit.SkoolParsingError

Raised when an error occurs while parsing a skool file.

Control file generator

This object is reponsible for generating a dictionary of control directives from a snapshot. Each key in the dictionary is an address, and the associated value is the control directive (e.g. ‘b’ or ‘c’) for that address. The control file generator object must supply the following API function, in common with skoolkit.snactl:

skoolkit.snactl.generate_ctls(snapshot, start, end, code_map, config)

Generate control directives from a snapshot.

Parameters:

Returns:

A dictionary of control directives.

Changed in version 9.6: Added the handle_rst attribute to the config object.

Disassembler

This class is responsible for converting byte values into assembly language instructions and DEFB/DEFM/DEFS/DEFW statements. It must supply the following API methods, in common with skoolkit.disassembler.Disassembler:

class skoolkit.disassembler.Disassembler(snapshot, config)

Initialise the disassembler.

Parameters:

defb_range(start, end, sublengths)

Produce a sequence of DEFB statements for an address range.

Parameters:

Returns:

A list of instruction objects created by imaker.

defm_range(start, end, sublengths)

Produce a sequence of DEFM statements for an address range.

Parameters:

Returns:

A list of instruction objects created by imaker.

defs_range(start, end, sublengths)

Produce a sequence of DEFS statements for an address range.

Parameters:

Returns:

A list of instruction objects created by imaker.

defw_range(start, end, sublengths)

Produce a sequence of DEFW statements for an address range.

Parameters:

Returns:

A list of instruction objects created by imaker.

disassemble(start, end, base)

Disassemble an address range.

Parameters:

Returns:

A list of instruction objects created by imaker.

The imaker callable used by these methods must accept three positional arguments:

The opcodes list is defined by the Opcodes configuration parameter ofsna2skool.py.

The sublengths argument of the defb_range(), defm_range(),defs_range() and defw_range() methods is a sequence of 2-element tuples of the form (size, base), each of which specifies the desired size (in bytes) and number base for an item in the DEFB/DEFM/DEFS/DEFW statement.base may have one of the following values:

If the first element of sublengths has a size value of 0, then the method should produce a list of statements with default sizes (as determined bydefb_size, defm_size and defw_size), using the specified base.

Changed in version 9.6: Added the handle_rst attribute to the disassembler configuration object.

Changed in version 9.3: Added the imaker and opcodes attributes to the disassembler configuration object. API methods must now return objects created by_imaker_.

Changed in version 8.5: Added the ability to disassemble an instruction that wraps around the 64K boundary, along with the wrap attribute on the disassembler configuration object to control this behaviour.

HTML template formatter

This class is responsible for formatting HTML templates. It must supply the following API methods, in common with skoolkit.skoolhtml.TemplateFormatter:

class skoolkit.skoolhtml.TemplateFormatter(templates)

Initialise the template formatter.

Parameters:

templates – A dictionary of templates keyed by template name.

format_template(page_id, name, fields)

Format a template.

Parameters:

Returns:

The text of the formatted template.

Image writer

This class is responsible for constructing images and writing them to files. It must supply the following API methods, in common with skoolkit.image.ImageWriter:

class skoolkit.image.ImageWriter(config=None, palette=None)

Initialise the image writer.

Parameters:

If config or palette is None, empty, or missing values, default values are used.

image_fname(fname)

Convert the fname parameter of an image macro into an image filename with an appropriate extension.

Parameters:

fname – The fname parameter of the image macro.

Returns:

The image filename.

write_image(frames, img_file)

Write an image file. If this method leaves the image file empty, the file will be removed.

Parameters:

Returns:

The content with which the image macro is replaced; if None, an appropriate <img .../> element is used.

Instruction utility

This object is responsible for performing various operations on the instructions in a skool file:

The object must supply the following API functions, in common with skoolkit.skoolparser.InstructionUtility:

class skoolkit.skoolparser.InstructionUtility

calculate_references(entries, remote_entries)

Generate a dictionary of references (for each instruction that refers to another instruction) and a dictionary of referrers (for each instruction that is referred to by other instructions) from the instructions in a skool file.

Parameters:

Returns:

A tuple containing the two dictionaries.

convert(entries, base, case)

Convert the base and case of every instruction in a skool file.

Parameters:

set_byte_values(instruction, assemble)

Decide whether to set byte values in the memory snapshot and for an instruction.

If byte values are set in the memory snapshot, then they are available to the #PEEK macro and the image macros. If byte values are set for an instruction, then they are available for display in HTML output via the instruction[bytes] replacement field in the asm template.

Parameters:

Returns:

2 if both the snapshot and the instruction should have byte values defined, 1 if only the snapshot should, or 0 if neither should.

substitute_labels(entries, remote_entries, labels, mode, warn)

Replace addresses with labels in the operands of every instruction in a skool file.

Parameters:

Memory map entries and remote entries have the following attributes:

Each instruction object has the following attributes:

Each key in the references dictionary should be an instruction object, and the corresponding value should be a 3-element tuple:

(ref_instruction, address_s, use_label)

Each key in the referrers dictionary should be an instruction object, and the corresponding value should be a collection of the entries that refer to that instruction.

Changed in version 8.2: Added the refs and rrefs attributes to instruction objects.

Changed in version 8.1: Added the mode parameter to the substitute_labels() method, and changed the required signature of the warn function. Added the _nowarn_and sub attributes to instruction objects.

Operand evaluator

This object is used by the assembler to evaluate instruction operands, and by the control directive composer to determine the length and sublengths of DEFB, DEFM and DEFS statements. It must supply the following API functions, in common with skoolkit.z80:

skoolkit.z80.eval_int(text)

Evaluate an integer operand.

Parameters:

text – The operand.

Returns:

The integer value.

Raises:

ValueError if the operand is not a valid integer.

skoolkit.z80.eval_string(text)

Evaluate a string operand.

Parameters:

text – The operand, including enclosing quotes.

Returns:

A list of byte values.

Raises:

ValueError if the operand is not a valid string.

skoolkit.z80.split_operands(text)

Split a comma-separated list of operands.

Parameters:

text – The operands.

Returns:

A list of individual operands.

Operand formatter

This class is used by the disassembler to format numeric instruction operands. It must supply the following API methods, in common with skoolkit.disassembler.OperandFormatter:

class skoolkit.disassembler.OperandFormatter(config)

Initialise the operand formatter.

Parameters:

config

Configuration object with the following attributes:

format_byte(value, base)

Format a byte value.

Parameters:

Returns:

The formatted byte value.

format_word(value, base)

Format a word (2-byte) value.

Parameters:

Returns:

The formatted word value.

is_char(value)

Return whether a byte value can be formatted as a character.

Parameters:

value – The byte value.

RST handler

This class is used by the control file generator (when activated by the --handle-rst option of sna2ctl.py) and by thedisassembler (when activated by the --handle-rstoption of sna2skool.py) to handle the arguments of RST instructions. It must supply the following API methods, in common with skoolkit.rst.RSTHandler:

class skoolkit.rst.RSTHandler(config)

Initialise the RST instruction handler.

Parameters:

config – The value of the RSTHandlerConfig configuration parameter in skoolkit.ini.

handle(snapshot, address)

If there is an RST instruction at address in snapshot and it has arguments, return a sub-block descriptor for those arguments. Otherwise return None.

Parameters:

The sub-block descriptor returned by handle() must be 2-element tuple of the form:

where:

Each sublength in sublengths must be a 2-element tuple of the form:

where:

skoolkit.rst.RSTHandler is configured by the RSTHandlerConfig parameter in_skoolkit.ini_. Its value must be a comma-separated list of RST specifications of the form:

where:

The default value of RSTHandlerConfig is 8:B, which makes RSTHandler produce sub-block descriptors for the byte arguments of ‘RST $08’ instructions, and ignore all other RST instructions.

When activated by the --handle-rst option of sna2ctl.py orsna2skool.py, the RST handler’s handle() method is called for every address at which an instruction - RST or otherwise - is identified. This means that a custom RST handler component could be implemented to handle the byte/word arguments of CALL instructions as well as or instead of RST instructions, for example.

Snapshot reader

This object is responsible for producing a list of byte values from a snapshot file. It must supply the following API functions, in common with skoolkit.snapshot:

skoolkit.snapshot.can_read(fname)

Return whether this snapshot reader can read the file fname.

skoolkit.snapshot.get_snapshot(fname, page=None)

Read a snapshot file and produce a list of byte values. For a 48K snapshot, or a 128K snapshot with a page number (0-7) specified, the list contains 65536 (64K) elements: a blank 16K ROM followed by 48K RAM. For a 128K snapshot with page equal to -1, the list contains 131072 (128K) elements: RAM banks 0-7 (16K each) in order.

Parameters:

Returns:

A list of byte values.

If get_snapshot() encounters an error while reading a snapshot file, it should raise a SnapshotError:

class skoolkit.snapshot.SnapshotError

Raised when an error occurs while reading a snapshot file.

Snapshot reference calculator

This object is responsible for generating a dictionary of entry point addresses from a snapshot. Each key in the dictionary is an entry point address, and the associated value is a collection of entries that jump to, call or otherwise refer to that entry point. This dictionary is needed by sna2skool.py for marking each entry point in a skool file with an asterisk, and listing its referrers.

The snapshot reference calculator must supply the following API function, in common with skoolkit.snaskool:

skoolkit.snaskool.calculate_references(entries, operations)

For each instruction address in a memory map entry, calculate a list of the entries containing instructions that jump to, call or otherwise refer to that address.

Parameters:

Returns:

A dictionary of entry point addresses.

The value of the operations argument is derived from theSnapshotReferenceOperations parameter in the [skoolkit] section ofskoolkit.ini. In its default form, this parameter is a comma-separated list of regular expression patterns that designates ‘DJNZ’, ‘JR’, ‘JP’, ‘CALL’ and ‘RST’ operations as those whose address operands will be used to identify entry points in the skool file:

SnapshotReferenceOperations=DJ,JR,JP,CA,RS

To use a pattern that contains a comma, an alternative (non-alphabetic) separator can be specified in the first character of the parameter value. For example:

SnapshotReferenceOperations=;DJ;JR;JP;CA;RS;LD A,(\i);LD (\i),A

This would additionally designate the ‘LD A,(nn)’ and ‘LD (nn),A’ operations as identifying entry points. As a convenience for dealing with decimal and hexadecimal numbers, wherever \i appears in a pattern, it is replaced by a pattern that matches a decimal number or a hexadecimal number preceded by$.

Each memory map entry has the following attributes:

Each instruction object has the following attributes:

Changed in version 8.5: The SnapshotReferenceOperations parameter defines a list of regular expression patterns.

Changed in version 8.2: Added the refs and rrefs attributes to instruction objects.

Component API

The following functions are provided to facilitate access to the components and other values declared in the [skoolkit] section of skoolkit.ini.

skoolkit.components.get_component(name, *args)

Return a component declared in the [skoolkit] section ofskoolkit.ini.

Parameters:

skoolkit.components.get_value(name)

Return a parameter value from the [skoolkit] section ofskoolkit.ini.

Parameters:

name – The parameter name.