mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-18 17:06:15 +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.
|
||||
if(line_control_ & 0x40) {
|
||||
set_interrupts(0x20);
|
||||
interrupts_.add(0x20);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
set_interrupts(interrupts_ & ~(mask & 0x60));
|
||||
interrupts_.clear(mask);
|
||||
}
|
||||
|
||||
void Video::set_interrupt_register(uint8_t mask) {
|
||||
set_interrupts(interrupts_ | (mask & 0x6));
|
||||
interrupts_.set_control(mask);
|
||||
}
|
||||
|
||||
uint8_t Video::get_interrupt_register() {
|
||||
return interrupts_;
|
||||
return interrupts_.status();
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -526,13 +526,7 @@ void Video::clear_megaii_interrupts() {
|
||||
}
|
||||
|
||||
void Video::notify_clock_tick() {
|
||||
set_interrupts(interrupts_ | 0x40);
|
||||
}
|
||||
|
||||
void Video::set_interrupts(uint8_t new_value) {
|
||||
interrupts_ = new_value & 0x7f;
|
||||
if((interrupts_ >> 4) & interrupts_ & 0x6)
|
||||
interrupts_ |= 0x80;
|
||||
interrupts_.add(0x40);
|
||||
}
|
||||
|
||||
void Video::set_border_colour(uint8_t colour) {
|
||||
|
@ -123,8 +123,56 @@ class Video: public Apple::II::VideoSwitches<Cycles> {
|
||||
void advance(Cycles);
|
||||
|
||||
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;
|
||||
const uint8_t *ram_ = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user