DMA Operation - sjsoftware/centurion-cpu6 GitHub Wiki

DMA Operation

Every approximately 5 to 10 cycles a check is made to see if a DMA operation needs to take place and a subroutine call is made to the DMA handler to manage the operation. A DMA error will occur if the DMA is on a register memory address or there is a parity error. The timer interrupt is also checked and the Z register at interrupt level 0xa is decremented and the interrupt is reset.

Microcode

785 0     CRY0 r06 r15 RAMA D                     D D D PUSH 5bd bd (42)                                       LOAD.MAP READ.ALO    (785) MAP <- r06; BSR 5bd ;* low bits DMA map; set up ARs
    0     CRY0 r00 r09 PASS A+Q                   D D D      601 01 (fe)                            DMA-                READ.SWP    (786) DMA-  ;* DMA on from CPU
601 0     CRY0 r00 r04 PASS A+Q         COND ???? P P D      0b0 b0 (4f)                            INC.DMA+            READ.SWP    (601) switch (!DMA.REQ/DMAE)     ;* wait for DMA error or request finished

;* request
600 0     CRY0 r00 r00 PASS A+Q         COND ???? P P D      0b0 b0 (4f)                                                READ.SWP    (600)

;* request, error 
604 0     CRY0 r00 r00 PASS A+Q         COND !DMA P P D      0b5 b5 (4a)                                                READ.SWP    (604) BRT (!DMA) 60d ;* wait to become free
605 0     CRY0 r00 r00 PASS A+Q         COND !DMA P P D      0b5 b5 (4a)                                                READ.SWP    (605) BRT (!DMA) 60d

;* no error, no dma
608 0     CRY0 r00 r00 PASS A+Q                   D D D      6b4 b4 (4b)                                                READ.SWP    (608) 
    0     CRY0 r00 r00 PASS A+Q                   P P P      610 10 (ef) JSR !BSY                                       READ.SWP    (6b4)
    0     CRY0 r00 r00 PASS A+Q                   D D D      6b4 b4 (4b)                                                READ.SWP    (6b5) BRT 6b4

;* error, no dma
60c 0     CRY0 r00 r00 PASS A+Q                   D D D      60d 0d (f2)                                                READ.SWP    (60c) ;* DMA error/DMA.REQ
    0     CRY0 r00 r00 PASS A+Q                   P P P      6b8 b8 (47) JSR !BSY                                       READ.SWP    (60d)
    0     CRY0 r00 r00 PASS A+Q                   D D D      60d 0d (f2)                                                READ.SWP    (60e) BRT 60d



5bd 0     CRY0 r00 r14 RAM  D                     D D D      5d0 d0 (2f)                                       LOAD.MAR READ.AHI    (5bd)
    0     CRY0 r12 r12 RAMA D                     D D D      5e0 e0 (1f)                            LOAD.ALO   LOAD.RR  READ.AHI    (5d0)
    0     CRY0 r13 r13 RAMA D                     D D D      5f1 f1 (0e)                   LOAD.AHI            LOAD.RR  READ.ALO    (5e0)
    0     CRY0 r00 r05 PASS A+Q                   D D D      5e8 e8 (17)                            INC.DMA-   LOAD.MAR READ.SWP    (5f1)
    0     CRY0 r11 r11 RAMA D                     D D D      5dc dc (23)                            LOAD.ALO   LOAD.RR  READ.ALO    (5e8)
    0     CRY0 r12 r12 RAM  D.EQV.A               P P P      0f0 f0 (0f)                                       LOAD.MAR READ.CONST  (5dc)
    0     CRY0 r10 r00 PASS A                     D D D      5ea ea (15)                            LOAD.ALO   LOAD.RR  READ.SWP    (5dd)
    0     CRY0 r11 r07 PASS A                     S S S POP  000 00 (ff)                   LOAD.AHI DIR+       LOAD.RR  READ.SWP    (5ea)

;* no error
610 0     CRY0 r00 r05 PASS D                     D D D POP  7a0 a0 (5f)                            INC.DMA-   LOAD.RIR READ.INR    (610) RIR <- INR; BRT 7a0 ;* test timer

;* error
6b8 0     CRY0 r00 r05 PASS NOT.D                 P P P POP  013 13 (ec)                            INC.DMA-   LOAD.RIR READ.CONST  (6b8) RIR <- 13  ;* BL at level 1
    0     CRY0 r08 r08 PASS A.EQV.B               P P P      000 00 (ff)                            DMA+       LOAD.RR  READ.SWP    (6b9) RR <- ff   ;* set to ff for error during DMA
7a0 0     CRY0 r00 r00 PASS D                     D D D      7a0 a0 (5f)                            WRITE.RF   LOAD.RIR READ.INR    (6ba) 
    0     CRY0 r00 r00 PASS A+Q                   P P P      74a 4a (b5) JSR ODD                                        READ.SWP    (7a0) ;* branch if timer triggered
    0     CRY0 r09 r00 PASS A                     D D D      611 11 (ee)                                       LOAD.RIR READ.SWP    (7a1) RIR <- r09
    0     CRY0 r11 r08 PASS A                     D D D PUSH 1ac ac (53)                            DMA+       LOAD.RR  READ.SWP    (611) 
    0     CRY0 r00 r15 RAM  D                     D D D PUSH 5bd bd (42)                                                READ.ALO    (612)
    0     CRY0 r00 r00 PASS A+Q                   D D D PUSH 1ac ac (53)                                                READ.SWP    (613)
    0     CRY0 r06 r14 RSH  A                     D D D PUSH 059 59 (a6)                                                READ.SWP    (614) ;* r06 /= 16
    0     CRY0 r14 r15 RAMA D                     D D D      079 79 (86)                                       LOAD.MAP READ.ALO    (615) ;* reload map
    0     CRY0 r00 r14 RAM  D                     D D D      1cc cc (33)                                                READ.AHI    (079)
    1     CRY0 r14 r14 RAM  D.EQV.A               S S S POP  0f0 f0 (0f)                                                READ.CONST  (1cc)  ;* back to main microcode execution

74a 0     CRY0 r00 r10 PASS NOT.D                 P P D POP  0a8 a8 (57)                            TIMER.RES+ LOAD.RIR READ.CONST  (74a) RIR <- a8
    0 RLO CRY0 r00 r11 PASS A+Q                   D D D      746 46 (b9)                            TIMER.RES-          READ.SWP    (748) 
    0     CRY0 r00 r00 PASS D-1                   D D D      744 44 (bb)                                       LOAD.RR  READ.RF     (746)
    0 RLO CRY0 r09 r00 PASS A                     D D D      611 11 (ee)                            WRITE.RF   LOAD.RIR READ.SWP    (744) RIR <- r09 ;* restore it back

;* swap ARs under DMA
1ac 0     CRY0 r15 r11 RAM  A                     D D D      1ae ae (51)                   LOAD.AHI LOAD.ALO   LOAD.MAR READ.SWP    (1ac) r11 <- r15
    0     CRY0 r14 r10 RAM  D.EQV.A               S S S POP  0f0 f0 (0f)                                                READ.CONST  (1ae) r10 <- r14 !^ 0f  ;* flip high nibble

059 0     CRY0 r14 r14 RSH  A                     D D D      069 69 (96)                                                READ.SWP    (059) 
    0     CRY0 r14 r14 RSH  A                     D D D      05f 5f (a0)                                                READ.SWP    (069)
    0     CRY0 r14 r14 RSH  A                     S S S POP  000 00 (ff)                                                READ.SWP    (05f)