BizHawk/waterbox/ngp/gfx.cpp

475 lines
8.7 KiB
C++

//---------------------------------------------------------------------------
// NEOPOP : Emulator as in Dreamland
//
// Copyright (c) 2001-2002 by neopop_uk
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
#include "neopop.h"
#include "mem.h"
#include "gfx.h"
#include "interrupt.h"
#include "dma.h"
namespace MDFN_IEN_NGP
{
NGPGFX_CLASS::NGPGFX_CLASS(void)
{
layer_enable_setting = 1 | 2 | 4;
for (int x = 0; x < 4096; x++)
{
int r = (x & 0xF) * 17;
int g = ((x >> 4) & 0xF) * 17;
int b = ((x >> 8) & 0xF) * 17;
ColorMap[x] = b | g << 8 | r << 16 | 0xff000000;
}
}
NGPGFX_CLASS::~NGPGFX_CLASS()
{
}
void NGPGFX_CLASS::reset(void)
{
memset(SPPLT, 0x7, sizeof(SPPLT));
memset(SCRP1PLT, 0x7, sizeof(SCRP1PLT));
memset(SCRP2PLT, 0x7, sizeof(SCRP2PLT));
raster_line = 0;
S1SO_H = 0;
S1SO_V = 0;
S2SO_H = 0;
S2SO_V = 0;
WBA_H = 0;
WBA_V = 0;
WSI_H = 0xFF;
WSI_V = 0xFF;
C_OVR = 0;
BLNK = 0;
PO_H = 0;
PO_V = 0;
P_F = 0;
BG_COL = 0x7;
CONTROL_2D = 0;
CONTROL_INT = 0;
SCREEN_PERIOD = 0xC6;
K2GE_MODE = 0;
delayed_settings();
}
void NGPGFX_CLASS::power(void)
{
reset();
memset(ScrollVRAM, 0, sizeof(ScrollVRAM));
memset(CharacterRAM, 0, sizeof(CharacterRAM));
memset(SpriteVRAM, 0, sizeof(SpriteVRAM));
memset(SpriteVRAMColor, 0, sizeof(SpriteVRAMColor));
memset(ColorPaletteRAM, 0, sizeof(ColorPaletteRAM));
}
void NGPGFX_CLASS::delayed_settings(void)
{
//Window dimensions
winx = WBA_H;
winy = WBA_V;
winw = WSI_H;
winh = WSI_V;
//Scroll Planes (Confirmed delayed)
scroll1x = S1SO_H;
scroll1y = S1SO_V;
scroll2x = S2SO_H;
scroll2y = S2SO_V;
//Sprite offset (Confirmed delayed)
scrollsprx = PO_H;
scrollspry = PO_V;
//Plane Priority (Confirmed delayed)
planeSwap = P_F & 0x80;
//Background colour register (Confirmed delayed)
bgc = BG_COL;
//2D Control register (Confirmed delayed)
oowc = CONTROL_2D & 7;
negative = CONTROL_2D & 0x80;
}
bool NGPGFX_CLASS::hint(void)
{
//H_Int / Delayed settings
if ((raster_line < SCREEN_HEIGHT - 1 || raster_line == SCREEN_PERIOD))
{
delayed_settings(); //Get delayed settings
//Allowed?
if (CONTROL_INT & 0x40)
return (1);
}
return (0);
}
bool NGPGFX_CLASS::draw(MDFN_Surface *surface, bool skip)
{
bool ret = 0;
//Draw the scanline
if (raster_line < SCREEN_HEIGHT && !skip)
{
if (!K2GE_MODE)
draw_scanline_colour(layer_enable_setting, raster_line);
else
draw_scanline_mono(layer_enable_setting, raster_line);
uint32 *dest = surface->pixels + surface->pitch32 * raster_line;
for (int x = 0; x < SCREEN_WIDTH; x++)
dest[x] = ColorMap[cfb_scanline[x] & 4095];
}
raster_line++;
//V_Int?
if (raster_line == SCREEN_HEIGHT)
{
BLNK = 1;
ret = 1;
if (CONTROL_INT & 0x80) // (statusIFF() <= 4
TestIntHDMA(5, 0x0B);
}
//End of V_Int
if (raster_line == SCREEN_PERIOD + 1) //Last scanline + 1
{
raster_line = 0;
C_OVR = 0;
BLNK = 0;
}
return (ret);
}
void NGPGFX_CLASS::SetLayerEnableMask(uint64 mask)
{
layer_enable_setting = mask;
}
//extern uint32 ngpc_soundTS;
void NGPGFX_CLASS::write8(uint32 address, uint8 data)
{
//if(address >= 0x8032 && address <= 0x8035)
// printf("%08x %02x %d\n", address, data, ngpc_soundTS);
if (address >= 0x9000 && address <= 0x9fff)
ScrollVRAM[address - 0x9000] = data;
else if (address >= 0xa000 && address <= 0xbfff)
CharacterRAM[address - 0xa000] = data;
else if (address >= 0x8800 && address <= 0x88ff)
SpriteVRAM[address - 0x8800] = data;
else if (address >= 0x8c00 && address <= 0x8c3f)
SpriteVRAMColor[address - 0x8c00] = data & 0x0f;
else if (address >= 0x8200 && address <= 0x83ff)
ColorPaletteRAM[address - 0x8200] = data;
else
switch (address)
{
//default: printf("HuhW: %08x\n", address); break;
case 0x8000:
CONTROL_INT = data & 0xC0;
break;
case 0x8002:
WBA_H = data;
break;
case 0x8003:
WBA_V = data;
break;
case 0x8004:
WSI_H = data;
break;
case 0x8005:
WSI_V = data;
break;
case 0x8006:
SCREEN_PERIOD = data;
break;
case 0x8012:
CONTROL_2D = data & 0x87;
break;
case 0x8020:
PO_H = data;
break;
case 0x8021:
PO_V = data;
break;
case 0x8030:
P_F = data & 0x80;
break;
case 0x8032:
S1SO_H = data;
break;
case 0x8033:
S1SO_V = data;
break;
case 0x8034:
S2SO_H = data;
break;
case 0x8035:
S2SO_V = data;
break;
case 0x8101:
SPPLT[0] = data & 0x7;
break;
case 0x8102:
SPPLT[1] = data & 0x7;
break;
case 0x8103:
SPPLT[2] = data & 0x7;
break;
case 0x8105:
SPPLT[3] = data & 0x7;
break;
case 0x8106:
SPPLT[4] = data & 0x7;
break;
case 0x8107:
SPPLT[5] = data & 0x7;
break;
case 0x8109:
SCRP1PLT[0] = data & 0x7;
break;
case 0x810a:
SCRP1PLT[1] = data & 0x7;
break;
case 0x810b:
SCRP1PLT[2] = data & 0x7;
break;
case 0x810d:
SCRP1PLT[3] = data & 0x7;
break;
case 0x810e:
SCRP1PLT[4] = data & 0x7;
break;
case 0x810f:
SCRP1PLT[5] = data & 0x7;
break;
case 0x8111:
SCRP2PLT[0] = data & 0x7;
break;
case 0x8112:
SCRP2PLT[1] = data & 0x7;
break;
case 0x8113:
SCRP2PLT[2] = data & 0x7;
break;
case 0x8115:
SCRP2PLT[3] = data & 0x7;
break;
case 0x8116:
SCRP2PLT[4] = data & 0x7;
break;
case 0x8117:
SCRP2PLT[5] = data & 0x7;
break;
case 0x8118:
BG_COL = data & 0xC7;
break;
case 0x87e0:
if (data == 0x52)
{
puts("GEreset");
reset();
}
break;
case 0x87e2:
K2GE_MODE = data & 0x80;
break;
}
}
void NGPGFX_CLASS::write16(uint32 address, uint16 data)
{
write8(address, data & 0xFF);
write8(address + 1, data >> 8);
}
#if 0
namespace TLCS900H
{
extern uint32 pc;
};
#endif
uint8 NGPGFX_CLASS::read8(uint32 address)
{
#if 0
if(address >= 0x8200 && address <= 0xbfff)
{
printf("[GFX] Read8: %08x -- %08x\n", address, TLCS900H::pc);
if(pc == 0x0028dd3d) //21)
{
TLCS900H::pc = 0x28DD15;
for(int x = 0; x < 256; x++)
puts(TLCS900h_disassemble());
abort();
}
}
#endif
if (address >= 0x9000 && address <= 0x9fff)
return (ScrollVRAM[address - 0x9000]);
else if (address >= 0xa000 && address <= 0xbfff)
return (CharacterRAM[address - 0xa000]);
else if (address >= 0x8800 && address <= 0x88ff)
return (SpriteVRAM[address - 0x8800]);
else if (address >= 0x8c00 && address <= 0x8c3f)
return (SpriteVRAMColor[address - 0x8c00]);
else if (address >= 0x8200 && address <= 0x83ff)
return (ColorPaletteRAM[address - 0x8200]);
else
switch (address)
{
//default: printf("Huh: %08x\n", address); break;
case 0x8000:
return (CONTROL_INT);
case 0x8002:
return (WBA_H);
case 0x8003:
return (WBA_V);
case 0x8004:
return (WSI_H);
case 0x8005:
return (WSI_V);
case 0x8006:
return (SCREEN_PERIOD);
case 0x8008:
return ((uint8)((abs(TIMER_HINT_RATE - (int)timer_hint)) >> 2)); //RAS.H read (Simulated horizontal raster position)
case 0x8009:
return (raster_line);
case 0x8010:
return ((C_OVR ? 0x80 : 0x00) | (BLNK ? 0x40 : 0x00));
case 0x8012:
return (CONTROL_2D);
case 0x8020:
return (PO_H);
case 0x8021:
return (PO_V);
case 0x8030:
return (P_F);
case 0x8032:
return (S1SO_H);
case 0x8033:
return (S1SO_V);
case 0x8034:
return (S2SO_H);
case 0x8035:
return (S2SO_V);
case 0x8101:
return (SPPLT[0]);
break;
case 0x8102:
return (SPPLT[1]);
break;
case 0x8103:
return (SPPLT[2]);
break;
case 0x8105:
return (SPPLT[3]);
break;
case 0x8106:
return (SPPLT[4]);
break;
case 0x8107:
return (SPPLT[5]);
break;
case 0x8108:
return (SCRP1PLT[0]);
break;
case 0x8109:
return (SCRP1PLT[1]);
break;
case 0x810a:
return (SCRP1PLT[2]);
break;
case 0x810d:
return (SCRP1PLT[3]);
break;
case 0x810e:
return (SCRP1PLT[4]);
break;
case 0x810f:
return (SCRP1PLT[5]);
break;
case 0x8111:
return (SCRP2PLT[0]);
break;
case 0x8112:
return (SCRP2PLT[1]);
break;
case 0x8113:
return (SCRP2PLT[2]);
break;
case 0x8115:
return (SCRP2PLT[3]);
break;
case 0x8116:
return (SCRP2PLT[4]);
break;
case 0x8117:
return (SCRP2PLT[5]);
break;
case 0x8118:
return (BG_COL);
case 0x87e2:
return (K2GE_MODE);
}
return (0);
}
uint16 NGPGFX_CLASS::read16(uint32 address)
{
uint16 ret;
ret = read8(address);
ret |= read8(address + 1) << 8;
return (ret);
}
}