         if state.pb6Pulse {
             state.pb6Pulse = false
         }
-        // if (timer running && (no counter delay || 1 clock left on delay but conter already 0)) || timer stopped on clock before)
-        if (state.cra & 0x01 != 0 && (state.timerACountDelay == 0 || (state.timerACountDelay == 1 && state.counterA == 0))) || state.timerAStopDelay > 0 {
-            if state.cra & 0x20 == 0x00 {
-                // o2 mode
-                state.counterA = state.counterA &- 1
-                if state.counterA == 0 || state.counterA == 0xFFFF {
-                    state.counterA = state.latchA
-                    if state.cra & 0x08 != 0 {
-                        state.cra &= ~0x01
-                    } else {
-                        state.timerACountDelay = 2
-                    }
-                    state.icr |= 0x01
-                    if state.imr & 0x01 != 0 {
-                        state.interruptDelay = 1
-                    }
-                    state.pb6Toggle = !state.pb6Toggle
-                    state.pb6Pulse = true
-                }
-            } else {
-                //TODO: CNT mode
-            }
-        }
-        if state.timerALoadDelay > 0 {
-            state.timerALoadDelay -= 1
-            if state.timerALoadDelay == 0 {
-                state.counterA = state.latchA
-                if state.timerACountDelay == 0 {
-                    state.timerACountDelay = 2
-                }
-            }
-        }
-        if state.timerACountDelay > 0 && state.timerALoadDelay == 0{
-            state.timerACountDelay -= 1
-        }
-        if state.timerAStopDelay > 0 {
-            state.timerAStopDelay -= 1
-        }
+        if state.timerAState.shouldDecrement() {
+            state.counterA = state.counterA &- 1
+        }
+        if state.counterA == 0 && state.timerAState.shouldOutput() {
+            if state.cra & 0x08 != 0 {
+                state.cra &= ~0x01
+                state.timerAState.stopOneShot()
+            }
+            state.icr |= 0x01
+            if state.imr & 0x01 != 0 {
+                state.interruptDelay = 1
+            }
+            state.pb6Toggle = !state.pb6Toggle
+            state.pb6Pulse = true
+            state.timerAState.setLoadThisCycle()
+        }
+        if state.timerAState.shouldLoad() {
+            state.counterA = state.latchA
+            state.timerAState.setSkipNextClock()
+        }
+        state.timerAState.cycle()
         if state.pb7Pulse {
             state.pb7Pulse = false
         }
-        if (state.crb & 0x01 != 0 && (state.timerBCountDelay == 0 || (state.timerBCountDelay == 1 && state.counterB == 0))) || state.timerBStopDelay > 0 {
-            if state.crb & 0x20 == 0x00 {
-                // o2 mode
-                state.counterB = state.counterB &- 1
-                if state.counterB == 0 || state.counterB == 0xFFFF {
-                    state.counterB = state.latchB
-                    if state.crb & 0x08 != 0 {
-                        state.crb &= ~0x01
-                    } else {
-                        state.timerBCountDelay = 2
-                    }
-                    state.icr |= 0x02
-                    if state.imr & 0x02 != 0 {
-                        state.interruptDelay = 1
-                    }
-                    state.pb7Toggle = !state.pb7Toggle
-                    state.pb7Pulse = true
-                }
-            } else {
-                //TODO: CNT mode
-            }
-        }
-        if state.timerBLoadDelay > 0 {
-            state.timerBLoadDelay -= 1
-            if state.timerBLoadDelay == 0 {
-                state.counterB = state.latchB
-                if state.timerBCountDelay == 0 {
-                    state.timerBCountDelay = 2
-                }
-            }
-        }
-        if state.timerBCountDelay > 0 && state.timerBLoadDelay == 0{
-            state.timerBCountDelay -= 1
-        }
-        if state.timerBStopDelay > 0 {
-            state.timerBStopDelay -= 1
-        }
+        if state.timerBState.shouldDecrement() {
+            state.counterB = state.counterB &- 1
+        }
+        if state.counterB == 0 && state.timerBState.shouldOutput() {
+            if state.crb & 0x08 != 0 {
+                state.crb &= ~0x01
+                state.timerBState.stopOneShot()
+            }
+            state.icr |= 0x02
+            if state.imr & 0x02 != 0 {
+                state.interruptDelay = 1
+            }
+            state.pb7Toggle = !state.pb7Toggle
+            state.pb7Pulse = true
+            state.timerBState.setLoadThisCycle()
+        }
+        if state.timerBState.shouldLoad() {
+            state.counterB = state.latchB
+            state.timerBState.setSkipNextClock()
+        }
+        state.timerBState.cycle()
         if state.interruptDelay == 0 {
             state.icr |= 0x80
             state.interruptDelay = -1

    
    //MARK: Helpers
    private var interruptPin: Bool = true
    private var timerACountDelay: UInt8 = 0
    private var timerALoadDelay: UInt8 = 0
    private var timerAStopDelay: UInt8 = 0
    private var timerBCountDelay: UInt8 = 0
    private var timerBLoadDelay: UInt8 = 0
    private var timerBStopDelay: UInt8 = 0
    private var interruptDelay: Int8 = -1
    private var todLatched: Bool = false
    private var todRunning: Bool = false

                state.interruptDelay = 1
            }
        case 0x0E:
            // bit4: force load
            if byte & 0x10 != 0 {
                state.timerAState.setLoadNextCycle()
            }
            if byte & 0x01 != 0 {
                state.timerAState.start()
                if state.cra & 0x01 == 0 {
                    state.pb6Toggle = true
                }
            } else {
               state.timerAState.stop()
            }
            state.cra = byte
        case 0x0F:
            // bit4: force load
            if byte & 0x10 != 0 {
                state.timerBState.setLoadNextCycle()
            }
            if byte & 0x01 != 0 {
                state.timerBState.start()
                if state.crb & 0x01 == 0 {
                    state.pb7Toggle = true
                }
            } else {
                state.timerBState.stop()
            }
            state.crb = byte
        default:
