mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Abstract out VGC interrupt register; fix clearing bug.
This commit is contained in:
parent
3bd931937f
commit
b34403164e
@ -285,7 +285,7 @@ void Video::output_row(int row, int start, int end) {
|
|||||||
|
|
||||||
// Post an interrupt if requested.
|
// Post an interrupt if requested.
|
||||||
if(line_control_ & 0x40) {
|
if(line_control_ & 0x40) {
|
||||||
set_interrupts(0x20);
|
interrupts_.add(0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up appropriately for fill mode (or not).
|
// Set up appropriately for fill mode (or not).
|
||||||
@ -498,19 +498,19 @@ uint8_t Video::get_new_video() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Video::clear_interrupts(uint8_t mask) {
|
void Video::clear_interrupts(uint8_t mask) {
|
||||||
set_interrupts(interrupts_ & ~(mask & 0x60));
|
interrupts_.clear(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::set_interrupt_register(uint8_t mask) {
|
void Video::set_interrupt_register(uint8_t mask) {
|
||||||
set_interrupts(interrupts_ | (mask & 0x6));
|
interrupts_.set_control(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Video::get_interrupt_register() {
|
uint8_t Video::get_interrupt_register() {
|
||||||
return interrupts_;
|
return interrupts_.status();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Video::get_interrupt_line() {
|
bool Video::get_interrupt_line() {
|
||||||
return (interrupts_&0x80) || (megaii_interrupt_mask_&megaii_interrupt_state_);
|
return interrupts_.active() || (megaii_interrupt_mask_ & megaii_interrupt_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::set_megaii_interrupts_enabled(uint8_t mask) {
|
void Video::set_megaii_interrupts_enabled(uint8_t mask) {
|
||||||
@ -526,13 +526,7 @@ void Video::clear_megaii_interrupts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Video::notify_clock_tick() {
|
void Video::notify_clock_tick() {
|
||||||
set_interrupts(interrupts_ | 0x40);
|
interrupts_.add(0x40);
|
||||||
}
|
|
||||||
|
|
||||||
void Video::set_interrupts(uint8_t new_value) {
|
|
||||||
interrupts_ = new_value & 0x7f;
|
|
||||||
if((interrupts_ >> 4) & interrupts_ & 0x6)
|
|
||||||
interrupts_ |= 0x80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::set_border_colour(uint8_t colour) {
|
void Video::set_border_colour(uint8_t colour) {
|
||||||
|
@ -123,8 +123,56 @@ class Video: public Apple::II::VideoSwitches<Cycles> {
|
|||||||
void advance(Cycles);
|
void advance(Cycles);
|
||||||
|
|
||||||
uint8_t new_video_ = 0x01;
|
uint8_t new_video_ = 0x01;
|
||||||
uint8_t interrupts_ = 0x00;
|
|
||||||
void set_interrupts(uint8_t);
|
class Interrupts {
|
||||||
|
public:
|
||||||
|
void add(uint8_t value) {
|
||||||
|
// Taken literally, status accumulates regardless of being enabled,
|
||||||
|
// potentially to be polled, it simply doesn't trigger an interrupt.
|
||||||
|
value_ |= value;
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(uint8_t value) {
|
||||||
|
// Zeroes in bits 5 or 6 clear the respective interrupts.
|
||||||
|
value_ &= value | ~0x60;
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_control(uint8_t value) {
|
||||||
|
// Ones in bits 1 or 2 enable the respective interrupts.
|
||||||
|
value_ = (value_ & ~0x6) | (value & 0x6);
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t status() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool active() const {
|
||||||
|
return value_ & 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void test() {
|
||||||
|
value_ &= 0x7f;
|
||||||
|
if((value_ >> 4) & value_ & 0x6) {
|
||||||
|
value_ |= 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overall meaning of value is as per the VGC interrupt register, i.e.
|
||||||
|
//
|
||||||
|
// b7: interrupt status;
|
||||||
|
// b6: 1-second interrupt status;
|
||||||
|
// b5: scan-line interrupt status;
|
||||||
|
// b4: reserved;
|
||||||
|
// b3: reserved;
|
||||||
|
// b2: 1-second interrupt enable;
|
||||||
|
// b1: scan-line interrupt enable;
|
||||||
|
// b0: reserved.
|
||||||
|
uint8_t value_ = 0x00;
|
||||||
|
} interrupts_;
|
||||||
|
|
||||||
int cycles_into_frame_ = 0;
|
int cycles_into_frame_ = 0;
|
||||||
const uint8_t *ram_ = nullptr;
|
const uint8_t *ram_ = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user