a "packer" and PC/DOS player for OPL2/3 register dumps, powered by upkr. mainly intended for tiny executable music entries, first used in Crystal Oscillator by Otomata Labs (released at Revision 2025 Oldskool Music competition). totally a partyhack but it works :D
-
OPL2/3 support, 9/18 channels, no percussion mode, 2-op only
-
186+ instructions, needs a fair chunk of conventional RAM (depends on source file size)
-
cook a banger OPL2/3 choon in any tool that support export to VGM format. note you can't use 4-op or percussion mode at this moment, and tick rate (i.e. 60hz) must be constant across the tune.
- make sure all channels are explicitly muted at the end of tune!
- also i would recommend to use any VGM optimization tool (like
vgm_cmpfrom vgm_tools) to remove redundant register writes and delays.
-
run
compressor [filename.vgm]- it will convert the VGM to a separatefilenamefolder with each stream saved as a separate file, and additionally produce a.opkbundle (not used actually, but you can play it withwin32_player). -
copy
filenamefolder andfilename/music.incfile todos_playerfolder -
cd dos_player, editplayer.inc:CQM_DETECTchecks for Creative CQM (one of the worst OPL3 clones in the entire universe) at startup, and displays an error message if found, so anyone having that garbage chip is warned.PRINT_PLAYTIMEprints current playing time.EXIT_AFTER_ENDspeaks for itself :)- do not touch other fields!
-
edit
text.incif you want to display custom text during playback. -
run
!build.bat. -
grab the resulting
player.com -
win the compo :D
the hardest part since I used whatever tools I had at hand - prerequisites are:
-
for the DOS player:
- Windows (since one of build stages produces a batch file)
- Netwide Assembler and upkr installed in
PATH
-
for the compressor/Win32 test player:
- Visual C++ whatever (tested with VS2022) - one day i'll cmake it, maybe
not too much to write, but here's some details anyway:
- first, the VGM register dump is preprocessed by determining the actual (and most fitting) tick rate, and all delays are requantized.
- then, register data is deduplicated (removing redundant register writes) and split to 9*3 or 18*3 streams, depending on chip type:
- 1st stream encodes instrument data registers, such as ADSR/waveform type/multiplier for each operator, feedback, and also stores key-on and key-off events.
- 2nd stream stores volume (total level) data for each operator, delta preprocessed to improve compression ratio. volume streams are additionally grouped if their total size does not exceed 64 kb.
- finally, 3rd stream stores pitch data, namely, FNum (delta preprocessed) and Block registers for each channel.
- each stream (and volume stream group) is independently compressed by upkr, then incbined to the player.
As you may (or may not) know, the OPL register space is both pretty sparse and grouped well (since channels are orthogonal for the common 2op no-perc-mode case) so this packer architecture turned out to be quite effective for player-only use cases.
the player itself first checks for 186\V20+ and memory size available, then decompresses each stream to memory and starts playing the tune. pretty simple yet working :)
much thanks to exoticorn for the excellent upkr - without it this player wouldn't exist in the first place!
additional kudos to pestis and TomCat for the x86 depacker - had to tweak it a bit to make it decompress arbitrary data at any source/destination address - I guess it could be rewritten better for that use case ;)
respect for Abstract and Natt for cooking that banger choon for the Revision 2025 music compo, and the whole Otomata Labs posse for moral (and not only) support =)
oh and tildearrow for furnace (don't be so drunk during coding lol)
the compressor and DOS/COM player are fully MIT compliant (see LICENSE.md). the Win32 player is a bit in gray zone as it uses a Nuked-OPL3 emulation core which is GNU LGPL.
--artёmka 26.o4.2o25 - post-revision25 release