AxibugEmuOnline/virtuanessrc097-master/NES/Mapper/MapperNSF.cpp

1035 lines
75 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//////////////////////////////////////////////////////////////////////////
// MapperNSF NSF:NES Sound Format //
//////////////////////////////////////////////////////////////////////////
#include "math.h"
#define NSF_PROFILE 0
#if NSF_PROFILE
static DWORD avecount = 0;
static float tave = 0.0f;
static float pave = 0.0f;
static float ptave = 0.0f;
static DWORD maxtotalclk = 0;
static DWORD maxprofclk = 0;
static DWORD maxproftotalclk = 0;
static DWORD maxproftotalcnt = 0;
#endif
BYTE MapperNSF::Font6x8[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,
0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00,
0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00,0x48,0xB0,0x50,0x20,0x50,0x68,0x90,0x00,
0x40,0xA0,0xA8,0x68,0x90,0x90,0x68,0x00,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00,0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00,
0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x00,
0x70,0x88,0x98,0xA8,0xC8,0x88,0x70,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0xF8,0x00,
0x70,0x88,0x08,0x30,0x40,0x80,0xF8,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00,
0x30,0x50,0x90,0x90,0xF8,0x10,0x10,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0xF0,0x00,
0x70,0x88,0x80,0xF0,0x88,0x88,0x70,0x00,0xF8,0x08,0x10,0x10,0x20,0x20,0x20,0x00,
0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00,
0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x40,0x00,
0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00,
0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00,
0x30,0x48,0x88,0x98,0xA8,0xA8,0x78,0x00,0x20,0x50,0x50,0x88,0xF8,0x88,0x88,0x00,
0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,
0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00,0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00,
0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00,0x70,0x88,0x80,0xB8,0x88,0x88,0x70,0x00,
0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,
0x38,0x08,0x08,0x08,0x08,0x88,0x70,0x00,0x88,0x88,0x90,0xE0,0x90,0x88,0x88,0x00,
0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x88,0xD8,0xA8,0xA8,0xA8,0xA8,0xA8,0x00,
0x88,0xC8,0xA8,0xA8,0xA8,0x98,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00,0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00,
0xF0,0x88,0x88,0xF0,0x88,0x88,0x88,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,
0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x00,0x88,0xA8,0xA8,0xA8,0xA8,0xD8,0x88,0x00,
0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00,0x88,0x88,0x88,0x70,0x20,0x20,0x20,0x00,
0xF8,0x08,0x10,0x20,0x40,0x80,0xF8,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x70,0x00,
0x88,0x50,0xF8,0x20,0xF8,0x20,0x20,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x70,0x00,
0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,
0x80,0xC0,0xE0,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0xF8,0x00,
0x80,0x80,0x80,0xF0,0x88,0x88,0xF0,0x00,0x00,0x00,0x78,0x80,0x80,0x80,0x78,0x00,
0x08,0x08,0x08,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x70,0x88,0xF8,0x80,0x78,0x00,
0x18,0x20,0xF8,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x78,0x88,0x78,0x08,0xF0,0x00,
0x80,0x80,0x80,0xF0,0x88,0x88,0x88,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00,
0x20,0x00,0x20,0x20,0x20,0x20,0xC0,0x00,0x80,0x80,0x88,0x90,0xE0,0x90,0x88,0x00,
0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,
0x00,0x00,0xF0,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,
0x00,0x00,0xF0,0x88,0xF0,0x80,0x80,0x00,0x00,0x00,0x78,0x88,0x78,0x08,0x08,0x00,
0x00,0x00,0xB8,0xC0,0x80,0x80,0x80,0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00,
0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x70,0x00,
0x00,0x00,0x88,0x88,0x50,0x50,0x20,0x00,0x00,0x00,0x88,0xA8,0xA8,0xD8,0x88,0x00,
0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x88,0x88,0x78,0x08,0xF0,0x00,
0x00,0x00,0xF8,0x08,0x70,0x80,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
BYTE MapperNSF::KeyBoardBitmap[] = {
48, 26,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x10, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20,
0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10,
0x10, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20,
0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20,
0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20,
0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
};
// KeyA(6x26)
BYTE MapperNSF::KeyBitmapA[] = {
6, 26,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF,
0x2A, 0x2A, 0x2A, 0x2A, 0x0F, 0x0F, 0x2A, 0x2A, 0x2A, 0x2A, 0x0F, 0x0F,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x1A, 0x2A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
};
// KeyB(6x26)
BYTE MapperNSF::KeyBitmapB[] = {
6, 26,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x2A, 0xFF, 0xFF,
0x0F, 0x0F, 0x1A, 0x2A, 0x0F, 0x0F, 0x0F, 0x0F, 0x2A, 0x2A, 0x0F, 0x0F,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x1A, 0x2A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
};
// KeyC(6x26)
BYTE MapperNSF::KeyBitmapC[] = {
6, 26,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A, 0xFF, 0xFF, 0x1A, 0x2A, 0x2A, 0x2A,
0x0F, 0x0F, 0x1A, 0x2A, 0x2A, 0x2A, 0x0F, 0x0F, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x1A, 0x2A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
};
// KeyD(5x16)
BYTE MapperNSF::KeyBitmapD[] = {
5, 16,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x2A, 0x1A, 0x1A, 0x1A,
0x1A, 0x2A, 0x2A, 0x2A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
};
// ネオン管(のつもり)
BYTE MapperNSF::NeonBitmapA[] = {
6, 26,
0xFF, 0x02, 0x12, 0x12, 0x02, 0xFF, 0x02, 0x12, 0x21, 0x21, 0x12, 0x02,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x12, 0x21, 0x31, 0x31, 0x21, 0x12, 0x12, 0x21, 0x31, 0x31, 0x21, 0x12,
0x02, 0x12, 0x21, 0x21, 0x12, 0x02, 0xFF, 0x02, 0x12, 0x12, 0x02, 0xFF,
};
BYTE MapperNSF::NeonBitmapB[] = {
6, 26,
0xFF, 0x09, 0x1A, 0x1A, 0x09, 0xFF, 0x09, 0x1A, 0x2A, 0x2A, 0x1A, 0x09,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A, 0x1A, 0x2A, 0x3B, 0x3B, 0x2A, 0x1A,
0x09, 0x1A, 0x2A, 0x2A, 0x1A, 0x09, 0xFF, 0x09, 0x1A, 0x1A, 0x09, 0xFF,
};
BYTE MapperNSF::NeonBitmapC[] = {
6, 26,
0xFF, 0x1E, 0x1D, 0x1D, 0x1E, 0xFF, 0x1E, 0x1D, 0x2D, 0x2D, 0x1D, 0x1E,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D, 0x1D, 0x2D, 0x00, 0x00, 0x2D, 0x1D,
0x1E, 0x1D, 0x2D, 0x2D, 0x1D, 0x1E, 0xFF, 0x1E, 0x1D, 0x1D, 0x1E, 0xFF,
};
INT MapperNSF::KeyBitmapOfs[] = {
0, 4, 7, 11, 14, 21, 25, 28, 32, 35, 39, 42,
};
LPBYTE MapperNSF::KeyBitmapTbl[] = {
MapperNSF::KeyBitmapA,
MapperNSF::KeyBitmapD,
MapperNSF::KeyBitmapB,
MapperNSF::KeyBitmapD,
MapperNSF::KeyBitmapC,
MapperNSF::KeyBitmapA,
MapperNSF::KeyBitmapD,
MapperNSF::KeyBitmapB,
MapperNSF::KeyBitmapD,
MapperNSF::KeyBitmapB,
MapperNSF::KeyBitmapD,
MapperNSF::KeyBitmapC,
};
BYTE MapperNSF::StarBitmapA[] = {
5, 5,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
BYTE MapperNSF::StarBitmapB[] = {
5, 5,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x1D, 0xFF, 0xFF,
0xFF, 0x1D, 0x2D, 0x1D, 0xFF,
0xFF, 0xFF, 0x1D, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
BYTE MapperNSF::StarBitmapC[] = {
5, 5,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0xFF, 0xFF,
0xFF, 0x2D, 0x10, 0x2D, 0xFF,
0xFF, 0xFF, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
BYTE MapperNSF::StarBitmapD[] = {
5, 5,
0xFF, 0xFF, 0x2D, 0xFF, 0xFF,
0xFF, 0x2D, 0x10, 0x2D, 0xFF,
0x2D, 0x10, 0x20, 0x10, 0x2D,
0xFF, 0x2D, 0x10, 0x2D, 0xFF,
0xFF, 0xFF, 0x2D, 0xFF, 0xFF,
};
LPBYTE MapperNSF::StarBitmapTbl[] = {
MapperNSF::StarBitmapA,
MapperNSF::StarBitmapB,
MapperNSF::StarBitmapC,
MapperNSF::StarBitmapD,
};
void MapperNSF::Reset()
{
INT i;
songno = 0;
pad = padold = 0;
repcnt = 0;
BGPAL[0] = BGPAL[1] = BGPAL[2] = BGPAL[3] =
SPPAL[0] = SPPAL[1] = SPPAL[2] = SPPAL[3] = 0x0F;
exaddr = 0;
ZEROMEMORY( exram, sizeof(exram) );
SetPROM_Bank( 2, WRAM+0xA000, BANKTYPE_RAM ); // 4000-5FFF
SetPROM_Bank( 3, WRAM+0x0000, BANKTYPE_RAM ); // 6000-7FFF
SetPROM_Bank( 4, WRAM+0x2000, BANKTYPE_RAM ); // 8000-9FFF
SetPROM_Bank( 5, WRAM+0x4000, BANKTYPE_RAM ); // A000-BFFF
SetPROM_Bank( 6, WRAM+0x6000, BANKTYPE_RAM ); // C000-DFFF
SetPROM_Bank( 7, WRAM+0x8000, BANKTYPE_RAM ); // E000-FFFF
nsfheader = *(nes->rom->GetNsfHeader());
exchip = nsfheader.ExtraChipSelect;
banksize = nes->rom->GetNSF_SIZE();
if( (songno = nsfheader.StartSong-1) >= nsfheader.TotalSong ) {
songno = 0;
}
bankswitch = 0;
for( i = 0; i < 8; i++ ) {
bankswitch |= nsfheader.BankSwitch[i];
}
if( bankswitch ) {
// Bankswitch on
BYTE start_bank = nsfheader.LoadAddress>>12;
for( i = 0; (start_bank+i) < 8; i++ ) {
BankSwitch( start_bank+i, i );
}
for( i = 0; i < 8; i++ ) {
BankSwitch( i+8, nsfheader.BankSwitch[i] );
}
if( exchip&0x04 ) {
BankSwitch( 6, nsfheader.BankSwitch[6] );
BankSwitch( 7, nsfheader.BankSwitch[7] );
}
} else {
// Bankswitch off
LPBYTE pPtr = nes->rom->GetPROM();
if( banksize < 8 ) {
for( i = 0; i < 0x1000*banksize; i++ ) {
if( nsfheader.LoadAddress-0x8000+i < 0x8000 ) {
WRAM[0x2000+nsfheader.LoadAddress-0x8000+i] = pPtr[i];
}
}
} else {
for( i = 0; i < 0x8000; i++ ) {
if( nsfheader.LoadAddress-0x8000+i < 0x8000 ) {
WRAM[0x2000+nsfheader.LoadAddress-0x8000+i] = pPtr[i];
}
}
}
}
// $4700は待機無限ループ
WRAM[0xA700] = 0x4c; //jmp
WRAM[0xA701] = 0x00;
WRAM[0xA702] = 0x47;
// $4710はInitルーチンを呼んだ後無限ループへ
WRAM[0xA710] = 0x20; // jsr
WRAM[0xA711] = (BYTE) nsfheader.InitAddress & 0xFF;
WRAM[0xA712] = (BYTE)(nsfheader.InitAddress>>8);
WRAM[0xA713] = 0x4c; // jmp
WRAM[0xA714] = 0x00;
WRAM[0xA715] = 0x47;
// $4720はPlayルーチンを呼んだ後無限ループへ
#if NSF_PROFILE
WRAM[0xA720] = 0x8D; // sta
WRAM[0xA721] = 0x1E; // $401E
WRAM[0xA722] = 0x40; // $401E
WRAM[0xA723] = 0x20; // jsr
WRAM[0xA724] = (BYTE) nsfheader.PlayAddress;
WRAM[0xA725] = (BYTE)(nsfheader.PlayAddress>>8);
WRAM[0xA726] = 0x8D; // sta
WRAM[0xA727] = 0x1F; // $401F
WRAM[0xA728] = 0x40; // $401F
WRAM[0xA729] = 0x4c; //jmp
WRAM[0xA72A] = 0x00;
WRAM[0xA72B] = 0x47;
#else
WRAM[0xA720] = 0x20; // jsr
WRAM[0xA721] = (BYTE) nsfheader.PlayAddress;
WRAM[0xA722] = (BYTE)(nsfheader.PlayAddress>>8);
WRAM[0xA723] = 0x4c; //jmp
WRAM[0xA724] = 0x00;
WRAM[0xA725] = 0x47;
#endif
nes->apu->SelectExSound( exchip );
nes->apu->Write( 0x4015, 0x1F );
nes->apu->ExWrite( 0x4080, 0x80 ); // FDS Volume 0
nes->apu->ExWrite( 0x408A, 0xE8 ); // FDS Envelope ON
// For DQ1/2??
nes->SetFrameIRQmode( FALSE );
// NTSC/PAL tune
nes->SetVideoMode( (nsfheader.NTSC_PALbits&0x01)?TRUE:FALSE );
// 周波数->Keyテーブルの作成
for( i = 0; i < 12*8+1; i++ ) {
Freq2KeyTbl[i] = (INT)(440.0*256.0*pow(2.0,((double)(i-45)-0.5)/12.0));
}
// おまけ
StarInitial();
//
#if NSF_PROFILE
avecount = 0;
tave = 0.0f;
pave = 0.0f;
ptave = 0.0f;
maxtotalclk = 0;
maxprofclk = 0;
maxproftotalclk = 0;
maxproftotalcnt = 0;
#endif
}
BYTE MapperNSF::ExRead( WORD addr )
{
BYTE data = 0;
if( addr >= 0x4040 && addr < 0x4100 ) {
data = nes->apu->ExRead( addr );
}
return data;
}
void MapperNSF::ExWrite( WORD addr, BYTE data )
{
if( addr >= 0x4040 && addr < 0x4100 ) {
nes->apu->ExWrite( addr, data );
}
}
BYTE MapperNSF::ReadLow( WORD addr )
{
if( addr == 0x4800 ) {
BYTE data = exram[exaddr&0x7F];
if( exaddr&0x80 )
exaddr = (exaddr+1)|0x80;
nes->apu->ExRead( addr );
return data;
} else if( addr == 0x5205 ) { // MMC5
return (BYTE)multipul[0]*multipul[1];
} else if( addr == 0x5206 ) { // MMC5
return (BYTE)(((WORD)multipul[0]*(WORD)multipul[1])>>8);
}
// if( addr >= 0x47A0 && addr < 0x4800 ) {
// return WRAM[addr+0x6000];
// }
if( addr >= 0x5C00 && addr < 0x5FFF ) { // MMC5
return DRAM[addr-0x5C00];
}
if( addr >= 0x6000 ) {
return WRAM[addr-0x6000];
}
return (BYTE)(addr>>8);
}
void MapperNSF::WriteLow( WORD addr, BYTE data )
{
if( addr == 0x4800 || (addr >= 0x5000 && addr <= 0x5015) ) {
//DEBUGOUT( "$4800 WR=%02X\n", data );
exram[exaddr&0x7F] = data;
if( exaddr&0x80 )
exaddr = (exaddr+1)|0x80;
nes->apu->ExWrite( addr, data );
} else if( addr == 0x5205 ) { // MMC5
multipul[0] = data;
} else if( addr == 0x5206 ) { // MMC5
multipul[1] = data;
} else if( addr >= 0x5C00 && addr < 0x5FF6 ) { // MMC5
DRAM[addr-0x5C00] = data;
}
// if( addr >= 0x47A0 && addr < 0x4800 ) {
// WRAM[addr+0x6000] = data;
// }
if( addr >= 0x5FF6 && addr <= 0x5FFF ) {
// Bank switch
BankSwitch( addr&0x0F, data );
}
if( addr >= 0x6000 ) {
WRAM[addr-0x6000] = data;
nes->apu->ExWrite( addr, data );
}
}
void MapperNSF::Write( WORD addr, BYTE data )
{
if( (exchip&0x04) ) {
WRAM[addr-0x6000] = data;
}
nes->apu->ExWrite( addr, data );
if( addr == 0xF800 ) {
exaddr = data;
}
}
void MapperNSF::BankSwitch( INT no, BYTE bank )
{
INT i;
INT addr, offs;
LPBYTE pPtr;
offs = 0x1000*(INT)bank-(INT)(nsfheader.LoadAddress&0x0FFF);
pPtr = nes->rom->GetPROM();
if( no == 6 || no == 7 ) {
for( i = 0; i < 0x1000; i++ ) {
addr = offs+i;
if( addr < 0 || addr > (4096*banksize)-1 ) {
WRAM[0x1000*(no&1)+i] = 0;
} else {
WRAM[0x1000*(no&1)+i] = pPtr[addr];
}
}
} else if( no >= 8 && no <= 15 ) {
for( i = 0; i < 0x1000; i++ ) {
addr = offs+i;
if( addr < 0 || addr > (4096*banksize)-1 ) {
WRAM[0x2000+0x1000*(no&7)+i] = 0;
} else {
WRAM[0x2000+0x1000*(no&7)+i] = pPtr[addr];
}
}
}
}
void MapperNSF::VSync()
{
// データ設定
padold = pad;
pad = nes->pad->GetNsfController();
BYTE padpush = ~padold & pad;
if( padpush ) {
repcnt = 20;
} else if( pad ) {
if( --repcnt == 0 ) {
repcnt = 8;
padpush |= pad & 0xFC;
}
}
// -1
if( padpush & (1<<2) ) {
if( --songno < 0 ) {
songno = nsfheader.TotalSong-1;
}
}
// +1
if( padpush & (1<<3) ) {
if( ++songno >= nsfheader.TotalSong ) {
songno = 0;
}
}
// -16
if( padpush & (1<<4) ) {
if( (songno-=16) < 0 ) {
while( songno < 0 ) {
songno += nsfheader.TotalSong;
}
songno %= nsfheader.TotalSong;
}
}
// +16
if( padpush & (1<<5) ) {
if( (songno+=16) >= nsfheader.TotalSong ) {
songno -= nsfheader.TotalSong;
songno %= nsfheader.TotalSong;
}
}
// Play
if( padpush & (1<<0) ) {
nes->SetNsfPlay( songno, 0 );
}
// Stop
if( padpush & (1<<1) ) {
nes->SetNsfStop();
}
// おまけ
Star();
// Drawing screen
// DrawString( 10, 16, "TITLE :", 0x30 );
// DrawString( 10, 31, "ARTIST:", 0x30 );
// DrawString( 10, 46, "(C) :", 0x30 );
// DrawString( 10, 61, "NO :", 0x30 );
DrawString( 10, 16, "Title :", 0x30 );
DrawString( 10, 31, "Artist:", 0x30 );
DrawString( 10, 46, "(C) :", 0x30 );
DrawString( 10, 61, "No :", 0x30 );
DrawString( 28, 76, "Keyboard", 0x30 );
DrawString( 32, 152, "Wave View", 0x30 );
// タイトルなど
CHAR str[64];
memcpy( str, nsfheader.SongName, 32 );
str[32] = 0;
DrawString( 53, 16, str, 0x30 );
memcpy( str, nsfheader.ArtistName, 32 );
str[32] = 0;
DrawString( 53, 31, str, 0x30 );
memcpy( str, nsfheader.CopyrightName, 32 );
str[32] = 0;
DrawString( 53, 46, str, 0x30 );
// Song no
sprintf( str, "%02X", songno );
DrawString( 53, 61, str, 0x30 );
// Extra sound
DrawString( 76+6* 0, 61, "VRC6", (exchip&0x01)?0x2B:0x2D );
DrawString( 76+6* 5, 61, "VRC7", (exchip&0x02)?0x2B:0x2D );
DrawString( 76+6*10, 61, "FDS", (exchip&0x04)?0x2B:0x2D );
DrawString( 76+6*14, 61, "MMC5", (exchip&0x08)?0x2B:0x2D );
DrawString( 76+6*19, 61, "N106", (exchip&0x10)?0x2B:0x2D );
// DrawString( 76+6*24, 61, "FME7", (exchip&0x20)?0x2B:0x2D );
DrawString( 76+6*24, 61, "SN5B", (exchip&0x20)?0x2B:0x2D );
// タイトルなどのライン
DrawRect( 52, 24, 243-52, 0, 0x30 );
DrawRect( 52, 39, 243-52, 0, 0x30 );
DrawRect( 52, 54, 243-52, 0, 0x30 );
DrawRect( 52, 69, 12, 0, 0x30 );
DrawRect( 75, 69, 243-75, 0, 0x30 );
// キーボード枠
DrawRect( 27, 84, 229-27, 148- 84, 0x30 );
// WAVEVIEW枠
#if !NSF_PROFILE
DrawRect( 31, 160, 224-31, 224-160, 0x30 );
DrawRect( 32, 192, 223-32, 0, 0x27 );
// Wave
DrawWave( 28+4, 192, 0x2A );
#endif
// キーボード上段(O5-O8)
DrawBitmap( 31+49*0, 88, KeyBoardBitmap );
DrawBitmap( 31+49*1, 88, KeyBoardBitmap );
DrawBitmap( 31+49*2, 88, KeyBoardBitmap );
DrawBitmap( 31+49*3, 88, KeyBoardBitmap );
// キーボード下段(O1-O4)
DrawBitmap( 31+49*0, 119, KeyBoardBitmap );
DrawBitmap( 31+49*1, 119, KeyBoardBitmap );
DrawBitmap( 31+49*2, 119, KeyBoardBitmap );
DrawBitmap( 31+49*3, 119, KeyBoardBitmap );
// キーボードが押されているのを描画
// Internal APU
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0000)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0001)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0002)) );
// Internal Noise
if( nes->apu->GetChannelFrequency(0x0003) ) {
DrawBitmap( 10, 88, NeonBitmapA );
DrawBitmap( 241, 88, NeonBitmapA );
DrawBitmap( 10, 119, NeonBitmapA );
DrawBitmap( 241, 119, NeonBitmapA );
} else {
DrawBitmap( 10, 88, NeonBitmapC );
DrawBitmap( 241, 88, NeonBitmapC );
DrawBitmap( 10, 119, NeonBitmapC );
DrawBitmap( 241, 119, NeonBitmapC );
}
// Internal DPCM
if( nes->apu->GetChannelFrequency(0x0004) ) {
DrawBitmap( 18, 88, NeonBitmapB );
DrawBitmap( 233, 88, NeonBitmapB );
DrawBitmap( 18, 119, NeonBitmapB );
DrawBitmap( 233, 119, NeonBitmapB );
} else {
DrawBitmap( 18, 88, NeonBitmapC );
DrawBitmap( 233, 88, NeonBitmapC );
DrawBitmap( 18, 119, NeonBitmapC );
DrawBitmap( 233, 119, NeonBitmapC );
}
// VRC6
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0100)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0101)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0102)) );
// VRC7
// Nothing...
// FDS
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0300)) );
// MMC5
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0400)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0401)) );
// N106
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0500)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0501)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0502)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0503)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0504)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0505)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0506)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0507)) );
// FME7
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0600)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0601)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0602)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0610)) ); // Noise
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0611)) ); // Noise
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0612)) ); // Noise
// VRC7
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0700)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0701)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0702)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0703)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0704)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0705)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0706)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0707)) );
DrawKey( GetKeyTable(nes->apu->GetChannelFrequency(0x0708)) );
// TEST
#if NSF_PROFILE
if( nes->IsNsfPlaying() ) {
DWORD total, profile;
total = nes->GetFrameTotalCycles();
profile = nes->GetProfileCycles();
if( maxtotalclk < total ) {
maxtotalclk = total;
}
if( maxprofclk < profile ) {
maxprofclk = profile;
}
if( maxproftotalclk < nes->GetProfileTotalCycles() ) {
maxproftotalclk = nes->GetProfileTotalCycles();
}
if( maxproftotalcnt < nes->GetProfileTotalCount() ) {
maxproftotalcnt = nes->GetProfileTotalCount();
}
tave += total;
pave += profile;
ptave += nes->GetProfileTotalCycles();
avecount++;
sprintf( str, "TOTAL CLK :%8d", total );
DrawString( 16, 160, str, 0x30 );
sprintf( str, "TOTAL MAX :%8d", maxtotalclk );
DrawString( 134, 160, str, 0x30 );
sprintf( str, "TOTAL AVE :%8.2f", tave / (float)avecount );
DrawString( 16, 168, str, 0x30 );
sprintf( str, "PROFILE :%8d", profile );
DrawString( 16, 176, str, 0x30 );
sprintf( str, "PROFILEMAX:%8d", maxprofclk );
DrawString( 134, 176, str, 0x30 );
sprintf( str, "POFILE AVE:%8.2f", pave / (float)avecount );
DrawString( 16, 184, str, 0x30 );
sprintf( str, "PRF/TTL %%:%8.2f", 100.0f * (float)profile / (float)total );
DrawString( 16, 192, str, 0x30 );
sprintf( str, "FRM-P TTL :%8d", nes->GetProfileTotalCycles() );
DrawString( 16, 200, str, 0x30 );
sprintf( str, "F-P TTLMAX:%8d", maxproftotalclk );
DrawString( 134, 200, str, 0x30 );
sprintf( str, "FRM-P CNT :%8d", nes->GetProfileTotalCount() );
DrawString( 16, 208, str, 0x30 );
sprintf( str, "F-P CNTMAX:%8d", maxproftotalcnt );
DrawString( 134, 208, str, 0x30 );
sprintf( str, "F P/T AVE :%8.2f", ptave / (float)avecount );
DrawString( 16, 216, str, 0x30 );
sprintf( str, "F PRF/TTL%%:%8.2f", 100.0f * (float)nes->GetProfileTotalCycles() / (float)total );
DrawString( 16, 224, str, 0x30 );
if( avecount >= 60 ) {
avecount = 0;
tave = 0.0f;
pave = 0.0f;
ptave = 0.0f;
maxtotalclk = 0;
maxprofclk = 0;
maxproftotalclk = 0;
maxproftotalcnt = 0;
}
}
#endif
}
INT MapperNSF::GetKeyTable( INT freq )
{
INT ret = -1;
if( freq < Freq2KeyTbl[0] )
return -1;
for( INT i = 0; i < 12*8+1; i++ ) {
if( freq < Freq2KeyTbl[i] )
return ret;
ret = i;
}
return -1;
}
void MapperNSF::DrawKey( INT key )
{
if( key < 0 || key > 12*8-1 )
return;
if( key < 12*4 ) {
DrawBitmap( 31+(key/12)*49+KeyBitmapOfs[key%12], 119, KeyBitmapTbl[key%12] );
} else {
DrawBitmap( 31+((key-12*4)/12)*49+KeyBitmapOfs[key%12], 88, KeyBitmapTbl[key%12] );
}
}
void MapperNSF::DrawRect( INT x, INT y, INT w, INT h, BYTE col )
{
INT i;
LPBYTE pScn = nes->ppu->GetScreenPtr()+8;
LPBYTE p0, p1;
p0 = pScn+(256+16)*y+x;
p1 = p0+(256+16)*h;
for( i = 0; i < w+1; i++ ) {
*p0++ = col;
*p1++ = col;
}
p0 = pScn+(256+16)*y+x;
p1 = p0+w;
for( i = 0; i < h+1; i++ ) {
*p0 = col;
*p1 = col;
p0 += (256+16);
p1 += (256+16);
}
}
void MapperNSF::DrawFont( INT x, INT y, BYTE chr, BYTE col )
{
INT i;
LPBYTE pFnt;
LPBYTE pPtr;
LPBYTE pScn = nes->ppu->GetScreenPtr()+8;
if( chr < 0x20 || chr > 0x7F )
return;
chr -= 0x20;
pFnt = &Font6x8[chr*8];
pPtr = pScn+(256+16)*y+x;
for( i = 0; i < 8; i++ ) {
if( pFnt[i] & 0x80 ) pPtr[0] = col;
if( pFnt[i] & 0x40 ) pPtr[1] = col;
if( pFnt[i] & 0x20 ) pPtr[2] = col;
if( pFnt[i] & 0x10 ) pPtr[3] = col;
if( pFnt[i] & 0x08 ) pPtr[4] = col;
if( pFnt[i] & 0x04 ) pPtr[5] = col;
pPtr += (256+16);
}
}
void MapperNSF::DrawString( INT x, INT y, LPSTR str, BYTE col )
{
while( *str ) {
DrawFont( x, y, *str, col );
str++;
x += 6;
}
}
void MapperNSF::DrawWave( INT x, INT y, INT col )
{
INT i, j;
INT yp, ypold;
LPBYTE pScn = nes->ppu->GetScreenPtr()+8+(256+16)*y+x;
LPBYTE pPtr;
ypold = 0;
LPSWORD pBuffer = (LPSWORD)nes->apu->GetSoundBuffer();
for( i = 0; i < 192; i++ ) {
yp = -((INT)*pBuffer)/1024;
if( yp < -31 ) yp = -31;
if( yp > 31 ) yp = 31;
if( abs( yp-ypold ) <= 1 || i == 0 ) {
pPtr = pScn+yp*(256+16)+i;
*pPtr = col;
} else {
// Line DDA
INT xpos, ypos;
INT sx, sy;
xpos = 65536*(i-1)+32768;
ypos = ypold;
sy = yp-ypold;
sx = 65536/abs(sy);
for( j = 0; j <= abs(sy); j++ ) {
pPtr = pScn+ypos*(256+16)+(xpos/65536);
*pPtr = col;
ypos += (sy>0)?1:-1;
xpos += sx;
}
}
ypold = yp;
pBuffer++;
}
}
void MapperNSF::DrawBitmap( INT x, INT y, LPBYTE lpBitmap )
{
INT i, j;
INT h, v;
LPBYTE pScn = nes->ppu->GetScreenPtr()+8+(256+16)*y+x;
LPBYTE pPtr;
h = (INT)*lpBitmap++;
v = (INT)*lpBitmap++;
for( j = 0; j < v; j++ ) {
pPtr = pScn;
for( i = 0; i < h; i++ ) {
if( *lpBitmap != 0xFF ) {
*pPtr = *lpBitmap;
}
lpBitmap++;
pPtr++;
}
pScn += 256+16;
}
}
void MapperNSF::StarInitial()
{
for( INT i = 0; i < STAR_MAX; i++ ) {
StarBuf[i].x = ((rand()%(256-10))-(256-10)/2)*256;
StarBuf[i].y = ((rand()%(240-10))-(240-10)/2)*256;
StarBuf[i].z = (rand()%250)+5;
}
}
void MapperNSF::Star()
{
INT x, y, z;
for( INT i = 0; i < STAR_MAX; i++ ) {
if( --StarBuf[i].z < 5 ) {
StarBuf[i].x = ((rand()%(256-10))-(256-10)/2)*256;
StarBuf[i].y = ((rand()%(240-10))-(240-10)/2)*256;
StarBuf[i].z = 255;
}
x = 256/2+(StarBuf[i].x-5/128)/StarBuf[i].z;
y = 240/2+(StarBuf[i].y-5/128)/StarBuf[i].z;
if( x < 3 || x >= 256-8 || y < 3 || y >= 240-8 ) {
StarBuf[i].x = ((rand()%(256-10))-(256-10)/2)*256;
StarBuf[i].y = ((rand()%(240-10))-(240-10)/2)*256;
StarBuf[i].z = 255;
continue;
}
if( StarBuf[i].z > 200 )
z = 0;
else if( StarBuf[i].z > 100 )
z = 1;
else if( StarBuf[i].z > 50 )
z = 2;
else
z = 3;
DrawBitmap( x, y, StarBitmapTbl[z] );
}
}