1.1 --- a/vga.S Sat Jun 03 22:50:28 2017 +0200
1.2 +++ b/vga.S Sat Jun 03 22:53:06 2017 +0200
1.3 @@ -717,11 +717,26 @@
1.4 li $v1, (1 << 9) /* IFS0<9> = T2IF = 0 */
1.5 sw $v1, CLR($v0)
1.6
1.7 - /* Increment the line counter. */
1.8 + /*
1.9 + The timer interrupt will only occur active outside the visible region,
1.10 + but the interrupt condition will still occur as the timer wraps around.
1.11 + Therefore, the handling of other interrupts may find the timer interrupt
1.12 + condition set.
1.13 +
1.14 + For the visible region, the event handler is invoked when handling the
1.15 + DMA interrupt. Otherwise, the event handler is invoked in response to
1.16 + the timer interrupt.
1.17 + */
1.18 +
1.19 + la $t8, visible_active
1.20 + beq $s1, $t8, irq_dma
1.21 + nop
1.22 +
1.23 + /* Increment the line counter (only outside the visible region). */
1.24
1.25 addiu $s0, $s0, 1
1.26
1.27 - /* Jump to the event handler. */
1.28 + /* Jump to the event handler (only outside the visible region). */
1.29
1.30 jalr $s1
1.31 nop
1.32 @@ -754,6 +769,21 @@
1.33 li $v1, (1 << 3) /* CHBCIF = 0 */
1.34 sw $v1, CLR($v0)
1.35
1.36 + /*
1.37 + The DMA interrupt should only be active within the visible region.
1.38 + The event handler is invoked here instead of in response to a timer
1.39 + interrupt within that region.
1.40 + */
1.41 +
1.42 + /* Increment the line counter (only within the visible region). */
1.43 +
1.44 + addiu $s0, $s0, 1
1.45 +
1.46 + /* Jump to the event handler (only within the visible region). */
1.47 +
1.48 + jalr $s1
1.49 + nop
1.50 +
1.51 /* Jump to the DMA update routine. */
1.52
1.53 j visible_update_address
1.54 @@ -857,6 +887,12 @@
1.55 li $v1, (1 << 4)
1.56 sw $v1, SET($v0)
1.57
1.58 + /* Disable the timer interrupt during the visible period. */
1.59 +
1.60 + la $v0, IEC0
1.61 + li $v1, (1 << 9)
1.62 + sw $v1, CLR($v0) /* T2IE = 0 */
1.63 +
1.64 _vbp_active_ret:
1.65 jr $ra
1.66 nop
1.67 @@ -876,6 +912,18 @@
1.68
1.69 la $s1, vfp_active
1.70
1.71 + /* Clear the timer interrupt condition. */
1.72 +
1.73 + la $v0, IFS0
1.74 + li $v1, (1 << 9) /* IFS0<9> = T2IF = 0 */
1.75 + sw $v1, CLR($v0)
1.76 +
1.77 + /* Re-enable the timer interrupt after the visible period. */
1.78 +
1.79 + la $v0, IEC0
1.80 + li $v1, (1 << 9)
1.81 + sw $v1, SET($v0) /* T2IE = 1 */
1.82 +
1.83 _visible_active_ret:
1.84 jr $ra
1.85 nop