mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-01 13:58:20 +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 "InputOutputController.hpp"
|
||||||
#include "Video.hpp"
|
#include "Video.hpp"
|
||||||
|
#include "Sound.hpp"
|
||||||
|
|
||||||
#include "../../../InstructionSets/ARM/Registers.hpp"
|
#include "../../../InstructionSets/ARM/Registers.hpp"
|
||||||
#include "../../../Outputs/Log.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.
|
/// Models the MEMC, making this the Archimedes bus. Owns various other chips on the bus as a result.
|
||||||
template <typename InterruptObserverT>
|
template <typename InterruptObserverT>
|
||||||
struct MemoryController {
|
struct MemoryController {
|
||||||
MemoryController(InterruptObserverT &delegate) : ioc_(delegate) {}
|
MemoryController(InterruptObserverT &observer) :
|
||||||
|
ioc_(observer), vidc_(observer, ioc_.sound()) {}
|
||||||
|
|
||||||
int interrupt_mask() const {
|
int interrupt_mask() const {
|
||||||
return ioc_.interrupt_mask();
|
return ioc_.interrupt_mask();
|
||||||
@ -251,7 +253,7 @@ struct MemoryController {
|
|||||||
std::array<uint8_t, 4*1024*1024> ram_{};
|
std::array<uint8_t, 4*1024*1024> ram_{};
|
||||||
std::array<uint8_t, 2*1024*1024> rom_;
|
std::array<uint8_t, 2*1024*1024> rom_;
|
||||||
InputOutputController<InterruptObserverT> ioc_;
|
InputOutputController<InterruptObserverT> ioc_;
|
||||||
Video vidc_;
|
Video<InterruptObserverT, Sound<InputOutputController<InterruptObserverT>>> vidc_;
|
||||||
|
|
||||||
template <typename IntT>
|
template <typename IntT>
|
||||||
IntT &physical_ram(uint32_t address) {
|
IntT &physical_ram(uint32_t address) {
|
||||||
|
@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Archimedes {
|
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>
|
template <typename InterruptObserverT>
|
||||||
struct Sound {
|
struct Sound {
|
||||||
Sound(InterruptObserverT &observer) : observer_(observer) {}
|
Sound(InterruptObserverT &observer) : observer_(observer) {}
|
||||||
@ -34,11 +37,23 @@ struct Sound {
|
|||||||
halted_ = false;
|
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() {
|
void tick() {
|
||||||
if(halted_) {
|
if(halted_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--divider_;
|
||||||
|
if(divider_) return;
|
||||||
|
divider_ = reload_;
|
||||||
|
|
||||||
current_.start += 16;
|
current_.start += 16;
|
||||||
if(current_.start == current_.end) {
|
if(current_.start == current_.end) {
|
||||||
if(next_buffer_valid_) {
|
if(next_buffer_valid_) {
|
||||||
@ -50,6 +65,8 @@ struct Sound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint8_t divider_ = 0, reload_ = 0;
|
||||||
|
|
||||||
void set_buffer_valid(bool valid) {
|
void set_buffer_valid(bool valid) {
|
||||||
next_buffer_valid_ = valid;
|
next_buffer_valid_ = valid;
|
||||||
observer_.update_sound_interrupt();
|
observer_.update_sound_interrupt();
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
|
|
||||||
namespace Archimedes {
|
namespace Archimedes {
|
||||||
|
|
||||||
|
template <typename InterruptObserverT, typename SoundT>
|
||||||
struct Video {
|
struct Video {
|
||||||
|
Video(InterruptObserverT &observer, SoundT &sound) :
|
||||||
|
observer_(observer), sound_(sound) {}
|
||||||
|
|
||||||
void write(uint32_t value) {
|
void write(uint32_t value) {
|
||||||
const auto target = (value >> 24) & 0xfc;
|
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);
|
logger.error().append("TODO: Cursor colour %d to %03x", (target - 0x44) >> 2, value & 0x1fff);
|
||||||
break;
|
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:
|
case 0x80:
|
||||||
logger.error().append("TODO: Video horizontal period: %d", (value >> 14) & 0x3ff);
|
logger.error().append("TODO: Video horizontal period: %d", (value >> 14) & 0x3ff);
|
||||||
break;
|
break;
|
||||||
@ -89,14 +88,24 @@ struct Video {
|
|||||||
logger.error().append("TODO: Video vertical cursor end: %d", (value >> 14) & 0x3ff);
|
logger.error().append("TODO: Video vertical cursor end: %d", (value >> 14) & 0x3ff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc0:
|
|
||||||
logger.error().append("TODO: Sound frequency: %d", value & 0x7f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
logger.error().append("TODO: video control: %08x", value);
|
logger.error().append("TODO: video control: %08x", value);
|
||||||
break;
|
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:
|
default:
|
||||||
logger.error().append("TODO: unrecognised VIDC write of %08x", value);
|
logger.error().append("TODO: unrecognised VIDC write of %08x", value);
|
||||||
break;
|
break;
|
||||||
@ -105,6 +114,8 @@ struct Video {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Log::Logger<Log::Source::ARMIOC> logger;
|
Log::Logger<Log::Source::ARMIOC> logger;
|
||||||
|
InterruptObserverT &observer_;
|
||||||
|
SoundT &sound_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user