Advertisement
Guest User

GPU.c

a guest
Nov 14th, 2015
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.62 KB | None | 0 0
  1. int RGBCOLOR(int r, int g, int b)
  2. {
  3.   return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8);
  4. }
  5.  
  6. void putImageData(const void* datar, int x, int y, int width, int height) {
  7.    color_t*data = (color_t*) datar;
  8.    color_t* VRAM = (color_t*)0xA8000000;
  9.    VRAM += LCD_WIDTH_PX*y + x;
  10.    for(int j=y; j<y+height; j++) {
  11.       for(int i=x; i<x+width; i++) {
  12.          *(VRAM++) = *(data++);
  13.      }
  14.      VRAM += LCD_WIDTH_PX-width;
  15.    }
  16. }
  17.  
  18.  void GPU_reset() {
  19.     for(int i=0; i<8192; i++) {
  20.       GPU_vram[i] = 0;
  21.     }
  22.     for(int i=0; i<160; i++) {
  23.       GPU_oam[i] = 0;
  24.     }
  25.     for(int i=0; i<4; i++) {
  26.       GPU_palettebg[i] = 255;
  27.       GPU_paletteobj0[i] = 255;
  28.       GPU_paletteobj1[i] = 255;
  29.     }
  30.     for(int i=0;i<512;i++)
  31.     {
  32.       for(int j=0;j<8;j++)
  33.       {
  34.         for(int k=0;k<8;k++)
  35.         {
  36.           GPU_tilemap[i][j][k] = 0;
  37.         }
  38.       }
  39.     }
  40.     //GPU_scrn = {'width':160, 'height':144, 'data':new Array(160*144*4)};
  41.     GPU_scrnwidth = 160;
  42.     GPU_scrnheight = 144;
  43.      
  44.     for(int i=0; i<(160 * 144); i++)
  45.         GPU_scrndata[i]=RGBCOLOR(255, 255, 255);
  46.     putImageData(GPU_scrndata, 0, 0, GPU_scrnwidth, GPU_scrnheight);
  47.  
  48.     GPU_curline=0;
  49.     GPU_curscan=0;
  50.     GPU_linemode=2;
  51.     GPU_modeclocks=0;
  52.     GPU_yscrl=0;
  53.     GPU_xscrl=0;
  54.     GPU_raster=0;
  55.     GPU_ints = 0;
  56.  
  57.     GPU_lcdon = 0;
  58.     GPU_bgon = 0;
  59.     GPU_objon = 0;
  60.     GPU_winon = 0;
  61.  
  62.     GPU_objsize = 0;
  63.     for(int i=0; i<160; i++) GPU_scanrow[i] = 0;
  64.  
  65.     for(int i=0; i<40; i++)
  66.     {
  67.       //GPU_objdata[i] = {'y':-16, 'x':-8, 'tile':0, 'palette':0, 'yflip':0, 'xflip':0, 'prio':0, 'num':i};
  68.       GPU_objdatax[i] = -8;
  69.       GPU_objdatay[i] = -16;
  70.       GPU_objdatatile[i] = 0;
  71.       GPU_objdatapalette[i] = 0;
  72.       GPU_objdatayflip[i] = 0;
  73.       GPU_objdataxflip[i] = 0;
  74.       GPU_objdataprio[i] = 0;
  75.       GPU_objdatanum[i] = i;
  76.     }
  77.  
  78.     // Set to values expected by BIOS, to start
  79.     GPU_bgtilebase = 0x0000;
  80.     GPU_bgmapbase = 0x1800;
  81.     GPU_wintilebase = 0x1800;
  82. };
  83.  
  84. void GPU_checkline() {
  85.     GPU_modeclocks += r_m;
  86.     switch(GPU_linemode)
  87.     {
  88.       // In hblank
  89.       case 0:
  90.         if(GPU_modeclocks >= 51)
  91.         {
  92.           // End of hblank for last scanline; render screen
  93.           if(GPU_curline == 143)
  94.           {
  95.             GPU_linemode = 1;
  96.             putImageData(GPU_scrndata, 0, 0, GPU_scrnwidth, GPU_scrnheight);
  97.             MMU_if |= 1;
  98.           }
  99.           else
  100.           {
  101.             GPU_linemode = 2;
  102.           }
  103.           GPU_curline++;
  104.           GPU_curscan += 640;
  105.           GPU_modeclocks=0;
  106.         }
  107.         break;
  108.  
  109.       // In vblank
  110.       case 1:
  111.         if(GPU_modeclocks >= 114)
  112.         {
  113.           GPU_modeclocks = 0;
  114.           GPU_curline++;
  115.           if(GPU_curline > 153)
  116.           {
  117.             GPU_curline = 0;
  118.         GPU_curscan = 0;
  119.             GPU_linemode = 2;
  120.           }
  121.         }
  122.         break;
  123.  
  124.       // In OAM-read mode
  125.       case 2:
  126.         if(GPU_modeclocks >= 20)
  127.         {
  128.           GPU_modeclocks = 0;
  129.           GPU_linemode = 3;
  130.         }
  131.         break;
  132.  
  133.       // In VRAM-read mode
  134.       case 3:
  135.         // Render scanline at end of allotted time
  136.         if(GPU_modeclocks >= 43)
  137.         {
  138.           GPU_modeclocks = 0;
  139.           GPU_linemode = 0;
  140.           if(GPU_lcdon)
  141.           {
  142.             if(GPU_bgon)
  143.             {
  144.               int linebase = GPU_curscan;
  145.               int mapbase = GPU_bgmapbase + ((((GPU_curline+GPU_yscrl)&255)>>3)<<5);
  146.               int y = (GPU_curline+GPU_yscrl)&7;
  147.               int x = GPU_xscrl&7;
  148.               int t = (GPU_xscrl>>3)&31;
  149.               int pixel;
  150.               int w=160;
  151.  
  152.               if(GPU_bgtilebase)
  153.               {
  154.             int tile = GPU_vram[mapbase+t];
  155.         if(tile<128) tile=256+tile;
  156.                 int *tilerow = GPU_tilemap[tile][y];
  157.                 do
  158.                 {
  159.           GPU_scanrow[160-x] = tilerow[x];
  160.                   GPU_scrndata[linebase+3] = GPU_palettebg[tilerow[x]];
  161.                   x++;
  162.                   if(x==8) { t=(t+1)&31; x=0; tile=GPU_vram[mapbase+t]; if(tile<128) tile=256+tile; tilerow = GPU_tilemap[tile][y]; }
  163.                   linebase+=4;
  164.                 } while(--w);
  165.               }
  166.               else
  167.               {
  168.                 int *tilerow=GPU_tilemap[GPU_vram[mapbase+t]][y];
  169.                 do
  170.                 {
  171.           GPU_scanrow[160-x] = tilerow[x];
  172.                   GPU_scrndata[linebase+3] = GPU_palettebg[tilerow[x]];
  173.                   x++;
  174.                   if(x==8) { t=(t+1)&31; x=0; tilerow=GPU_tilemap[GPU_vram[mapbase+t]][y]; }
  175.                   linebase+=4;
  176.                 } while(--w);
  177.           }
  178.             }
  179.             if(GPU_objon)
  180.             {
  181.               int cnt = 0;
  182.               if(GPU_objsize)
  183.               {
  184.                 for(int i=0; i<40; i++)
  185.                 {
  186.                 }
  187.               }
  188.               else
  189.               {
  190.                 int *tilerow;
  191.                 int objx;
  192.                 int objy;
  193.                 int objtile;
  194.                 int objpalette;
  195.                 int objyflip;
  196.                 int objxflip;
  197.                 int objprio;
  198.                 int *pal;
  199.                 int pixel;
  200.                 int x;
  201.                 int linebase = GPU_curscan;
  202.                 for(int i=0; i<40; i++)
  203.                 {
  204.                   objx = GPU_objdatax[i];
  205.                   objy = GPU_objdatay[i];
  206.                   objtile = GPU_objdatatile[i];
  207.                   objpalette = GPU_objdatapalette[i];
  208.                   objyflip = GPU_objdatayflip[i];
  209.                   objxflip = GPU_objdataxflip[i];
  210.                   objprio = GPU_objdataprio[i];
  211.                  
  212.                   if(objy <= GPU_curline && (objy+8) > GPU_curline)
  213.                   {
  214.                     if(objyflip)
  215.                       tilerow = GPU_tilemap[objtile][7-(GPU_curline-objy)];
  216.                     else
  217.                       tilerow = GPU_tilemap[objtile][GPU_curline-objy];
  218.  
  219.                     if(objpalette) pal=GPU_paletteobj1;
  220.                     else pal=GPU_paletteobj0;
  221.  
  222.                     linebase = (GPU_curline*160+objx)*4;
  223.                     if(objxflip)
  224.                     {
  225.                       for(x=0; x<8; x++)
  226.                       {
  227.                         if(objx+x >=0 && objx+x < 160)
  228.                         {
  229.                           if(tilerow[7-x] && (objprio || !GPU_scanrow[x]))
  230.                           {
  231.                             GPU_scrndata[linebase+3] = pal[tilerow[7-x]];
  232.                           }
  233.                         }
  234.                         linebase+=4;
  235.                       }
  236.                     }
  237.                     else
  238.                     {
  239.                       for(x=0; x<8; x++)
  240.                       {
  241.                         if(objx+x >=0 && objx+x < 160)
  242.                         {
  243.                           if(tilerow[x] && (objprio || !GPU_scanrow[x]))
  244.                           {
  245.                             GPU_scrndata[linebase+3] = pal[tilerow[x]];
  246.                           }
  247.                         }
  248.                         linebase+=4;
  249.                       }
  250.                     }
  251.                     cnt++; if(cnt>10) break;
  252.                   }
  253.                 }
  254.               }
  255.             }
  256.           }
  257.         }
  258.         break;
  259.     }
  260. };
  261.  
  262. void GPU_updatetile(int addr, int val) {
  263.     int saddr = addr;
  264.     if(addr&1) { saddr--; addr--; }
  265.     int tile = (addr>>4)&511;
  266.     int y = (addr>>1)&7;
  267.     int sx;
  268.     for(int x=0;x<8;x++)
  269.     {
  270.       sx=1<<(7-x);
  271.       GPU_tilemap[tile][y][x] = ((GPU_vram[saddr]&sx)?1:0) | ((GPU_vram[saddr+1]&sx)?2:0);
  272.     }
  273. };
  274.  
  275.  void GPU_updateoam(int addr, int val) {
  276.     addr-=0xFE00;
  277.     int obj=addr>>2;
  278.     if(obj<40)
  279.     {
  280.       switch(addr&3)
  281.       {
  282.         case 0: GPU_objdatay[obj]=val-16; break;
  283.         case 1: GPU_objdatax[obj]=val-8; break;
  284.         case 2:
  285.           if(GPU_objsize) GPU_objdatatile[obj] = (val&0xFE);
  286.           else GPU_objdatatile[obj] = val;
  287.           break;
  288.         case 3:
  289.           GPU_objdatapalette[obj] = (val&0x10)?1:0;
  290.           GPU_objdataxflip[obj] = (val&0x20)?1:0;
  291.           GPU_objdatayflip[obj] = (val&0x40)?1:0;
  292.           GPU_objdataprio[obj] = (val&0x80)?1:0;
  293.           break;
  294.      }
  295.     }
  296. };
  297.  
  298.  int GPU_rb(int addr) {
  299.     int gaddr = addr-0xFF40;
  300.     switch(gaddr)
  301.     {
  302.       case 0:
  303.         return (GPU_lcdon?0x80:0)|
  304.                ((GPU_bgtilebase==0x0000)?0x10:0)|
  305.                ((GPU_bgmapbase==0x1C00)?0x08:0)|
  306.                (GPU_objsize?0x04:0)|
  307.                (GPU_objon?0x02:0)|
  308.                (GPU_bgon?0x01:0);
  309.  
  310.       case 1:
  311.         return (GPU_curline==GPU_raster?4:0)|GPU_linemode;
  312.  
  313.       case 2:
  314.         return GPU_yscrl;
  315.  
  316.       case 3:
  317.         return GPU_xscrl;
  318.  
  319.       case 4:
  320.         return GPU_curline;
  321.  
  322.       case 5:
  323.         return GPU_raster;
  324.  
  325.       default:
  326.         return GPU_reg[gaddr];
  327.     }
  328.   };
  329.  
  330. void GPU_wb(int addr, int val) {
  331.     int gaddr = addr-0xFF40;
  332.     GPU_reg[gaddr] = val;
  333.     switch(gaddr)
  334.     {
  335.       case 0:
  336.         GPU_lcdon = (val&0x80)?1:0;
  337.         GPU_bgtilebase = (val&0x10)?0x0000:0x0800;
  338.         GPU_bgmapbase = (val&0x08)?0x1C00:0x1800;
  339.         GPU_objsize = (val&0x04)?1:0;
  340.         GPU_objon = (val&0x02)?1:0;
  341.         GPU_bgon = (val&0x01)?1:0;
  342.         break;
  343.  
  344.       case 2:
  345.         GPU_yscrl = val;
  346.         break;
  347.  
  348.       case 3:
  349.         GPU_xscrl = val;
  350.         break;
  351.  
  352.       case 5:
  353.         GPU_raster = val;
  354.  
  355.       // OAM DMA
  356.       case 6: ;
  357.         int v;
  358.         for(int i=0; i<160; i++)
  359.         {
  360.           v = MMU_rb((val<<8)+i);
  361.           GPU_oam[i] = v;
  362.           GPU_updateoam(0xFE00+i, v);
  363.         }
  364.         break;
  365.  
  366.       // BG palette mapping
  367.       case 7:
  368.         for(int i=0;i<4;i++)
  369.         {
  370.           switch((val>>(i*2))&3)
  371.           {
  372.             case 0: GPU_palettebg[i] = 255; break;
  373.             case 1: GPU_palettebg[i] = 192; break;
  374.             case 2: GPU_palettebg[i] = 96; break;
  375.             case 3: GPU_palettebg[i] = 0; break;
  376.           }
  377.         }
  378.         break;
  379.  
  380.       // OBJ0 palette mapping
  381.       case 8:
  382.         for(int i=0;i<4;i++)
  383.         {
  384.           switch((val>>(i*2))&3)
  385.           {
  386.             case 0: GPU_paletteobj0[i] = 255; break;
  387.             case 1: GPU_paletteobj0[i] = 192; break;
  388.             case 2: GPU_paletteobj0[i] = 96; break;
  389.             case 3: GPU_paletteobj0[i] = 0; break;
  390.           }
  391.         }
  392.         break;
  393.  
  394.       // OBJ1 palette mapping
  395.       case 9:
  396.         for(int i=0;i<4;i++)
  397.         {
  398.           switch((val>>(i*2))&3)
  399.           {
  400.             case 0: GPU_paletteobj1[i] = 255; break;
  401.             case 1: GPU_paletteobj1[i] = 192; break;
  402.             case 2: GPU_paletteobj1[i] = 96; break;
  403.             case 3: GPU_paletteobj1[i] = 0; break;
  404.           }
  405.         }
  406.         break;
  407.     }
  408. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement