diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp
index 1bdf666c5..4cb79358d 100644
--- a/InstructionSets/M50740/Executor.cpp
+++ b/InstructionSets/M50740/Executor.cpp
@@ -68,11 +68,9 @@ void Executor::set_interrupt_line(bool line) {
 	// is active, amongst other things.
 	if(interrupt_line_ != line) {
 		interrupt_line_ = line;
-
-		// TODO: verify interrupt connection. Externally, but stubbed off here.
-//		if(!interrupt_disable_ && line) {
-//			perform_interrupt<false>(0x1ff4);
-//		}
+		if(line) {
+			set_interrupt_request(interrupt_control_, 0x02, 0x1ff4);
+		}
 	}
 }
 
@@ -225,6 +223,13 @@ template<bool is_brk> inline void Executor::perform_interrupt(uint16_t vector) {
 	set_program_counter(uint16_t(memory_[vector] | (memory_[vector+1] << 8)));
 }
 
+void Executor::set_interrupt_request(uint8_t &reg, uint8_t value, uint16_t vector) {
+	reg |= value;
+	if(!interrupt_disable_ && (reg & (value >> 1))) {
+		perform_interrupt<false>(vector);
+	}
+}
+
 template <Operation operation, AddressingMode addressing_mode> void Executor::perform() {
 	// Post cycle cost; this emulation _does not provide accurate timing_.
 #define TLength(mode, base)	case AddressingMode::mode: subtract_duration(base + t_lengths[index_mode_]); break;
@@ -789,12 +794,17 @@ inline void Executor::subtract_duration(int duration) {
 										// this additional divide by 4 produces the correct net divide by 16.
 
 	timer_divider_ += duration;
-	const int t12_ticks = update_timer(prescalers_[0], timer_divider_ / t12_divider);
+	const int clock_ticks = timer_divider_ / t12_divider;
 	timer_divider_ &= (t12_divider-1);
 
-	// Update timers 1 and 2. TODO: interrupts (elsewhere?).
-	if(update_timer(timers_[0], t12_ticks)) interrupt_control_ |= 0x20;
-	if(update_timer(timers_[1], t12_ticks)) interrupt_control_ |= 0x08;
+	// Update timers 1 and 2.
+	const int t12_ticks = update_timer(prescalers_[0], timer_divider_ / t12_divider);
+	if(update_timer(timers_[0], t12_ticks)) {
+		set_interrupt_request(interrupt_control_, 0x20, 0x1ff8);
+	}
+	if(update_timer(timers_[1], t12_ticks)) {
+		set_interrupt_request(interrupt_control_, 0x08, 0x1ff6);
+	}
 
 	// If timer X is disabled, stop.
 	if(timer_control_&0x20) {
@@ -804,9 +814,10 @@ inline void Executor::subtract_duration(int duration) {
 	// Update timer X prescaler.
 	switch(timer_control_ & 0x0c) {
 		default: {
-			const int tx_ticks = update_timer(prescalers_[1], t12_ticks);	// TODO: don't hard code this. And is this even right?
-			if(update_timer(timers_[2], tx_ticks))
-				timer_control_ |= 0x80;	// TODO: interrupt result of this.
+			const int tx_ticks = update_timer(prescalers_[1], clock_ticks);
+			if(update_timer(timers_[2], tx_ticks)) {
+				set_interrupt_request(timer_control_, 0x80, 0x1ffa);
+			}
 		} break;
 		case 0x04:
 			LOG("TODO: Timer X; Pulse output mode");
diff --git a/InstructionSets/M50740/Executor.hpp b/InstructionSets/M50740/Executor.hpp
index 8d87e9de3..193cae11c 100644
--- a/InstructionSets/M50740/Executor.hpp
+++ b/InstructionSets/M50740/Executor.hpp
@@ -165,6 +165,8 @@ class Executor: public CachingExecutor {
 		template<bool is_brk> inline void perform_interrupt(uint16_t vector);
 		inline void set_port_output(int port);
 
+		void set_interrupt_request(uint8_t &reg, uint8_t value, uint16_t vector);
+
 		// MARK: - Execution time
 
 		Cycles cycles_;
diff --git a/Machines/Apple/AppleIIgs/ADB.cpp b/Machines/Apple/AppleIIgs/ADB.cpp
index 3ffd099f0..97fa9dff2 100644
--- a/Machines/Apple/AppleIIgs/ADB.cpp
+++ b/Machines/Apple/AppleIIgs/ADB.cpp
@@ -289,5 +289,6 @@ void GLU::run_ports_for(Cycles cycles) {
 }
 
 void GLU::set_vertical_blank(bool is_blank) {
+	vertical_blank_ = is_blank;
 	executor_.set_interrupt_line(is_blank);
 }