# HG changeset patch # User Paul Boddie # Date 1510059869 -3600 # Node ID 83ebe9cd031429a88368d86a8d1c79becfcd4505 # Parent ae02a1821af37580a8c176f1b1a706158e35573a Employ a basic CPU priority and keep the timer interrupt enabled (but not at CPU level), guarding priority changes by disabling and re-enabling the interrupt. The timer interrupt should probably be enabled during the active display period for the DMA channels to operate, even though circumstances appear to allow the channels to function in this configuration with the timer interrupt disabled. diff -r ae02a1821af3 -r 83ebe9cd0314 mips.h --- a/mips.h Sat Nov 04 21:47:48 2017 +0100 +++ b/mips.h Tue Nov 07 14:04:29 2017 +0100 @@ -27,7 +27,10 @@ #define STATUS_CP0 0x10000000 #define STATUS_BEV 0x00400000 + #define STATUS_IRQ 0x0000fc00 +#define STATUS_IRQ_SHIFT 10 + #define STATUS_UM 0x00000010 #define STATUS_ERL 0x00000004 #define STATUS_EXL 0x00000002 diff -r ae02a1821af3 -r 83ebe9cd0314 vga.S --- a/vga.S Sat Nov 04 21:47:48 2017 +0100 +++ b/vga.S Tue Nov 07 14:04:29 2017 +0100 @@ -284,8 +284,6 @@ la $v0, IPC2 li $v1, 0b11111 sw $v1, CLR($v0) /* T2IP, T2IS = 0 */ - - la $v0, IPC2 li $v1, 0b11111 sw $v1, SET($v0) /* T2IP = 7; T2IS = 3 */ @@ -662,6 +660,7 @@ mfc0 $t3, CP0_STATUS li $t4, ~STATUS_IRQ /* Clear interrupt priority bits. */ and $t3, $t3, $t4 + ori $t3, $t3, (3 << STATUS_IRQ_SHIFT) li $t4, ~STATUS_BEV /* CP0_STATUS &= ~STATUS_BEV (use non-bootloader vectors) */ and $t3, $t3, $t4 ori $t3, $t3, STATUS_IE @@ -937,6 +936,25 @@ li $v1, (1 << 4) /* DCH0ECON<4> = SIRQEN = 1 */ sw $v1, SET($v0) + /* + Suspend delivery of the timer interrupt during the visible period. + The condition still occurs, however. + */ + + la $v0, IEC0 + li $v1, (1 << 9) + sw $v1, CLR($v0) /* T2IE = 0 */ + + la $v0, IPC2 + li $v1, 0b11111 + sw $v1, CLR($v0) /* T2IP, T2IS = 0 */ + li $v1, 0b00111 + sw $v1, SET($v0) /* T2IP = 1; T2IS = 3 */ + + la $v0, IEC0 + li $v1, (1 << 9) + sw $v1, SET($v0) /* T2IE = 0 */ + _vbp_active_ret: jr $ra nop @@ -956,6 +974,22 @@ la $s1, vfp_active + /* Restore delivery of the timer interrupt after the visible period. */ + + la $v0, IEC0 + li $v1, (1 << 9) + sw $v1, CLR($v0) /* T2IE = 0 */ + + la $v0, IPC2 + li $v1, 0b11111 + sw $v1, CLR($v0) /* T2IP, T2IS = 0 */ + li $v1, 0b11111 + sw $v1, SET($v0) /* T2IP = 7; T2IS = 3 */ + + la $v0, IEC0 + li $v1, (1 << 9) + sw $v1, SET($v0) /* T2IE = 1 */ + _visible_active_ret: jr $ra nop