Skip to content

Commit

Permalink
Pipe further sound parameters; obey divider.
Browse files Browse the repository at this point in the history
  • Loading branch information
TomHarte committed Mar 20, 2024
1 parent 208f3e2 commit 389541b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
6 changes: 4 additions & 2 deletions Machines/Acorn/Archimedes/MemoryController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "InputOutputController.hpp"
#include "Video.hpp"
#include "Sound.hpp"

#include "../../../InstructionSets/ARM/Registers.hpp"
#include "../../../Outputs/Log.hpp"
Expand All @@ -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();
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 17 additions & 0 deletions Machines/Acorn/Archimedes/Sound.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand All @@ -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_) {
Expand All @@ -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();
Expand Down
29 changes: 20 additions & 9 deletions Machines/Acorn/Archimedes/Video.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -105,6 +114,8 @@ struct Video {

private:
Log::Logger<Log::Source::ARMIOC> logger;
InterruptObserverT &observer_;
SoundT &sound_;
};

}

0 comments on commit 389541b

Please sign in to comment.