# SkoolKit components

SkoolKit relies on several components in order to function:

- Assembler

- Audio writer

- AY audio writer

- Code map reader

- Comment generator

- Control directive composer

- Control file generator

- Disassembler

- HTML template formatter

- Image writer

- Instruction utility

- Operand evaluator

- Operand formatter

- RST handler

- Screen

- Snapshot reader

- Snapshot reference calculator

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
    AYAudioWriter=skoolkit.ay.AYAudioWriter
    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
    Screen=skoolkit.screen.Screen
    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:

- `DefaultDisassemblyStartAddress` - the address at which to start disassembling a snapshot when no control file is provided; this is used by sna2ctl.py and sna2skool.py, and also by snapinfo.py when generating a call graph

- `RSTHandlerConfig` - the configuration parameter for the RST handler

- `SnapshotReferenceOperations` - the instructions whose address operands are used by the snapshot reference calculator to identify entry points in routines and data blocks

## 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:

      - operation – The operation to convert (e.g. ‘XOR A’).

      - address – The instruction address.

    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:

      - operation – The operation (e.g. ‘XOR A’).

      - address – The instruction address.

    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, options)

    Write an audio file.

    Parameters:

      - audio_file – The file object to write the audio to.

      - delays – A sequence of integers representing the intervals (in T-states) between speaker flips.

      - options –

        Configuration object with the following attributes:

        - contention - whether to simulate additional delays due to memory and I/O contention

        - interrupts - whether to simulate additional delays due to interrupts

        - is128k - whether to use 128K timings

        - offset - the offset (in T-states) of the first speaker flip from the start of the frame (used when contention or interrupts is True)

        - volume - audio volume percentage

Changed in version 10.1: Moved the contention, interrupts, offset and is128k arguments of the write_audio() method into the options object, alongside the new volume attribute.

Changed in version 10.0: Removed the ma_filter argument of the write_audio() method.

## AY audio writer

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

class skoolkit.ay.AYAudioWriter(config=None)

  Initialise the AY 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, audio_log, options)

    Write an audio file.

    Parameters:

      - audio_file – The file object to write the audio to.

      - audio_log –

        The log of beeper and AY output. It is a list of 3-element sequences of the form `(t, r, v)`, where:

        - `t` is the time in T-states

        - `r` is either the AY register (0-13), or 255 to indicate a beeper flip

        - `v` is the AY register value (if applicable)

      - options –

        Configuration object with the following attributes:

        - ay_res - AY sample resolution (in T-states)

        - beeper - whether to include beeper audio

        - mode - AY stereo mode: 0 - mono; 1 - ABC; 2 - ACB

        - volume - audio volume percentage

## Code map reader

This object is responsible 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:

    - fname – The name of the code map file.

    - snapshot – The snapshot (list of 65536 byte values) corresponding to the code map.

    - start – The start address.

    - end – The end address.

  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.

## Comment generator

This class is responsible for generating instruction comments. It must supply the following API method, in common with skoolkit.comment.CommentGenerator:

class skoolkit.comment.CommentGenerator
  get_comment(instruction)

    Return an instruction comment. The instruction object has the following attributes:

    - address - the address of the instruction

    - bytes - the byte values of the instruction

## 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:

      - `ctl` is ‘B’ (DEFB), ‘C’ (regular instruction), ‘S’ (DEFS), ‘T’ (DEFM) or ‘W’ (DEFW)

      - `length` is the number of bytes in the DEFB/DEFM/DEFS/DEFW statement, or the operand base indicator for a regular instruction (e.g. ‘b’ for ‘LD A,%00000001’)

      - `sublengths` is a colon-separated sequence of sublengths (e.g. ‘1:c1’ for ‘DEFB 0,”a”’), or None for a regular instruction

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 responsible 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:

    - snapshot – The snapshot.

    - start – Start address. No control directives should be generated before this address.

    - end – End address. No control directives should be generated after this address.

    - code_map – Code map filename (may be None).

    - config –

      Configuration object with the following attributes:

      - handle_rst - whether to handle RST instruction arguments

      - text_chars - string of characters eligible for being marked as text

      - text_min_length_code - minimum length of a string of characters eligible for being marked as text in a block identified as code

      - text_min_length_data - minimum length of a string of characters eligible for being marked as text in a block identified as data

      - words - collection of allowed words; if not empty, a string of characters should be marked as text only if it contains at least one of the words in this collection

  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:

    - snapshot – The snapshot (list of 65536 byte values) to disassemble.

    - config –

      Configuration object with the following attributes:

      - asm_hex - if True, produce a hexadecimal disassembly

      - asm_lower - if True, produce a lower case disassembly

      - defb_size - default maximum number of bytes in a DEFB statement

      - defm_size - default maximum number of characters in a DEFM statement

      - defw_size - default maximum number of words in a DEFW statement

      - handle_rst - if True, handle RST instruction arguments

      - imaker - callable that returns an instruction object

      - opcodes - comma-separated list of values specifying additional opcode sequences to disassemble

      - wrap - if True, disassemble an instruction that wraps around the 64K boundary

  defb_range(start, end, sublengths)

    Produce a sequence of DEFB statements for an address range.

    Parameters:

      - start – The start address.

      - end – The end address.

      - sublengths – Sequence of sublength identifiers.

    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:

      - start – The start address.

      - end – The end address.

      - sublengths – Sequence of sublength identifiers.

    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:

      - start – The start address.

      - end – The end address.

      - sublengths – Sequence of sublength identifiers.

    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:

      - start – The start address.

      - end – The end address.

      - sublengths – Sequence of sublength identifiers.

    Returns:

      A list of instruction objects created by imaker.

  disassemble(start, end, base)

    Disassemble an address range.

    Parameters:

      - start – The start address.

      - end – The end address.

      - base – Base indicator (‘b’, ‘c’, ‘d’, ‘h’, ‘m’ or ‘n’). For instructions with two numeric operands (e.g. ‘LD (IX+d),n’), the indicator may consist of two letters, one for each operand (e.g. ‘dh’).

    Returns:

      A list of instruction objects created by imaker.

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

- `address` - the address of the instruction

- `operation` - the operation (e.g. ‘XOR A’, ‘DEFB 1’)

- `data` - a sequence of byte values for the instruction (e.g. (62, 0) for ‘LD A,0’)

The opcodes list is defined by the `Opcodes` configuration parameter of sna2skool.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:

- ‘b’ - binary

- ‘c’ - character

- ‘d’ - decimal

- ‘h’ - hexadecimal

- ‘m’ - negative

- ‘n’ - default base

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 by defb_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:

      - page_id – The ID of the current page.

      - name – The template name.

      - fields – A dictionary of replacement field values.

    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:

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

    - palette – A dictionary constructed from the contents of the [Colours] section of the ref file. Each key is a colour name, and each value is a three-element tuple representing an RGB triplet.

  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:

      - frames – A list of `Frame` objects from which to build the image.

      - img_file – The file object to write the image to.

    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:

- converting base and case

- replacing addresses with labels (or other addresses) in instruction operands; this is required both for ASM output and for binary output

- generating a dictionary of references (for each instruction that refers to another instruction); this is required for hyperlinking instruction operands in HTML output

- generating a dictionary of referrers (for each instruction that is referred to by other instructions); this is required by the special `EREF` and `REF` variables of the #FOREACH macro

- deciding whether to set byte values; this affects the #PEEK macro and the image macros, and instruction byte values in HTML output

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:

      - entries – A collection of memory map entries.

      - remote_entries – A collection of remote entries (as defined by @remote directives).

    Returns:

      A tuple containing the two dictionaries.

  convert(entries, base, case)

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

    Parameters:

      - entries – A collection of memory map entries.

      - base – The base to convert to: 0 for no conversion, 10 for decimal, or 16 for hexadecimal.

      - case – The case to convert to: 0 for no conversion, 1 for lower case, or 2 for upper case.

  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:

      - instruction – The instruction.

      - assemble – The current value of the assemble property (as set by the @assemble directive).

    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:

      - entries – A collection of memory map entries.

      - remote_entries – A collection of remote entries (as defined by @remote directives).

      - labels – A dictionary mapping addresses to labels.

      - mode – The substitution mode: 1 (`@isub`), 2 (`@ssub`), 3 (`@rsub`), or 0 (none).

      - warn –

        A function to be called if a warning is generated when attempting to replace an address in an instruction operand with a label. The function must accept two arguments:

        - message - the warning message.

        - instruction - the instruction object.

Memory map entries and remote entries have the following attributes:

- ctl - the entry’s control directive (‘b’, ‘c’, ‘g’, ‘i’, ‘s’, ‘t’, ‘u’ or ‘w’ for a memory map entry; None for a remote entry)

- instructions - a collection of instruction objects

Each instruction object has the following attributes:

- address - the address of the instruction as stated in the skool file; note that this will not be the same as the actual address of the instruction if it has been moved by the insertion, removal or replacement of other instructions by `@*sub` or `@*fix` directives

- keep - None if the instruction has no @keep directive; an empty collection if it has a bare @keep directive; or a collection of addresses if it has a @keep directive with one or more values

- nowarn - None if the instruction has no @nowarn directive; an empty collection if it has a bare @nowarn directive; or a collection of addresses if it has a @nowarn directive with one or more values

- operation - the operation (e.g. ‘XOR A’) after any `@*sub` or `@*fix` directives have been applied; for an instruction in a remote entry, this is an empty string

- refs - the addresses of the instruction’s indirect referrers, as declared by a @refs directive

- rrefs - the addresses of the instruction’s direct referrers to be removed, as declared by a @refs directive

- sub - True if the operation was supplied by `@*sub` or `@*fix` directive, False otherwise

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)

- `ref_instruction` - the instruction referred to

- `address_s` - the address string in the operand of the referring instruction (to be replaced by a hyperlink in HTML output)

- `use_label` - whether to use a label as the link text for the hyperlink in HTML output; if no label for `ref_instruction` is defined, or `use_label` is False, the address string (`address_s`) will be used as the link text

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:

    - asm_hex - if True, default base is hexadecimal

    - asm_lower - if True, format operands in lower case

  format_byte(value, base)

    Format a byte value.

    Parameters:

      - value – The byte value.

      - base – The desired base (‘b’, ‘c’, ‘d’, ‘h’, ‘m’ or ‘n’).

    Returns:

      The formatted byte value.

  format_word(value, base)

    Format a word (2-byte) value.

    Parameters:

      - value – The word value.

      - base – The desired base (‘b’, ‘c’, ‘d’, ‘h’, ‘m’ or ‘n’).

    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 the disassembler (when activated by the `--handle-rst` option 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:

      - snapshot – The memory snapshot.

      - address – The address of an instruction.

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

    (subctl, sublengths)

where:

- `subctl` is the sub-block control directive: ‘B’ (DEFB) or ‘W’ (DEFW)

- `sublengths` is a sequence of one or more sublengths for the sub-block

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

    (size, base)

where:

- `size` is the size in bytes

- `base` is the number base: ‘b’ (binary), ‘d’ (decimal), ‘h’ (hexadecimal), ‘m’ (minus) or ‘n’ (none/default)

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:

    addr:subctl

where:

- `addr` is the address of the RST routine (0, 8, etc.)

- `subctl` is ‘B’ (for byte arguments) or ‘W’ (for word arguments)

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 or sna2skool.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.

## Screen

This class is responsible for displaying screen contents and reading the keyboard while Z80 code execution is being simulated. It must supply the following API methods, in common with skoolkit.screen.Screen:

class skoolkit.screen.Screen(scale, fps, caption, is128k)

  Initialise the screen.

  Parameters:

    - scale – The screen scale factor.

    - fps – The target frame rate.

    - caption – Window title bar text.

    - is128k – Whether to use 128K screen draw timings.

  draw(scr, frame, border, keyboard=None)

    Draw the screen.

    Parameters:

      - scr – A 6912-element list of byte values from the display file and attribute file.

      - frame – Frame number (used to determine the state of flashing cells).

      - border – A log of the output to port 0xFE.

      - keyboard – A list for capturing the keyboard state.

    Returns:

      False if the window has been closed, True otherwise.

border is a non-empty list of 2-element tuples of the form `(t, v)`, where:

- `t` is the OUT time in T-states

- `v` is the OUT value (border colour in bits 0-2)

After processing, the contents of border are replaced by a single item of the form `(0, v)`, where `v` is the OUT value of the last item in the list as it was upon entry.

If provided, keyboard is populated with eight values, each one corresponding to the state of a keyboard row:

- row 0: CS-Z-X-C-V

- row 1: A-S-D-F-G

- row 2: Q-W-E-R-T

- row 3: 1-2-3-4-5

- row 4: 6-7-8-9-0

- row 5: Y-U-I-O-P

- row 6: H-J-K-L-ENTER

- row 7: B-N-M-SS-SPACE

Bit 0 of each value is 1 if and only if the outermost key in the row is being pressed (e.g. SPACE in row 7), bit 1 corresponds to the next key in the row, and so on up to the innermost key in bit 4 (e.g. CAPS SHIFT in row 0).

## 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:

    - fname – The snapshot filename.

    - page – The page number (0-7) to map to addresses 49152-65535 (C000-FFFF), or -1 to return all RAM banks. This is relevant only when reading a 128K snapshot file.

  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:

    - entries – A collection of memory map entries.

    - operations – A tuple of regular expression patterns. The address operand of any instruction whose operation matches one of these patterns identifies an entry point that will be marked with an asterisk in the skool file.

  Returns:

    A dictionary of entry point addresses.

The value of the operations argument is derived from the `SnapshotReferenceOperations` parameter in the `[skoolkit]` section of skoolkit.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:

- ctl - the entry’s control directive (‘b’, ‘c’, ‘g’, ‘i’, ‘s’, ‘t’, ‘u’ or ‘w’)

- instructions - a collection of instruction objects

Each instruction object has the following attributes:

- address - the address of the instruction

- bytes - the byte values of the instruction

- label - the instruction’s label, as defined by a @label directive

- operation - the operation (e.g. ‘XOR A’)

- refs - the addresses of the instruction’s indirect referrers, as declared by a @refs directive

- rrefs - the addresses of the instruction’s direct referrers to be removed, as declared by a @refs directive

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 of skoolkit.ini.

  Parameters:

    - name – The component name.

    - args – Arguments passed to the component’s constructor.

skoolkit.components.get_value(name)

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

  Parameters:

    name – The parameter name.