mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-21 21:33:54 +00:00
Pipe further sound parameters; obey divider.
This commit is contained in:
parent
208f3e24de
commit
389541be6d
@ -10,6 +10,7 @@
|
||||
|
||||
#include "InputOutputController.hpp"
|
||||
#include "Video.hpp"
|
||||
#include "Sound.hpp"
|
||||
|
||||
#include "../../../InstructionSets/ARM/Registers.hpp"
|
||||
#include "../../../Outputs/Log.hpp"
|
||||
@ -30,7 +31,8 @@ static_assert(BitMask<15, 14>::value == 49152);
|
||||
/// Models the MEMC, making this the Archimedes bus. Owns various other chips on the bus as a result.
|
||||
template <typename InterruptObserverT>
|
||||
struct MemoryController {
|
||||
MemoryController(InterruptObserverT &delegate) : ioc_(delegate) {}
|
||||
MemoryController(InterruptObserverT &observer) :
|
||||
ioc_(observer), vidc_(observer, ioc_.sound()) {}
|
||||
|
||||
int interrupt_mask() const {
|
||||
return ioc_.interrupt_mask();
|
||||
@ -251,7 +253,7 @@ struct MemoryController {
|
||||
std::array<uint8_t, 4*1024*1024> ram_{};
|
||||
std::array<uint8_t, 2*1024*1024> rom_;
|
||||
InputOutputController<InterruptObserverT> ioc_;
|
||||
Video vidc_;
|
||||
Video<InterruptObserverT, Sound<InputOutputController<InterruptObserverT>>> vidc_;
|
||||
|
||||
template <typename IntT>
|
||||
IntT &physical_ram(uint32_t address) {
|
||||
|
@ -8,8 +8,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Archimedes {
|
||||
|
||||
/// Models the Archimedes sound output; in a real machine this is a joint efort between the VIDC and the MEMC.
|
||||
template <typename InterruptObserverT>
|
||||
struct Sound {
|
||||
Sound(InterruptObserverT &observer) : observer_(observer) {}
|
||||
@ -34,11 +37,23 @@ struct Sound {
|
||||
halted_ = false;
|
||||
}
|
||||
|
||||
void set_frequency(uint8_t frequency) {
|
||||
divider_ = reload_ = frequency;
|
||||
}
|
||||
|
||||
void set_stereo_image([[maybe_unused]] uint8_t channel, [[maybe_unused]] uint8_t value) {
|
||||
// TODO.
|
||||
}
|
||||
|
||||
void tick() {
|
||||
if(halted_) {
|
||||
return;
|
||||
}
|
||||
|
||||
--divider_;
|
||||
if(divider_) return;
|
||||
divider_ = reload_;
|
||||
|
||||
current_.start += 16;
|
||||
if(current_.start == current_.end) {
|
||||
if(next_buffer_valid_) {
|
||||
@ -50,6 +65,8 @@ struct Sound {
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t divider_ = 0, reload_ = 0;
|
||||
|
||||
void set_buffer_valid(bool valid) {
|
||||
next_buffer_valid_ = valid;
|
||||
observer_.update_sound_interrupt();
|
||||
|
@ -14,7 +14,11 @@
|
||||
|
||||
namespace Archimedes {
|
||||
|
||||
template <typename InterruptObserverT, typename SoundT>
|
||||
struct Video {
|
||||
Video(InterruptObserverT &observer, SoundT &sound) :
|
||||
observer_(observer), sound_(sound) {}
|
||||
|
||||
void write(uint32_t value) {
|
||||
const auto target = (value >> 24) & 0xfc;
|
||||
|
||||
@ -34,11 +38,6 @@ struct Video {
|
||||
logger.error().append("TODO: Cursor colour %d to %03x", (target - 0x44) >> 2, value & 0x1fff);
|
||||
break;
|
||||
|
||||
case 0x60: case 0x64: case 0x68: case 0x6c:
|
||||
case 0x70: case 0x74: case 0x78: case 0x7c:
|
||||
logger.error().append("TODO: Stereo image register %d to %03x", (target - 0x60) >> 2, value & 0x7);
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
logger.error().append("TODO: Video horizontal period: %d", (value >> 14) & 0x3ff);
|
||||
break;
|
||||
@ -89,14 +88,24 @@ struct Video {
|
||||
logger.error().append("TODO: Video vertical cursor end: %d", (value >> 14) & 0x3ff);
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
logger.error().append("TODO: Sound frequency: %d", value & 0x7f);
|
||||
break;
|
||||
|
||||
case 0xe0:
|
||||
logger.error().append("TODO: video control: %08x", value);
|
||||
break;
|
||||
|
||||
//
|
||||
// Sound parameters.
|
||||
//
|
||||
case 0x60: case 0x64: case 0x68: case 0x6c:
|
||||
case 0x70: case 0x74: case 0x78: case 0x7c: {
|
||||
const uint8_t channel = ((value >> 26) + 7) & 7;
|
||||
sound_.set_stereo_image(channel, value & 7);
|
||||
} break;
|
||||
|
||||
case 0xc0:
|
||||
sound_.set_frequency(value & 0x7f);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
logger.error().append("TODO: unrecognised VIDC write of %08x", value);
|
||||
break;
|
||||
@ -105,6 +114,8 @@ struct Video {
|
||||
|
||||
private:
|
||||
Log::Logger<Log::Source::ARMIOC> logger;
|
||||
InterruptObserverT &observer_;
|
||||
SoundT &sound_;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user