Table of Contents

x68k Music: MXDRV MML/MDX Tutorial and Documentation

So, you've been enlighted with the knowledge of a little machine called the Sharp x68000. It was powerful, beautiful, and maybe even a tad expensive ( that didn't keep people from flocking to purchase one :-) ).

You probably know that one of its major strong points were two sound chips called the YM2151 and the OKI MSM6258.

And as with any computer worth buying, if you're into composing music, then this computer will work for you. Especially since it's got FM audio + ADPCM. Sega Genesis? Who needs it?! It's got a system that will stomp it any day (and yes, I mean the SNES)!

But the blessed Japanese folks were the only ones who got ahold of this machine.

So, what if you wanted to, I dunno, compose music using the x68k's beautiful FM synthesis + ADPCM audio. MXDRV MML is the name of the game (not an actual game though).

The problem is that there's not a lot of documentation on it in English. So make sure you thank me well, and maybe give me a nice pat on the back (and send me lotsa money so I can buy some C64 peripherals, an Amiga 500, a Sharp x68k of my own, and every other vintage computer I'd like to get my bony hands on! Ooops! Forgot to mention the Compaq Presario 425!). Kidding about the money part, although that doesn't mean I won't accept money :-).

LOL

x68k Sound Information

The Sharp x68000 has two chips for audio within the main unit. These two chips are the Yamaha YM2151 (a.k.a. OPM), and the OKI MSM6258, which are used for FM Synthesis and ADPCM sampled audio respectively.

The early models of the x68k have 8 channels of FM and 1 channel of ADPCM. Later Sharp decided to expand the ADPCM audio, and added 7 extra channels of ADPCM, dubbing the new ADPCM expansion the Mercury unit. There is also a software called PCM8 which uses software mixing to add more ADPCM channels, but from what I've tested of it, it's a CPU cycle thief. There are other software mixing ADPCM TSR drivers, but I haven't tried them.

MXDRV allows you to use PCM8/Mercury expansion in addition to the normal FM Synthesis and ADPCM.

Required/Optional Tools and Information Links

Here are some useful links to tools and information that you might want to see.

The following tools are required to write MXDRV MML code:

Run68k - Sharp x68k command line emulator, necessary to run x68k programs from 
term/cmd:
https://osdn.jp/projects/sfnet_run68/
Alternatively, you can use a full x68k emulator, but I have no idea how you 
would handle file transfer that way. The command line emulator has access to 
files on your hard drive, so you can run x68k command line programs from your 
system'snative command line.
MDX_TOOL - x68k MXDRV tools, necessary to compile your MML->MDX:
http://nfggames.com/x68000/Mirrors/x68pub/x68tools/SOUND/MXDRV/MDX_TOOL.LZH
This archive contains mxc.x, the x68k MDX compiler. You will need to run it 
with run68k and your MML file to compile to MDX.
There are other MDX compilers, but this is the one I use.
MKPDX
http://x.haun.org/software/mkpdx/mkpdx.txt
This tool is required to create PDX files. See the section on making a PDX for this.
It's a Win32 executable, so no emulator required (unless you're using Linux or Mac).
WAV2ADP 
http://nfggames.com/x68000/Mirrors/x68pub/x68tools/SOUND/ADPCM/W2ADP101.LZH
This tool is required to convert any .wav audio files you have lying around, that
you want to convert to ADPCM for use in a PDX. See the section on making a PDX for this.

GR_ALL.lzh - Battle Garegga MDX tunes:
http://kmkz.jp/mtm/mag/mus/mdxdat/GR_ALL.lzh
This archive contains all the MDX tunes from Battle Garegga, but I mainly linked to it 
because it has a PDX file if you don't want to create your own. The PDX contains some nice
samples from synths and drum machines (the TR-909 and others) that Manabu Namiki didn't want, or 
need to program as FM instruments.
VOPM - OPM Emulation VST, necessary for making your own FM patches:
http://www.geocities.jp/sam_kb/VOPM/
You can experiment with VOPM and make your own FM sounds, or rip them from other
FM tunes using mdxtools or .opm files from the internet. This is important 
because if you don't have any FM patches, you won't be able to make music on an FM
chip lol.

Savihost - Standalone Virtual Instrument Host, necessary if you want to run VOPM without
a DAW:
http://www.hermannseib.com/english/savihost.htm

mdxtools - "A bunch of tools for handling the MDX music format (music for the 
Sharp X68000 using the MXDRV sound driver).":
https://github.com/vampirefrog/mdxtools
You need these tools if you want to do things like rip FM patches from other MDX 
tunes or decompile MDX. I've only gotten this toolkit to compile on Linux, which 
shouldn't be too much of a problem for you if you don't use Linux (VM or dual boot).

opm2mml - A program to convert MiOPMdrv .opm banks to MXDRV mml:
https://drive.google.com/open?id=0B-5MDOTTWQK9a0hhbFNFUlBXdDQ
This is a tool I coded in Java to do exactly what the description says. With it, you'll be able to 
convert .opm banks to MML. You can find lots of .opm banks online, and you can rip them from software/games on
systems using the YM2151 or YM2612 chips. Even better, you can export VOPM preset banks to .opm, so you can use
your own patches. If, for whatever reason, you need a version in C++ or C because you don't use or like Java, then I may
port it to one of those languages. 

To play your compiled mdx tunes:

mxv - MXDRV World Vision, an MDX player:
http://gorry.haun.org/cgitest/download.pl?subject=CGI-DOWNLOAD%20mxv200b.lzh&info=readcount&file=mx.html&downfile=mxv200b.lzh
The player requires the libraries X68Sound.dll and MXDRV.dll
X68Sound.dll - X68k YM2151 and OKI Emulation library, necessary for mxv:
http://gorry.haun.org/cgitest/download.pl?subject=CGI-DOWNLOAD%20X68Sound_020609_g20020611.lzh&info=readcount&file=mx.html&downfile=X68Sound_020609_g20020611.lzh
mxdrv.dll - Mdx driver for Windows, necessary for mxv:
http://gorry.haun.org/cgitest/download.pl?subject=CGI-DOWNLOAD%20mxdrv200b.lzh&info=readcount&file=mx.html&downfile=mxdrv200b.lzh

Alternatively, you can use the Winamp in_mdx.dll plugin in Winamp or XMPlay, or use the native MDX player for the X68k
Note that the Winamp plugin requires you to have mxdrv.dll and X68Sound.dll in the same directory as the player (Winamp or XMPlay)
Putting those libraries in the same directory as the plugin will not work if you put your plugins in subdirectories

The following tools and infos are optional:

PPMCK MML Beginner's guide:
http://www.nullsleep.com/treasure/mck_guide/

Notepad++ - Windows text editor made especially for coders: 
https://notepad-plus-plus.org/
Notepad++ will make it a lot easier to write in MML in because you can define your own
language syntaxes. I might make an MXDRV MML user defined language someday, but not atm.

Woolyss chipmusic > MML - MML tools and editors 
http://woolyss.com/chipmusic-mml.php
This page has a great deal of MML editors and compilers (though none for the x68k).
It has MML syntax highlighters for various text editors at the bottom of the page (including 
Notepad++), but they were made for PPMCK mml. However, you can still use them.

General MML Information

If you don't already know what MML is or how it works, then hold your $400 studio headphones, because I'm about to explain. Well, only the basics, because a lot of general MML information is already documented in English.

MML, or Music Macro Language, is a programming language used for nothing other than composing music. Sounds a bit masochistic, but it's not as bad as you think, so keep reading.

The core of MML is rooted in traditional musical notation. So it's not like you'll be programming your music routines in assembly…bless Rob Hubbard's heart. But it also means that you'll be doing everything in textual format, unlike many other electronic composition methods.

As with any worthwhile electronic composition method, MML uses commands which allow things like portamento, ties, vibrato, and other important musical techniques.

General MML Macros and Syntax

Get ready, because I'm about to get straight to the point with this one. If some of these terms are confusing you, then you might need to learn basic music theory.

Macro arguments in brackets are optional, and the brackets are NOT part of the command, with the only exception to this being the loop macro.

!

Ignore all following commands on the current channel
Sort of like commenting out code, although you can use ; or /* */ for that
@#

Select voice, where # = the desired voice(0 - 255)

The precondition here is that the voice must already be defined, else your 
compiler will flip you the bird.
Assuming that you're writing this on an FM channel, using this command will 
switch to the desired instrument denoted by num. There is a very 
important variation of this syntax which I will discuss later.
#TITLE title

Sets the title of a tune

Ex. #title mytune
& 

Tie macro
When this macro is used between notes, it will tie to the next note. For porta-
mento, you want to use the glide macro instead. This just 
( )

Decrement/Increment Volume, respectively.
( ~ lowers the volume of the current channel by one
) ~ raises the volume of the current channel by one 
_

Portamento to note
When specified directly after a note, this command will glide to the next note. 
Note: the note to be glided to must not have a duration macro after it
Ex. c4_e
glides from c to e in a quarter note
< >

Decrement/Increment octave, respectively.
Where > increments the octave and < decrements it
Use these instead of o when you want to change the octave up or down by a value
of one.
.

Dotted note macro
Add half (of a note's duration) to a note's duration
Ex. c4. 
A dotted quarter c note

[]#
Loop macro, loops the macros inside the brackets
The macros to be looped go inside the brackets and # is the number of times to 
loop them.

Ex. [c4]3    ~ Plays c quarter note 3 times and exits the loop

/
Break a loop on the last iteration
This macro goes inside the brackets with the rest of the macros

Ex. [c4 / d4]4		~ Plays c quarter note four times, but d quarter only 3 
times
;
Line comment
Use this to comment on a single line
/* */
  
Block comment
Use this to make a comment that extends multiple lines or to make single line
comments look nicer
chan

Specify the channel
Where chan is the corresponding letter for the channel. This macro must always 
be at the beginning of a line in which you intend to coerce any digital farts 
out of your poor x68k (or emulator).

Ex. A  		~ This sets the current channel to channel A
D#

Detune current voice
Where # is the value to detune by in 1/64 semitones
k# 

Delay macro
Where # is the number of ticks to delay by
L
Set loop start
Use this command in a channel when you wish to loop everything after this 
command
l[length]

Set the default note length.
Where length is the numerical value of the length in powers of two (ex. l4 
sets default note length to quarter notes).

When a note is specified without a length after, the note will default 
to this length. If this command is not set, the default length is set to 4,
a.k.a. a quarter note
MPwaveform,speed,depth
Set pitch LFO 
Where waveform is the LFO waveform (0 = sawtooth, 1 = square, 2 = triangle), 
speed is 1/4 of the LFO cycle in ticks, and depth is the 
max amplitude of the LFO. 
Useful for vibrato.

MPON 
Turn pitch LFO on for current channel, only needed if you have turned the 
pitch LFO off (setting the LFO automatically turns it on).

MPOF
Turn pitch LFO off for current channel. Only needed when it is already on.
n#,length

Play a note by its numerical value, with the length separated by a comma.
"length" is the length of the note in eights. See the next entry for proper
lengths.
Ex. n21,8 
Play note 21 as an eigth note
note[accidental][length]

Play a note with the desired length.
Where "note" is the letter of the musical note you want to play (a-g), 
"accidental" is the desired accidental (+ for sharp and - for flat), 
and "length" is the length of the note in eights.
For the note lengths, you can use any standard note length:
1 - whole note
2 - half note
4 - quarter note
8 - eighth note
16 - sixteenth note
32 - thirty-second note

Any length not a power of 2 or > 32 is not supported and will cause your compiler to 
question your sanity. When a length is not specified, the compiler will default
to the default length, which is by default a quarter note unless you specified 
otherwise. Unless you specified the default length as something like 33, which 
will mean that your compiler will complain that DE fault was yours...by default. :-P

Ex. c4 - play the note c as a quarter note
Ex. e-8 - play the note e flat as an eighth note
Ex. c - play the note c with whatever the default note length is
o#

Set the octave.
Where # is the desired octave (0 - 9)
q# 

Note cutoff (stacatto) 
Sets note duration (in eights) of cutoff. Range is 1 - 8 inclusive.
t#

Set the tempo 
Where # = the number of quarter notes per second

Ex. t180
v#

Set the coarse volume, where # is a number between 0 and 15

MXDRV MML Macros and Syntax

The following macros are MXDRV specific:

#PCMFILE "somefile.pdx"

Includes a PDX pcmfile, for pcm audio
This file will need to be in the same directory as your mdx when you want to 
listen to your compiled code (with pcm samples)


Ex. #pcmfile "GR-PCM.pdx"
@#={ 
	AR, DR, SR, RR, SL, OL, KS, ML, DT1, DT2, AME,
	AR, DR, SR, RR, SL, OL, KS, ML, DT1, DT2, AME,
	AR, DR, SR, RR, SL, OL, KS, ML, DT1, DT2, AME,
	AR, DR, SR, RR, SL, OL, KS, ML, DT1, DT2, AME,
	CON, FL, OP
}

Voice Definition macro
As the YM2151 is a four operator FM chip, in order to define the voices, you
must define each operator, and the voice's parameters.
Two things here:
1. I'm assuming you know a bit about synthesis and envelopes here, and
2. I'm not an expert on FM Synthesis :-P, but I will tell you what I know

AR = Attack Rate. How quickly you want the operator to reach full amplitude.

DR = Decay Rate. How quickly you want the operator to reach the sustain.

SR = Sustain Rate. How quickly you want the operator to reach the release after
a note off.

RR = Release Rate. How quickly you want the amplitude to reach zero after a 
note off.

SL = Sustain Level. The amplitude of the operator during sustain.

OL = ?

KS = Key sync 

ML = Phase multiplicity

DT1 = Detune in Hz from base note * ML

DT2 = Detune in semitones

AME = Enable amplitude modulation for current operator. 
Setting this value to a 1 will enable the amplitude modulation for the 
op and 0 will disable it.

CON = FM synthesis connection/algorithm, determines how the operators are routed.
You would want to play with VOPM to figure these out.

FL = Feedback level, setting this to higher values distorts the voice

OP = ? I always see this value set to 15, so I don't know what it does

Here's an example bass voice:
@2={
	/* AR DR SR RR SL OL KS ML DT1 DT2 AME */
	31, 14, 0, 15,  4, 13, 0, 1,  0, 0, 0,
	31, 9, 0, 10,  1, 0, 0, 4,  0, 0, 0,
	31, 9, 0, 10,  1, 0, 0, 1,  0, 0, 0,
	31, 9, 0, 10,  1, 0, 0, 1,  0, 0, 0,
	/* CON FL OP */
	5, 4, 15
}

It will be easier for you to rip voices from other tunes or make them in VOPM 
than to program them on the fly. See the resources for my program opm2mml which 
will automatically convert MiOPMdrv (.opm) patches to MML for you.
@t#

Set the value of OPM register B, consequently setting the tempo
This is different from the t command, which is what you'd want to use normally.	
0 < # < 255
@v#
  
Set fine volume (for a single channel)
0 < # < 255
This allows more precise control over the volume. For effects like fade-ins or
  	fade outs, you can use coarse volume instead (unless you find pain pleasurable)
A-H, P-W
  
Set channel
This macro must always appear at the very beginning of a line in which 
you intend to sequence notes and macros. The exceptions are voice definitions, 
comments, and metadata definitions.
Ex. A 
sets channel to A (FM channel 1)

Ex. P
Sets channel to P (PCM channel 1)
F#

Change PCM frequency (pitch)
Range is 0-4 inclusive, default is 4

0 = 3.9kHz
1 = 5.2kHz
2 = 7.8kHz
3 = 10.4kHz
4 = 15.6kHz

This changes the frequency of the ADPCM samples being played back. Really wish
that the OKI had note sample pitching instead of this, but nope, it would have to be done 
through software, and MXDRV doesn't have an implementation for this. 

(One of the things on my bucket list is to make a chiptracker for the x68k which
allows pitched samples)
MAwaveform,speed,amplitude
Set amplitude LFO
Where waveform is the LFO waveform (0 = sawtooth, 1 = square, 2 = triangle), 
speed is 1/4 of the LFO cycle in ticks, and amplitude is the max amplitude
of the LFO.

MAON 
Turn amplitude LFO on for current channel, only needed if you have turned the 
amplitude LFO off (setting the LFO automatically turns it on).

MAOF
Turn amplitude LFO off for current channel. Only needed when it is already on.
MD#
Set the delay from note on to LFO start(excluding OPM LFO)
Where # is the delay in ticks
MH#1,#2,#3,#4,#5,#6,#7

Set OPM LFO values
#1 = LFO Waveform (0 = sawtooth, 1 = square, 2 = triangle)
#2 = LFRQ
#3 = PMD
#4 = AMD
#5 = PMS
#6 = AMS
#7 = Key sync (0 = no sync, 1 = sync)

MHON
Turn OPM LFO on for current channel (setting OPM LFO automatically turns it on)

MHOF
Turn OPM LFO off for current channel.
p#

Set (hard) panning position
0 = no output, 1 = left, 2 = right, 3 = center
@q# 

Note cutoff (stacatto) in ticks
Set the cutoff of a note, with duration in ticks.
S#

Sync send macro
Continue playback on channel if it is in sync wait mode
y[reg],[val]

Write OPM register reg with value val 
w# 

Set OPM Noise frequency
W

Sync wait macro
Set current channel in sync wait mode, pausing playback of the channel

Short Tutorial

So, now that you know all of the macros used in MXDRV mml, you need to know how to correctly use them to make an MDX tune.

Here is a short sample MML source code:

#title "Darude - Sandstorm" ;song name?
#pcmfile "SampleText.pdx"

;below is the instrument 0 definition
@0={
		/* AR DR SR RR SL OL KS ML DT1 DT2 AME */
		31, 14, 0, 15,  4, 13, 0, 1,  0, 0, 0,
		31, 9, 0, 10,  1, 0, 0, 4,  0, 0, 0,
		31, 9, 0, 10,  1, 0, 0, 1,  0, 0, 0,
		31, 9, 0, 10,  1, 0, 0, 1,  0, 0, 0,
		/* CON FL OP */
		5, 4, 15
	}
A t140 v8 o4 @0 L c4 c4 e8 e8 e-4

So here, I first set the title of the song to “Darude - Sandstorm”, using the title macro. I then specified the PCM file as “SampleText.pdx”, then defined instrument 0's FM parameters. Then on channel A, I set the song tempo to 140, set the channel volume to 8 (max volume), set the octave to 4, the instrument to 0. I then set the rest of the following code to loop, and played the notes c-quarter, c-quarter, e-eigth, e-eigth, and e-flat-quarter. When compiled into MDX and played back, it should play those notes a few times in a loop before stopping.

You can put spaces between some (but not all) macros to make your MML source code cleaner and more readable. I should have told you which ones you can and cannot in the documentation.

With the documentation on all the commands, this should show you how to code your MML tune.

Compiling Your Tune

So now that I've included a short sample tune (nothing special, just random notes), now you need to know how to compile it.

If you have all the required tools, you will need the following for compilation:

1. A Sharp x68000 emulator - run68k is easy as it emulates human68k, although you could use a full Sharp x68k emulator

2. A Sharp x68k MDX compiler - mxc.x from MDX_TOOL is the one I use

3. Your MML source code (go figure) as a .mml plain text file

From the command line, to compile your .mml tune to MDX, run the following command:

run68 \directory\for\MDX_TOOL\mxc \tune\location\songname.mml

In a full Sharp x68k emulator or real x68k environment, you can run mxc.x directly:

mxc songname.mml

If your code is syntactically correct, you should have a resulting .mdx file in the directory where your source was.

Making a PDX File

To make a PDX, you first need to get some raw ADPCM files (.pcm extension).

You can either rip them from games with ADPCM chips, or convert wav files to the format with WAV2ADP (link in tools section).

To convert a wav to PCM, run the following in cmd or human68k:

wav2adp \directory\to\dubstep\somewav.wav

If you're using run68k, then just put “run68” at the beginning.

After you've got an ADPCM or two, you'll need to put all your pcm's into a PDX with mkpdx (link in tools as well). But first, you'll need to make a PDL file mapping all of the PCMs to the desired note values.

A PDL file is just a plain text file.

Example PDL:

#ex-pdx 1

@0
21=some.pcm
23=some.pcm
31=some.pcm

Here, I specify something important at the beginning: I am using ex-pdx.

Later after MXDRV was created, the PDX file format was extended so one could switch ADPCM banks for tons of PCM files in a single PDX. A single bank can have a maximum of 90 or so ADPCM binaries.

I then defined which ADPCM bank I want to define with “@0”. Then I set notes 21, 23, and 31 to “some.pcm”.

After you finish your PDL file, you'll need to make your PDX. Run the following in CMD (or just drag and drop your pdl on mkpdx):

mkpdx \directory\to\mypdl.pdl

The mkpdx binary I provided is for Win32, so you don't need to use an x68k emulator or DOSBox for it.

If your PDL file is syntactically correct, then mkpdx will spit out a PDX file in the same directory as your PDL.

Now you can use your PDX in your MML tunes by defining the following at the top:

#pcmfile "mypdx.pdx"

To use PCM in a MML tune, use channels P-W. It's easier to use the numerical note values for PCM than it is to use letter notes.

Ex.

P v8 n21,8 n21,8 ;plays pcm at note 21 with eighth note duration twice