# HG changeset patch # User Paul Boddie # Date 1509827638 -3600 # Node ID 80c792d32e5e4d014db818f1adb9a487e7dfe28f # Parent 426ff3c6a4dab592a04c2f7956c3369ada98abb5 Test chaining of DMA channels, adding one between the line and reset channels. diff -r 426ff3c6a4da -r 80c792d32e5e vga.S --- a/vga.S Sat Nov 04 17:47:52 2017 +0100 +++ b/vga.S Sat Nov 04 21:33:58 2017 +0100 @@ -481,13 +481,13 @@ /* Disable DMA interrupts. */ la $v0, IEC1 - li $v1, (3 << 28) /* IEC1<29:28> = DMA1IE, DMA0IE = 0 */ + li $v1, (0b111 << 28) /* IEC1<30:28> = DMA2IE, DMA1IE, DMA0IE = 0 */ sw $v1, CLR($v0) /* Clear DMA interrupt flags. */ la $v0, IFS1 - li $v1, (3 << 28) /* IFS1<29:28> = DMA1IF, DMA0IF = 0 */ + li $v1, (0b111 << 28) /* IFS1<30:28> = DMA2IF, DMA1IF, DMA0IF = 0 */ sw $v1, CLR($v0) /* Enable DMA. */ @@ -529,6 +529,10 @@ li $v1, 0b1100011 sw $v1, 0($v0) + la $v0, DCH2CON + li $v1, 0b1100011 + sw $v1, 0($v0) + /* Initiate channel transfers when the initiating interrupt condition occurs: @@ -552,6 +556,10 @@ li $v1, (60 << 8) | (1 << 4) sw $v1, 0($v0) + la $v0, DCH2ECON + li $v1, (61 << 8) | (1 << 4) + sw $v1, 0($v0) + /* The line channel has a cell size of the number bytes in a line: DCHxCSIZ<15:0> = CHCSIZ<15:0> = LINE_LENGTH @@ -570,6 +578,9 @@ li $v1, 1 sw $v1, 0($v0) + la $v0, DCH2CSIZ + sw $v1, 0($v0) + /* The source has a size identical to the cell size: DCHxSSIZ<15:0> = CHSSIZ<15:0> = LINE_LENGTH or 1 @@ -583,6 +594,9 @@ li $v1, 1 sw $v1, 0($v0) + la $v0, DCH2SSIZ + sw $v1, 0($v0) + /* The source address is the physical address of the line data: DCHxSSA = physical(line data address) @@ -598,6 +612,12 @@ */ la $v0, DCH1SSA + la $v1, fulldata + li $t8, KSEG0_BASE + subu $v1, $v1, $t8 + sw $v1, 0($v0) + + la $v0, DCH2SSA la $v1, zerodata li $t8, KSEG0_BASE subu $v1, $v1, $t8 @@ -615,6 +635,9 @@ la $v0, DCH1DSIZ sw $v1, 0($v0) + la $v0, DCH2DSIZ + sw $v1, 0($v0) + /* The destination address is the physical address of PORTB: DCHxDSA = physical(PORTB) @@ -629,6 +652,9 @@ la $v0, DCH1DSA sw $v1, 0($v0) + la $v0, DCH2DSA + sw $v1, 0($v0) + /* Use the block transfer completion interrupt to indicate when the source address can be updated. @@ -638,18 +664,22 @@ li $v1, (1 << 19) /* CHBCIE = 1 */ sw $v1, 0($v0) + la $v0, DCH1INT + li $v1, (1 << 19) /* CHBCIE = 1 */ + sw $v1, 0($v0) + /* Enable interrupt for address updating. */ la $v0, IPC10 - li $v1, 0b11111 /* DMA0IP, DMA0IS = 0 */ + li $v1, 0b1111100011111 /* DMA1IP, DMA1IS, DMA0IP, DMA0IS = 0 */ sw $v1, CLR($v0) la $v0, IPC10 - li $v1, 0b11111 /* DMA0IP = 7, DMA0IS = 3 */ + li $v1, 0b1111100011111 /* DMA1IP, DMA0IP = 7, DMA1IS, DMA0IS = 3 */ sw $v1, SET($v0) la $v0, IEC1 - li $v1, (1 << 28) /* IEC1<28> = DMA0IE = 1 */ + li $v1, (0b11 << 28) /* IEC1<29:28> = DMA1IE, DMA0IE = 1 */ sw $v1, SET($v0) /* Enable line channel. */ @@ -664,6 +694,9 @@ zerodata: .word 0 +fulldata: +.word 255 + /* Utilities. */ @@ -803,7 +836,7 @@ la $v0, IFS1 lw $v1, 0($v0) - li $t8, (1 << 28) /* DMA0IF */ + li $t8, (0b11 << 28) /* DMA1IF, DMA0IF */ and $v1, $v1, $t8 beqz $v1, irq_exit nop @@ -817,6 +850,19 @@ la $v0, DCH0INT lw $v1, 0($v0) andi $v1, $v1, (1 << 3) /* CHBCIF */ + beqz $v1, irq_dma_next + nop + + /* Clear the block transfer completion interrupt flag. */ + + sw $v1, CLR($v0) + +irq_dma_next: + /* Test the block transfer completion interrupt flag. */ + + la $v0, DCH1INT + lw $v1, 0($v0) + andi $v1, $v1, (1 << 3) /* CHBCIF */ beqz $v1, irq_exit nop