mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +00:00
Switch to specifying number of bits, to reduce potential error.
This commit is contained in:
parent
debdad350d
commit
6d315b4660
@ -929,7 +929,10 @@ void Base<personality>::write_register(uint8_t value) {
|
||||
|
||||
// The RAM pointer is always set on a second write, regardless of
|
||||
// whether the caller is intending to enqueue a VDP operation.
|
||||
install_field<8, 0x3f>(ram_pointer_, value);
|
||||
//
|
||||
// The top two bits are used to determine the type of write; only
|
||||
// the lower six are actual address.
|
||||
install_field<8, 6>(ram_pointer_, value);
|
||||
|
||||
write_phase_ = false;
|
||||
if(value & 0x80) {
|
||||
|
@ -450,10 +450,12 @@ template <Personality personality> struct Base: public Storage<personality> {
|
||||
TVStandard tv_standard_ = TVStandard::NTSC;
|
||||
using AddressT = typename Storage<personality>::AddressT;
|
||||
|
||||
/// Mutates @c target such that @c source & @c source_mask replaces the bits that currently start
|
||||
/// at @c shift bits from least significant. Subsequently ensures @c target is constrained by the
|
||||
/// Mutates @c target such that @c source replaces the @c length bits that currently start
|
||||
/// at bit @c shift . Subsequently ensures @c target is constrained by the
|
||||
/// applicable @c memory_mask.
|
||||
template <int shift, uint8_t source_mask = 0xff> void install_field(AddressT &target, uint8_t source) {
|
||||
template <int shift, int length = 8> void install_field(AddressT &target, uint8_t source) {
|
||||
static_assert(length > 0 && length <= 8);
|
||||
constexpr auto source_mask = (1 << length) - 1;
|
||||
constexpr auto mask = AddressT(~(source_mask << shift));
|
||||
target = (
|
||||
(target & mask) |
|
||||
@ -491,6 +493,17 @@ template <Personality personality> struct Base: public Storage<personality> {
|
||||
int sprite_height_ = 8;
|
||||
|
||||
// Programmer-specified addresses.
|
||||
//
|
||||
// The TMS and descendants combine various parts of the address with AND operations,
|
||||
// e.g. the fourth byte in the pattern name table will be at `pattern_name_address_ & 4`;
|
||||
// ordinarily the difference between that and plain substitution is invisible because
|
||||
// the programmer mostly can't set low-enough-order bits. That's not universally true
|
||||
// though, so this implementation uses AND throughout.
|
||||
//
|
||||
// ... therefore, all programmer-specified addresses are seeded as all '1's. As and when
|
||||
// actual addresses are specified, the relevant bits will be substituted in.
|
||||
//
|
||||
// Cf. install_field.
|
||||
AddressT pattern_name_address_ = memory_mask(personality); // Address of the tile map.
|
||||
AddressT colour_table_address_ = memory_mask(personality); // Address of the colour map (if applicable).
|
||||
AddressT pattern_generator_table_address_ = memory_mask(personality); // Address of the tile contents.
|
||||
|
Loading…
Reference in New Issue
Block a user