123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329 |
- /*
- * PPU emulation - The peTI-NESulator Project
- * ppu.c
- *
- * Define and emulate the PPU (Picture Processing Unit) of the real NES
- *
- * Created by Manoel TRAPIER.
- * Copyright (c) 2003-2008 986Corp. All rights reserved.
- *
- * $LastChangedDate$
- * $Author$
- * $HeadURL$
- * $Revision$
- *
- */
- #include <allegro.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "ppu.h"
- #include "memory.h"
- #include "M6502.h"
- #define __TINES_PLUGINS__
- #include "plugins.h"
- #define GetTileColor(tile,x1,y1) ( ( ppu.Memory[tile+y1] & (1<<(7-x1)) ) == 0 ? 0 : 1 ) | \
- ( ( ppu.Memory[tile+y1+8] & (1<<(7-x1)) ) == 0 ? 0 : 1<<1 )
- #define GetColor(col) (col&0xFF)
- extern PPU ppu;
- extern BITMAP *Buffer;
- extern unsigned short ScanLine;
- unsigned long BgColor;
- volatile extern int frame;
- volatile extern unsigned long IPS, FPS;
- extern unsigned long ColorPalette[ 8 * 63 ];
- extern short IRQScanHit;
- byte NOBLIT = 0;
- int InitPPU(PPU * ppu)
- {
- int i;
- if ((ppu->Memory = (unsigned char *) malloc(0x4000)) == NULL)
- return -1;
- NOBLIT = 0;
-
- /* Initializing register.. */
- ppu->In_VBlank = 0;
-
- ppu->BaseOneScreen = 0x2000;
-
- ppu->ControlRegister1.b = 0;
- ppu->ControlRegister2.b = 0;
- ppu->StatusRegister.b = 0;
- ppu->SPR_RAMAddr = 0;
- ppu->VRAMAddrReg1.W = 0;
- ppu->VRAMAddrReg2.W = 0;
- ppu->VRAMAddrMode = 0;
- ppu->Bg_Pattern_Table = 0x0000;
- ppu->Name_Table_Addresse = 0x2000;
- ppu->Sprt_Pattern_Table = 0x0000;
- ppu->PPU_Inc = 1;
- ppu->MirrorDir = 0;
- ppu->ScreenType = 1;
- ppu->ForceBgVisibility = 0;
- ppu->ForceSpriteVisibility = 0;
- ppu->DisplayNameTables = ~0;
- ppu->DisplayAttributeTable = ~0;
- ppu->DisplayPalette = ~0;
- ppu->DisplayVRAM = ~0;
- /* Set PPU registers */
- set_page_rd_hook(0x20, ReadPPUReg);
- set_page_wr_hook(0x20, WritePPUReg);
-
- set_page_readable(0x20, true);
- set_page_writeable(0x20, true);
-
-
- /* Set PPU Ghost Registers */
- for(i = 0x21; i < 0x40; i++)
- set_page_ghost(i, true, 0x20);
- plugin_install_keypressHandler('i', DebugSprites);
- plugin_install_keypressHandler('I', DebugSprites);
-
- plugin_install_keypressHandler('u', DebugColor);
- plugin_install_keypressHandler('U', DebugColor);
-
-
-
- return 0;
- }
- PPUSprite PPUGetSprite(unsigned short i)
- {
- PPUSprite ret;
- ret.y = ppu.SPRRAM[i * 4];
- ret.tileid = ppu.SPRRAM[i * 4 + 1];
- /*ret.flags.s.BgPrio = (ppu.SPRRAM[i * 4 + 2] & (1 << 5)) == 0 ? 0 : 1;
- ret.flags.s.HFlip = (ppu.SPRRAM[i * 4 + 2] & (1 << 6)) == 0 ? 0 : 1;
- ret.flags.s.UpperColor = ppu.SPRRAM[i * 4 + 2] & 0x03;
- ret.flags.s.VFlip = (ppu.SPRRAM[i * 4 + 2] & (1 << 7)) == 0 ? 0 : 1;*/
- ret.flags.b = ppu.SPRRAM[i * 4 + 2];
- ret.x = ppu.SPRRAM[i * 4 + 3];
- return ret;
- }
- void PPUSetSprite(unsigned short i, PPUSprite *sprt)
- {
- ppu.SPRRAM[i * 4] = sprt->y;
- ppu.SPRRAM[i * 4 + 1] = sprt->tileid;
- /*ret.flags.s.BgPrio = (ppu.SPRRAM[i * 4 + 2] & (1 << 5)) == 0 ? 0 : 1;
- ret.flags.s.HFlip = (ppu.SPRRAM[i * 4 + 2] & (1 << 6)) == 0 ? 0 : 1;
- ret.flags.s.UpperColor = ppu.SPRRAM[i * 4 + 2] & 0x03;
- ret.flags.s.VFlip = (ppu.SPRRAM[i * 4 + 2] & (1 << 7)) == 0 ? 0 : 1;*/
- ppu.SPRRAM[i * 4 + 2] = sprt->flags.b;
- ppu.SPRRAM[i * 4 + 3] = sprt->x;
- }
- //(Addr & 0x1FF) /* Addr In NT */
- // (Addr & 0xC00) >> 2 /* NT number */
- #define GetNT(a) ( (a&0xC00) >> 10 )
- #define RelAddr(a) (a & 0x3FF)
- #define PalAddr(a) (a & 0x1F)
- unsigned char PPU_Rd(unsigned short Addr)
- {
- if (Addr > (unsigned short) 0x3FFF)
- {
- Addr &= 0x3FFF;
- }
- if ((Addr < 0x3F00) && (Addr >= 0x2000))
- {
- if (Addr > 0x3000)
- {
- Addr -= 0x1000;
- }
- if (ppu.ScreenType == 0)
- { /* 1 Screen Mode */
- return ppu.Memory[RelAddr(Addr) + ppu.BaseOneScreen];
- }
- else
- if (ppu.ScreenType)
- { /* Miroring mode */
- if (ppu.MirrorDir)
- { /* Horizontal */
- if (GetNT(Addr) & 0x2)
- { /* NT2-3 */
- return ppu.Memory[0x2000 + RelAddr(Addr)];
- }
- else
- {
- return ppu.Memory[0x2400 + RelAddr(Addr)];
- }
- }
- else
- { /* Vertical */
- if (GetNT(Addr) & 0x1)
- { /* NT0-2 */
- return ppu.Memory[0x2400 + RelAddr(Addr)];
- }
- else
- {
- return ppu.Memory[0x2000 + RelAddr(Addr)];
- }
- }
- }
- else
- { /* Four Screen mode */
- }
- }
- else
- if (Addr >= 0x3F00)
- {
- return ppu.Memory[0x3F00 | PalAddr(Addr)];
- }
- return ppu.Memory[Addr];
- }
- void PPU_Wr(unsigned short Addr, unsigned char Value)
- {
- if (Addr > (unsigned short) 0x3FFF)
- {
- Addr &= 0x3FFF;
- }
- if ((Addr < 0x3F00) && (Addr >= 0x2000))
- {
- if (Addr > 0x3000)
- {
- Addr -= 0x1000;
- }
- if (ppu.ScreenType == 0)
- { /* 1 Screen Mode */
- ppu.Memory[RelAddr(Addr) + 0x2000] = Value;
- }
- else
- if (ppu.ScreenType == 1)
- { /* Miroring mode */
- if (ppu.MirrorDir == 0)
- { /* Vertical */
- if (GetNT(Addr) & 0x1)
- { /* NT0-2 */
- ppu.Memory[0x2400 + RelAddr(Addr)] = Value;
- }
- else
- {
- ppu.Memory[0x2000 + RelAddr(Addr)] = Value;
- }
- }
- else
- { /* Horizontal */
- if (GetNT(Addr) & 0x2)
- { /* NT2-3 */
- ppu.Memory[0x2000 + RelAddr(Addr)] = Value;
- }
- else
- {
- ppu.Memory[0x2400 + RelAddr(Addr)] = Value;
- }
- }
- }
- else
- { /* Four Screen mode */
- }
- }
- else
- if (Addr >= 0x3F00)
- {
- //console_printf(Console_Default, "%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr);
- ppu.Memory[ /* 0x3F00 | PalAddr(Addr) */ Addr] = Value & 0x3F;
- if (PalAddr(Addr) == 0x10)
- ppu.Memory[0x3F00] = Value & 0x3F;
- }
- else
- {
- ppu.Memory[Addr] = Value;
- }
- }
- unsigned short NbOfSprite[255];
- void NewPPUDispSprite()
- {
- int x, y, x1, y1, px, py, i;
- unsigned long Color;
- PPUSprite sprite;
- unsigned short bg;
- short SprtAddr;
- for (i = 63; i >= 0; i--)
- {
- sprite = PPUGetSprite(i);
- bg = sprite.flags.b & PPUSPRITE_FLAGS_BGPRIO;
-
- y = sprite.y;
- if (y < 248)
- {
- SprtAddr = ((sprite.tileid) << 4) + ppu.Sprt_Pattern_Table;
- x = sprite.x;
-
- for (y1 = 0; y1 < 8; y1++)
- {
- py = y + ((sprite.flags.b & PPUSPRITE_FLAGS_VFLIP) == 0 ? y1 : ((8 - 1) - y1));
- if ((py > 0) && (py < 249) && ((++NbOfSprite[py]) > 7))
- {
- ppu.StatusRegister.b |= PPU_FLAG_SR_8SPRT ;
- //console_printf(Console_Default, "%d Hohoho!\n", py);
- // line(Buffer, 0, py+1, 256, py+1, 10);
- //continue; // Do not display more than 8 sprites on this line :p
- }
- for (x1 = 0; x1 < 8; x1++)
- {
- px = x + ((sprite.flags.b & PPUSPRITE_FLAGS_HFLIP) != 0 ? (7 - x1) : x1);
- Color = GetTileColor(SprtAddr, x1, y1);
- if (Color)
- {
- Color = (Color) | ((sprite.flags.b & PPUSPRITE_FLAGS_UPPERCOLOR) << 2);
- Color = ppu.Memory[0x3F10 + Color];
- if ((i == 0) && (_getpixel(Buffer,px,py) != BgColor) && (ppu.HitSpriteAt == 255))
- {
- //Ligne utilis� pour le d�buguage
- //line(Buffer, 0, py+1, 256, py+1, GetColor(10));
- ppu.HitSpriteAt = py+1;
- }
- if ((bg == 0) || ((bg != 0) && (_getpixel(Buffer,px,py) == BgColor)))
- _putpixel(Buffer, px, py, GetColor(Color));
- }
- }
- }
- }
- }
- }
- void NewPPUDispSprite_8x16()
- {
- int x, y, x1, y1, px, py, i, loop, tile;
- unsigned long Color;
- PPUSprite sprite;
- unsigned short bg;
- short SprtAddr;
-
- unsigned short SprtTable;
-
- for (i = 63; i >= 0; i--)
- {
- sprite = PPUGetSprite(i);
- bg = sprite.flags.b & PPUSPRITE_FLAGS_BGPRIO;
- tile = sprite.tileid;
- y = sprite.y + 1;
- if (y < 248)
- {
- if ( (SprtTable = (tile & 0x1) * 0x1000) == 0x1000)
- tile -=1;
- if ((sprite.flags.b & PPUSPRITE_FLAGS_VFLIP) != 0)
- {
- y +=8;
- }
- for (loop = 0; loop < 2; loop++)
- {
- SprtAddr = ((tile) << 4) + SprtTable;
- x = sprite.x;
-
- for (y1 = 0; y1 < 8; y1++)
- {
- py = y + ((sprite.flags.b & PPUSPRITE_FLAGS_VFLIP) == 0 ? y1 : ((8 - 1) - y1));
- if ((py > 0) && (py < 249) && ((++NbOfSprite[py]) > 7))
- {
- ppu.StatusRegister.b |= PPU_FLAG_SR_8SPRT ;
- // puts("Ho!");
- //continue; // No more sprites on this line :p
- }
- for (x1 = 0; x1 < 8; x1++)
- {
- px = x + (((sprite.flags.b & PPUSPRITE_FLAGS_HFLIP) != 0) ? (7 - x1) : x1);
- Color = GetTileColor(SprtAddr, x1, y1);
- if (Color)
- {
- Color = (Color) | ((sprite.flags.b & PPUSPRITE_FLAGS_UPPERCOLOR) << 2);
- Color = ppu.Memory[0x3F10 + Color];
- if ((i == 0) && (_getpixel(Buffer, px, py) != BgColor) && (ppu.HitSpriteAt == 255))
- {
- //Ligne utilise pour le debuguage
- //line(Buffer, 0, py, 256, py, 10);
- ppu.HitSpriteAt = py+1;
- }
- if ((bg == 0) || ((bg != 0) && (_getpixel(Buffer, px, py) == BgColor)))
- _putpixel(Buffer, px, py, GetColor(Color));
- }
- }
- }
- tile += 1;
- if ( (sprite.flags.b & PPUSPRITE_FLAGS_VFLIP) != 0)
- y -= 8;
- else
- y += 8;
- }
- }
- }
- }
- void DebugColor()
- {
- static unsigned short x = 128;
- static unsigned short y = 128;
- unsigned char OldDisplayPalette = ppu.DisplayPalette;
- byte keyb;
- unsigned int i;
- unsigned long Color;
- NOBLIT = 1;
- ppu.DisplayPalette = ~0;
- while(!key[KEY_ESC])
- {
- frame++;
- PPUVBlank();
- Color = /*Buffer->line[y][x]*/ _getpixel(Buffer, x, y);
- textprintf(Buffer, font, 5, 340, GetColor(3), "Pos [%d:%d] Color: %d Bg: %d", x, y, Color, BgColor);
- line(Buffer, x-10, y, x+10, y, GetColor(1));
- line(Buffer, x, y-10, x, y+10, GetColor(1));
- /*
- rect(Buffer, 0, 255, 4 * 20 + 2, 255 + 4 * 20 + 2, 0);
- rect(Buffer, 90, 255, 90 + 4 * 20 + 2, 255 + 4 * 20 + 2, 0);
- for (i = 0; i < 16; i++)
- {
- rectfill(Buffer, 1 + (i % 4) * 20, 256 + (i / 4) * 20, 1 + (i % 4) * 20 + 20, 256 + (i / 4) * 20 + 20, ppu.Memory[0x3F00 + i]);
- rectfill(Buffer, 91 + (i % 4) * 20, 256 + (i / 4) * 20, 91 + (i % 4) * 20 + 20, 256 + (i / 4) * 20 + 20, ppu.Memory[0x3F10 + i]);
- }*/
- for( i = 0; i < 16; i++)
- {
- if (GetColor(ppu.Memory[0x3F00 + i]) == Color)
- {
- line(Buffer, 1+(i%4)*20, 256 + (i / 4) * 20, 1 + (i % 4) * 20 + 20, 256 + (i / 4) * 20 + 20, 0xFFFFFFFF);
- line(Buffer, 1+(i%4)*20, 256 + (i / 4) * 20 + 20, 1 + (i % 4) * 20 + 20, 256 + (i / 4) * 20, 0xFFFFFFFF);
- }
- if (GetColor(ppu.Memory[0x3F10 + i]) == Color)
- {
- line(Buffer, 91+(i%4)*20, 256 + (i / 4) * 20, 91 + (i % 4) * 20 + 20, 256 + (i / 4) * 20 + 20, 0xFFFFFFFF);
- line(Buffer, 91+(i%4)*20, 256 + (i / 4) * 20 + 20, 91 + (i % 4) * 20 + 20, 256 + (i / 4) * 20, 0xFFFFFFFF);
- }
-
- }
- blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
- if (keypressed())
- {
- keyb = (readkey() & 0xFF);
- if (keyb == '4')
- {
- x--;
- }
- if (keyb == '8')
- {
- y--;
- }
- if (keyb == '6')
- {
- x++;
- }
- if (keyb == '2')
- {
- y++;
- }
- }
- }
- ppu.DisplayPalette = OldDisplayPalette;
- NOBLIT = 0;
- }
- void DebugSprites()
- {
- byte keyb;
- static int SelSprite = 0;
- PPUSprite sprite;
- NOBLIT = 1;
- ppu.ControlRegister2.b |= PPU_CR2_SPRTVISIBILITY;
- while(!key[KEY_ESC])
- {
- frame++;
- PPUVBlank();
- sprite = PPUGetSprite(SelSprite);
- if (ppu.ControlRegister1.b & PPU_CR1_SPRTSIZE)
- {
- rect(Buffer, sprite.x-1, sprite.y-1, sprite.x+9, sprite.y+17, 1);
- }
- else
- {
- rect(Buffer, sprite.x-1, sprite.y-1, sprite.x+9, sprite.y+9, 1);
- }
- textprintf(Buffer, font, 5, 340, GetColor(3), "Sprite %d [%d:%d]", SelSprite, sprite.x, sprite.y);
- textprintf(Buffer, font, 5, 349, GetColor(3), "B0: 0x%X B1: 0x%X B2: 0x%X B3: 0x%X",sprite.y,sprite.tileid,sprite.flags.b,sprite.x);
- textprintf(Buffer, font, 5, 358, GetColor(3), "Tile Index: %d", sprite.tileid);
- textprintf(Buffer, font, 5, 367, GetColor(3), "Vertical Flip: %d", sprite.flags.s.VFlip);
- textprintf(Buffer, font, 5, 376, GetColor(3), "Horizontal Flip: %d", sprite.flags.s.HFlip);
- textprintf(Buffer, font, 5, 385, GetColor(3), "Background Priority: %d", sprite.flags.s.BgPrio);
- textprintf(Buffer, font, 5, 394, GetColor(3), "Upper Color: %d", sprite.flags.s.UpperColor);
- blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
- if (keypressed())
- {
- keyb = (readkey() & 0xFF);
- if (keyb == '+')
- SelSprite = (SelSprite<63)?SelSprite+1:0;
- if (keyb == '-')
- SelSprite = (SelSprite>0)?SelSprite-1:63;
- if (keyb == 'h')
- {
- sprite.flags.s.HFlip = ~sprite.flags.s.HFlip;
- PPUSetSprite(SelSprite, &sprite);
- }
- if (keyb == 'b')
- {
- sprite.flags.s.BgPrio = ~sprite.flags.s.BgPrio;
- PPUSetSprite(SelSprite, &sprite);
- }
- if (keyb == 'v')
- {
- sprite.flags.s.VFlip = ~sprite.flags.s.VFlip;
- PPUSetSprite(SelSprite, &sprite);
- }
- if (keyb == '4')
- {
- sprite.x--;
- PPUSetSprite(SelSprite, &sprite);
- }
- if (keyb == '8')
- {
- sprite.y--;
- PPUSetSprite(SelSprite, &sprite);
- }
- if (keyb == '6')
- {
- sprite.x++;
- PPUSetSprite(SelSprite, &sprite);
- }
- if (keyb == '2')
- {
- sprite.y++;
- PPUSetSprite(SelSprite, &sprite);
- }
- }
- }
- NOBLIT = 0;
- }
- #define GetTilePos(addr,x,y) (addr+x+(y*32))
- void ppu_displayNameTables()
- {
- int x, y, x1, y1, i;
- unsigned long Reg2;
- unsigned short ab_x, ab_y;
- unsigned short Color;
- unsigned short AttrByte;
- unsigned short TileID;
- if (ppu.DisplayAttributeTable)
- {
- /* NT 2000 */
- for (x = 0; x < 0x40; x++)
- {
- AttrByte = /*ppu.Memory[0x23C0 + x];*/PPU_Rd(0x23C0 + x);
- x1 = x % 8;
- y1 = x / 8;
-
-
- Color = AttrByte & 0x3; // Pattern 1;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+(x1*32),240+(y1*32),256+15+(x1*32),240+15+(y1*32),Color);
-
- Color = (AttrByte>>2) & 0x3; // Pattern 2;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+(x1*32),240+(y1*32),16+256+15+(x1*32),240+15+(y1*32),Color);
-
- Color = (AttrByte>>4) & 0x3; // Pattern 3;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+(x1*32),16+240+(y1*32),256+15+(x1*32),16+240+15+(y1*32),Color);
-
- Color = (AttrByte>>6) & 0x3; // Pattern 4;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+(x1*32),16+240+(y1*32),16+256+15+(x1*32),16+240+15+(y1*32),Color);
- }
- /* NT 2800 */
- for (x = 0; x < 0x40; x++)
- {
- AttrByte = PPU_Rd(0x2BC0 + x);
- x1 = x % 8;
- y1 = x / 8;
-
-
- Color = AttrByte & 0x3; // Pattern 1;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+(x1*32),(y1*32),256+15+(x1*32),15+(y1*32),Color);
-
- Color = (AttrByte>>2) & 0x3; // Pattern 2;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+(x1*32),(y1*32),16+256+15+(x1*32),15+(y1*32),Color);
-
- Color = (AttrByte>>4) & 0x3; // Pattern 3;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+(x1*32),16+(y1*32),256+15+(x1*32),16+15+(y1*32),Color);
-
- Color = (AttrByte>>6) & 0x3; // Pattern 4;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+(x1*32),16+(y1*32),16+256+15+(x1*32),16+15+(y1*32),Color);
- }
-
- /* NT 2400 */
- for (x = 0; x < 0x40; x++)
- {
- AttrByte = PPU_Rd(0x27C0 + x);
- x1 = x % 8;
- y1 = x / 8;
-
-
- Color = AttrByte & 0x3; // Pattern 1;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+256+(x1*32),240+(y1*32),256+256+15+(x1*32),240+15+(y1*32),Color);
-
- Color = (AttrByte>>2) & 0x3; // Pattern 2;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+256+(x1*32),240+(y1*32),16+256+256+15+(x1*32),240+15+(y1*32),Color);
-
- Color = (AttrByte>>4) & 0x3; // Pattern 3;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+256+(x1*32),240+16+(y1*32),256+256+15+(x1*32),240+16+15+(y1*32),Color);
-
- Color = (AttrByte>>6) & 0x3; // Pattern 4;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+256+(x1*32),240+16+(y1*32),16+256+256+15+(x1*32),240+16+15+(y1*32),Color);
- }
- /* NT 2C00 */
- for (x = 0; x < 0x40; x++)
- {
- AttrByte = PPU_Rd(0x2FC0 + x);//PPU_Rd(0x27C0 + x);
- x1 = x % 8;
- y1 = x / 8;
-
-
- Color = AttrByte & 0x3; // Pattern 1;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+256+(x1*32),(y1*32),256+256+15+(x1*32),15+(y1*32),Color);
-
- Color = (AttrByte>>2) & 0x3; // Pattern 2;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+256+(x1*32),(y1*32),16+256+256+15+(x1*32),15+(y1*32),Color);
-
- Color = (AttrByte>>4) & 0x3; // Pattern 3;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,256+256+(x1*32),16+(y1*32),256+256+15+(x1*32),16+15+(y1*32),Color);
-
- Color = (AttrByte>>6) & 0x3; // Pattern 4;
- if (ppu.DisplayNameTables == 0)
- Color = ppu.Memory[0x3F00 + (Color * 4) + 1];
-
- rectfill(Buffer,16+256+256+(x1*32),16+(y1*32),16+256+256+15+(x1*32),16+15+(y1*32),Color);
- }
- if (ppu.DisplayNameTables == 0)
- {
- for (x = 0; x < 33; x++)
- {
- line(Buffer, 256 + x * 16, 0, 256 + x * 16, 240 + 240, 8);
- line(Buffer, 256, 0 + x * 16, 256 + 256 + 256, 0 + x * 16, 8);
- }
- for (x = 0; x < 17; x++)
- {
- line(Buffer, 256 + x * 32, 0, 256 + x * 32, 240 + 240, 6);
- line(Buffer, 256, 0 + x * 32, 256 + 256 + 256, 0 + x * 32, 6);
- }
- }
- }
- if (ppu.DisplayNameTables)
- {
- /* NT 2000 */
- for (x = 0; x < 32; x++)
- for (y = 0; y < 30; y++)
- {
- TileID = (PPU_Rd/*ppu.Memory[*/(0x2000 + x + (y * 32))/*]*/ << 4) + ppu.Bg_Pattern_Table;
- for (x1 = 0; x1 < 8; x1++)
- for (y1 = 0; y1 < 8; y1++)
- {
- Color = GetTileColor(TileID, x1, y1);
- if (ppu.DisplayAttributeTable != 0)
- Color |= (Buffer->line[(8 * y) + 240 + y1][(8 * x) + 256 + x1] & 0x3) << 2;
- if ((Color != 0) || (ppu.DisplayAttributeTable != 0))
- {
- Color = ppu.Memory[0x3F00 + Color];
- Buffer->line[(8 * y) + 240 + y1][(8 * x) + 256 + x1] = Color;
- }
- }
- }
- /* NT 2800 */
- for (x = 0; x < 32; x++)
- for (y = 0; y < 30; y++)
- {
- TileID = (PPU_Rd(0x2800 + x + (y * 32)) << 4) + ppu.Bg_Pattern_Table;
- for (x1 = 0; x1 < 8; x1++)
- for (y1 = 0; y1 < 8; y1++)
- {
- Color = GetTileColor(TileID, x1, y1);
- if (Color != 0)
- {
- Color = ppu.Memory[0x3F00 + Color + 4];
- Buffer->line[(8 * y) + y1][(8 * x) + 256 + x1] = Color;
- }
- }
- }
- /* NT 2400 */
- for (x = 0; x < 32; x++)
- for (y = 0; y < 30; y++)
- {
- TileID = (PPU_Rd(0x2400 + x + (y * 32)) << 4) + ppu.Bg_Pattern_Table;
-
- for (x1 = 0; x1 < 8; x1++)
- for (y1 = 0; y1 < 8; y1++)
- {
- Color = GetTileColor(TileID, x1, y1);
- if (ppu.DisplayAttributeTable != 0)
- Color |= (Buffer->line[(8 * y) + 240 + y1][(8 * x) + 256 + x1] & 0x3) << 2;
-
- if ((Color != 0) || (ppu.DisplayAttributeTable != 0))
- {
- Color = ppu.Memory[0x3F00 + Color];
- Buffer->line[(8 * y) + 240+ y1][(8 * x) + 256 + 256 + x1] = Color;
- }
- }
- }
- /* NT 2C00 */
- for (x = 0; x < 32; x++)
- for (y = 0; y < 30; y++)
- {
- TileID = (PPU_Rd(0x2C00 + x + (y * 32)) << 4) + ppu.Bg_Pattern_Table;
- for (x1 = 0; x1 < 8; x1++)
- for (y1 = 0; y1 < 8; y1++)
- {
- Color = GetTileColor(TileID, x1, y1);
- if (Color != 0)
- {
- Color = ppu.Memory[0x3F00 + Color + 12];
- Buffer->line[(8 * y) + y1][(8 * x) + 256 + 256 + x1] = Color;
- }
- }
- }
- }
- }
- int
- PPUVBlank()
- {
- int x, y, x1, y1, i;
- unsigned long Reg2;
- unsigned short ab_x, ab_y;
- unsigned long Color;
- unsigned short AttrByte;
- unsigned short TileID;
- static short LAST_FPS = 0;
- unsigned char XScroll, YScroll;
- ppu.StatusRegister.b |= PPU_FLAG_SR_VBLANK;
-
- BgColor = ppu.Memory[0x3F00];//0xC0;
- //goto NoDraw;
- acquire_bitmap(Buffer);
-
- clear_to_color(Buffer, GetColor(BgColor));
- ppu_displayNameTables();
- if (ppu.ControlRegister2.s.Colour != 0)
- console_printf(Console_Default, "ppu.ColorEmphasis : %d\n", ppu.ControlRegister2.s.Colour);
- for (i = 0; i < 249; i++)
- NbOfSprite[i] = 0;
- ppu.StatusRegister.b &= ~(PPU_FLAG_SR_8SPRT);
- ppu.HitSpriteAt = 255;
- /*
- * A faires les choses qui faut faire durant un lanc� de vblank,
- * comme dessiner par ex..
- */
- if (((ppu.ControlRegister2.b & PPU_CR2_BGVISIBILITY) != 0) || ppu.ForceBgVisibility)
- {
- /* Display BG with scrolling informations */
- /* J'ai la solution :D */
- /*
- frame start (line 0) (if background or sprites are enabled):
- v=t
- */
- ppu.VRAMAddrReg2.W = ppu.TimedTmpPtr[0]|0x2000;
- //console_printf(Console_Default, "Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W);
- YScroll = ppu.TmpVScroll;
- for (y = 0; y < 240; y++)
- {
- /*
- scanline start (if background and sprites are enabled):
- 8421 8421 8421 8421 8421 8421 8421 8421
- v:0000 0100 0001 1111=t:0000 0100 0001 1111
- 1111 1198 7654 3210
- 5432 10
- */
- if ((y == IRQScanHit)||(y == IRQScanHit + 1))
- console_printf(Console_Default, "%s: IRQ Hit : bf Reg2: 0x%04X\n", __func__, ppu.VRAMAddrReg2.W);
- #define PPU_SSCAN_MASK 0x041F
- ppu.VRAMAddrReg2.W = (ppu.VRAMAddrReg2.W & (~PPU_SSCAN_MASK))
- | (ppu.TimedTmpPtr[y] & PPU_SSCAN_MASK )
- | 0x2000;
- TileID = (PPU_Rd(ppu.VRAMAddrReg2.W) << 4)
- | ppu.Bg_Pattern_Table;
- XScroll = ppu.TimedHScroll[y];
- if (y == IRQScanHit)
- console_printf(Console_Default, "%s: IRQ Hit : Reg2: 0x%04X TmpPtr:0x%04X \n", __func__, ppu.VRAMAddrReg2.W, ppu.TimedTmpPtr[y]);
- if (y == IRQScanHit + 1)
- console_printf(Console_Default, "%s: IRQ Hit + 1: Reg2: 0x%04X TmpPtr:0x%04X \n", __func__, ppu.VRAMAddrReg2.W, ppu.TimedTmpPtr[y]);
-
- for (x = 0; x < 256; x++)
- {
- /* Calculer la couleur du point */
- /* Bits 1 et 0 */
- Color = GetTileColor(TileID, XScroll, YScroll);
- /* Bits 3 et 2 */
- /*
- XScroll : 0,1,2,3,4
- X = (ppu.VRAMAddrReg2.W & 0x1F)
- Y : 5,6,7,8,9
- Y = (ppu.VRAMAddrReg2.W & 0x3E0) >> 5
- */
- /*ab_y = ((ppu.VRAMAddrReg2.W & 0x3E0) >> 5);
- ab_x = (ppu.VRAMAddrReg2.W & 0x1F);
- AttrByte = (((ab_y) >> 2) << 3) +
- ((ab_x) >> 2);
- AttrByte = (PPU_Rd((ppu.VRAMAddrReg2.W & 0x2C00) + 0x3C0 + AttrByte) >>
- ((((ab_y & 2) * 2) + (((ppu.VRAMAddrReg2.W & 0x2C00)) & 2)))) & 0x03;*/
-
- /*
-
- 00DC BA98 7654 3210
-
- 0000 BA54 3c-2 10b-
- 0000 0000 0001 1100 : 0x001C >> 2
- 0000 0011 1000 0000 : 0x0380 >> 4
-
- 10 --11 11-- ----
-
- 0xC000
- & 0x0C3F | 0x23C0
-
- b
- val >> ( (Reg2 & 0x2) | ( (Reg2 & 0x0x40)>>4)
- */
-
- Reg2 = ppu.VRAMAddrReg2.W;
- AttrByte = ((Reg2 & 0x0380) >> 4) | ((Reg2 & 0x001C) >> 2) | (Reg2 & 0x0C00);
- AttrByte &= 0x0C3F;
- AttrByte |= 0x23C0;
- AttrByte = PPU_Rd(AttrByte);
- AttrByte = AttrByte >> ( 0x0 | (Reg2 & 0x02) | ( (Reg2 & 0x40) >> 4) );
- AttrByte &= 0x3;
-
- if (Color)
- {
- Color |= (AttrByte << 2);
- Color = ppu.Memory[0x3F00 + Color];
- _putpixel(Buffer, x,y, GetColor(Color));
- }
-
- XScroll++;
- XScroll &= 7;
- if (XScroll == 0)
- { /* On incr�mente le compteur de tile */
- if ((ppu.VRAMAddrReg2.W & 0x1F) == 0x1F)
- { /* On met a 0 et change
- * l'etat du bit 10 */
- ppu.VRAMAddrReg2.W &= ~0x1F;
- /* A voir si ya pas bcp mieux */
- /* if ((ppu.VRAMAddrReg2.W & 0x400))
- ppu.VRAMAddrReg2.W &= ~0x400;
- else
- ppu.VRAMAddrReg2.W |= 0x400;*/
- ppu.VRAMAddrReg2.W ^= 0x400;
- }
- else
- { /* on incremente juste */
- ppu.VRAMAddrReg2.W = (ppu.VRAMAddrReg2.W & ~0x1F) | ((ppu.VRAMAddrReg2.W + 1) & 0x1F);
- }
- TileID = (PPU_Rd(ppu.VRAMAddrReg2.W) << 4)
- | ppu.Bg_Pattern_Table;
- }
- }
- /*
- you can think of bits 5,6,7,8,9 as the "y scroll"(*8). this functions
- slightly different from the X. it wraps to 0 and bit 11 is switched when
- it's incremented from _29_ instead of 31. there are some odd side effects
- from this.. if you manually set the value above 29 (from either 2005 or
- 2006), the wrapping from 29 obviously won't happen, and attrib data will be
- used as name table data. the "y scroll" still wraps to 0 from 31, but
- without switching bit 11. this explains why writing 240+ to 'Y' in 2005
- appeared as a negative scroll value.
- 8421 8421 8421 8421
- v:0000 0011 1110 0000
- 1111 1198 7654 3210
- 5432 10
- */
- YScroll++;
- YScroll &= 7;
- if (YScroll == 0)
- { /* On incr�mente le compteur de tile */
- if ((ppu.VRAMAddrReg2.W & 0x3E0) == (29<<5))
- { /* On met a 0 et change l'etat du bit 11 */
- ppu.VRAMAddrReg2.W &= ~0x3E0;
- /* A voir si ya pas bcp mieux */
- /* if ((ppu.VRAMAddrReg2.W & 0x800))
- ppu.VRAMAddrReg2.W &= ~0x800;
- else
- ppu.VRAMAddrReg2.W |= 0x800;*/
-
- ppu.VRAMAddrReg2.W ^= 0x800;
- }
- else
- { /* on incremente juste */
- ppu.VRAMAddrReg2.W = (ppu.VRAMAddrReg2.W & (~0x3F0))
- | ((((ppu.VRAMAddrReg2.W & 0x3F0) >> 5) + 1) << 5);
- }
- }
- }
- //while (!key[KEY_ENTER]);
- }
- /*
- * if (ppu.ControlRegister2.s.SpriteVisibility == 1)
- * PPUDispSprite(0);
- */
- if (((ppu.ControlRegister2.b & PPU_CR2_SPRTVISIBILITY) != 0) || ppu.ForceSpriteVisibility)
- {
- if (ppu.ControlRegister1.b & PPU_CR1_SPRTSIZE)
- {
- NewPPUDispSprite_8x16();
- }
- else
- {
- NewPPUDispSprite();
- }
- }
- if (ppu.DisplayPalette)
- {
- textout(Buffer, font, "Bg Palette", 0, 247, 5);
- textout(Buffer, font, "Sprt Palette", 90, 247, 5);
- rect(Buffer, 0, 255, 4 * 20 + 2, 255 + 4 * 20 + 2, GetColor(0));
- rect(Buffer, 90, 255, 90 + 4 * 20 + 2, 255 + 4 * 20 + 2, GetColor(0));
- for (i = 0; i < 16; i++)
- {
- rectfill(Buffer, 1 + (i % 4) * 20, 256 + (i / 4) * 20, 1 + (i % 4) * 20 + 20, 256 + (i / 4) * 20 + 20, GetColor(ppu.Memory[0x3F00 + i]));
- rectfill(Buffer, 91 + (i % 4) * 20, 256 + (i / 4) * 20, 91 + (i % 4) * 20 + 20, 256 + (i / 4) * 20 + 20, GetColor(ppu.Memory[0x3F10 + i]));
- }
- }
- if (ppu.DisplayVRAM)
- {
- /* y:346 */
- x1 = 0;
- y1 = 0;
- for (i = 0; i < 256; i++)
- {
- TileID = 0x0000 + (i << 4);
- for (x = 0; x < 8; x++)
- for (y = 0; y < 8; y++)
- {
- Color = GetTileColor(TileID, x, y);
- _putpixel(Buffer, 10 + x1 + x, 347 + y1 + y, GetColor(ppu.Memory[0x3F00 + Color]));
- }
- x1 += 8;
- if (x1 >= 128)
- {
- x1 = 0;
- y1 += 8;
- }
- }
- x1 = 0;
- y1 = 0;
- for (i = 0; i < 256; i++)
- {
- TileID = 0x1000 + (i << 4);
- for (x = 0; x < 8; x++)
- for (y = 0; y < 8; y++)
- {
- Color = GetTileColor(TileID, x, y);
- _putpixel(Buffer, 10 + 128 + x1 + x, 347 + y1 + y, GetColor(ppu.Memory[0x3F10 + Color]) );
- }
- x1 += 8;
- if (x1 >= 128)
- {
- x1 = 0;
- y1 += 8;
- }
- }
- }
- for (i = 0; i < 240; i++)
- {
- _putpixel(Buffer, 257 + 0, i, 48);
-
- _putpixel(Buffer, 257 + 1, i, ((ppu.TimedTmpPtr[y]*4))&0xFF);
- _putpixel(Buffer, 257 + 2, i, ((ppu.TimedTmpPtr[y]*4)>>8)&0xFF);
- _putpixel(Buffer, 257 + 3, i, ((ppu.TimedTmpPtr[y]*4)>>16)&0xFF);
-
- _putpixel(Buffer, 257 + 4, i, ((ppu.TmpVScroll*4))&0xFF);
- _putpixel(Buffer, 257 + 5, i, ((ppu.TmpVScroll*4)>>8)&0xFF);
- _putpixel(Buffer, 257 + 6, i, ((ppu.TmpVScroll*4)>>16)&0xFF);
-
- _putpixel(Buffer, 257 + 7, i, ((ppu.TimedHScroll[i]*4)) & 0xFF);
- _putpixel(Buffer, 257 + 8, i, ((ppu.TimedHScroll[i]*4)>>8) & 0xFF);
- _putpixel(Buffer, 257 + 9, i, ((ppu.TimedHScroll[i]*4)>>16)& 0xFF);
- _putpixel(Buffer, 257 + 10, i, 48);
-
- }
-
- if (IRQScanHit != -1)
- {
- line(Buffer, 257+12, IRQScanHit, 257+22, IRQScanHit, 10);
- line(Buffer, 257+12, IRQScanHit, 257+18, IRQScanHit-3, 10);
- line(Buffer, 257+12, IRQScanHit, 257+18, IRQScanHit+3, 10);
- }
- NoDraw:
- textprintf(Buffer, font, 5, 340, GetColor(4), "FPS : %d IPS : %d", FPS, IPS);
- textprintf(Buffer, font, 5, 3, GetColor(4), "FPS : %d (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0));
-
- release_bitmap(Buffer);
- if (NOBLIT == 0)
- {
- blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
- //stretch_blit(Buffer, screen, 0, 0, 256, 240, 0, 0, 512, 480);
- }
- if ((ppu.ControlRegister1.b & PPU_CR1_EXECNMI) != 0)
- return 1;
- return 0;
- }
- byte ReadPPUReg(byte RegID)
- {
- /* RegID is the nb of the reg 0-7 */
- unsigned char ret;
- RegID &= 0x07;
-
- switch (RegID)
- {
- default:
- ret = (unsigned char) 0x00; /* Can return every thing you
- * want here :D */
- break;
- case 1: /* Control Register 2 */
- ret = ppu.ControlRegister2.b;
- break;
- case 2:
- ret = ppu.StatusRegister.b;
- ppu.StatusRegister.b &= ~(PPU_FLAG_SR_VBLANK);
-
- ppu.StatusRegister.b &= ~(PPU_FLAG_SR_SPRT0);
- ppu.VRAMAddrMode = 0;
- break;
- case 5:
- ret = ppu.VRAMAddrReg2.B.l;
- break;
- case 6:
- ret = ppu.VRAMAddrReg2.B.h;
- break;
- case 7: /* PPU in NES is really strange.. Bufferised
- * send is weird.. */
- if (ppu.VRAMAddrReg2.W < 0x3EFF)
- {
- ret = ppu.VRAMBuffer;
- ppu.VRAMBuffer = PPU_Rd(ppu.VRAMAddrReg2.W);
- ppu.VRAMAddrReg2.W += ppu.PPU_Inc;
- ppu.VRAMAddrReg2.W &= 0x3FFF;
- }
- else
- {
- ret = PPU_Rd(ppu.VRAMAddrReg2.W);
- ppu.VRAMAddrReg2.W += ppu.PPU_Inc;
- }
- break;
- }
- return ret;
- }
- void WritePPUReg(byte RegID, byte val)
- {
- /* RegID is the nb of the reg 0-7 */
- RegID &= 0x07;
- switch (RegID)
- {
- default:/* For not writeable reg */
- console_printf(Console_Default, "WritePPU error\n");
- break;
- case 0: /* Control Register 1 */
- ppu.ControlRegister1.b = val;
- ppu.Bg_Pattern_Table = (ppu.ControlRegister1.s.BgPattern == 1) ? 0x1000 : 0x0000;
- ppu.Sprt_Pattern_Table = (ppu.ControlRegister1.s.SptPattern == 1) ? 0x1000 : 0x0000;
- ppu.PPU_Inc = (ppu.ControlRegister1.s.AddrIncrmt == 1) ? 32 : 1;
- ppu.Name_Table_Addresse = 0x2000;
- switch (ppu.ControlRegister1.s.NameTblAddr)
- {
- case 3:
- ppu.Name_Table_Addresse += 0x400;
- case 2:
- ppu.Name_Table_Addresse += 0x400;
- case 1:
- ppu.Name_Table_Addresse += 0x400;
- case 0:
- break;
- }
- ppu.TimedNT[ScanLine] = ppu.ControlRegister1.s.NameTblAddr;
- /*
- 2000 write:
- 1111 0011 1111 1111 ( F3FF )
- t:0000 1100 0000 0000 = d:0000 0011
- */
- ppu.TmpVRamPtr = ( (ppu.TmpVRamPtr & 0xF3FF)
- | ( (ppu.ControlRegister1.s.NameTblAddr & 0x03) << 10 )
- );
-
- break;
- case 1: /* Control Register 2 */
- //console_printf(Console_Default, "PPU: new CR2 ; 0x%x\n", val);
- ppu.ControlRegister2.b = val;
- break;
- case 3: /* SPR-RAM Addresse Register */
- ppu.SPR_RAMAddr = val;
- break;
- case 4: /* SPR-RAM Input Register */
- ppu.SPRRAM[ppu.SPR_RAMAddr] = val;
- break;
- case 5: /* VRAM Address register 1 */
- if (ppu.VRAMAddrMode == 0)
- {
- /*
- 2005 first write:
- t:0000 0000 0001 1111=d:1111 1000
- x=d:00000111
- */
- //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
- ppu.VRAMAddrMode = 1;
- ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFFE0) | ((val & 0xF8) >> 3));
- ppu.HScroll = val & 0x7;
- //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
- //console_printf(Console_Default, "%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val);
- }
- else
- {
- /*
- 2005 second write:
- 1111 1100 0000 0000
- 5432 1098 7654 3210
-
- 8421 8421 8421 8421
- -------------------
- t:0000 0011 1110 0000=d:1111 1000
- t:0111 0000 0000 0000=d:0000 0111
- */
- //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
- ppu.VRAMAddrMode = 0;
- ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & ~(0x03E0)) | ((val & 0xF8) << 2));
- ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0x8FFF ) | ((val & 0x07) << 12));
- ppu.TmpVScroll = (val & 0x7);
- //if (ppu.TmpVScroll != 0)
- //console_printf(Console_Default, "2002: TmpVScroll == %d \n", ppu.TmpVScroll);
- //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
-
- //console_printf(Console_Default, "%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val);
- }
- break;
- case 6: /* VRAM Address register 2 */
- if (ppu.VRAMAddrMode == 0)
- {
- //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
- ppu.VRAMAddrMode = 1;
- /*
- 2006 first write:
- t:0011 1111 0000 0000 = d:0011 1111
- t:1100 0000 0000 0000=0
- */
- ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0x00FF) | ((val&0x3F) << 8));
- //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
-
- //console_printf(Console_Default, "%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val);
- }
- else
- {
- //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
- ppu.VRAMAddrMode = 0;
- /*
- 2006 second write:
- t:0000000011111111=d:11111111
- v=t
- */
- ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFF00) | (val & 0x00FF));
- ppu.VRAMAddrReg2.W = ppu.TmpVRamPtr;
- //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr);
- //console_printf(Console_Default, "%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val);
- }
- break;
- case 7: /* VRAM I/O */
- PPU_Wr(ppu.VRAMAddrReg2.W, val);
- ppu.VRAMAddrReg2.W += ppu.PPU_Inc;
- break;
- }
- }
- void FillSprRamDMA(byte value)
- {
- int i;
- for (i = 0x00; i < 0x100; i++)
- {
- ppu.SPRRAM[i] = ReadMemory( value, i);
- }
- }
|