245 lines
5.8 KiB
C++
245 lines
5.8 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 "Z80_interface.h"
|
|
#include "interrupt.h"
|
|
#include "mem.h"
|
|
#include "gfx.h"
|
|
#include "sound.h"
|
|
#include "dma.h"
|
|
#include "bios.h"
|
|
#include "flash.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace MDFN_IEN_NGP
|
|
{
|
|
bool lagged;
|
|
void (*inputcallback)();
|
|
|
|
|
|
extern uint8 CPUExRAM[16384];
|
|
|
|
NGPGFX_CLASS *NGPGfx = NULL;
|
|
|
|
COLOURMODE system_colour = COLOURMODE_AUTO;
|
|
|
|
uint8 NGPJoyLatch;
|
|
uint8 settings_language;
|
|
time_t frontend_time;
|
|
|
|
int (*comms_read_cb)(uint8* buffer);
|
|
int (*comms_poll_cb)(uint8* buffer);
|
|
void (*comms_write_cb)(uint8 data);
|
|
|
|
bool system_comms_read(uint8 *buffer)
|
|
{
|
|
if (comms_read_cb)
|
|
return comms_read_cb(buffer);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool system_comms_poll(uint8 *buffer)
|
|
{
|
|
if (comms_poll_cb)
|
|
return comms_poll_cb(buffer);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void system_comms_write(uint8 data)
|
|
{
|
|
if (comms_write_cb)
|
|
comms_write_cb(data);
|
|
}
|
|
|
|
void instruction_error(char *vaMessage, ...)
|
|
{
|
|
/*char message[1000];
|
|
va_list vl;
|
|
|
|
va_start(vl, vaMessage);
|
|
vsprintf(message, vaMessage, vl);
|
|
va_end(vl);
|
|
|
|
MDFN_printf("[PC %06X] %s\n", pc, message);*/
|
|
}
|
|
|
|
bool NGPFrameSkip;
|
|
int32 ngpc_soundTS = 0;
|
|
//static int32 main_timeaccum;
|
|
static int32 z80_runtime;
|
|
|
|
EXPORT void FrameAdvance(MyFrameInfo* frame)
|
|
{
|
|
lagged = true;
|
|
bool MeowMeow = 0;
|
|
MDFN_Surface surface;
|
|
surface.pixels = frame->VideoBuffer;
|
|
surface.pitch32 = 160;
|
|
frame->Width = 160;
|
|
frame->Height = 152;
|
|
frontend_time = frame->FrontendTime;
|
|
storeB(0x6f82, frame->Buttons);
|
|
|
|
ngpc_soundTS = 0;
|
|
NGPFrameSkip = frame->SkipRendering;
|
|
|
|
do
|
|
{
|
|
int32 timetime = (uint8)TLCS900h_interpret(); // This is sooo not right, but it's replicating the old behavior(which is necessary
|
|
// now since I've fixed the TLCS900h core and other places not to truncate cycle counts
|
|
// internally to 8-bits). Switch to the #if 0'd block of code once we fix cycle counts in the
|
|
// TLCS900h core(they're all sorts of messed up), and investigate if certain long
|
|
// instructions are interruptable(by interrupts) and later resumable, RE Rockman Battle
|
|
// & Fighters voice sample playback.
|
|
|
|
//if(timetime > 255)
|
|
// printf("%d\n", timetime);
|
|
|
|
// Note: Don't call updateTimers with a time/tick/cycle/whatever count greater than 255.
|
|
MeowMeow |= updateTimers(&surface, timetime);
|
|
|
|
z80_runtime += timetime;
|
|
|
|
while (z80_runtime > 0)
|
|
{
|
|
int z80rantime = Z80_RunOP();
|
|
|
|
if (z80rantime < 0) // Z80 inactive, so take up all run time!
|
|
{
|
|
z80_runtime = 0;
|
|
break;
|
|
}
|
|
|
|
z80_runtime -= z80rantime << 1;
|
|
}
|
|
} while (!MeowMeow);
|
|
|
|
frame->Cycles = ngpc_soundTS;
|
|
frame->Samples = MDFNNGPCSOUND_Flush(frame->SoundBuffer, 8192);
|
|
frame->Lagged = lagged;
|
|
}
|
|
|
|
static MDFN_COLD bool Load(const uint8* romdata, int32 romlength)
|
|
{
|
|
const uint64 fp_size = romlength;
|
|
|
|
if (fp_size > 1024 * 1024 * 8) // 4MiB maximum ROM size, 2* to be a little tolerant of garbage.
|
|
return false;
|
|
//throw MDFN_Error(0, _("NGP/NGPC ROM image is too large."));
|
|
|
|
ngpc_rom.length = fp_size;
|
|
ngpc_rom.data = (uint8*)alloc_plain(ngpc_rom.length);
|
|
memcpy(ngpc_rom.data, romdata, romlength);
|
|
|
|
rom_loaded();
|
|
//if (!FLASH_LoadNV())
|
|
// return false;
|
|
|
|
//MDFNMP_Init(1024, 1024 * 1024 * 16 / 1024);
|
|
|
|
NGPGfx = new NGPGFX_CLASS();
|
|
|
|
//MDFNGameInfo->fps = (uint32)((uint64)6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198
|
|
|
|
MDFNNGPCSOUND_Init();
|
|
|
|
//MDFNMP_AddRAM(16384, 0x4000, CPUExRAM);
|
|
|
|
SetFRM(); // Set up fast read memory mapping
|
|
|
|
bios_install();
|
|
|
|
//main_timeaccum = 0;
|
|
z80_runtime = 0;
|
|
|
|
reset();
|
|
|
|
MDFNNGPC_SetSoundRate(44100);
|
|
return true;
|
|
}
|
|
}
|
|
using namespace MDFN_IEN_NGP;
|
|
|
|
int main(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
EXPORT int LoadSystem(const uint8* rom, int romlength, int language)
|
|
{
|
|
settings_language = language;
|
|
return Load(rom, romlength);
|
|
}
|
|
|
|
EXPORT void SetLayers(int enable) // 1, 2, 4 bg,fg,sprites
|
|
{
|
|
NGPGfx->SetLayerEnableMask(enable);
|
|
}
|
|
|
|
EXPORT void HardReset()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
EXPORT void SetInputCallback(void (*callback)())
|
|
{
|
|
inputcallback = callback;
|
|
}
|
|
|
|
EXPORT void SetCommsCallbacks(int (*read_cb)(uint8* buffer), int (*poll_cb)(uint8* buffer), void (*write_cb)(uint8 data))
|
|
{
|
|
comms_read_cb = read_cb;
|
|
comms_poll_cb = poll_cb;
|
|
comms_write_cb = write_cb;
|
|
}
|
|
|
|
EXPORT void GetMemoryAreas(MemoryArea* m)
|
|
{
|
|
m[0].Data = CPUExRAM;
|
|
m[0].Name = "RAM";
|
|
m[0].Size = 16384;
|
|
m[0].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WORDSIZE4;
|
|
|
|
m[1].Data = ngpc_rom.data;
|
|
m[1].Name = "ROM";
|
|
m[1].Size = ngpc_rom.length;
|
|
m[1].Flags = MEMORYAREA_FLAGS_WORDSIZE4;
|
|
|
|
m[2].Data = ngpc_rom.orig_data;
|
|
m[2].Name = "ORIGINAL ROM";
|
|
m[2].Size = ngpc_rom.length;
|
|
m[2].Flags = MEMORYAREA_FLAGS_WORDSIZE4;
|
|
}
|
|
|
|
EXPORT bool HasSaveRam()
|
|
{
|
|
return FLASH_IsModified();
|
|
}
|
|
|
|
EXPORT bool PutSaveRam(const uint8* data, uint32 length)
|
|
{
|
|
return FLASH_LoadNV(data, length);
|
|
}
|
|
|
|
EXPORT void GetSaveRam(void (*callback)(const uint8* data, uint32 length))
|
|
{
|
|
FLASH_SaveNV(callback);
|
|
}
|
|
|