# HG changeset patch # User Paul Boddie # Date 1496523186 -7200 # Node ID 466e83cd82b7b2234be2006fd13eb5b1d85f7234 # Parent 2d185cb3e4373abfe8f6b002e43635b10158b6dd Disable the timer interrupt in order to reduce memory contention with the line channel DMA, itself initiated by the timer wraparound event. diff -r 2d185cb3e437 -r 466e83cd82b7 vga.S --- a/vga.S Sat Jun 03 22:50:28 2017 +0200 +++ b/vga.S Sat Jun 03 22:53:06 2017 +0200 @@ -717,11 +717,26 @@ li $v1, (1 << 9) /* IFS0<9> = T2IF = 0 */ sw $v1, CLR($v0) - /* Increment the line counter. */ + /* + The timer interrupt will only occur active 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. + */ + + la $t8, visible_active + beq $s1, $t8, irq_dma + nop + + /* Increment the line counter (only outside the visible region). */ addiu $s0, $s0, 1 - /* Jump to the event handler. */ + /* Jump to the event handler (only outside the visible region). */ jalr $s1 nop @@ -754,6 +769,21 @@ li $v1, (1 << 3) /* CHBCIF = 0 */ 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). */ + + addiu $s0, $s0, 1 + + /* Jump to the event handler (only within the visible region). */ + + jalr $s1 + nop + /* Jump to the DMA update routine. */ j visible_update_address @@ -857,6 +887,12 @@ li $v1, (1 << 4) sw $v1, SET($v0) + /* Disable the timer interrupt during the visible period. */ + + la $v0, IEC0 + li $v1, (1 << 9) + sw $v1, CLR($v0) /* T2IE = 0 */ + _vbp_active_ret: jr $ra nop @@ -876,6 +912,18 @@ la $s1, vfp_active + /* Clear the timer interrupt condition. */ + + la $v0, IFS0 + li $v1, (1 << 9) /* IFS0<9> = T2IF = 0 */ + sw $v1, CLR($v0) + + /* Re-enable the timer interrupt after the visible period. */ + + la $v0, IEC0 + li $v1, (1 << 9) + sw $v1, SET($v0) /* T2IE = 1 */ + _visible_active_ret: jr $ra nop