Skip to content
This repository has been archived by the owner on Feb 12, 2023. It is now read-only.

Creating Configurations

utz82 edited this page May 28, 2017 · 3 revisions

MDAL configurations describe the relation between the user input (in form of an MDAL module) and the data output (usually in form of assembly data). More specifically, MDAL configurations do three things:

  1. Specify the overall structure of an MDAL module for a given sound driver, and define the MDAL commands available to the user.
  2. Define the structure of the data output for the target sound driver.
  3. Describe how the user input is converted into data output.

Contents


General Concepts

Users provide input in form of an MDAL module through the use of commands. Any statement in an MDAL module is considered a command. MDAL itself does not provide any commands, save for a very small set of standard commands. The set of commands that is available to the user is, for the most part, defined in the configuration file. The configuration file is thus the essential puzzle piece that is needed to have an MDAL compiler do anything meaningful.

A module consists of a number of different blocks, which closely mimic the structure of a tracker module. In essence, all blocks are user-defined sets of data. The first block in an MDAL module is always the header block, which specifies the configuration to be used, and may additionally set various global commands, as defined by the configuration. This is usually followed by a sequence block, which contains an order list of data block pointers, thereby setting the general structure of the song. Furthermore, a number of data blocks may be present. Any number of different data block types can be present in an MDAL module. Block types are derived from a set of standard types, including patterns, fx tables, and other generic blocks.

Data blocks consist of one or more rows, which you can think of as single-note measures in terms of classical sheet music notation. Any command can only be used once per row. As an intermediate compilation step, the data input from commands used in data blocks is internally converted into data fields. The relation between commands and fields is again specified in the configuration.

In order to create an MDAL configuration for your sound driver, you will need to take the following steps:

  1. Specify some global settings
  2. Define one or more commands
  3. Define one or more block types
  4. Specify the data fields to be used for every block type.
  5. Specify how the sequence is constructed from the pattern blocks.

Syntax

MDAL configurations are written in XML, and follow XML syntax rules. Most importantly, this means:

  • Elements must have a closing tag.
  • Tags are case-sensitive.
  • Attribute values must be quoted.
  • Characters & and < are forbidden in statements.

By default, MDAL configurations use the the .mdconf file extension.

Unless type checking is required, MDAL treats all value statements as strings. Where integer values are required, they can either be supplied in decimal or hexadecimal form. Hexadecimal numbers are prefixed with $. Boolean values are indicated with true|false.

MDAL ignores whitespace between elements, and trims leading and trailing whitespace in statements.

Each MDAL configuration must be enclosed in the <mdalconfig> root tag, which in turn must specify the version attribute.


Quickstart Example

A minimal MDAL configuration example, containing only the mandatory tags and attributes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--The standard XML prolog. Not strictly required, 
but may cause problems with parsers if omitted.-->
<mdalconfig version="1">
  <!--The root tag and MDAL version specification.-->
  <sequence tracks="1" />
  <!--The sequence configuration, specifying the number of tracks
  to use in the sequence.-->
  <commands>
  <!--The command configuration block.-->
    <command id="NOTE" size="word" />
    <!--A command definition. This defines a command
    named "NOTE", which produces two bytes (one word) of data 
    output.-->
  </commands>
  <blocktype id="Patterns" type="pattern">
  <!--A blocktype configuration. This defines a blocktype
  named "Patterns", which is of base type "pattern".-->
    <field size="word">
    <!--A data field configuration. The data output from
    this field will be two bytes (1 word).-->
      <set from="NOTE" />
      <!--Specify that the field's output value will be
      set from input to the NOTE command.-->
    </field>
  </blocktype>
</mdalconfig>

Global Settings

<mdalconfig>

The mandatory root tag. All configuration elements must be enclosed in it.

Parent: none

Children: <global>, <commands>, <blocktype>, <sequence>

attribute required Parameter Type Description
version yes unsigned int Specify the MDAL version to use. Current version is 1.

<global>

Optional definition of global parameters. May only occur once in the configuration.

Parent: <mdalconfig>

Children: none

attribute required Parameter Type Description
target no string Specify the target platform of the sound driver. This setting has no effect on data output, but may be read by applications using MDAL.
byte_directive no string Specify which assembly directive to use for byte definitions. Defaults to db.
word_directive no string Specify which assembly directive to use for word definitions. Defaults to dw.
hex_prefix no string Specify which prefix to use for hexadecimal numbers. Defaults to $.

Command Configuration

<commands>

Mandatory tag which encloses the command definitions. This tag has no attributes, and must occur exactly once in the configuration.

Parent: <mdalconfig>

Children: <command>


<command>

Defines an MDAL module command. At least one command must be defined.

Parent: <mdalconfig><commands>

Children: <auto>, <allow_modifiers>, <default_substitute>, <force_int>, <force_repeat>, <force_string>, <global_const>, <range>, <reference>, <substitute>, <use_last_set>, <use_note_names>

attribute required Parameter Type Description
id yes string Specify a unique command ID. Commonly MDAL uses UPPERCASE strings for command IDs.
size yes flag Specify the data size of the commands. Available flags: bool, byte, word
default no string Specify the command's default value. Defaults to false for bool commands, and 0 for byte/word commands.

<auto>

Specify that users do not need to supply a value for this command. Instead, the parameter of the value attribute is supplied whenever the command is used.

Parent: <mdalconfig><commands><command>

Children: none

attribute required Parameter Type Description
value yes string Specify the parameter to be supplied when the command is used.

<allow_modifiers>

Allow common arithmetic operators to be used to modify arguments to this command. This setting has no effect on data output, but may be read by applications using MDAL. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


<default_substitute>

Specify that the command's default value will be supplied from another command, usually a global constant.

Parent: <mdalconfig><commands><command>

Children: none

attribute required Parameter Type Description
from yes command ID Specify which command should supply the default value.

<force_int>

Configure the command to only accept unsigned integer arguments. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


<force_repeat>

Configure the command to be repeated on every row of data blocks using it, even if the user does not set it. The last used value will be substituted. If no value has previously been set by the user, the default value will be substituted. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


<force_string>

Configure the command to reject integer and bool arguments. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


<global_const>

Configure the command to be a global constant. Global constants can only be set outside of data blocks, and can be set only once per module. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


<range>

Limit the range of integer arguments to the command. Note that the range check can be bypassed by supplying a string argument to the command. To enforce strict checking, you should additionally set <force_int>.

Parent: <mdalconfig><commands><command>

Children: none

attribute required Parameter Type Description
lower_limit yes unsigned int Specify the lower limit of the range.
upper_limit yes unsigned int Specify the upper limit of the range.

<reference>

Specify that arguments to this command are to be interpreted as a reference to another data block by the MDAL parser.

Parent: <mdalconfig><commands><command>

Children: none

attribute required Parameter Type Description
to yes blocktype ID The target blocktype ID.

<substitute>

Specify a key argument that will be replaced by the given value. Multiple instances of this tag can be used.

Parent: <mdalconfig><commands><command>

Children: none

attribute required Parameter Type Description
key yes string The argument value to be replaced.
value yes string The value that will replace the key argument.

<use_last_set>

Specify that the last used argument is repeated if the data output is requested from the command and the command is not currently set. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


<use_note_names>

Specify that note names may be used as argument to this command. This setting has no effect on data output, but may be read by applications using MDAL. This tag has no attributes.

Parent: <mdalconfig><commands><command>

Children: none


Standard Commands

Standard commands are provided by MDAL iself. They are always available to the user, and cannot be customized through configurations. The standard commands are:

  • CONFIG - used to specify which configuration to use
  • : - The block delimiter. Used to declare the start of a new block, and followed by the block name (:SEQUENCE is used to declare the sequence block).
  • . - The "no-op" command. Used to specify a data block row that does not change any values from the preceding row.

Blocktype Configuration

<blocktype>

Define a data block type. Data block types can be derived from the base types pattern, table, and generic. An MDAL configuration must define at least one data block of type pattern.

Parent: <mdalconfig>

Children: <init_defaults>, <field>

attribute required Parameter Type Description
id yes string Specify a unique ID for this block type.
type no flag Specify the base type that this block type will be derived from. Available flags are pattern, table, and generic. Block types with base type pattern will generate a sequence. table and generic are considered synonymous by MDAL itself, but may be read by applications using MDAL. This setting defaults to generic if not specified.
end no string The given value will be inserted into the data output at the end of a block instance.
label_prefix no string The given value will be prefixed to block name labels in the data output. Defaults to "mdb_blocktype_id_" if not specified.
max_length no unsigned int Limit the number of data rows in instances of this block type to the given value.

<init_defaults>

Specify that commands used in this block type will be reset to their default values at the beginning of each block instance. This tag has no attributes.

Parent: <mdalconfig><blocktype>

Children: none


Data Field Configuration

<field>

Define an output data field, and describe how it is composed from command data input. The order in which you define the fields of a given data block type determines the order in which the data will be output.

Parent: <mdalconfig><blocktype>

Children: <required_seq_begin>, <required_blk_begin>, <required>, <set>, <set_hi>, <set_lo>, <set_bits>, <set_if>

attribute required Parameter Type Description
size yes flag Specify the size of the data output. Available flags are byte and word.

<required_seq_begin>

Specify that this field is required on the first row of the first pattern block in the sequence. Has no effect if the block type's base type is not pattern. This tag has no attributes.

Parent: <mdalconfig><blocktype><field>

Children: none


<required_blk_begin>

Specify that this field is required on the first row of every block instance. This tag has no attributes.

Parent: <mdalconfig><blocktype><field>

Children: none


<required>

Specify at which condition the given data field will be required to be placed in the output data.

Parent: <mdalconfig><blocktype><field>

Children: none

attribute required Parameter Type Description
if no flag/requirement condition Specify the requirement condition. If not specified or specified with an empty argument, the field will be considered to be always required. See the section on requirement conditions for further information.

<set>

Derive the data output of the field from the given command input. This operation may only be used once per field.

Parent: <mdalconfig><blocktype><field>

Children: none

attribute required Parameter Type Description
from yes command ID Specify the ID of the source command.

<set_hi>

Derive the high byte of the data output of the field from the given command input. Using this setting is only allowed if the field's size is word. The input command must be of size byte. This operation may only be used once per field.

Parent: <mdalconfig><blocktype><field>

Children: none

attribute required Parameter Type Description
from yes command ID Specify the ID of the source command.

<set_lo>

Derive the low byte of the data output of the field from the given command input. The input command must be of size byte. This operation may only be used once per field.

Parent: <mdalconfig><blocktype><field>

Children: none

attribute required Parameter Type Description
from yes command ID Specify the ID of the source command.

<set_bits>

Configure the current field data to be logically ORed with a given value if the given boolean command is set and evaluates to true. Multiple instances of this operation may be used on a single field, in this case they are evaluated in the order in which they are specified.

Parent: <mdalconfig><blocktype><field>

Children: none

attribute required Parameter Type Description
from yes command ID Specify the ID of the boolean source command.
value yes unsigned int Specify the value to set/OR with.
clear no flag Specify that a the field value or a part of it should be cleared before the OR operation is performed. Available flags are all (clears the entire field), hi (clears the high byte), and lo (clears the low byte). Note that clearing the high/low byte is skipped if the current field value is not an integer.

<set_if>

Configure the current field data to be logically ORed with a given value if the given requirement condition evaluates to true. Multiple instances of this operation may be used on a single field, in this case they are evaluated in the order in which they are specified.

Parent: <mdalconfig><blocktype><field>

Children: none

attribute required Parameter Type Description
if yes requirement condition Specify the condition at which the operation will be triggered. See the section on requirement conditions for further information.
value yes unsigned int Specify the value to set/OR with.
clear no flag Specify that a the field value or a part of it should be cleared before the OR operation is performed. Available flags are all (clears the entire field), hi (clears the high byte), and lo (clears the low byte). Note that clearing the high/low byte is skipped if the current field value is not an integer.

Requirement Conditions

Requirement conditions are used as arguments to the <required> and [<set_if>] data field child tags. They consist of one or more command IDs, connected by conjunction or disjunction. The entire expression may additionally be negated. The pipe character (|) is used to express disjunction, the plus character (+) is used to express conjunction (since & is forbidden in XML), and the exclamation mark (!) is used to express negation. When using negation, the remaining expression must be enclosed in brackets (()) if it consist of more than one operand.

Condition expression evaluation in existing MDAL compilers is currently very simple. Conjunction and disjunction may not be mixed, and negation can only be applied globally to the whole expression.

Conditions apply to the actual internal state of the commands. Commands will be considered set if the user has set them on the module data row being currently evaluated, or if they have been auto-triggered through another requirement setting. The no-op standard command is always ignored.

Examples;

  • NOTE1: True if command NOTE1 is currently set.
  • !NOTE1: True if command NOTE1 is currently not set.
  • NOTE1+NOTE2: True if commands NOTE1 and NOTE2 are currently set.
  • NOTE1|NOTE2: True if either command NOTE1 or NOTE2, or both are currently set.
  • !(NOTE1+NOTE2): True if neither command NOTE1 nor NOTE2 are currently set.
  • !(NOTE1|NOTE2): True if either command NOTE1 or NOTE2, or both are currently not set.
  • !NOTE1+NOTE2: Error: Expression too complex.
  • NOTE1+NOTE2|NOTE3: Error: Expression too complex.

In place of an actual requirement condition, a number of flags can be used. These are:

  • all: Evaluates as true if all commands used in the data block type are currently set.
  • any: Evaluates as true if any of the commands used in the data block type is currently set.
  • none: Evaluates as true if no command is currently set.

Sequence Configuration

<sequence>

Mandatory configuration of options for the sequence data output. Must occur exactly once in the configuration. Sequence configuration is currently under review, and may undergo major changes in the future.

Parent: <mdalconfig>

Children: <track>, <loop>

attribute required Parameter Type Description
end no string Construct an end marker. The given string will be appended at the end of the sequence data.
label no string Specify a label that will be inserted before the sequence in the output data.
max_length no unsigned int Specify the maximum length of the sequence.

<track>

Adds a track to the sequence. Each sequence must contain at least one track.

Parent: <mdalconfig><sequence>

Children: none

attribute required Parameter Type Description
from yes blocktype ID Specify the source block type.

<loop>

Enable the generation of a loop point in the sequence.

Parent: <mdalconfig><sequence>

Children: none

attribute required Parameter Type Description
type yes flag Specify how to handle the loop point. The flag label will cause a label to be inserted into the sequence data, before the point that the player should loop to. The flag pointer will do the same, but will also cause a pointer to be appended to the sequence, after the end marker.
label yes string Specify the loop point label.