Skip to content

DMA IRQ never cleared #10

@dombo280

Description

@dombo280

Hello,
I have tried to write an interrupt-based driver using DMA.
DMA transfer completes and fires correctly DMA Interrupt.
within the interrupt handler I do clear both TC and EPS flags in the DMA Transaction descriptor, but still IRQ is not cleared.

Looking at z280.c file the only condition a DMA IRQ line is cleared seems to be when DMA reached TC and the DMA IRQ enable flag is zero.

comparing to the TIMER code: resetting the CTCSR CC flag is enough to cancel the current pending interrupt.

In both cases the official Z280 documentation is not telling if just entering the interrupt handler is enough to clear the pending interrupt, or if other register manipulations are required.
I will try my code on a genuine Z280 chip ...

here the extract of the sample code:

init DMA 0:
04D9 2E FF + ld l,..dma
04DB 0E 08 + ld c,..iopage
04DD ED 6E + db 0edh,06eh ; = ldctl (c),hl
04DF 21 0000 ld hl,0 ; reset all to 0 = DMA off
04E2 0E 1F ld c,..dmamcr
04E4 ED BF + db 0edh,0bfh ; = outw (c),hl
04E6 0E 05 ld c,..tdr0 ; disable DMA0
04E8 ED BF + db 0edh,0bfh ; outw (c),hl
; transfer 20 bytes from 00 8000 to 00 A000
04EA 21 0000 ld hl,ram1 mod 4096
04ED 0E 02 ld c,..sl0 ; source (Lower 12 bits, right aligned)
04EF ED BF + db 0edh,0bfh ; = outw (c),hl
04F1 21 0080 ld hl, ram1 / 4096 * 16 and 0f0h
04F4 0E 03 ld c,..sh0 ; source (upper 12 bits, left aligned)
04F6 ED BF + db 0edh,0bfh ; = outw (c),hl
04F8 21 0000 ld hl, ram2 mod 4096
04FB 0E 00 ld c,..dl0 ; destination (Lower 12 bits, right aligned)
04FD ED BF + db 0edh,0bfh ; = outw (c),hl
04FF 21 00A0 ld hl, ram2 / 4096 * 16 and 0f0h
0502 0E 01 ld c,..dh0 ; destination (upper 12 bits, right aligned)
0504 ED BF + db 0edh,0bfh ; = outw (c),hl
0506 21 0020 ld hl,len
0509 0E 04 ld c,..cnt0 ; count
050B ED BF + db 0edh,0bfh ; outw (c),hl
050D 21 8B00 ld hl,08B00h ; word transfer, auto-inc memory, continuos, enable IRQ, enable DMA
0510 0E 05 ld c,..tdr0
0512 ED BF + db 0edh,0bfh ; outw (c),hl
0514 21 0020 ld hl,dm_sr0 ; SW enable DMA
0517 0E 1F ld c,..dmamcr
0519 ED BF + db 0edh,0bfh ; outw (c),hl

Interrupt handler:
00A8 E3 t$dma0: ex (sp),hl ; swap top od stack with HL, so effectively removes reason code and saves HL
00A9 F5 push af ; saves AF
00AA E5 push hl ; saves old reason code
00AB C5 push bc ; saves BC
00AC 2E FF + ld l,..dma
00AE 0E 08 + ld c,..iopage
00B0 ED 6E + db 0edh,06eh ;ldctl (c),hl
00B2 0E 05 ld c,..tdr0 ; read DMA TDR and reset EN, TC & EPS bits
00B4 ED B7 + db 0edh,0b7h ; inw hl,(c)
00B6 CB 85 res 0,l
00B8 CB A5 res 4,l
00BA CB BC res 7,h
00BC ED BF + db 0edh,0bfh ; outw (c),hl
00BE 0E 1F ld c,..dmamcr
...
00D7 C1 pop bc
00D8 E1 pop hl ; old reason code
00D9 F1 pop af
00DA E1 pop hl
00DB ED 55 + db 0edh,055h ; = RETIL

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions