# HG changeset patch # User Paul Boddie # Date 1510873196 -3600 # Node ID 7edceda19310c46d591e96bec2eb73131b90079e # Parent 0c6e88eb049f2a1f53ee953f65dd66fd923b904a Reorganised interrupt handling to only test either timer or DMA interrupt conditions, not both, also merging the execution of the visible/active region and address update routines within a single call. diff -r 0c6e88eb049f -r 7edceda19310 vga.S --- a/vga.S Tue Nov 07 14:38:33 2017 +0100 +++ b/vga.S Thu Nov 16 23:59:56 2017 +0100 @@ -709,40 +709,29 @@ li $sp, IRQ_STACK_TOP - /* Check for a timer interrupt condition. */ - - la $v0, IFS0 - lw $v1, 0($v0) - andi $v1, $v1, (1 << 9) /* T2IF */ - beqz $v1, irq_dma - nop - - /* Clear the timer interrupt condition. */ - - sw $v1, CLR($v0) - /* The timer interrupt will only occur outside the visible region, but the interrupt condition will still occur as the timer wraps around. - Therefore, the handling of other interrupts may find the timer interrupt - condition set. - - For the visible region, the event handler is invoked when handling the - DMA interrupt. Otherwise, the event handler is invoked in response to - the timer interrupt. + + Here, we deliberately ignore the timer condition during the visible/ + active region. + + The DMA interrupt should only be active within the visible region. */ la $t8, visible_active beq $s1, $t8, irq_dma nop - /* Increment the line counter (only outside the visible region). */ - - addiu $s0, $s0, 1 + /* Check for a timer interrupt condition. */ - /* Jump to the event handler (only outside the visible region). */ + la $v0, IFS0 + lw $v1, 0($v0) + andi $v1, $v1, (1 << 9) /* T2IF */ + beqz $v1, irq_exit + nop - jalr $s1 + j irq_handle nop irq_dma: @@ -767,30 +756,20 @@ beqz $v1, irq_exit nop - /* Clear the block transfer completion interrupt flag. */ +irq_handle: + /* Clear the interrupt condition. */ sw $v1, CLR($v0) - /* - The DMA interrupt should only be active within the visible region. - The event handler is invoked here instead of in response to a timer - interrupt within that region. - */ - - /* Increment the line counter (only within the visible region). */ + /* Increment the line counter. */ addiu $s0, $s0, 1 - /* Jump to the event handler (only within the visible region). */ + /* Jump to the event handler. */ jalr $s1 nop - /* Jump to the DMA update routine. */ - - j visible_update_address - nop - irq_exit: /* Save state. */ @@ -920,7 +899,7 @@ /* Test for front porch. */ sltiu $v0, $s0, VFP_START - bnez $v0, _visible_active_ret + bnez $v0, visible_update_address nop /* Start the front porch region. */ @@ -943,6 +922,12 @@ li $v1, (1 << 9) sw $v1, SET($v0) /* T2IE = 1 */ + /* Disable the line channel. */ + + la $v0, DCH0ECON + li $v1, (1 << 4) /* DCH0ECON<4> = SIRQEN = 0 */ + sw $v1, CLR($v0) + _visible_active_ret: jr $ra nop @@ -953,23 +938,6 @@ visible_update_address: - /* Test for the last visible line. */ - - la $v0, vfp_active - bne $s1, $v0, _visible_update_address - nop - - /* Disable the line channel. */ - - la $v0, DCH0ECON - li $v1, (1 << 4) /* DCH0ECON<4> = SIRQEN = 0 */ - sw $v1, CLR($v0) - - j _visible_update_ret - nop - -_visible_update_address: - /* Update the line data address if the line counter (referring to the next line) is even. @@ -1002,7 +970,7 @@ sw $s2, 0($v0) _visible_update_ret: - j irq_exit + jr $ra nop