Advertisement
Guest User

COTO: DMA (ARM7TDMI) Software Module

a guest
Mar 1st, 2015
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.76 KB | None | 0 0
  1. //Coto
  2. //Software DMA emulation
  3. //DMAs must exist because GBA logic offers linear DMA reads (fast) and it is used by common CPU load/store mechanisms.
  4.  
  5. //HBlank thread
  6. //{
  7. //checks if DMAXCNT's is enabled and there is WORD transfers queued so DMAXTransfers occur
  8.     if( ((((gba.DM0CNT_H)>>15)&1)==1) ){
  9.        
  10.         dma_gbavirt(gba.dma0source,gba.dma0dest,(u16)(gba.DM0CNT_L&0xffff),(u16)(gba.DM0CNT_H&0xffff),0);
  11.        
  12.         if((gba.DM0CNT_H>>14)&0x1){ //irq enable?
  13.             gbavirt_ifmasking|=(1<<8);
  14.         }
  15.         iprintf("[DMA0 served!] \n");
  16.         gba.DM0CNT_H&=0x7fff;
  17.     }
  18.    
  19.     else if( ((((gba.DM1CNT_H)>>15)&1)==1) ){
  20.        
  21.         dma_gbavirt(gba.dma1source,gba.dma1dest,(u16)(gba.DM1CNT_L&0xffff),(u16)(gba.DM1CNT_H&0xffff),1);
  22.        
  23.         if((gba.DM1CNT_H>>14)&0x1){ //irq enable?
  24.             gbavirt_ifmasking|=(1<<9);
  25.         }
  26.         iprintf("[DMA1 served!] \n");
  27.         gba.DM1CNT_H&=0x7fff;
  28.     }
  29.    
  30.     else if( ((((gba.DM2CNT_H)>>15)&1)==1) ){
  31.        
  32.         dma_gbavirt(gba.dma2source,gba.dma2dest,(u16)(gba.DM2CNT_L&0xffff),(u16)(gba.DM2CNT_H&0xffff),2);
  33.        
  34.         if((gba.DM2CNT_H>>14)&0x1){ //irq enable?
  35.             gbavirt_ifmasking|=(1<<10);
  36.         }
  37.         iprintf("[DMA2 served!] \n");
  38.         gba.DM2CNT_H&=0x7fff;
  39.     }
  40.    
  41.     else if( ((((gba.DM3CNT_H)>>15)&1)==1) ){
  42.        
  43.         dma_gbavirt(gba.dma3source,gba.dma3dest,(u16)(gba.DM3CNT_L&0xffff),(u16)(gba.DM3CNT_H&0xffff),3);
  44.        
  45.         if((gba.DM3CNT_H>>14)&0x1){ //irq enable?
  46.             gbavirt_ifmasking|=(1<<11);
  47.         }
  48.         iprintf("[DMA3 served!] \n");
  49.         gba.DM3CNT_H&=0x7fff;
  50.     }
  51. //}
  52.  
  53. //DMA Process
  54. u32 __attribute__ ((hot)) dma_gbavirt(u32 source,u32 dest,u32 wordcnt,u16 control,u8 dma_ch){
  55. int offset_src=0;
  56. int offset_dest=0;
  57. int cntertemp=0;
  58. if((dma_ch==0) || (dma_ch==1) || (dma_ch==2)){
  59.         if(wordcnt==0){
  60.                 wordcnt=0x4000; //default by GBACore
  61.         }
  62.         wordcnt=(wordcnt&0x7fff); //14bit wordcount field
  63. }
  64. else if (dma_ch==3){
  65.         if(wordcnt==0){
  66.                 wordcnt=0x10000;
  67.         }
  68.         wordcnt=(wordcnt&0x1ffff); //16bit wordcount field
  69. }
  70. else
  71.         return 0; //quit if DMA channel isn't 0--3
  72.  
  73. if(((control>>10)&1)==0){ //because each loop is half-word depth (16bit)
  74.  
  75.         while(0<wordcnt){
  76.                
  77.                 DC_InvalidateAll();
  78.                         cpuwrite_hword(dest+(offset_dest*4), cpuread_hword(source+(offset_src*4))); //hword aligned
  79.                        
  80.                         //dest addr control
  81.                         switch((control>>5)&3){
  82.                                 case(0):
  83.                                         offset_dest++; //incr
  84.                                 break;
  85.                                 case(1):
  86.                                         offset_dest--; //decr
  87.                                 break;
  88.                                 case(2):
  89.                                         offset_dest=0; //fixed
  90.                                 break;
  91.                                 case(3):
  92.                                         //increment reload
  93.                                 break;
  94.                         }
  95.                        
  96.                         //src addr control
  97.                         switch((control>>7)&3){
  98.                                 case(0):
  99.                                         offset_src++; //incr
  100.                                 break;
  101.                                 case(1):
  102.                                         offset_src--; //decr
  103.                                 break;
  104.                                 case(2):
  105.                                         offset_src=0; //fixed
  106.                                 break;
  107.                                 case(3):
  108.                                         //prohibited
  109.                                 break;
  110.                         }
  111.                        
  112.                 wordcnt-=0x2;
  113.                 cntertemp++; //uncomment later, debug
  114.                 drainwrite();
  115.         }
  116. }
  117. else{   //because each loop is word depth (32bit) transfers
  118.  
  119.         while(0<wordcnt){
  120.                 DC_InvalidateAll();
  121.                         cpuwrite_word(dest+(offset_dest*4), cpuread_word(source+(offset_src*4))); //hword aligned
  122.                        
  123.                         //dest addr control
  124.                         switch((control>>5)&3){
  125.                                 case(0):
  126.                                         offset_dest++; //incr
  127.                                 break;
  128.                                 case(1):
  129.                                         offset_dest--; //decr
  130.                                 break;
  131.                                 case(2):
  132.                                         offset_dest=0; //fixed
  133.                                 break;
  134.                                 case(3):
  135.                                         //increment reload
  136.                                 break;
  137.                         }
  138.                        
  139.                         //src addr control
  140.                         switch((control>>7)&3){
  141.                                 case(0):
  142.                                         offset_src++; //incr
  143.                                 break;
  144.                                 case(1):
  145.                                         offset_src--; //decr
  146.                                 break;
  147.                                 case(2):
  148.                                         offset_src=0; //fixed
  149.                                 break;
  150.                                 case(3):
  151.                                         //prohibited
  152.                                 break;
  153.                         }
  154.                        
  155.                 wordcnt-=0x4;
  156.                 cntertemp++; //uncomment later, debug
  157.                 drainwrite();
  158.         }
  159. }
  160.  
  161. iprintf("\n copied (%d)bytes from DMA! | src:%x | dest:%x",(int)(cntertemp*4),(unsigned int)source,(unsigned int)dest);
  162. return 0;
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement