← John Doe's Reports日本語
MCPLAYER · Technical notes

MICRO CABIN MUSIC PLAYER - Technical notes

See README_en.txt in the package for how to use it. This document describes how the tools and the player work.

Overview

  1. tools/extract_disks.py extracts the songs (MCM) from the disk images and writes the playlist player/playlist.txt from the database tools/mcm_db.csv.
  2. player/build_rom.py puts the songs, titles and pictures of the playlist, together with the game drivers and tables (instruments etc.) taken from the disk images, into an ASCII16 MegaROM.
  3. The player in the ROM (player/player.asm) copies the driver of each song's game to RAM and plays the song with it.

Extracting songs (extract_disks.py)

Database (mcm_db.csv)

A UTF-8 CSV (with BOM). One row is "one song of one game". Songs are identified by their content (MD5), so the same data with a different file name or disk position is the same song. When the same data is used by several games, each game has its own row and its own title (e.g. the same data is "Forest of Boroz" in Xak II and "Forest" in Tower of Gazzel).

Column
idRow id (S0001 ...)
game / game_enGame name / English game name
orderOrder in the game
title / title_enTitle / English title
excludeReason for exclusion (empty = included)
loopsLoop count (empty = default)
folder / fileFile used for the song (disk_image folder and file name)
md5 etc.Values for matching, where it was found

Maintenance commands (tools/mcm_db.py):

python tools/mcm_db.py sync          # titles etc. of a full-format playlist.txt -> database
python tools/mcm_db.py playlist      # database + data -> playlist.txt
python tools/mcm_db.py find FILE     # which song a file is (also lists similar songs by channel)

extract_disks.py --full writes the full-format playlist (with title columns).

Playlist format

# comment
@startup ../data/CABIN/CABI112.MCM | タイトル | Title   # song at boot (not in the list)
@startup_cg ../data/cabin.png                          # picture at boot
@game Xak | Xak                                        # game name | English game name
@cg ../data/xak.png                                    # picture of the game
../data/XAK/XAK201.MCM                           # title from the database
../data/XAK/XAK202.MCM | 教会                     # title
../data/XAK/XAK202.MCM | 教会 |  |  | Church      # 5th field: English title
@song_cg ../data/xak_botu.png                    # picture only while the previous song plays
../data/ILLUSION/ILLU110.MCM | City | 1          # loop count
../data/FFANTASY/FFAN101.MCM |      | 0          # 0 = loop until the song ends or the time limit

Drivers (per game)

Each song is played with the sound driver of the game it comes from. When building the ROM, the driver is taken from the disk images in the disk_image folder with the same name as the song file's folder, patched and stored in the ROM. Before playing a song, the player copies its driver to its original address in RAM.

Version (drivers.json)GameAddress
PMAKERPrincess MakerCE00h
RISK2Dai Senryaku IICCC0h
CABIN_CD00The Tower of Cabin (disk 1, 2)CCC0h
XAKII / GAZZELXak II, Tower of GazzelCE00h
CABIN_CF00Fray (MSX2), The Tower of Cabin (disk 3)CE00h
FRAY_TRFray (turboR)CE00h
ILLUSIONIllusion City8000h
XAKXakD000h
FFANTASYFinal Fantasy752Fh (page 1, work area from BD00h)

Patches applied when building the ROM (Drivers in build_rom.py):

Final Fantasy's driver (page 1)

FF's driver is part of the game program (from 4000h) and runs in page 1. Page 1 is this ROM, so the driver is placed in the RAM behind page 1 (the RAM in the same slot as page 3), and page 1 is switched to RAM only while the driver is called (with interrupts disabled, A8h and the sub-slot register are switched and restored afterwards). Therefore the hooks called by the drivers (HookLoop, HookNote) and the switching code are in page 3 RAM (RamHooks).

Tables per game (instruments etc.)

The tables for envelopes, vibrato, effects and FM instruments (32 soft instruments), 0x1E0 bytes, differ per game. They are collected from the disk images when building the ROM, and the song's table is copied to page 2 RAM before playing it.

Behaviour

Pictures (CG)

Screen

Text is drawn on SCREEN 2 (256x192) with k8x12 (8x12 dots) for kanji and kana and the full-width letters of k6x8 (6x8 dots, placed 2 dots below the top of a 12-dot line) for letters. " ' - ~ have no full-width glyphs, so similar characters are used. Characters are positioned in 2-dot units; half-width letters advance 6 dots, full-width 8 dots. The name table is filled with 0-255 so the screen is a bitmap, without a limit on the number of different kanji. A line is 12 dots high and the screen has 16 lines.

LineLeftRight
0TitleLevel meters (12: PSG 3 + FM 9)
1Sound chips〃
2TRACK, LOOP (current pass / loop count)〃
3TIME, play modeChannel names (PSG A B C, FM 1-9; B S H for the last 3 FM channels in rhythm mode; used channels white, unused grey)
4"game / title" of the playing song (STOP when stopped)
5previous game <- [selected game] -> next game
6-15Songs of the selected game (10)

ROM layout (ASCII16)

BankMappedContents
04000h-7FFFhProgram, driver information (DrvDir: 40 bytes each, up to 12), driver/table sets (SetDir: up to 32), playlist table (12 bytes per song), game information (picture location and name), half-width font
1-Page 1, only while readingGame drivers (about 3KB each), game tables, titles (Japanese and English), song data (packed without crossing banks), pictures (from the start of a bank)
Last〃Full-width font (only the characters used, 16 bytes each)

A playlist entry (12 bytes): bank / address / length of the song data, bank / address of the titles, loop count, driver/table set number (from 1 in SetDir), address of the game information.

Memory

AddressContents
RAM behind page 1, 752Fh-7FAFhFinal Fantasy's driver (page 1 is switched to RAM only while it is called)
Page 2 RAM 8000h-8D76hIllusion City's driver
8F00h-9FFFhGame tables (copied for each song; address depends on the driver)
A000h-BFFFhSong being played (copied for each song). With FF's driver, BD00h- is its work area
C000h-Player work, routines in RAM (bank reading, picture decompression, hooks)
-CCBFhStack
CCC0h-DDFFhGame drivers (address depends on the driver, followed by its work area)

Tested

Fonts

"k8x12" and "k6x8" (letters) by Num Kadoma. Both are free to use, modify and redistribute (see font/misaki_12x8/k8x12.txt and font/k6x8/k6x8.txt).