mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-26 15:45:41 +00:00
206 lines
5.2 KiB
C++
206 lines
5.2 KiB
C++
/**
|
|
** Supermodel
|
|
** A Sega Model 3 Arcade Emulator.
|
|
** Copyright 2011 Bart Trzynadlowski
|
|
**
|
|
** This file is part of Supermodel.
|
|
**
|
|
** Supermodel 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 3 of the License, or (at your option)
|
|
** any later version.
|
|
**
|
|
** Supermodel 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 Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
|
**/
|
|
|
|
/*
|
|
* TileGen.cpp
|
|
*
|
|
* Implementation of the CTileGen class: 2D tile generator.
|
|
*
|
|
* TO-DO List:
|
|
* -----------
|
|
* - For consistency, the registers should probably be byte reversed (this is a
|
|
* little endian device), forcing the Model3 Read32/Write32 handlers to
|
|
* manually reverse the data. This keeps with the convention for VRAM.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "Supermodel.h"
|
|
|
|
|
|
/******************************************************************************
|
|
Save States
|
|
******************************************************************************/
|
|
|
|
void CTileGen::SaveState(CBlockFile *SaveState)
|
|
{
|
|
SaveState->NewBlock("Tile Generator", __FILE__);
|
|
SaveState->Write(memoryPool, 0x100000+0x20000);
|
|
SaveState->Write(regs, sizeof(regs));
|
|
}
|
|
|
|
void CTileGen::LoadState(CBlockFile *SaveState)
|
|
{
|
|
if (OKAY != SaveState->FindBlock("Tile Generator"))
|
|
{
|
|
ErrorLog("Unable to load tile generator state. Save state file is corrupted.");
|
|
return;
|
|
}
|
|
|
|
// Load memory one word at a time
|
|
for (int i = 0; i < (0x100000+0x20000); i += 4)
|
|
{
|
|
UINT32 data;
|
|
|
|
SaveState->Read(&data, sizeof(data));
|
|
Render2D->WriteVRAM(i, data);
|
|
*(UINT32 *) &memoryPool[i] = data;
|
|
}
|
|
|
|
SaveState->Read(regs, sizeof(regs));
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
Rendering
|
|
******************************************************************************/
|
|
|
|
void CTileGen::BeginFrame(void)
|
|
{
|
|
Render2D->BeginFrame();
|
|
/*
|
|
printf("08: %X\n", regs[0x08/4]);
|
|
printf("0C: %X\n", regs[0x0C/4]);
|
|
printf("20: %X\n", regs[0x20/4]);
|
|
printf("40: %X\n", regs[0x40/4]);
|
|
printf("44: %X\n", regs[0x44/4]);
|
|
printf("60: %08X\n", regs[0x60/4]);
|
|
printf("64: %08X\n", regs[0x64/4]);
|
|
printf("68: %08X\n", regs[0x68/4]);
|
|
printf("6C: %08X\n", regs[0x6C/4]);
|
|
*/
|
|
}
|
|
|
|
void CTileGen::EndFrame(void)
|
|
{
|
|
Render2D->EndFrame();
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
Emulation Functions
|
|
******************************************************************************/
|
|
|
|
UINT32 CTileGen::ReadRAM(unsigned addr)
|
|
{
|
|
return *(UINT32 *) &memoryPool[addr];
|
|
}
|
|
|
|
void CTileGen::WriteRAM(unsigned addr, UINT32 data)
|
|
{
|
|
Render2D->WriteVRAM(addr,data); // inform renderer of update first
|
|
*(UINT32 *) &memoryPool[addr] = data;
|
|
}
|
|
|
|
void CTileGen::WriteRegister(unsigned reg, UINT32 data)
|
|
{
|
|
reg &= 0xFF;
|
|
regs[reg/4] = data;
|
|
|
|
switch (reg)
|
|
{
|
|
case 0x10: // IRQ acknowledge
|
|
IRQ->Deassert(data&0xFF);
|
|
break;
|
|
case 0x60:
|
|
break;
|
|
case 0x64:
|
|
break;
|
|
case 0x68:
|
|
break;
|
|
case 0x6C:
|
|
break;
|
|
default:
|
|
DebugLog("Tile Generator reg %02X = %08X\n", reg, data);
|
|
//printf("%02X = %08X\n", reg, data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CTileGen::Reset(void)
|
|
{
|
|
memset(regs, 0, sizeof(regs));
|
|
memset(memoryPool, 0, 0x120000);
|
|
DebugLog("Tile Generator reset\n");
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
Configuration, Initialization, and Shutdown
|
|
******************************************************************************/
|
|
|
|
void CTileGen::AttachRenderer(CRender2D *Render2DPtr)
|
|
{
|
|
Render2D = Render2DPtr;
|
|
Render2D->AttachVRAM(memoryPool);
|
|
Render2D->AttachRegisters(regs);
|
|
DebugLog("Tile Generator attached a Render2D object\n");
|
|
}
|
|
|
|
#define MEMORY_POOL_SIZE 0x120000
|
|
|
|
BOOL CTileGen::Init(CIRQ *IRQObjectPtr)
|
|
{
|
|
float memSizeMB = (float)MEMORY_POOL_SIZE/(float)0x100000;
|
|
|
|
// Allocate all memory for ROMs and PPC RAM
|
|
memoryPool = new(std::nothrow) UINT8[MEMORY_POOL_SIZE];
|
|
if (NULL == memoryPool)
|
|
return ErrorLog("Insufficient memory for tile generator object (needs %1.1f MB).", memSizeMB);
|
|
|
|
// Hook up the IRQ controller
|
|
IRQ = IRQObjectPtr;
|
|
|
|
DebugLog("Initialized Tile Generator (allocated %1.1f MB and connected to IRQ controller)\n", memSizeMB);
|
|
return OKAY;
|
|
}
|
|
|
|
CTileGen::CTileGen(void)
|
|
{
|
|
IRQ = NULL;
|
|
memoryPool = NULL;
|
|
DebugLog("Built Tile Generator\n");
|
|
}
|
|
|
|
CTileGen::~CTileGen(void)
|
|
{
|
|
// Dump tile generator RAM
|
|
#if 0
|
|
FILE *fp;
|
|
fp = fopen("tileram", "wb");
|
|
if (NULL != fp)
|
|
{
|
|
fwrite(memoryPool, sizeof(UINT8), 0x120000, fp);
|
|
fclose(fp);
|
|
printf("dumped %s\n", "tileram");
|
|
}
|
|
else
|
|
printf("unable to dump %s\n", "tileram");
|
|
#endif
|
|
|
|
IRQ = NULL;
|
|
if (memoryPool != NULL)
|
|
{
|
|
delete [] memoryPool;
|
|
memoryPool = NULL;
|
|
}
|
|
DebugLog("Destroyed Tile Generator\n");
|
|
}
|