Merge branch 'master' of github.com:tildearrow/furnace

This commit is contained in:
tildearrow 2022-12-20 22:36:57 -05:00
commit 019b036853
22 changed files with 403 additions and 573 deletions

296
README.md
View File

@ -1,297 +1,7 @@
# Furnace (chiptune tracker)
![screenshot](papers/screenshot2.png)
# HELP
the biggest multi-system chiptune tracker ever made!
Furnace has a serious crash bug! download the latest artifact (either from the Actions tab or [nightly.link](https://nightly.link/tildearrow/furnace/workflows/build/master)) or compile it and help me diagnose and track the origin!
[downloads](#downloads) | [discussion/help](#quick-references) | [developer info](#developer-info) | [unofficial packages](#unofficial-packages) | [FAQ](#frequently-asked-questions)
---
## downloads
check out the [Releases](https://github.com/tildearrow/furnace/releases) page. available for Windows, macOS and Linux (AppImage).
[see here](https://nightly.link/tildearrow/furnace/workflows/build/master) for unstable developer builds.
## features
- over 50 sound chips - and counting:
- Yamaha FM chips:
- YM2151 (OPM)
- YM2203 (OPN)
- YM2413 (OPLL)
- YM2414 (OPZ) used in Yamaha TX81Z
- YM2608 (OPNA) used in PC-98
- YM2610 (OPNB) used in Neo Geo
- YM2610B (OPNB2)
- YM2612 (OPN2) used in Sega Genesis and FM Towns
- YM3526 (OPL) used in C64 Sound Expander
- YM3812 (OPL2)
- YMF262 (OPL3) with full 4-op support!
- Y8950 (OPL with ADPCM)
- square wave chips:
- AY-3-8910/YM2149(F) used in several computers and game consoles
- Commodore VIC used in the VIC-20
- Microchip AY8930
- TI SN76489 used in Sega Master System and BBC Micro
- PC Speaker
- Philips SAA1099 used in SAM Coupé
- sample chips:
- Amiga
- SegaPCM - all 16 channels
- Capcom QSound
- Yamaha YMZ280B (PCMD8)
- Ricoh RF5C68 used in Sega CD and FM Towns
- OKI MSM6258 and MSM6295
- wavetable chips:
- HuC6280 used in PC Engine
- Konami Bubble System WSG
- Konami SCC/SCC+
- Namco arcade chips (WSG/C15/C30)
- WonderSwan
- Seta/Allumer X1-010
- NES (Ricoh 2A03/2A07), with additional expansion sound support:
- Konami VRC6
- Konami VRC7
- MMC5
- Famicom Disk System
- Sunsoft 5B
- Namco 163
- Family Noraebang (OPLL)
- SID (6581/8580) used in Commodore 64
- Mikey used in Atari Lynx
- ZX Spectrum beeper (SFX-like engine)
- Commodore PET
- TIA used in Atari 2600
- Game Boy
- modern/fantasy:
- Commander X16 VERA
- tildearrow Sound Unit
- mix and match sound chips!
- over 200 ready to use presets from computers, game consoles and arcade boards...
- ...or create your own - up to 32 of them or a total of 128 channels!
- DefleMask compatibility
- loads .dmf modules from all versions (beta 1 to 1.1.3)
- saves .dmf modules - both modern and legacy
- Furnace doubles as a module downgrader
- loads/saves .dmp instruments and .dmw wavetables as well
- clean-room design (guesswork and ABX tests only, no decompilation involved)
- bug/quirk implementation for increased playback accuracy through compatibility flags
- VGM export
- modular layout that you may adapt to your needs
- audio file export - entire song, per chip or per channel
- quality emulation cores (Nuked, MAME, SameBoy, Mednafen PCE, NSFplay, puNES, reSID, Stella, SAASound, vgsound_emu and ymfm)
- wavetable synthesizer
- available on wavetable chips
- create complex sounds with ease - provide up to two wavetables, select and effect and let go!
- MIDI input support
- additional features:
- FM macros!
- negative octaves
- arbitrary pitch samples
- sample loop points
- SSG envelopes and ADPCM-B in Neo Geo
- full duty/cutoff range in C64
- ability to change tempo mid-song
- multiple sub-songs in a module
- per-channel oscilloscope with waveform centering
- built-in sample editor
- chip mixing settings
- built-in visualizer in pattern view
- open-source under GPLv2 or later.
---
# quick references
- **discussion**: see the [Discussions](https://github.com/tildearrow/furnace/discussions) section, or (preferably) the [official Discord server](https://discord.gg/EfrwT2wq7z).
- **help**: check out the [documentation](papers/doc/README.md). it's mostly incomplete, but has details on effects.
## unofficial packages
[![Packaging status](https://repology.org/badge/tiny-repos/furnace.svg)](https://repology.org/project/furnace/versions)
some people have provided packages for Unix/Unix-like distributions. here's a list.
- **Arch Linux**: [furnace-git is in the AUR.](https://aur.archlinux.org/packages/furnace-git) thank you Essem!
- **FreeBSD**: [a package in ports](https://www.freshports.org/audio/furnace/) is available courtesy of ehaupt.
- **Nix**: [package](https://search.nixos.org/packages?channel=unstable&show=furnace&from=0&size=50&sort=relevance&type=packages&query=furnace) thanks to OPNA2608.
- **openSUSE**: [a package](https://software.opensuse.org/package/furnace) is available, courtesy of fpesari.
---
# developer info
[![Build furnace](https://github.com/tildearrow/furnace/actions/workflows/build.yml/badge.svg)](https://github.com/tildearrow/furnace/actions/workflows/build.yml)
if you can't download these artifacts (because GitHub requires you to be logged in), [go here](https://nightly.link/tildearrow/furnace/workflows/build/master) instead.
**NOTE: do not download the project's source as a .zip or .tar.gz as these do not include the project's submodules which are necessary to proceed with building. please instead use Git as shown below.**
## dependencies
- CMake
- JACK (optional, macOS/Linux only)
if building under Windows or macOS, no additional dependencies are required.
otherwise, you may also need the following:
- libpulse
- libx11
- libasound
- libGL
some Linux distributions (e.g. Ubuntu or openSUSE) will require you to install the `-dev` versions of these.
## getting the source
type the following on a terminal/console: (make sure Git is installed)
```
git clone --recursive https://github.com/tildearrow/furnace.git
cd furnace
```
(the `--recursive` parameter ensures submodules are fetched as well)
## compilation
your typical CMake project.
### Windows using MSVC
as of now tildearrow uses MinGW for Windows builds, but thanks to OPNA2608 this works again!
from the developer tools command prompt:
```
mkdir build
cd build
cmake ..
msbuild ALL_BUILD.vcxproj
```
### macOS and Linux
```
mkdir build
cd build
cmake ..
make
```
Alternatively, build scripts are provided in the `scripts/` folder in the root of the repository.
### CMake options
To add an option from the command-line: `-D<NAME>=<VALUE>`
Example: `cmake -DBUILD_GUI=OFF -DWARNINGS_ARE_ERRORS=ON ..`
Available options:
| Name | Default | Description |
| :--: | :-----: | ----------- |
| `BUILD_GUI` | `ON` | Build the tracker (disable to build only a headless player) |
| `USE_RTMIDI` | `ON` | Build with MIDI support using RtMidi |
| `USE_SDL2` | `ON` | Build with SDL2 (required to build with GUI) |
| `USE_SNDFILE` | `ON` | Build with libsndfile (required in order to work with audio files) |
| `USE_BACKWARD` | `ON` | Use backward-cpp to print a backtrace on crash/abort |
| `WITH_JACK` | `ON` if system-installed JACK detected, otherwise `OFF` | Whether to build with JACK support. Auto-detects if JACK is available |
| `SYSTEM_FFTW` | `OFF` | Use a system-installed version of FFTW instead of the vendored one |
| `SYSTEM_FMT` | `OFF` | Use a system-installed version of fmt instead of the vendored one |
| `SYSTEM_LIBSNDFILE` | `OFF` | Use a system-installed version of libsndfile instead of the vendored one |
| `SYSTEM_RTMIDI` | `OFF` | Use a system-installed version of RtMidi instead of the vendored one |
| `SYSTEM_ZLIB` | `OFF` | Use a system-installed version of zlib instead of the vendored one |
| `SYSTEM_SDL2` | `OFF` | Use a system-installed version of SDL2 instead of the vendored one |
| `WARNINGS_ARE_ERRORS` | `OFF` (but consider enabling this & reporting any errors that arise from it!) | Whether warnings in furnace's C++ code should be treated as errors |
| `WITH_DEMOS` | `ON` | Install demo songs on `make install` |
| `WITH_INSTRUMENTS` | `ON` | Install demo instruments on `make install` |
## console usage
```
./furnace
```
this opens the program.
```
./furnace -console <file>
```
this will play a compatible file.
```
./furnace -console -view commands <file>
```
this will play a compatible file and enable the commands view.
**note that these commands only actually work in Linux environments. on other command lines, such as Windows' Command Prompt, or MacOS Terminal, it may not work correctly.**
---
# frequently asked questions
> woah! 50 sound chips?! I can't believe it!
yup, it's real.
> where's the manual?
see [papers/](papers/doc/README.md). it's kind of incomplete, but at least the sound chips section is there.
> it doesn't open under macOS!
this is due to Apple's application signing policy. a workaround is to right click on the Furnace app icon and select Open.
**as of Monterey, this workaround no longer works (especially on ARM).** yeah, Apple has decided to be strict on the matter.
if you happen to be on that version, use this workaround instead (on a Terminal):
```
xattr -d com.apple.quarantine /path/to/Furnace.app
```
(replace /path/to/ with the path where Furnace.app is located)
you may need to log out and/or reboot after doing this.
> how do I use C64 absolute filter/duty?
on Instrument Editor in the C64 tab there are two options to toggle these.
also provided are two effects:
- `3xxx`: set fine duty.
- `4xxx`: set fine cutoff. `xxx` range is 000-7ff.
additionally, you can change the cutoff and/or duty as a macro inside an instrument by clicking the `absolute cutoff macro` and/or `absolute duty macro` checkbox at the bottom of the instrument. (for the filter, you also need to click the checkbox that says `volume macro is cutoff macro`.)
> how do I use PCM on a PCM-capable chip?
two possibilities:
- the recommended way is by creating the "Sample" type instrument and assigning a sample to it.
- otherwise you may employ the DefleMask-compatible method, using `17xx` effect.
> my .dmf song sounds very odd at a certain point
file a bug report. use the Issues page. it's probably another playback inaccuracy.
> my .dmf song sounds correct, but it doesn't in DefleMask
file a bug report **here**. it still is a playback inaccuracy.
> my song sounds terrible after saving as .dmf!
the DefleMask format has several limitations. save in Furnace song format instead (.fur).
> how do I solo channels?
right click on the channel name.
---
# footnotes
copyright (C) 2021-2022 tildearrow and contributors.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
despite the fact this program works with the .dmf file format, it is NOT affiliated with Delek or DefleMask in any way, nor it is a replacement for the original program.
see the [bug report](https://github.com/tildearrow/furnace/issues/793) for more info.

View File

@ -1,8 +1,5 @@
# to-do for 0.6pre2
- Pokémon Mini
- register layout
- confirm emulation
- (maybe) YM2612 CSM (no DualPCM)
- YM2612 CSM (no DualPCM)
- port op macro code to all other OPN chips
- bug fixes
- bug fixes

View File

@ -215,8 +215,8 @@ size | description
| - 0x8a: FDS - 1 channel
| - 0x8b: MMC5 - 3 channels
| - 0x8c: Namco 163 - 8 channels
| - 0x8d: OPN (YM2203) - 6 channels
| - 0x8e: PC-98 (YM2608) - 16 channels
| - 0x8d: YM2203 - 6 channels
| - 0x8e: YM2608 - 16 channels
| - 0x8f: OPL (YM3526) - 9 channels
| - 0x90: OPL2 (YM3812) - 9 channels
| - 0x91: OPL3 (YMF262) - 18 channels
@ -256,8 +256,8 @@ size | description
| - 0xb3: Yamaha Y8950 drums - 12 channels
| - 0xb4: Konami SCC+ - 5 channels
| - 0xb5: tildearrow Sound Unit - 8 channels
| - 0xb6: OPN extended - 9 channels
| - 0xb7: PC-98 extended - 19 channels
| - 0xb6: YM2203 extended - 9 channels
| - 0xb7: YM2608 extended - 19 channels
| - 0xb8: YMZ280B - 8 channels
| - 0xb9: Namco WSG - 3 channels
| - 0xba: Namco 15xx - 8 channels
@ -269,8 +269,8 @@ size | description
| - 0xc0: PCM DAC - 1 channel
| - 0xc1: YM2612 CSM - 10 channels
| - 0xc2: Neo Geo CSM (YM2610) - 18 channels
| - 0xc3: OPN CSM - 10 channels
| - 0xc4: PC-98 CSM - 20 channels
| - 0xc3: YM2203 CSM - 10 channels
| - 0xc4: YM2608 CSM - 20 channels
| - 0xc5: YM2610B CSM - 20 channels
| - 0xc6: K007232 - 2 channels
| - 0xc7: GA20 - 4 channels
@ -1441,7 +1441,7 @@ chips which aren't on this list don't have any flags.
- bit 4-6: channels (int)
- bit 7: multiplex (bool)
## 0x8d: OPN (YM2203) and 0xb6: OPN extended
## 0x8d: YM2203 and 0xb6: YM2203 extended
- bit 0-4: clockSel (int)
- 0: NTSC
@ -1455,7 +1455,7 @@ chips which aren't on this list don't have any flags.
- 1: /3
- 2: /2
## 0x8e: PC-98 (YM2608) and 0xb7: PC-98 extended
## 0x8e: YM2608 and 0xb7: YM2608 extended
- bit 0-4: clockSel (int)
- 0: 8MHz

View File

@ -201,12 +201,12 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
((DivPlatformGenesisExt*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
((DivPlatformGenesisExt*)dispatch)->setSoftPCM(false);
break;
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_DUALPCM:
dispatch=new DivPlatformGenesis;
((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
((DivPlatformGenesis*)dispatch)->setSoftPCM(true);
break;
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
dispatch=new DivPlatformGenesisExt;
((DivPlatformGenesisExt*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
((DivPlatformGenesisExt*)dispatch)->setSoftPCM(true);
@ -269,16 +269,16 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
case DIV_SYSTEM_TIA:
dispatch=new DivPlatformTIA;
break;
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_YM2203:
dispatch=new DivPlatformYM2203;
break;
case DIV_SYSTEM_OPN_EXT:
case DIV_SYSTEM_YM2203_EXT:
dispatch=new DivPlatformYM2203Ext;
break;
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_YM2608:
dispatch=new DivPlatformYM2608;
break;
case DIV_SYSTEM_PC98_EXT:
case DIV_SYSTEM_YM2608_EXT:
dispatch=new DivPlatformYM2608Ext;
break;
case DIV_SYSTEM_OPLL:

View File

@ -1207,8 +1207,8 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
break;
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
switch (oldFlags&0x7fffffff) {
case 0:
newFlags.set("clockSel",0);
@ -1295,8 +1295,8 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
newFlags.set("channels",(int)((oldFlags>>4)&7));
if (oldFlags&128) newFlags.set("multiplex",true);
break;
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT:
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT:
switch (oldFlags&31) {
case 0:
newFlags.set("clockSel",0);
@ -1329,8 +1329,8 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
break;
}
break;
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_PC98_EXT:
case DIV_SYSTEM_YM2608:
case DIV_SYSTEM_YM2608_EXT:
switch (oldFlags&31) {
case 0:
newFlags.set("clockSel",0);
@ -2484,14 +2484,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
case DIV_SYSTEM_YM2610_FULL_EXT:
case DIV_SYSTEM_YM2610B:
case DIV_SYSTEM_YM2610B_EXT:
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT:
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_PC98_EXT:
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT:
case DIV_SYSTEM_YM2608:
case DIV_SYSTEM_YM2608_EXT:
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
opnCount++;
break;
default:
@ -2514,12 +2514,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
if (ds.version<125) {
for (int i=0; i<ds.systemLen; i++) {
if (ds.system[i]==DIV_SYSTEM_YM2612_EXT ||
ds.system[i]==DIV_SYSTEM_YM2612_FRAC_EXT ||
ds.system[i]==DIV_SYSTEM_YM2612_DUALPCM_EXT ||
ds.system[i]==DIV_SYSTEM_YM2610_EXT ||
ds.system[i]==DIV_SYSTEM_YM2610_FULL_EXT ||
ds.system[i]==DIV_SYSTEM_YM2610B_EXT ||
ds.system[i]==DIV_SYSTEM_OPN_EXT ||
ds.system[i]==DIV_SYSTEM_PC98_EXT) {
ds.system[i]==DIV_SYSTEM_YM2203_EXT ||
ds.system[i]==DIV_SYSTEM_YM2608_EXT) {
ds.systemFlags[i].set("noExtMacros",true);
}
}

View File

@ -147,17 +147,19 @@ class DivPlatformOPN: public DivPlatformFMBase {
double fmFreqBase;
unsigned int fmDivBase;
unsigned int ayDiv;
unsigned char csmChan;
bool extSys;
DivConfig ayFlags;
friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int);
DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32, bool isExtSys=false):
DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32, bool isExtSys=false, unsigned char cc=255):
DivPlatformFMBase(),
fmFreqBase(f),
fmDivBase(d),
ayDiv(a),
csmChan(cc),
extSys(isExtSys) {}
};

View File

@ -554,7 +554,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
switch (c.cmd) {
case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
if (c.chan==7 && extMode && softPCM) { // CSM
if (c.chan==csmChan && extMode && softPCM) { // CSM
chan[c.chan].macroInit(ins);
chan[c.chan].insChanged=false;
@ -686,7 +686,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
break;
}
case DIV_CMD_NOTE_OFF:
if (c.chan>=5 && c.chan<7) {
if (c.chan>=5 && c.chan<csmChan) {
chan[c.chan].dacSample=-1;
if (dumpWrites) addWrite(0xffff0002,0);
if (parent->song.brokenDACMode) {
@ -781,7 +781,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
}
break;
}
if (c.chan==7) {
if (c.chan==csmChan) {
int destFreq=NOTE_PERIODIC(c.value2);
bool return2=false;
if (destFreq>chan[c.chan].baseFreq) {
@ -850,7 +850,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
break;
}
case DIV_CMD_LEGATO: {
if (c.chan==7) {
if (c.chan==csmChan) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
} else if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) {
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);

View File

@ -128,7 +128,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformGenesis():
DivPlatformOPN(9440540.0, 72, 32) {}
DivPlatformOPN(9440540.0, 72, 32, false, 7) {}
~DivPlatformGenesis();
};
#endif

View File

@ -454,7 +454,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
}
}
if (writeSomething) {
if (chan[7].active) { // CSM
if (chan[csmChan].active) { // CSM
writeMask^=0xf0;
}
/*printf(
@ -589,17 +589,17 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
}
if (extMode && softPCM) {
if (chan[7].freqChanged) {
chan[7].freq=parent->calcFreq(chan[7].baseFreq,chan[7].pitch,chan[7].fixedArp?chan[7].baseNoteOverride:chan[7].arpOff,chan[7].fixedArp,true,0,chan[7].pitch2,chipClock,CHIP_DIVIDER);
if (chan[7].freq<1) chan[7].freq=1;
if (chan[7].freq>1024) chan[7].freq=1024;
int wf=0x400-chan[7].freq;
if (chan[csmChan].freqChanged) {
chan[csmChan].freq=parent->calcFreq(chan[csmChan].baseFreq,chan[csmChan].pitch,chan[csmChan].fixedArp?chan[csmChan].baseNoteOverride:chan[csmChan].arpOff,chan[csmChan].fixedArp,true,0,chan[csmChan].pitch2,chipClock,CHIP_DIVIDER);
if (chan[csmChan].freq<1) chan[csmChan].freq=1;
if (chan[csmChan].freq>1024) chan[csmChan].freq=1024;
int wf=0x400-chan[csmChan].freq;
immWrite(0x24,wf>>2);
immWrite(0x25,wf&3);
chan[7].freqChanged=false;
chan[csmChan].freqChanged=false;
}
if (chan[7].keyOff || chan[7].keyOn) {
if (chan[csmChan].keyOff || chan[csmChan].keyOn) {
writeNoteOn=true;
for (int i=0; i<4; i++) {
writeMask|=opChan[i].active<<(4+i);
@ -608,7 +608,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
}
if (writeNoteOn) {
if (chan[7].active) { // CSM
if (chan[csmChan].active) { // CSM
writeMask^=0xf0;
}
/*printf(
@ -622,13 +622,13 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
}
if (extMode && softPCM) {
if (chan[7].keyOn) {
if (chan[csmChan].keyOn) {
immWrite(0x27,0x81);
chan[7].keyOn=false;
chan[csmChan].keyOn=false;
}
if (chan[7].keyOff) {
if (chan[csmChan].keyOff) {
immWrite(0x27,0x40);
chan[7].keyOff=false;
chan[csmChan].keyOff=false;
}
}
}

View File

@ -26,7 +26,20 @@
#define CHIP_DIVIDER 1
const char* regCheatSheetPokeMini[]={
"Period", "0",
"TMR3_SCALE", "1C",
"TMR3_OSC", "1D",
"TMR3_CTRL_L", "48",
"TMR3_CTRL_H", "49",
"TMR3_PRE_L", "4A",
"TMR3_PRE_H", "4B",
"TMR3_PVT_L", "4C",
"TMR3_PVT_H", "4D",
"TMR3_CNT_L", "4E",
"TMR3_CNT_H", "4F",
"IO_DIR", "60",
"IO_DATA", "61",
"AUD_CTRL", "70",
"AUD_VOL", "71",
NULL
};
@ -42,6 +55,37 @@ const char** DivPlatformPokeMini::getRegisterSheet() {
return regCheatSheetPokeMini;
}
void DivPlatformPokeMini::rWrite(unsigned char addr, unsigned char val) {
if (addr<128) regPool[addr]=val;
switch (addr) {
case 0x1c:
// ignore
break;
case 0x1d:
// ignore
break;
case 0x48: case 0x49:
on=val&4;
if (val&2) pos=0;
break;
case 0x4a:
preset=(preset&0xff00)|val;
break;
case 0x4b:
preset=(preset&0xff)|(val<<8);
break;
case 0x4c:
pivot=(pivot&0xff00)|val;
break;
case 0x4d:
pivot=(pivot&0xff)|(val<<8);
break;
case 0x71:
vol=val&3;
break;
}
}
void DivPlatformPokeMini::acquire(short* bufL, short* bufR, size_t start, size_t len) {
int out=0;
for (size_t i=start; i<start+len; i++) {
@ -72,7 +116,7 @@ void DivPlatformPokeMini::tick(bool sysTick) {
chan[i].std.next();
if (chan[i].std.vol.had) {
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol,chan[i].std.vol.val,2);
vol=(chan[i].outVol==2)?3:chan[i].outVol;
rWrite(0x71,(chan[i].outVol==2)?3:chan[i].outVol);
}
if (NEW_ARP_STRAT) {
chan[i].handleArp();
@ -100,13 +144,16 @@ void DivPlatformPokeMini::tick(bool sysTick) {
if (chan[i].freq<0) chan[i].freq=0;
if (chan[i].freq>65535) chan[i].freq=65535;
if (chan[i].keyOn) {
on=true;
rWrite(0x48,4);
}
if (chan[i].keyOff) {
on=false;
rWrite(0x48,0);
}
preset=chan[i].freq;
pivot=(chan[i].duty*preset)>>8;
rWrite(0x4a,chan[i].freq&0xff);
rWrite(0x4b,chan[i].freq>>8);
int pvt=(chan[i].duty*chan[i].freq)>>8;
rWrite(0x4c,pvt&0xff);
rWrite(0x4d,pvt>>8);
if (chan[i].keyOn) chan[i].keyOn=false;
if (chan[i].keyOff) chan[i].keyOff=false;
chan[i].freqChanged=false;
@ -122,7 +169,7 @@ int DivPlatformPokeMini::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value;
}
vol=(chan[c.chan].outVol==2)?3:chan[c.chan].outVol;
rWrite(0x71,(chan[c.chan].outVol==2)?3:chan[c.chan].outVol);
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_POKEMINI));
@ -151,7 +198,7 @@ int DivPlatformPokeMini::dispatch(DivCommand c) {
chan[c.chan].outVol=c.value;
}
if (chan[c.chan].active) {
on=chan[c.chan].vol;
rWrite(0x71,(chan[c.chan].outVol==2)?3:chan[c.chan].outVol);
}
}
break;
@ -186,14 +233,13 @@ int DivPlatformPokeMini::dispatch(DivCommand c) {
break;
}
case DIV_CMD_LEGATO:
if (c.chan==3) break;
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)));
chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value;
break;
case DIV_CMD_PRE_PORTA:
if (chan[c.chan].active && c.value2) {
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_POKEMINI));
}
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
chan[c.chan].inPorta=c.value;
@ -239,18 +285,11 @@ DivDispatchOscBuffer* DivPlatformPokeMini::getOscBuffer(int ch) {
}
unsigned char* DivPlatformPokeMini::getRegisterPool() {
if (on) {
regPool[0]=preset;
regPool[1]=preset>>8;
} else {
regPool[0]=0;
regPool[1]=0;
}
return regPool;
}
int DivPlatformPokeMini::getRegisterPoolSize() {
return 2;
return 128;
}
void DivPlatformPokeMini::reset() {
@ -272,7 +311,7 @@ void DivPlatformPokeMini::reset() {
pivot=0;
elapsedMain=0;
memset(regPool,0,2);
memset(regPool,0,128);
}
bool DivPlatformPokeMini::keyOffAffectsArp(int ch) {
@ -294,11 +333,11 @@ void DivPlatformPokeMini::notifyInsDeletion(void* ins) {
}
void DivPlatformPokeMini::poke(unsigned int addr, unsigned short val) {
// ???
rWrite(addr,val);
}
void DivPlatformPokeMini::poke(std::vector<DivRegWrite>& wlist) {
// ???
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
}
int DivPlatformPokeMini::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {

View File

@ -37,9 +37,11 @@ class DivPlatformPokeMini: public DivDispatch {
int pos;
unsigned char timerScale, vol;
unsigned short preset, pivot;
unsigned char regPool[2];
unsigned char regPool[128];
unsigned short elapsedMain;
void rWrite(unsigned char addr, unsigned char val);
friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int);

View File

@ -74,6 +74,14 @@ void DivPlatformPOKEY::acquire(short* bufL, short* bufR, size_t start, size_t le
}
mzpokeysnd_process_16(&pokey,&bufL[h],1);
if (++oscBufDelay>=14) {
oscBufDelay=0;
oscBuf[0]->data[oscBuf[0]->needle++]=pokey.outvol_0<<11;
oscBuf[1]->data[oscBuf[1]->needle++]=pokey.outvol_1<<11;
oscBuf[2]->data[oscBuf[2]->needle++]=pokey.outvol_2<<11;
oscBuf[3]->data[oscBuf[3]->needle++]=pokey.outvol_3<<11;
}
}
}
@ -409,7 +417,7 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock;
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate/16;
oscBuf[i]->rate=rate/14;
}
}
@ -425,6 +433,7 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon
parent=p;
dumpWrites=false;
skipRegisterWrites=false;
oscBufDelay=0;
for (int i=0; i<4; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;

View File

@ -47,6 +47,7 @@ class DivPlatformPOKEY: public DivDispatch {
std::queue<QueuedWrite> writes;
unsigned char audctl;
bool audctlChanged;
unsigned char oscBufDelay;
PokeyState pokey;
unsigned char regPool[16];
friend void putDispatchChip(void*,int);

View File

@ -1637,23 +1637,6 @@ void Update_pokey_sound_mz(PokeyState* ps, unsigned short addr, unsigned char va
#define MAX_SAMPLE 152
void mzpokeysnd_process_8(PokeyState* ps, void* sndbuffer, int sndn)
{
int i;
int nsam = sndn;
unsigned char *buffer = (unsigned char *) sndbuffer;
/* if there are two pokeys, then the signal is stereo
we assume even sndn */
while(nsam >= 1)
{
buffer[0] = (unsigned char)floor(generate_sample(ps)
* (255.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95) + 128 + 0.5 + 0.5 * rand() / RAND_MAX - 0.25);
buffer += 1;
nsam -= 1;
}
}
void mzpokeysnd_process_16(PokeyState* ps, void* sndbuffer, int sndn)
{
int i;
@ -1665,7 +1648,7 @@ void mzpokeysnd_process_16(PokeyState* ps, void* sndbuffer, int sndn)
while(nsam >= (int) 1)
{
buffer[0] = (short)floor(generate_sample(ps)
* (65535.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95) + 0.5 + 0.5 * rand() / RAND_MAX - 0.25);
* (65535.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95));
buffer += 1;
nsam -= 1;
}

View File

@ -149,7 +149,6 @@ typedef struct stPokeyState
int outvol_3;
} PokeyState;
void mzpokeysnd_process_8(PokeyState* ps, void* sndbuffer, int sndn);
void mzpokeysnd_process_16(PokeyState* ps, void* sndbuffer, int sndn);
void Update_pokey_sound_mz(PokeyState* ps, unsigned short addr, unsigned char val, unsigned char gain);

View File

@ -64,10 +64,10 @@ enum DivSystem {
DIV_SYSTEM_FDS,
DIV_SYSTEM_MMC5,
DIV_SYSTEM_N163,
DIV_SYSTEM_OPN,
DIV_SYSTEM_OPN_EXT,
DIV_SYSTEM_PC98,
DIV_SYSTEM_PC98_EXT,
DIV_SYSTEM_YM2203,
DIV_SYSTEM_YM2203_EXT,
DIV_SYSTEM_YM2608,
DIV_SYSTEM_YM2608_EXT,
DIV_SYSTEM_OPL,
DIV_SYSTEM_OPL2,
DIV_SYSTEM_OPL3,
@ -111,15 +111,20 @@ enum DivSystem {
DIV_SYSTEM_NAMCO,
DIV_SYSTEM_NAMCO_15XX,
DIV_SYSTEM_NAMCO_CUS30,
DIV_SYSTEM_YM2612_FRAC,
DIV_SYSTEM_YM2612_FRAC_EXT,
DIV_SYSTEM_YM2612_DUALPCM,
DIV_SYSTEM_YM2612_DUALPCM_EXT,
DIV_SYSTEM_MSM5232,
DIV_SYSTEM_T6W28,
DIV_SYSTEM_K007232,
DIV_SYSTEM_GA20,
DIV_SYSTEM_PCM_DAC,
DIV_SYSTEM_PONG,
DIV_SYSTEM_DUMMY
DIV_SYSTEM_DUMMY,
DIV_SYSTEM_YM2612_CSM,
DIV_SYSTEM_YM2610_CSM,
DIV_SYSTEM_YM2610B_CSM,
DIV_SYSTEM_YM2203_CSM,
DIV_SYSTEM_YM2608_CSM
};
struct DivSubSong {

View File

@ -1006,7 +1006,7 @@ void DivEngine::registerSystems() {
}
);
sysDefs[DIV_SYSTEM_OPN]=new DivSysDef(
sysDefs[DIV_SYSTEM_YM2203]=new DivSysDef(
"Yamaha YM2203 (OPN)", NULL, 0x8d, 0, 6, true, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"cost-reduced version of the OPM with a different register layout and no stereo...\n...but it has a built-in AY-3-8910! (actually an YM2149)",
{"FM 1", "FM 2", "FM 3", "PSG 1", "PSG 2", "PSG 3"},
@ -1018,7 +1018,7 @@ void DivEngine::registerSystems() {
fmOPNPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_OPN_EXT]=new DivSysDef(
sysDefs[DIV_SYSTEM_YM2203_EXT]=new DivSysDef(
"Yamaha YM2203 (OPN) Extended Channel 3", NULL, 0xb6, 0, 9, true, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"cost-reduced version of the OPM with a different register layout and no stereo...\n...but it has a built-in AY-3-8910! (actually an YM2149)\nthis one is in Extended Channel mode, which turns the third FM channel into four operators with independent notes/frequencies",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "PSG 1", "PSG 2", "PSG 3"},
@ -1030,7 +1030,19 @@ void DivEngine::registerSystems() {
fmOPNPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_PC98]=new DivSysDef(
sysDefs[DIV_SYSTEM_YM2203_CSM]=new DivSysDef(
"Yamaha YM2203 (OPN) CSM", NULL, 0xc3, 0, 10, true, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"cost-reduced version of the OPM with a different register layout and no stereo...\n...but it has a built-in AY-3-8910! (actually an YM2149)\nCSM blah blah",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "CSM Timer", "PSG 1", "PSG 2", "PSG 3"},
{"F1", "F2", "O1", "O2", "O3", "O4", "CSM", "S1", "S2", "S3"},
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE},
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY},
{},
fmEffectHandlerMap,
fmOPNPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_YM2608]=new DivSysDef(
"Yamaha YM2608 (OPNA)", NULL, 0x8e, 0, 16, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"OPN but twice the FM channels, stereo makes a come-back and has rhythm and ADPCM channels.",
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"},
@ -1042,7 +1054,7 @@ void DivEngine::registerSystems() {
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_PC98_EXT]=new DivSysDef(
sysDefs[DIV_SYSTEM_YM2608_EXT]=new DivSysDef(
"Yamaha YM2608 (OPNA) Extended Channel 3", NULL, 0xb7, 0, 19, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"OPN but twice the FM channels, stereo makes a come-back and has rhythm and ADPCM channels.\nthis one is in Extended Channel mode, which turns the third FM channel into four operators with independent notes/frequencies",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"},
@ -1054,6 +1066,18 @@ void DivEngine::registerSystems() {
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_YM2608_CSM]=new DivSysDef(
"Yamaha YM2608 (OPNA) CSM", NULL, 0xc4, 0, 20, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"OPN but twice the FM channels, stereo makes a come-back and has rhythm and ADPCM channels.\nCSM blah blah",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "CSM Timer", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"},
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "CSM", "S1", "S2", "S3", "BD", "SD", "TP", "HH", "TM", "RM", "P"},
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM},
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMB},
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA},
fmEffectHandlerMap,
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_OPL]=new DivSysDef(
"Yamaha YM3526 (OPL)", NULL, 0x8f, 0, 9, true, false, 0x151, false, 0,
"OPN, but what if you only had two operators, no stereo, no detune and a lower ADSR parameter range?",
@ -1119,7 +1143,7 @@ void DivEngine::registerSystems() {
);
sysDefs[DIV_SYSTEM_POKEY]=new DivSysDef(
"POKEY", NULL, 0x94, 0, 4, false, true, 0, false, 0,
"POKEY", NULL, 0x94, 0, 4, false, true, 0x161, false, 0,
"TIA, but better and more flexible.\nused in the Atari 8-bit family of computers (400/800/XL/XE).",
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
{"CH1", "CH2", "CH3", "CH4"},
@ -1262,6 +1286,18 @@ void DivEngine::registerSystems() {
fmOPN2PostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_YM2612_CSM]=new DivSysDef(
"Yamaha YM2612 (OPN2) CSM", NULL, 0xc1, 0, 10, true, false, 0x150, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).\nthis one includes CSM mode control for special effects on Channel 3.",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "CSM Timer"},
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "CSM"},
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE},
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM},
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_NULL},
fmOPN2EffectHandlerMap,
fmOPN2PostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_SCC]=new DivSysDef(
"Konami SCC", NULL, 0xa1, 0, 5, false, true, 0x161, false, 0,
"a wavetable chip made by Konami for use with the MSX.\nthe last channel shares its wavetable with the previous one though.",
@ -1333,6 +1369,18 @@ void DivEngine::registerSystems() {
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_YM2610_CSM]=new DivSysDef(
"Yamaha YM2610 (OPNB) CSM", NULL, 0xc2, 0, 18, true, false, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_A)|(1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"this chip was used in SNK's Neo Geo arcade board and video game console.\nit's like OPNA but the rhythm channels are ADPCM channels and two FM channels went missing.\nthis one includes CSM mode control for special effects on Channel 2.",
{"FM 1", "FM 2 OP1", "FM 2 OP2", "FM 2 OP3", "FM 2 OP4", "FM 3", "FM 4", "CSM Timer", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"},
{"F1", "O1", "O2", "O3", "O4", "F3", "F4", "CSM", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"},
{DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMB},
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
fmEffectHandlerMap,
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_OPLL_DRUMS]=new DivSysDef(
"Yamaha YM2413 (OPLL) with drums", NULL, 0xa7, 0, 11, true, false, 0x150, false, 0,
"the OPLL chips but with drums mode turned on.",
@ -1410,6 +1458,18 @@ void DivEngine::registerSystems() {
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_YM2610B_CSM]=new DivSysDef(
"Yamaha YM2610B (OPNB2) CSM", NULL, 0xc5, 0, 20, true, false, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_A)|(1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"so Taito asked Yamaha if they could get the two missing FM channels back, and Yamaha gladly provided them with this chip.\nCSM blah blah",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "CSM Timer", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"},
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "CSM", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"},
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMB},
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
fmEffectHandlerMap,
fmOPNAPostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_SEGAPCM_COMPAT]=new DivSysDef(
"SegaPCM (compatible 5-channel mode)", NULL, 0xa9, 0, 5, false, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"this is the same thing as SegaPCM, but only exposes 5 of the channels for compatibility with DefleMask.",
@ -1652,7 +1712,7 @@ void DivEngine::registerSystems() {
}
);
sysDefs[DIV_SYSTEM_YM2612_FRAC]=new DivSysDef(
sysDefs[DIV_SYSTEM_YM2612_DUALPCM]=new DivSysDef(
"Yamaha YM2612 (OPN2) with DualPCM", NULL, 0xbe, 0, 7, true, false, 0x150, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).\nthis system uses software mixing to provide two sample channels.",
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6/PCM 1", "PCM 2"},
@ -1664,7 +1724,7 @@ void DivEngine::registerSystems() {
fmOPN2PostEffectHandlerMap
);
sysDefs[DIV_SYSTEM_YM2612_FRAC_EXT]=new DivSysDef(
sysDefs[DIV_SYSTEM_YM2612_DUALPCM_EXT]=new DivSysDef(
"Yamaha YM2612 (OPN2) Extended Channel 3 with DualPCM and CSM", NULL, 0xbd, 0, 11, true, false, 0x150, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).\nthis system uses software mixing to provide two sample channels.\nthis one is in Extended Channel mode, which turns the third FM channel into four operators with independent notes/frequencies.",
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6/PCM 1", "PCM 2", "CSM Timer"},

View File

@ -34,8 +34,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
switch (sys) {
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
for (int i=0; i<3; i++) { // set SL and RR to highest
w->writeC(2|baseAddr1);
w->writeC(0x80+i);
@ -252,8 +252,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(0);
}
break;
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT:
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT:
for (int i=0; i<3; i++) { // set SL and RR to highest
w->writeC(5|baseAddr1);
w->writeC(0x80+i);
@ -333,6 +333,13 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(0);
}
break;
case DIV_SYSTEM_POKEY:
for (int i=0; i<9; i++) {
w->writeC(0xbb);
w->writeC(i|baseAddr2);
w->writeC(0);
}
break;
case DIV_SYSTEM_LYNX:
w->writeC(0x4e);
w->writeC(0x44);
@ -566,8 +573,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
switch (sys) {
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
switch (write.addr>>8) {
case 0: // port 0
w->writeC(2|baseAddr1);
@ -659,14 +666,14 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
break;
}
break;
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT:
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT:
w->writeC(5|baseAddr1);
w->writeC(write.addr&0xff);
w->writeC(write.val);
break;
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_PC98_EXT:
case DIV_SYSTEM_YM2608:
case DIV_SYSTEM_YM2608_EXT:
switch (write.addr>>8) {
case 0: // port 0
w->writeC(6|baseAddr1);
@ -698,6 +705,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(baseAddr2|(write.addr&0xff));
w->writeC(write.val);
break;
case DIV_SYSTEM_POKEY:
w->writeC(0xbb);
w->writeC(baseAddr2|(write.addr&0x0f));
w->writeC(write.val&0xff);
break;
case DIV_SYSTEM_LYNX:
w->writeC(0x4e);
w->writeC(write.addr&0xff);
@ -1168,8 +1180,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
break;
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
if (!hasOPN2) {
hasOPN2=disCont[i].dispatch->chipClock;
willExport[i]=true;
@ -1192,8 +1204,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
howManyChips++;
}
break;
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT:
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT:
if (!hasOPN) {
hasOPN=disCont[i].dispatch->chipClock;
willExport[i]=true;
@ -1205,8 +1217,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
howManyChips++;
}
break;
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_PC98_EXT:
case DIV_SYSTEM_YM2608:
case DIV_SYSTEM_YM2608_EXT:
if (!hasOPNA) {
hasOPNA=disCont[i].dispatch->chipClock;
willExport[i]=true;
@ -1246,6 +1258,17 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
howManyChips++;
}
break;
case DIV_SYSTEM_POKEY:
if (!hasPOKEY) {
hasPOKEY=disCont[i].dispatch->chipClock;
willExport[i]=true;
} else if (!(hasPOKEY&0x40000000)) {
isSecond[i]=true;
willExport[i]=true;
hasPOKEY|=0x40000000;
howManyChips++;
}
break;
case DIV_SYSTEM_LYNX:
if (!hasLynx) {
hasLynx=disCont[i].dispatch->chipClock;
@ -1825,8 +1848,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
switch (song.system[i]) {
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT:
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
w->writeC(0x90);
w->writeC(streamID);
w->writeC(0x02);

View File

@ -241,8 +241,8 @@ void putDispatchChip(void* data, int type) {
switch (type) {
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT: {
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT: {
GENESIS_CHIP_DEBUG;
break;
}
@ -256,8 +256,8 @@ void putDispatchChip(void* data, int type) {
SMS_CHIP_DEBUG;
break;
}
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT: {
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT: {
DivPlatformYM2203* ch=(DivPlatformYM2203*)data;
ImGui::Text("> YM2203");
FM_OPN_CHIP_DEBUG;
@ -267,8 +267,8 @@ void putDispatchChip(void* data, int type) {
ImGui::TextColored(ch->extMode?colorOn:colorOff,">> ExtMode");
break;
}
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_PC98_EXT: {
case DIV_SYSTEM_YM2608:
case DIV_SYSTEM_YM2608_EXT: {
DivPlatformYM2608* ch=(DivPlatformYM2608*)data;
ImGui::Text("> YM2608");
FM_OPN_CHIP_DEBUG;
@ -541,12 +541,12 @@ void putDispatchChan(void* data, int chanNum, int type) {
break;
}
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_FRAC: {
case DIV_SYSTEM_YM2612_DUALPCM: {
GENESIS_CHAN_DEBUG;
break;
}
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC_EXT: {
case DIV_SYSTEM_YM2612_DUALPCM_EXT: {
if (chanNum>=2 && chanNum<=5) {
DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data;
ImGui::Text("> YM2612 (per operator)");
@ -560,11 +560,11 @@ void putDispatchChan(void* data, int chanNum, int type) {
SMS_CHAN_DEBUG;
break;
}
case DIV_SYSTEM_OPN: {
case DIV_SYSTEM_YM2203: {
OPN_CHAN_DEBUG;
break;
}
case DIV_SYSTEM_OPN_EXT: {
case DIV_SYSTEM_YM2203_EXT: {
if (chanNum>=2 && chanNum<=5) {
OPN_OPCHAN_DEBUG;
} else {
@ -572,13 +572,13 @@ void putDispatchChan(void* data, int chanNum, int type) {
}
break;
}
case DIV_SYSTEM_PC98: {
case DIV_SYSTEM_YM2608: {
DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data;
ImGui::Text("> YM2608");
OPNB_CHAN_DEBUG;
break;
}
case DIV_SYSTEM_PC98_EXT: {
case DIV_SYSTEM_YM2608_EXT: {
if (chanNum>=2 && chanNum<=5) {
DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data;
ImGui::Text("> YM2608 (per operator)");

View File

@ -913,8 +913,8 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
const int availableSystems[]={
DIV_SYSTEM_YM2612,
DIV_SYSTEM_YM2612_EXT,
DIV_SYSTEM_YM2612_FRAC,
DIV_SYSTEM_YM2612_FRAC_EXT,
DIV_SYSTEM_YM2612_DUALPCM,
DIV_SYSTEM_YM2612_DUALPCM_EXT,
DIV_SYSTEM_SMS,
DIV_SYSTEM_GB,
DIV_SYSTEM_PCE,
@ -939,10 +939,10 @@ const int availableSystems[]={
DIV_SYSTEM_YMU759,
DIV_SYSTEM_DUMMY,
DIV_SYSTEM_SOUND_UNIT,
DIV_SYSTEM_OPN,
DIV_SYSTEM_OPN_EXT,
DIV_SYSTEM_PC98,
DIV_SYSTEM_PC98_EXT,
DIV_SYSTEM_YM2203,
DIV_SYSTEM_YM2203_EXT,
DIV_SYSTEM_YM2608,
DIV_SYSTEM_YM2608_EXT,
DIV_SYSTEM_OPLL,
DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_VRC7,
@ -994,8 +994,8 @@ const int availableSystems[]={
const int chipsFM[]={
DIV_SYSTEM_YM2612,
DIV_SYSTEM_YM2612_EXT,
DIV_SYSTEM_YM2612_FRAC,
DIV_SYSTEM_YM2612_FRAC_EXT,
DIV_SYSTEM_YM2612_DUALPCM,
DIV_SYSTEM_YM2612_DUALPCM_EXT,
DIV_SYSTEM_YM2151,
DIV_SYSTEM_YM2610,
DIV_SYSTEM_YM2610_EXT,
@ -1004,10 +1004,10 @@ const int chipsFM[]={
DIV_SYSTEM_YM2610B,
DIV_SYSTEM_YM2610B_EXT,
DIV_SYSTEM_YMU759,
DIV_SYSTEM_OPN,
DIV_SYSTEM_OPN_EXT,
DIV_SYSTEM_PC98,
DIV_SYSTEM_PC98_EXT,
DIV_SYSTEM_YM2203,
DIV_SYSTEM_YM2203_EXT,
DIV_SYSTEM_YM2608,
DIV_SYSTEM_YM2608_EXT,
DIV_SYSTEM_OPLL,
DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_VRC7,

View File

@ -57,13 +57,13 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Sega Genesis (DualPCM)", {
CH(DIV_SYSTEM_YM2612_FRAC, 64, 0, ""),
CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, ""),
CH(DIV_SYSTEM_SMS, 32, 0, "")
}
);
ENTRY(
"Sega Genesis (DualPCM, extended channel 3)", {
CH(DIV_SYSTEM_YM2612_FRAC_EXT, 64, 0, ""),
CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, ""),
CH(DIV_SYSTEM_SMS, 32, 0, "")
}
);
@ -421,25 +421,25 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"NEC PC-88 (with PC-8801-11)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-88 (with PC-8801-11; extended channel 3)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-88 (with PC-8801-23)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-88 (with PC-8801-23; extended channel 3)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1") // external
}
);
ENTRY(
@ -451,7 +451,7 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-10)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15"), // external
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15") // ""
}
@ -459,7 +459,7 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-10; extended channel 3)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15"), // external
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15") // ""
}
@ -467,77 +467,77 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-11)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-11; extended channel 3 on internal OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-11; extended channel 3 on external OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-11; extended channel 3 on both OPNs)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-23)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-23; extended channel 3 on internal OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-23; extended channel 3 on external OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with PC-8801-23; extended channel 3 on both OPNs)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801mk2SR (with HMB-20 HIBIKI-8800)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2151, 64, 0, "clockSel=2") // external; 4.0000MHz
}
);
ENTRY(
"NEC PC-8801mk2SR (with HMB-20 HIBIKI-8800; extended channel 3)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2151, 64, 0, "clockSel=2") // external; 4.0000MHz
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-10)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15"), // external
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15") // ""
}
@ -545,7 +545,7 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"NEC PC-8801FA (with PC-8801-10; extended channel 3)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=4"), // internal
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15"), // external
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=15") // ""
}
@ -553,144 +553,144 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"NEC PC-8801FA (with PC-8801-11)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-11; extended channel 3 on internal OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-11; extended channel 3 on external OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-11; extended channel 3 on both OPNs)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4") // external
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-23)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-23; extended channel 3 on internal OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-23; extended channel 3 on external OPN)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801FA (with PC-8801-23; extended channel 3 on both OPNs)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1") // external
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1") // external
}
);
ENTRY(
"NEC PC-8801FA (with HMB-20 HIBIKI-8800)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2151, 64, 0, "clockSel=2") // external; 4.0000MHz
}
);
ENTRY(
"NEC PC-8801FA (with HMB-20 HIBIKI-8800; extended channel 3)", {
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"), // internal
CH(DIV_SYSTEM_YM2151, 64, 0, "clockSel=2") // external; 4.0000MHz
}
);
ENTRY(
"NEC PC-98 (with PC-9801-26/K)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"), // 3.9936MHz but some compatible card has 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"), // 3.9936MHz but some compatible card has 4MHz
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with PC-9801-26/K; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"), // 3.9936MHz but some compatible card has 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"), // 3.9936MHz but some compatible card has 4MHz
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_OPL2, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_OPL2, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra in drums mode)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra in drums mode; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra V)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_Y8950, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra V; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_Y8950, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra V in drums mode)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_Y8950_DRUMS, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Orchestra V in drums mode; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_Y8950_DRUMS, 64, 0, "clockSel=4"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with PC-9801-86)", { // -73 also has OPNA
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PCM_DAC, 64, 0, // 2x 16-bit Burr Brown DAC
"rate=44100\n"
"outDepth=15\n"
@ -704,7 +704,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NEC PC-98 (with PC-9801-86; extended channel 3)", { // -73 also has OPNA
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=44100\n"
"outDepth=15\n"
@ -718,19 +718,19 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NEC PC-98 (with PC-9801-73)", {
CH(DIV_SYSTEM_PC98, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2608, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with PC-9801-73; extended channel 3)", {
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_PCSPKR, 64, 0, "clockSel=1")
}
);
ENTRY(
"NEC PC-98 (with Sound Blaster 16 for PC-9800 w/PC-9801-26/K compatible)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=44100\n"
"outDepth=15\n"
@ -742,7 +742,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NEC PC-98 (with Sound Blaster 16 for PC-9800 w/PC-9801-26/K compatible; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=44100\n"
"outDepth=15\n"
@ -754,7 +754,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NEC PC-98 (with Sound Blaster 16 for PC-9800 w/PC-9801-26/K compatible in drums mode)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=44100\n"
"outDepth=15\n"
@ -766,7 +766,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NEC PC-98 (with Sound Blaster 16 for PC-9800 w/PC-9801-26/K compatible in drums mode; extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=44100\n"
"outDepth=15\n"
@ -789,29 +789,29 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"ZX Spectrum (128K) with TurboSound FM", {
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=1")
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=1")
}
);
ENTRY(
"ZX Spectrum (128K) with TurboSound FM (extended channel 3 on first OPN)", {
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=1")
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=1")
}
);
ENTRY(
"ZX Spectrum (128K) with TurboSound FM (extended channel 3 on second OPN)", {
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=1")
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=1")
}
);
ENTRY(
"ZX Spectrum (128K) with TurboSound FM (extended channel 3 on both OPNs)", {
CH(DIV_SYSTEM_AY8910, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=1")
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=1"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=1")
}
);
ENTRY(
@ -1081,22 +1081,22 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Yamaha YM2203 (OPN)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=3")
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3")
}
);
ENTRY(
"Yamaha YM2203 (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=3")
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3")
}
);
ENTRY(
"Yamaha YM2608 (OPNA)", {
CH(DIV_SYSTEM_PC98, 64, 0, "")
CH(DIV_SYSTEM_YM2608, 64, 0, "")
}
);
ENTRY(
"Yamaha YM2608 (extended channel 3)", {
CH(DIV_SYSTEM_PC98_EXT, 64, 0, "")
CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "")
}
);
ENTRY(
@ -1131,12 +1131,12 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Yamaha YM2612 (OPN2) with DualPCM", {
CH(DIV_SYSTEM_YM2612_FRAC, 64, 0, "ladderEffect=true")
CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, "ladderEffect=true")
}
);
ENTRY(
"Yamaha YM2612 (extended channel 3) with DualPCM", {
CH(DIV_SYSTEM_YM2612_FRAC_EXT, 64, 0, "ladderEffect=true")
CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, "ladderEffect=true")
}
);
ENTRY(
@ -1166,12 +1166,12 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Yamaha YM3438 (OPN2C) with DualPCM", {
CH(DIV_SYSTEM_YM2612_FRAC, 64, 0, "")
CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, "")
}
);
ENTRY(
"Yamaha YM3438 (extended channel 3) with DualPCM", {
CH(DIV_SYSTEM_YM2612_FRAC_EXT, 64, 0, "")
CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, "")
}
);
ENTRY(
@ -1692,13 +1692,13 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Sega Hang-On", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_SEGAPCM, 64, 0, "") // discrete logics, 62.5KHz output rate
}
);
ENTRY(
"Sega Hang-On (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_SEGAPCM, 64, 0, "") // discrete logics, 62.5KHz output rate
}
);
@ -1788,26 +1788,26 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Capcom Arcade", { // 1943, Side arms, etc
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 4 or 1.5MHz; various per games
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5")
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 4 or 1.5MHz; various per games
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5")
}
);
ENTRY(
"Capcom Arcade (extended channel 3 on first OPN)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"),
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5")
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"),
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5")
}
);
ENTRY(
"Capcom Arcade (extended channel 3 on second OPN)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5")
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5")
}
);
ENTRY(
"Capcom Arcade (extended channel 3 on both OPNs)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"),
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5")
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"),
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5")
}
);
ENTRY(
@ -1842,7 +1842,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NMK 16-bit Arcade", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 1.5MHz; optional
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 1.5MHz; optional
CH(DIV_SYSTEM_MSM6295, 64, 0,
"clockSel=2\n"
"rateSel=true\n"
@ -1855,7 +1855,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"NMK 16-bit Arcade (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"), // 1.5MHz; optional
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"), // 1.5MHz; optional
CH(DIV_SYSTEM_MSM6295, 64, 0,
"clockSel=2\n"
"rateSel=true\n"
@ -1868,21 +1868,21 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Kaneko DJ Boy", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, -127, "clockSel=12"), // 1.5MHz, Left output
CH(DIV_SYSTEM_MSM6295, 64, 127, "clockSel=12"), // 1.5MHz, Right output
}
);
ENTRY(
"Kaneko DJ Boy (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, -127, "clockSel=12"), // 1.5MHz, Left output
CH(DIV_SYSTEM_MSM6295, 64, 127, "clockSel=12") // 1.5MHz, Right output
}
);
ENTRY(
"Kaneko Air Buster", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, 0,
"clockSel=13\n"
"rateSel=true\n"
@ -1891,7 +1891,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Kaneko Air Buster (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, 0,
"clockSel=13\n"
"rateSel=true\n"
@ -1923,29 +1923,29 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Tecmo Ninja Gaiden", { // Ninja Gaiden, Raiga, etc
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1MHz
}
);
ENTRY(
"Tecmo Ninja Gaiden (extended channel 3 on first OPN)", { // Ninja Gaiden, Raiga, etc
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1MHz
}
);
ENTRY(
"Tecmo Ninja Gaiden (extended channel 3 on second OPN)", { // Ninja Gaiden, Raiga, etc
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1MHz
}
);
ENTRY(
"Tecmo Ninja Gaiden (extended channel 3 on both OPNs)", { // Ninja Gaiden, Raiga, etc
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1MHz
}
);
@ -2022,66 +2022,66 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Data East Karnov", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL, 64, 0, "clockSel=3") // 3MHz
}
);
ENTRY(
"Data East Karnov (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL, 64, 0, "clockSel=3") // 3MHz
}
);
ENTRY(
"Data East Karnov (drums mode)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL_DRUMS, 64, 0, "clockSel=3") // 3MHz
}
);
ENTRY(
"Data East Karnov (extended channel 3; drums mode)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL_DRUMS, 64, 0, "clockSel=3") // 3MHz
}
);
ENTRY(
"Data East Arcade", { // Bad dudes, Robocop, etc
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL2, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1 to 1.056MHz; various per games or optional
}
);
ENTRY(
"Data East Arcade (extended channel 3)", { // Bad dudes, Robocop, etc
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL2, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1 to 1.056MHz; various per games or optional
}
);
ENTRY(
"Data East Arcade (drums mode)", { // Bad dudes, Robocop, etc
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1 to 1.056MHz; various per games or optional
}
);
ENTRY(
"Data East Arcade (extended channel 3; drums mode)", { // Bad dudes, Robocop, etc
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_MSM6295, 64, 0, "") // 1 to 1.056MHz; various per games or optional
}
);
ENTRY(
"Data East PCX", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_PCE, 64, 0, "")
// software controlled MSM5205
}
);
ENTRY(
"Data East PCX (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=5"), // 1.5MHz
CH(DIV_SYSTEM_PCE, 64, 0, "")
// software controlled MSM5205
}
@ -2089,7 +2089,7 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"Data East Dark Seal", { // Dark Seal, Crude Buster, Vapor Trail, etc
CH(DIV_SYSTEM_YM2151, 64, 0, ""), // 3.580MHz (32.22MHz / 9)
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=2"), // 4.0275MHz (32.22MHz / 8); optional
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=2"), // 4.0275MHz (32.22MHz / 8); optional
CH(DIV_SYSTEM_MSM6295, 64, 0, ""), // 1.007MHz (32.22MHz / 32)
CH(DIV_SYSTEM_MSM6295, 64, 0, "clockSel=8") // 2.014MHz (32.22MHz / 16); optional
// HuC6280 is for control them, internal sound isn't used
@ -2098,7 +2098,7 @@ void FurnaceGUI::initSystemPresets() {
ENTRY(
"Data East Dark Seal (extended channel 3)", { // Dark Seal, Crude Buster, Vapor Trail, etc
CH(DIV_SYSTEM_YM2151, 64, 0, ""), // 3.580MHz (32.22MHz / 9)
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=2"), // 4.0275MHz (32.22MHz / 8); optional
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=2"), // 4.0275MHz (32.22MHz / 8); optional
CH(DIV_SYSTEM_MSM6295, 64, 0, ""), // 1.007MHz (32.22MHz / 32)
CH(DIV_SYSTEM_MSM6295, 64, 0, "clockSel=8") // 2.014MHz (32.22MHz / 16); optional
// HuC6280 is for control them, internal sound isn't used
@ -2213,7 +2213,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Alpha denshi Alpha-68K", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_OPLL, 64, 0, "clockSel=0"), // 3.58MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=7614\n"
@ -2223,7 +2223,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Alpha denshi Alpha-68K (extended channel 3)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_OPLL, 64, 0, "clockSel=0"), // 3.58MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=7614\n"
@ -2233,7 +2233,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Alpha denshi Alpha-68K (drums mode)", {
CH(DIV_SYSTEM_OPN, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_OPLL_DRUMS, 64, 0, "clockSel=0"), // 3.58MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=7614\n"
@ -2243,7 +2243,7 @@ void FurnaceGUI::initSystemPresets() {
);
ENTRY(
"Alpha denshi Alpha-68K (extended channel 3; drums mode)", {
CH(DIV_SYSTEM_OPN_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3"), // 3MHz
CH(DIV_SYSTEM_OPLL_DRUMS, 64, 0, "clockSel=0"), // 3.58MHz
CH(DIV_SYSTEM_PCM_DAC, 64, 0,
"rate=7614\n"

View File

@ -30,8 +30,8 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
switch (type) {
case DIV_SYSTEM_YM2612:
case DIV_SYSTEM_YM2612_EXT:
case DIV_SYSTEM_YM2612_FRAC:
case DIV_SYSTEM_YM2612_FRAC_EXT: {
case DIV_SYSTEM_YM2612_DUALPCM:
case DIV_SYSTEM_YM2612_DUALPCM_EXT: {
int clockSel=flags.getInt("clockSel",0);
bool ladder=flags.getBool("ladderEffect",0);
bool noExtMacros=flags.getBool("noExtMacros",false);
@ -59,7 +59,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
if (ImGui::Checkbox("Enable DAC distortion",&ladder)) {
altered=true;
}
if (type==DIV_SYSTEM_YM2612_EXT || type==DIV_SYSTEM_YM2612_FRAC_EXT) {
if (type==DIV_SYSTEM_YM2612_EXT || type==DIV_SYSTEM_YM2612_DUALPCM_EXT) {
if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) {
altered=true;
}
@ -834,8 +834,8 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
}
break;
}
case DIV_SYSTEM_OPN:
case DIV_SYSTEM_OPN_EXT: {
case DIV_SYSTEM_YM2203:
case DIV_SYSTEM_YM2203_EXT: {
int clockSel=flags.getInt("clockSel",0);
int prescale=flags.getInt("prescale",0);
bool noExtMacros=flags.getBool("noExtMacros",false);
@ -879,7 +879,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
altered=true;
}
if (type==DIV_SYSTEM_OPN_EXT) {
if (type==DIV_SYSTEM_YM2203_EXT) {
if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) {
altered=true;
}
@ -894,8 +894,8 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
}
break;
}
case DIV_SYSTEM_PC98:
case DIV_SYSTEM_PC98_EXT: {
case DIV_SYSTEM_YM2608:
case DIV_SYSTEM_YM2608_EXT: {
int clockSel=flags.getInt("clockSel",0);
int prescale=flags.getInt("prescale",0);
bool noExtMacros=flags.getBool("noExtMacros",false);
@ -923,7 +923,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
altered=true;
}
if (type==DIV_SYSTEM_PC98_EXT) {
if (type==DIV_SYSTEM_YM2608_EXT) {
if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) {
altered=true;
}