Files
mazegame/engine/src/msx-music.c
T

160 lines
5.2 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄ ▄ ▄▄▄ ▄▄ ▄ ▄ ▄ ▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ██▀█ ▀█▄ ▀█▄▀ ▄▄ ██▀█ ██ █ ██▀ ▄ ▄█▀▀
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ██ █ ▄▄█▀ ██ █ ██ █ ▀█▄█ ▄██ ██ ▀█▄▄
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘
// by Guillaume 'Aoineko' Blanchard under CC BY-SA license
//─────────────────────────────────────────────────────────────────────────────
// MSX-Music (YM2413) handler module
//
// References:
// - YM2413 FM Operator Type-LL (OPLL) Application Manual
// https://www.smspower.org/maxim/Documents/YM2413ApplicationManual
// - MSX-MUSIC programming
// https://www.msx.org/wiki/MSX-MUSIC_programming
//─────────────────────────────────────────────────────────────────────────────
//=============================================================================
// INCLUDES
//=============================================================================
#include "msx-music.h"
#include "bios.h"
#include "system.h"
#include "system_port.h"
#include "memory.h"
//=============================================================================
// DEFINES
//=============================================================================
//=============================================================================
// READ-ONLY DATA
//=============================================================================
const c8 g_MSXMusic_Ident[] = "APRLOPLL";
//=============================================================================
// MEMORY DATA
//=============================================================================
u8 g_MSXMusic_SlotId = SLOT_NOTFOUND;
#if (MSXMUSIC_USE_RESUME)
bool g_MSXMusic_DoBackup = TRUE;
u8 g_MSXMusic_RegBackup[16];
#define MSXMUSIC_DOBACKUP(do) g_MSXMusic_DoBackup = do
#else
#define MSXMUSIC_DOBACKUP(do)
#endif
//=============================================================================
// FUNCTIONS
//=============================================================================
//-----------------------------------------------------------------------------
// Initialize MSX-Music module
u8 MSXMusic_Initialize()
{
u8 ret = MSXMusic_Detect();
#if (MSXMUSIC_USE_RESUME)
Mem_Set(0, g_MSXMusic_RegBackup, 16);
#endif
return ret;
}
//-----------------------------------------------------------------------------
//
bool MSXMusic_CheckInternal(u8 slotId)
{
const c8* ptr = g_MSXMusic_Ident;
u16 dest = 0x4018;
while (*ptr != 0)
{
if (*ptr != BIOS_InterSlotRead(slotId, dest++))
return FALSE;
ptr++;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
bool MSXMusic_CheckExternal(u8 slotId)
{
const c8* ptr = g_MSXMusic_Ident + 4;
u16 dest = 0x401C;
while (*ptr != 0)
{
if (*ptr != BIOS_InterSlotRead(slotId, dest++))
return FALSE;
ptr++;
}
return TRUE;
}
//-----------------------------------------------------------------------------
// Search for MSX-Music (YM2413) chip
u8 MSXMusic_Detect()
{
// Check internal MSX-Music chip
g_MSXMusic_SlotId = Sys_CheckSlot(MSXMusic_CheckInternal);
if (g_MSXMusic_SlotId != SLOT_NOTFOUND)
return MSXMUSIC_INTERNAL;
// Check external MSX-Music chip
g_MSXMusic_SlotId = Sys_CheckSlot(MSXMusic_CheckExternal);
if (g_MSXMusic_SlotId != SLOT_NOTFOUND)
{
// Activate external FM-PAC
u8 val = BIOS_InterSlotRead(g_MSXMusic_SlotId, 0x7FF6);
BIOS_InterSlotWrite(g_MSXMusic_SlotId, 0x7FF6, val | 0x01);
return MSXMUSIC_EXTERNAL;
}
return MSXMUSIC_NOTFOUND;
}
//-----------------------------------------------------------------------------
// Set MSX-Music register value
void MSXMusic_SetRegister(u8 reg, u8 value)
{
g_MSXMusic_IndexPort = reg;
g_MSXMusic_DataPort = value;
#if (MSXMUSIC_USE_RESUME)
if ((g_MSXMusic_DoBackup) && ((reg & 0xF0) == 0x20)) // MSXMUSIC_REG_CTRL_x
g_MSXMusic_RegBackup[reg & 0x0F] = value;
#endif
}
//-----------------------------------------------------------------------------
// Get MSX-Music register value (most of the registers are write-only)
u8 MSXMusic_GetRegister(u8 reg)
{
g_MSXMusic_IndexPort = reg;
return g_MSXMusic_DataPort;
}
//-----------------------------------------------------------------------------
// Mute MSX-Music sound
void MSXMusic_Mute()
{
MSXMUSIC_DOBACKUP(FALSE);
loop (i, 9)
{
MSXMusic_SetRegister(MSXMUSIC_REG_CTRL_1 + i, 0); // seem to be enough
}
MSXMUSIC_DOBACKUP(TRUE);
}
#if (MSXMUSIC_USE_RESUME)
//-----------------------------------------------------------------------------
// Resume MSX-Music sound
void MSXMusic_Resume()
{
loop (i, 9)
{
MSXMusic_SetRegister(MSXMUSIC_REG_CTRL_1 + i, g_MSXMusic_RegBackup[i]); // seem to be enough
}
}
#endif