1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-26 09:29:45 +00:00

Establishes that there is such as a thing as a Konami SCC.

Creates one, ensures it appears in memory when intended to, lets it handle reads and writes. It currently does nothing.
This commit is contained in:
Thomas Harte 2018-01-06 20:15:55 -05:00
parent 3e1d8ea082
commit 655b971976
6 changed files with 146 additions and 9 deletions

View File

@ -0,0 +1,38 @@
//
// KonamiSCC.cpp
// Clock Signal
//
// Created by Thomas Harte on 06/01/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#include "KonamiSCC.hpp"
#include <cstring>
using namespace Konami;
SCC::SCC(Concurrency::DeferringAsyncTaskQueue &task_queue) :
task_queue_(task_queue) {}
bool SCC::is_silent() {
return !(channel_enable_ & 0x1f);
}
void SCC::get_samples(std::size_t number_of_samples, std::int16_t *target) {
if(is_silent()) {
std::memset(target, 0, sizeof(std::int16_t) * number_of_samples);
return;
}
// TODO
}
void SCC::write(uint16_t address, uint8_t value) {
// TODO
}
uint8_t SCC::read(uint16_t address) {
// TODO
return 0xff;
}

View File

@ -0,0 +1,59 @@
//
// KonamiSCC.hpp
// Clock Signal
//
// Created by Thomas Harte on 06/01/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef KonamiSCC_hpp
#define KonamiSCC_hpp
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
#include "../../Concurrency/AsyncTaskQueue.hpp"
namespace Konami {
/*!
Provides an emulation of Konami's Sound Creative Chip ('SCC').
The SCC is a primitive wavetable synthesis chip, offering 32-sample tables,
and five channels of output. The original SCC uses the same wave for channels
four and five, the SCC+ supports different waves for the two channels.
*/
class SCC: public ::Outputs::Speaker::SampleSource {
public:
/// Creates a new SCC.
SCC(Concurrency::DeferringAsyncTaskQueue &task_queue);
/// As per ::SampleSource; provides a broadphase test for silence.
bool is_silent();
/// As per ::SampleSource; provides audio output.
void get_samples(std::size_t number_of_samples, std::int16_t *target);
/// Writes to the SCC.
void write(uint16_t address, uint8_t value);
/// Reads from the SCC.
uint8_t read(uint16_t address);
private:
struct Channel {
int period = 0;
int amplitude = 0;
} channels_[5];
struct Wavetable {
std::int16_t samples[32];
} waves_[4];
std::uint8_t channel_enable_ = 0;
std::uint8_t test_register_ = 0;
Concurrency::DeferringAsyncTaskQueue &task_queue_;
};
}
#endif /* KonamiSCC_hpp */

View File

@ -10,16 +10,17 @@
#define KonamiWithSCC_hpp
#include "../ROMSlotHandler.hpp"
#include "../../../Components/KonamiSCC/KonamiSCC.hpp"
namespace MSX {
namespace Cartridge {
class KonamiWithSCCROMSlotHandler: public ROMSlotHandler {
public:
KonamiWithSCCROMSlotHandler(MSX::MemoryMap &map, int slot) :
map_(map), slot_(slot) {}
KonamiWithSCCROMSlotHandler(MSX::MemoryMap &map, int slot, Konami::SCC &scc) :
map_(map), slot_(slot), scc_(scc) {}
void write(uint16_t address, uint8_t value) {
void write(uint16_t address, uint8_t value) override {
switch(address >> 11) {
default: break;
case 0x0a:
@ -29,7 +30,16 @@ class KonamiWithSCCROMSlotHandler: public ROMSlotHandler {
map_.map(slot_, value * 8192, 0x6000, 0x2000);
break;
case 0x12:
map_.map(slot_, value * 8192, 0x8000, 0x2000);
if((value&0x3f) == 0x3f) {
scc_is_visible_ = true;
map_.unmap(slot_, 0x8000, 0x2000);
} else {
scc_is_visible_ = false;
map_.map(slot_, value * 8192, 0x8000, 0x2000);
}
break;
case 0x13:
if(scc_is_visible_) scc_.write(address, value);
break;
case 0x16:
map_.map(slot_, value * 8192, 0xa000, 0x2000);
@ -37,9 +47,18 @@ class KonamiWithSCCROMSlotHandler: public ROMSlotHandler {
}
}
uint8_t read(uint16_t address) override {
if(scc_is_visible_ && address >= 0x9800 && address < 0xa000) {
return scc_.read(address);
}
return 0xff;
}
private:
MSX::MemoryMap &map_;
int slot_;
Konami::SCC &scc_;
bool scc_is_visible_ = false;
};
}

View File

@ -22,6 +22,7 @@
#include "../../Components/9918/9918.hpp"
#include "../../Components/8255/i8255.hpp"
#include "../../Components/AY38910/AY38910.hpp"
#include "../../Components/KonamiSCC/KonamiSCC.hpp"
#include "../../Storage/Tape/Parsers/MSX.hpp"
#include "../../Storage/Tape/Tape.hpp"
@ -120,7 +121,8 @@ class ConcreteMachine:
i8255_(i8255_port_handler_),
ay_(audio_queue_),
audio_toggle_(audio_queue_),
mixer_(ay_, audio_toggle_),
scc_(audio_queue_),
mixer_(ay_, audio_toggle_, scc_),
speaker_(mixer_),
tape_player_(3579545 * 2),
i8255_port_handler_(*this, audio_toggle_, tape_player_),
@ -167,7 +169,7 @@ class ConcreteMachine:
break;
case StaticAnalyser::MSXCartridgeType::KonamiWithSCC:
// TODO: enable an SCC.
memory_slots_[1].set_handler(new Cartridge::KonamiWithSCCROMSlotHandler(*this, 1));
memory_slots_[1].set_handler(new Cartridge::KonamiWithSCCROMSlotHandler(*this, 1, scc_));
break;
case StaticAnalyser::MSXCartridgeType::ASCII8kb:
memory_slots_[1].set_handler(new Cartridge::ASCII8kbROMSlotHandler(*this, 1));
@ -317,6 +319,7 @@ class ConcreteMachine:
int slot_hit = (paged_memory_ >> ((address >> 14) * 2)) & 3;
if(memory_slots_[slot_hit].handler) {
update_audio();
memory_slots_[slot_hit].handler->run_for(memory_slots_[slot_hit].cycles_since_update.flush());
memory_slots_[slot_hit].handler->write(address, *cycle.value);
}
@ -568,8 +571,9 @@ class ConcreteMachine:
Concurrency::DeferringAsyncTaskQueue audio_queue_;
GI::AY38910::AY38910 ay_;
AudioToggle audio_toggle_;
Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle> mixer_;
Outputs::Speaker::LowpassSpeaker<Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle>> speaker_;
Konami::SCC scc_;
Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle, Konami::SCC> mixer_;
Outputs::Speaker::LowpassSpeaker<Outputs::Speaker::CompoundSource<GI::AY38910::AY38910, AudioToggle, Konami::SCC>> speaker_;
Storage::Tape::BinaryTapePlayer tape_player_;
bool use_fast_tape_ = false;

View File

@ -205,6 +205,8 @@
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */; };
4B4518A51F75FD1C00926311 /* SSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518991F75FD1B00926311 /* SSD.cpp */; };
4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; };
4B4B1A3C200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */; };
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
4B5073071DDD3B9400C48FBD /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; };
@ -797,6 +799,8 @@
4B4518A81F76022000926311 /* DiskImageImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskImageImplementation.hpp; sourceTree = "<group>"; };
4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AY38910.cpp; path = AY38910/AY38910.cpp; sourceTree = "<group>"; };
4B4A762F1DB1A3FA007AAE2E /* AY38910.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AY38910.hpp; path = AY38910/AY38910.hpp; sourceTree = "<group>"; };
4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KonamiSCC.cpp; sourceTree = "<group>"; };
4B4B1A3B200198C900A0F866 /* KonamiSCC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KonamiSCC.hpp; sourceTree = "<group>"; };
4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = "<group>"; };
4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = "<group>"; };
4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = "<group>"; };
@ -1801,6 +1805,15 @@
name = AY38910;
sourceTree = "<group>";
};
4B4B1A39200198C900A0F866 /* KonamiSCC */ = {
isa = PBXGroup;
children = (
4B4B1A3A200198C900A0F866 /* KonamiSCC.cpp */,
4B4B1A3B200198C900A0F866 /* KonamiSCC.hpp */,
);
path = KonamiSCC;
sourceTree = "<group>";
};
4B4DC81D1D2C2425003C5BF8 /* Commodore */ = {
isa = PBXGroup;
children = (
@ -2607,11 +2620,12 @@
4BC9DF4B1D04691600F44158 /* 6522 */,
4B1E85791D174DEC001EF87D /* 6532 */,
4BC9DF4C1D04691600F44158 /* 6560 */,
4B4A762D1DB1A35C007AAE2E /* AY38910 */,
4BE845221F2FF7F400A5EA22 /* 6845 */,
4BD9137C1F3115AC009BCF85 /* 8255 */,
4BBC951F1F368D87008F4C34 /* 8272 */,
4B0E04F71FC9F2C800F43484 /* 9918 */,
4B4A762D1DB1A35C007AAE2E /* AY38910 */,
4B4B1A39200198C900A0F866 /* KonamiSCC */,
);
name = Components;
path = ../../Components;
@ -3319,6 +3333,7 @@
4B055AA31FAE85DF0060FFFF /* ImplicitSectors.cpp in Sources */,
4B055AAE1FAE85FD0060FFFF /* TrackSerialiser.cpp in Sources */,
4B055A981FAE85C50060FFFF /* Drive.cpp in Sources */,
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4B055AE21FAE9B6F0060FFFF /* CRTOpenGL.cpp in Sources */,
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */,
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */,
@ -3445,6 +3460,7 @@
4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */,
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */,
4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */,
4B4B1A3C200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.mm in Sources */,
4B96F7221D75119A0058BB2D /* Tape.cpp in Sources */,
4B4518811F75E91A00926311 /* PCMPatchedTrack.cpp in Sources */,

View File

@ -17,6 +17,7 @@ SOURCES += glob.glob('../../Components/8272/*.cpp')
SOURCES += glob.glob('../../Components/9918/*.cpp')
SOURCES += glob.glob('../../Components/9918/Implementation/*.cpp')
SOURCES += glob.glob('../../Components/AY38910/*.cpp')
SOURCES += glob.glob('../../Components/KonamiSCC/*.cpp')
SOURCES += glob.glob('../../Concurrency/*.cpp')