# HG changeset patch # User Paul Boddie # Date 1496520276 -7200 # Node ID b106107349679a1bf2805d3592138a89157a7573 # Parent e3ec1c594d8e4a7325729a0dd996b007b7541e8f Created a separate DMA address update routine. Note that it does not use $ra since this appears to cause an exception somehow. diff -r e3ec1c594d8e -r b10610734967 vga.S --- a/vga.S Sat Jun 03 19:13:09 2017 +0200 +++ b/vga.S Sat Jun 03 22:04:36 2017 +0200 @@ -675,6 +675,7 @@ nop + /* Interrupt servicing. */ .org 0x200 @@ -753,47 +754,10 @@ li $v1, (1 << 3) /* CHBCIF = 0 */ sw $v1, CLR($v0) - /* - Update the line data address if the line counter (referring to the - next line) is even. - */ - - andi $t8, $s0, 1 - bnez $t8, irq_exit - nop - - /* Reference the next line and update the DMA source address. */ - - addiu $s2, $s2, LINE_LENGTH - - /* Test for wraparound. */ - - li $t8, (SCREEN_BASE + SCREEN_SIZE) - sltu $t8, $s2, $t8 - bnez $t8, irq_dma_update - nop + /* Jump to the DMA update routine. */ - /* Reset the source address. */ - - li $s2, SCREEN_BASE - -irq_dma_update: - - /* Disable line channel. */ - - la $v0, DCH0CON - li $v1, 0b10000000 - sw $v1, CLR($v0) - - /* Update the source address. */ - - la $v0, DCH0SSA - sw $s2, 0($v0) - - /* Enable line channel. */ - - la $v0, DCH0CON - sw $v1, SET($v0) + j visible_update_address + nop irq_exit: /* Save state. */ @@ -823,7 +787,7 @@ exc_handler: li $t9, 0x80000000 - mfc0 $t6, CP0_CAUSE + mfc0 $t6, CP0_ERROREPC nop exc_loop: and $t7, $t9, $t6 @@ -924,6 +888,58 @@ +/* DMA update routine. */ + +visible_update_address: + + /* + Update the line data address if the line counter (referring to the + next line) is even. + */ + + andi $t8, $s0, 1 + bnez $t8, _visible_update_ret + nop + + /* Reference the next line and update the DMA source address. */ + + addiu $s2, $s2, LINE_LENGTH + + /* Test for wraparound. */ + + li $t8, (SCREEN_BASE + SCREEN_SIZE) + sltu $t8, $s2, $t8 + bnez $t8, _visible_dma_update + nop + + /* Reset the source address. */ + + li $s2, SCREEN_BASE + +_visible_dma_update: + + /* Disable line channel. */ + + la $v0, DCH0CON + li $v1, 0b10000000 + sw $v1, CLR($v0) + + /* Update the source address. */ + + la $v0, DCH0SSA + sw $s2, 0($v0) + + /* Enable line channel. */ + + la $v0, DCH0CON + sw $v1, SET($v0) + +_visible_update_ret: + j irq_exit + nop + + + /* Within the vertical front porch. */ vfp_active: