1.1 --- a/vga.S Tue Nov 07 14:38:33 2017 +0100
1.2 +++ b/vga.S Thu Nov 16 23:59:56 2017 +0100
1.3 @@ -709,40 +709,29 @@
1.4
1.5 li $sp, IRQ_STACK_TOP
1.6
1.7 - /* Check for a timer interrupt condition. */
1.8 -
1.9 - la $v0, IFS0
1.10 - lw $v1, 0($v0)
1.11 - andi $v1, $v1, (1 << 9) /* T2IF */
1.12 - beqz $v1, irq_dma
1.13 - nop
1.14 -
1.15 - /* Clear the timer interrupt condition. */
1.16 -
1.17 - sw $v1, CLR($v0)
1.18 -
1.19 /*
1.20 The timer interrupt will only occur outside the visible region, but the
1.21 interrupt condition will still occur as the timer wraps around.
1.22 - Therefore, the handling of other interrupts may find the timer interrupt
1.23 - condition set.
1.24 -
1.25 - For the visible region, the event handler is invoked when handling the
1.26 - DMA interrupt. Otherwise, the event handler is invoked in response to
1.27 - the timer interrupt.
1.28 +
1.29 + Here, we deliberately ignore the timer condition during the visible/
1.30 + active region.
1.31 +
1.32 + The DMA interrupt should only be active within the visible region.
1.33 */
1.34
1.35 la $t8, visible_active
1.36 beq $s1, $t8, irq_dma
1.37 nop
1.38
1.39 - /* Increment the line counter (only outside the visible region). */
1.40 -
1.41 - addiu $s0, $s0, 1
1.42 + /* Check for a timer interrupt condition. */
1.43
1.44 - /* Jump to the event handler (only outside the visible region). */
1.45 + la $v0, IFS0
1.46 + lw $v1, 0($v0)
1.47 + andi $v1, $v1, (1 << 9) /* T2IF */
1.48 + beqz $v1, irq_exit
1.49 + nop
1.50
1.51 - jalr $s1
1.52 + j irq_handle
1.53 nop
1.54
1.55 irq_dma:
1.56 @@ -767,30 +756,20 @@
1.57 beqz $v1, irq_exit
1.58 nop
1.59
1.60 - /* Clear the block transfer completion interrupt flag. */
1.61 +irq_handle:
1.62 + /* Clear the interrupt condition. */
1.63
1.64 sw $v1, CLR($v0)
1.65
1.66 - /*
1.67 - The DMA interrupt should only be active within the visible region.
1.68 - The event handler is invoked here instead of in response to a timer
1.69 - interrupt within that region.
1.70 - */
1.71 -
1.72 - /* Increment the line counter (only within the visible region). */
1.73 + /* Increment the line counter. */
1.74
1.75 addiu $s0, $s0, 1
1.76
1.77 - /* Jump to the event handler (only within the visible region). */
1.78 + /* Jump to the event handler. */
1.79
1.80 jalr $s1
1.81 nop
1.82
1.83 - /* Jump to the DMA update routine. */
1.84 -
1.85 - j visible_update_address
1.86 - nop
1.87 -
1.88 irq_exit:
1.89 /* Save state. */
1.90
1.91 @@ -920,7 +899,7 @@
1.92 /* Test for front porch. */
1.93
1.94 sltiu $v0, $s0, VFP_START
1.95 - bnez $v0, _visible_active_ret
1.96 + bnez $v0, visible_update_address
1.97 nop
1.98
1.99 /* Start the front porch region. */
1.100 @@ -943,6 +922,12 @@
1.101 li $v1, (1 << 9)
1.102 sw $v1, SET($v0) /* T2IE = 1 */
1.103
1.104 + /* Disable the line channel. */
1.105 +
1.106 + la $v0, DCH0ECON
1.107 + li $v1, (1 << 4) /* DCH0ECON<4> = SIRQEN = 0 */
1.108 + sw $v1, CLR($v0)
1.109 +
1.110 _visible_active_ret:
1.111 jr $ra
1.112 nop
1.113 @@ -953,23 +938,6 @@
1.114
1.115 visible_update_address:
1.116
1.117 - /* Test for the last visible line. */
1.118 -
1.119 - la $v0, vfp_active
1.120 - bne $s1, $v0, _visible_update_address
1.121 - nop
1.122 -
1.123 - /* Disable the line channel. */
1.124 -
1.125 - la $v0, DCH0ECON
1.126 - li $v1, (1 << 4) /* DCH0ECON<4> = SIRQEN = 0 */
1.127 - sw $v1, CLR($v0)
1.128 -
1.129 - j _visible_update_ret
1.130 - nop
1.131 -
1.132 -_visible_update_address:
1.133 -
1.134 /*
1.135 Update the line data address if the line counter (referring to the
1.136 next line) is even.
1.137 @@ -1002,7 +970,7 @@
1.138 sw $s2, 0($v0)
1.139
1.140 _visible_update_ret:
1.141 - j irq_exit
1.142 + jr $ra
1.143 nop
1.144
1.145