261 lines
5.8 KiB
C++
261 lines
5.8 KiB
C++
/******************************************************************************/
|
|
/* Mednafen NEC PC-FX Emulation Module */
|
|
/******************************************************************************/
|
|
/* huc6273.cpp - Unfinished emulation of the HuC6273, 3D chip in the PC-FXGA
|
|
** Copyright (C) 2007-2016 Mednafen Team
|
|
**
|
|
** 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.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/* Definitions:
|
|
CMT = Command Macro Table
|
|
*/
|
|
|
|
#include "pcfx.h"
|
|
#include "huc6273.h"
|
|
|
|
namespace MDFN_IEN_PCFX
|
|
{
|
|
|
|
enum
|
|
{
|
|
OP_NOP = 0x00,
|
|
OP_TRIANGLE_STRIP = 0x01,
|
|
OP_TRIANGLE_LIST = 0x02,
|
|
OP_POLY_LINE = 0x03,
|
|
OP_LINE_LIST = 0x04,
|
|
OP_RESERVED0 = 0x05,
|
|
OP_PUT_IMAGE = 0x06,
|
|
OP_READ_PIXEL = 0x07,
|
|
OP_WRITE_TE_REGISTERS = 0x08,
|
|
OP_WRITE_PE_REGISTERS = 0x09,
|
|
OP_MISC = 0x0A,
|
|
OP_RESERVED1 = 0x0B,
|
|
OP_READ_TE_REGISTERS = 0x0C,
|
|
OP_READ_PE_REGISTERS = 0x0D,
|
|
OP_WRITE_LUT = 0x0E,
|
|
OP_READ_LUT = 0x0F,
|
|
};
|
|
|
|
enum
|
|
{
|
|
INT_RHIT = 15, // Raster Hit
|
|
INT_HBL = 14, // H blank
|
|
INT_VBL = 13, // V blank
|
|
INT_HSY = 12, // H sync
|
|
INT_VSY = 11, // V sync
|
|
INT_RBDONE = 10, // Read back done
|
|
INT_TESYNC = 9, // TE Sync
|
|
INT_SPDONE = 8, // Sprite done
|
|
INT_CMDONE = 7, // Command macro done
|
|
INT_PESYNC = 6, // PE sync
|
|
INT_AEMP = 5, // Almost empty
|
|
INT_CSE = 4, // Command sync error
|
|
INT_AFL = 3, // Almost full
|
|
INT_OVF = 2, // Overflow
|
|
INT_FSY = 1, // Frame sync
|
|
};
|
|
|
|
static uint16 FIFO[0x20];
|
|
static uint8 InFIFO;
|
|
#define AFW (0x20 - InFIFO)
|
|
|
|
#define AEMPWD ((FIFOControl >> 4) & 0xFF)
|
|
#define AFLWD (FIFOControl & 0xF)
|
|
static uint16 FIFOControl; // 0x00004
|
|
|
|
static uint8 CMTBankSelect;
|
|
static uint16 CMTStartAddress;
|
|
static uint16 CMTByteCount;
|
|
|
|
static uint16 InterruptMask;
|
|
static uint16 InterruptStatus;
|
|
|
|
static uint16 ReadBack;
|
|
|
|
static uint16 HorizontalTiming, VerticalTiming;
|
|
|
|
static uint16 SCTAddressHi;
|
|
static uint16 SpriteControl;
|
|
static uint16 CDResult[2];
|
|
static uint16 SPWindowX[2]; // left and right
|
|
static uint16 SPWindowY[2]; // top and bottom
|
|
static uint16 MiscStatus;
|
|
static uint16 ErrorStatus; // Read only!
|
|
static uint16 DisplayControl;
|
|
static uint16 StatusControl;
|
|
static uint16 Config;
|
|
|
|
static uint16 RasterHit;
|
|
|
|
|
|
static uint16 Results[0x10];
|
|
|
|
static void CheckIRQ(void)
|
|
{
|
|
//uint16 MaskedResults = InterruptStatus & InterruptMask;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
static void ProcessFIFO(void)
|
|
{
|
|
uint8 length = FIFO[0] & 0xFF;
|
|
|
|
if(length > 0x20)
|
|
{
|
|
length = 0x20;
|
|
puts("Length too long");
|
|
}
|
|
|
|
if(InFIFO >= length)
|
|
{
|
|
int opcode = FIFO[0] >> 12;
|
|
int option = (FIFO[0] >> 8) & 0x0F;
|
|
|
|
printf("Op: %02x, option: %02x\n", opcode, option);
|
|
|
|
InFIFO -= length;
|
|
for(int i = 0; i < InFIFO; i++)
|
|
FIFO[i] = FIFO[length + i];
|
|
}
|
|
}
|
|
|
|
|
|
static void StoreInFIFO(uint16 V)
|
|
{
|
|
if(AFW > 0)
|
|
{
|
|
FIFO[InFIFO] = V;
|
|
InFIFO++;
|
|
|
|
ProcessFIFO();
|
|
}
|
|
}
|
|
|
|
uint8 HuC6273_Read8(uint32 A)
|
|
{
|
|
puts("73 Read8");
|
|
return(0);
|
|
}
|
|
|
|
uint16 HuC6273_Read16(uint32 A)
|
|
{
|
|
A &= 0xfffff;
|
|
|
|
printf("HuC6273 Read: %04x\n", A);
|
|
|
|
switch(A)
|
|
{
|
|
case 0x00000:
|
|
case 0x00002: return(AFW); // Command FIFO status
|
|
|
|
case 0x00004: return(FIFOControl);
|
|
case 0x00006: return(CMTBankSelect);
|
|
case 0x00008: return(CMTStartAddress);
|
|
case 0x0000A: return(CMTByteCount);
|
|
case 0x0000C: return(InterruptMask);
|
|
case 0x0000E: return(0);
|
|
case 0x00010: return(InterruptStatus);
|
|
case 0x00012: return(ReadBack);
|
|
case 0x00014: return(HorizontalTiming);
|
|
case 0x00016: return(VerticalTiming);
|
|
case 0x00018: return(SCTAddressHi);
|
|
case 0x0001A: return(SpriteControl);
|
|
case 0x0001C: return(CDResult[0]);
|
|
case 0x0001E: return(CDResult[1]);
|
|
case 0x00020: return(SPWindowX[0]);
|
|
case 0x00022: return(SPWindowY[0]);
|
|
case 0x00024: return(SPWindowX[1]);
|
|
case 0x00026: return(SPWindowY[1]);
|
|
case 0x00028: return(MiscStatus);
|
|
case 0x0002A: return(ErrorStatus);
|
|
case 0x0002C: return(DisplayControl);
|
|
case 0x0002E: return(Config);
|
|
}
|
|
if(A >= 0x00060 && A <= 0x0007E)
|
|
{
|
|
return(Results[(A >> 1) & 0xF]);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
void HuC6273_Write16(uint32 A, uint16 V)
|
|
{
|
|
A &= 0xfffff;
|
|
|
|
printf("HuC6273 Write: %04x:%04x\n", A, V);
|
|
|
|
switch(A)
|
|
{
|
|
case 0x00000:
|
|
case 0x00002: StoreInFIFO(V); break;
|
|
|
|
case 0x00004: FIFOControl = V; break;
|
|
case 0x00006: CMTBankSelect = V & 0x1F; break;
|
|
case 0x00008: CMTStartAddress = V & 0xFFFE; break;
|
|
case 0x0000A: CMTByteCount = V & 0xFFFE; break;
|
|
case 0x0000C: InterruptMask = V;
|
|
CheckIRQ();
|
|
break;
|
|
case 0x0000E: // Interrupt Clear
|
|
CheckIRQ();
|
|
break;
|
|
case 0x00010: InterruptStatus = V;
|
|
CheckIRQ();
|
|
break;
|
|
case 0x00012: ReadBack = V; break;
|
|
case 0x00014: HorizontalTiming = V; break;
|
|
case 0x00016: VerticalTiming = V; break;
|
|
case 0x00018: SCTAddressHi = V; break;
|
|
case 0x0001A: SpriteControl = V; break;
|
|
case 0x0001C: CDResult[0] = V; break;
|
|
case 0x0001E: CDResult[1] = V; break;
|
|
case 0x00020: SPWindowX[0] = V; break; // X Left
|
|
case 0x00022: SPWindowY[0] = V; break; // Y Top
|
|
case 0x00024: SPWindowX[1] = V; break; // X Right
|
|
case 0x00026: SPWindowY[1] = V; break; // Y Bottom
|
|
case 0x00028: MiscStatus = V; break;
|
|
case 0x0002C: DisplayControl = V; break;
|
|
case 0x0002E: StatusControl = V; break;
|
|
|
|
case 0x0003C: RasterHit = V; break;
|
|
}
|
|
}
|
|
|
|
void HuC6273_Write8(uint32 A, uint8 V)
|
|
{
|
|
puts("73 Write8");
|
|
}
|
|
|
|
void HuC6273_Reset(void)
|
|
{
|
|
InFIFO = 0;
|
|
FIFOControl = 0x5 | (0x20 << 4);
|
|
}
|
|
|
|
|
|
|
|
bool HuC6273_Init(void)
|
|
{
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
}
|