1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 00:29:34 +00:00

Pipe further sound parameters; obey divider.

This commit is contained in:
Thomas Harte 2024-03-20 14:43:47 -04:00
parent 208f3e24de
commit 389541be6d
3 changed files with 41 additions and 11 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -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_;
};
}