Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Coto
- //Software DMA emulation
- //DMAs must exist because GBA logic offers linear DMA reads (fast) and it is used by common CPU load/store mechanisms.
- //HBlank thread
- //{
- //checks if DMAXCNT's is enabled and there is WORD transfers queued so DMAXTransfers occur
- if( ((((gba.DM0CNT_H)>>15)&1)==1) ){
- dma_gbavirt(gba.dma0source,gba.dma0dest,(u16)(gba.DM0CNT_L&0xffff),(u16)(gba.DM0CNT_H&0xffff),0);
- if((gba.DM0CNT_H>>14)&0x1){ //irq enable?
- gbavirt_ifmasking|=(1<<8);
- }
- iprintf("[DMA0 served!] \n");
- gba.DM0CNT_H&=0x7fff;
- }
- else if( ((((gba.DM1CNT_H)>>15)&1)==1) ){
- dma_gbavirt(gba.dma1source,gba.dma1dest,(u16)(gba.DM1CNT_L&0xffff),(u16)(gba.DM1CNT_H&0xffff),1);
- if((gba.DM1CNT_H>>14)&0x1){ //irq enable?
- gbavirt_ifmasking|=(1<<9);
- }
- iprintf("[DMA1 served!] \n");
- gba.DM1CNT_H&=0x7fff;
- }
- else if( ((((gba.DM2CNT_H)>>15)&1)==1) ){
- dma_gbavirt(gba.dma2source,gba.dma2dest,(u16)(gba.DM2CNT_L&0xffff),(u16)(gba.DM2CNT_H&0xffff),2);
- if((gba.DM2CNT_H>>14)&0x1){ //irq enable?
- gbavirt_ifmasking|=(1<<10);
- }
- iprintf("[DMA2 served!] \n");
- gba.DM2CNT_H&=0x7fff;
- }
- else if( ((((gba.DM3CNT_H)>>15)&1)==1) ){
- dma_gbavirt(gba.dma3source,gba.dma3dest,(u16)(gba.DM3CNT_L&0xffff),(u16)(gba.DM3CNT_H&0xffff),3);
- if((gba.DM3CNT_H>>14)&0x1){ //irq enable?
- gbavirt_ifmasking|=(1<<11);
- }
- iprintf("[DMA3 served!] \n");
- gba.DM3CNT_H&=0x7fff;
- }
- //}
- //DMA Process
- u32 __attribute__ ((hot)) dma_gbavirt(u32 source,u32 dest,u32 wordcnt,u16 control,u8 dma_ch){
- int offset_src=0;
- int offset_dest=0;
- int cntertemp=0;
- if((dma_ch==0) || (dma_ch==1) || (dma_ch==2)){
- if(wordcnt==0){
- wordcnt=0x4000; //default by GBACore
- }
- wordcnt=(wordcnt&0x7fff); //14bit wordcount field
- }
- else if (dma_ch==3){
- if(wordcnt==0){
- wordcnt=0x10000;
- }
- wordcnt=(wordcnt&0x1ffff); //16bit wordcount field
- }
- else
- return 0; //quit if DMA channel isn't 0--3
- if(((control>>10)&1)==0){ //because each loop is half-word depth (16bit)
- while(0<wordcnt){
- DC_InvalidateAll();
- cpuwrite_hword(dest+(offset_dest*4), cpuread_hword(source+(offset_src*4))); //hword aligned
- //dest addr control
- switch((control>>5)&3){
- case(0):
- offset_dest++; //incr
- break;
- case(1):
- offset_dest--; //decr
- break;
- case(2):
- offset_dest=0; //fixed
- break;
- case(3):
- //increment reload
- break;
- }
- //src addr control
- switch((control>>7)&3){
- case(0):
- offset_src++; //incr
- break;
- case(1):
- offset_src--; //decr
- break;
- case(2):
- offset_src=0; //fixed
- break;
- case(3):
- //prohibited
- break;
- }
- wordcnt-=0x2;
- cntertemp++; //uncomment later, debug
- drainwrite();
- }
- }
- else{ //because each loop is word depth (32bit) transfers
- while(0<wordcnt){
- DC_InvalidateAll();
- cpuwrite_word(dest+(offset_dest*4), cpuread_word(source+(offset_src*4))); //hword aligned
- //dest addr control
- switch((control>>5)&3){
- case(0):
- offset_dest++; //incr
- break;
- case(1):
- offset_dest--; //decr
- break;
- case(2):
- offset_dest=0; //fixed
- break;
- case(3):
- //increment reload
- break;
- }
- //src addr control
- switch((control>>7)&3){
- case(0):
- offset_src++; //incr
- break;
- case(1):
- offset_src--; //decr
- break;
- case(2):
- offset_src=0; //fixed
- break;
- case(3):
- //prohibited
- break;
- }
- wordcnt-=0x4;
- cntertemp++; //uncomment later, debug
- drainwrite();
- }
- }
- iprintf("\n copied (%d)bytes from DMA! | src:%x | dest:%x",(int)(cntertemp*4),(unsigned int)source,(unsigned int)dest);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement