The homebrew module

The homebrew module offers configurable ports useful to homebrew game
developers.

By reading and writing to new ports at configurable addresses, a rom may
* write to stdout
* write to stderr
* exit the emulator with a given exit status

These can be used to create automated test suites.
This commit is contained in:
rdanbrook 2018-07-10 22:43:33 -07:00
parent 6baed9b36a
commit b8e4f1f501
12 changed files with 875 additions and 7 deletions

View file

@ -150,6 +150,7 @@ nestopia_SOURCES = \
source/core/NstCartridge.hpp \
source/core/NstStream.cpp \
source/core/NstCheats.hpp \
source/core/NstHomebrew.hpp \
source/core/vssystem/NstVsSystem.hpp \
source/core/vssystem/NstVsRbiBaseball.hpp \
source/core/vssystem/NstVsSuperXevious.cpp \
@ -199,6 +200,7 @@ nestopia_SOURCES = \
source/core/api/NstApiEmulator.hpp \
source/core/api/NstApiVideo.cpp \
source/core/api/NstApiCheats.cpp \
source/core/api/NstApiHomebrew.cpp \
source/core/api/NstApiMovie.hpp \
source/core/api/NstApiCartridge.cpp \
source/core/api/NstApi.hpp \
@ -221,6 +223,7 @@ nestopia_SOURCES = \
source/core/api/NstApiFds.hpp \
source/core/api/NstApiVideo.hpp \
source/core/api/NstApiCheats.hpp \
source/core/api/NstApiHomebrew.hpp \
source/core/api/NstApiBarcodeReader.cpp \
source/core/api/NstApiInput.hpp \
source/core/api/NstApiInput.cpp \
@ -234,6 +237,7 @@ nestopia_SOURCES = \
source/core/NstFpuPrecision.hpp \
source/core/NstRam.hpp \
source/core/NstCheats.cpp \
source/core/NstHomebrew.cpp \
source/core/NstZlib.cpp \
source/core/NstStream.hpp \
source/core/NstBase.hpp \
@ -703,6 +707,8 @@ nestopia_SOURCES += \
source/common/nstcommon.h \
source/common/cheats.cpp \
source/common/cheats.h \
source/common/homebrew.cpp \
source/common/homebrew.h \
source/common/cli.cpp \
source/common/cli.h \
source/common/config.cpp \

View file

@ -2,7 +2,8 @@
* Nestopia UE
*
* Copyright (C) 2012-2016 R. Danbrook
*
* Copyright (C) 2018-2018 Phil Smith
*
* 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
@ -136,8 +137,12 @@ void config_file_write(const char *nstdir) {
fprintf(fp, "last_folder=%s\n", conf.misc_last_folder);
fprintf(fp, "; 0=0x00, 1=0xFF, 2=Random\n");
fprintf(fp, "power_state=%d\n", conf.misc_power_state);
fprintf(fp, "overclock=%d\n", conf.misc_overclock);
fprintf(fp, "overclock=%d\n\n", conf.misc_overclock);
fprintf(fp, "; Valid values are -1 (disabled) or 0 to 65535.\n");
fprintf(fp, "homebrew_exit=%d\n", conf.misc_homebrew_exit);
fprintf(fp, "homebrew_stdout=%d\n", conf.misc_homebrew_stdout);
fprintf(fp, "homebrew_stderr=%d\n", conf.misc_homebrew_stderr);
fclose(fp);
}
else {
@ -207,6 +212,9 @@ void config_set_default() {
conf.misc_last_folder = NULL;
conf.misc_power_state = 0;
conf.misc_overclock = false;
conf.misc_homebrew_exit = -1;
conf.misc_homebrew_stdout = -1;
conf.misc_homebrew_stderr = -1;
}
static int config_match(void* user, const char* section, const char* name, const char* value) {
@ -273,7 +281,10 @@ static int config_match(void* user, const char* section, const char* name, const
else if (MATCH("misc", "last_folder")) { pconfig->misc_last_folder = strdup(value); }
else if (MATCH("misc", "power_state")) { pconfig->misc_power_state = atoi(value); }
else if (MATCH("misc", "overclock")) { pconfig->misc_overclock = atoi(value); }
else if (MATCH("misc", "homebrew_exit")) { pconfig->misc_homebrew_exit = atoi(value); }
else if (MATCH("misc", "homebrew_stdout")) { pconfig->misc_homebrew_stdout = atoi(value); }
else if (MATCH("misc", "homebrew_stderr")) { pconfig->misc_homebrew_stderr = atoi(value); }
else { return 0; }
return 1;
}

View file

@ -63,6 +63,9 @@ typedef struct {
char* misc_last_folder;
int misc_power_state;
bool misc_overclock;
int misc_homebrew_exit;
int misc_homebrew_stdout;
int misc_homebrew_stderr;
} settings_t;
void config_file_read(const char *nstdir);

View file

@ -0,0 +1,46 @@
/*
* Nestopia UE
*
* Copyright (C) 2018-2018 Phil Smith
*
* 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.
*
*/
#include "config.h"
#include "homebrew.h"
extern Emulator emulator;
void nst_homebrew_init() {
Homebrew homebrew(emulator);
homebrew.ClearPorts();
if (conf.misc_homebrew_exit != -1)
{
homebrew.SetExitPort(conf.misc_homebrew_exit);
}
if (conf.misc_homebrew_stdout != -1)
{
homebrew.SetStdOutPort(conf.misc_homebrew_stdout);
}
if (conf.misc_homebrew_stderr != -1)
{
homebrew.SetStdErrPort(conf.misc_homebrew_stderr);
}
}

33
source/common/homebrew.h Normal file
View file

@ -0,0 +1,33 @@
/*
* Nestopia UE
*
* Copyright (C) 2018-2018 Phil Smith
*
* 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.
*
*/
#ifndef _HOMEBREW_H_
#define _HOMEBREW_H_
#include "core/api/NstApiEmulator.hpp"
#include "core/api/NstApiHomebrew.hpp"
using namespace Nes::Api;
void nst_homebrew_init();
#endif

View file

@ -3,7 +3,8 @@
*
* Copyright (C) 2007-2008 R. Belmont
* Copyright (C) 2012-2018 R. Danbrook
*
* Copyright (C) 2018-2018 Phil Smith
*
* 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
@ -46,6 +47,7 @@
#include "nstcommon.h"
#include "config.h"
#include "cheats.h"
#include "homebrew.h"
#include "input.h"
#include "audio.h"
#include "video.h"
@ -890,7 +892,8 @@ void nst_play() {
audio_init();
nst_input_init();
nst_cheats_init(nstpaths.cheatpath);
nst_homebrew_init();
cNstVideo = new Video::Output;
cNstSound = new Sound::Output;
cNstPads = new Input::Controllers;

307
source/core/NstHomebrew.cpp Normal file
View file

@ -0,0 +1,307 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2018-2018 Phil Smith
//
// This file is part of Nestopia.
//
// Nestopia 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.
//
// Nestopia 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 Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include "NstCpu.hpp"
#include "NstHomebrew.hpp"
namespace Nes
{
namespace Core
{
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("s", on)
#endif
Homebrew::Homebrew(Cpu& c)
: cpu(c)
, exitAddress(0)
, exitSet(false)
, exitPort(NULL)
, stdOutAddress(0)
, stdOutSet(false)
, stdOutPort(NULL)
, stdErrAddress(0)
, stdErrSet(false)
, stdErrPort(NULL)
{}
Homebrew::~Homebrew()
{
ClearPorts();
}
void Homebrew::Reset()
{
ActivateExitPort();
ActivateStdOutPort();
ActivateStdErrPort();
}
void Homebrew::ClearPorts()
{
ClearExitPort();
ClearStdOutPort();
ClearStdErrPort();
}
Result Homebrew::SetExitPort
(
const word address,
const bool activate
)
{
if
(
exitSet
&& exitAddress == address
&& (!activate || exitPort != NULL)
)
return RESULT_NOP;
ClearExitPort();
exitAddress = address;
exitSet = true;
if (activate)
return ActivateExitPort();
else
return RESULT_OK;
}
Result Homebrew::ClearExitPort()
{
exitSet = false;
if (exitPort != NULL)
{
cpu.Unlink
(
exitAddress,
this,
&Homebrew::Peek_Exit,
&Homebrew::Poke_Exit
);
exitPort = NULL;
return RESULT_OK;
}
else
return RESULT_NOP;
}
Result Homebrew::SetStdOutPort
(
const word address,
const bool activate
)
{
if
(
stdOutSet
&& stdOutAddress == address
&& (!activate || stdOutPort != NULL)
)
return RESULT_NOP;
ClearStdOutPort();
stdOutAddress = address;
stdOutSet = true;
if (activate)
return ActivateStdOutPort();
else
return RESULT_OK;
}
Result Homebrew::ClearStdOutPort()
{
stdOutSet = false;
if (stdOutPort != NULL)
{
cpu.Unlink
(
stdOutAddress,
this,
&Homebrew::Peek_StdOut,
&Homebrew::Poke_StdOut
);
stdOutPort = NULL;
return RESULT_OK;
}
else
return RESULT_NOP;
}
Result Homebrew::SetStdErrPort
(
const word address,
const bool activate
)
{
if
(
stdErrSet
&& stdErrAddress == address
&& (!activate || stdErrPort != NULL)
)
return RESULT_NOP;
ClearStdErrPort();
stdErrAddress = address;
stdErrSet = true;
if (activate)
return ActivateStdErrPort();
else
return RESULT_OK;
}
Result Homebrew::ClearStdErrPort()
{
stdErrSet = false;
if (stdErrPort != NULL)
{
cpu.Unlink
(
stdErrAddress,
this,
&Homebrew::Peek_StdErr,
&Homebrew::Poke_StdErr
);
stdErrPort = NULL;
return RESULT_OK;
}
else
return RESULT_NOP;
}
dword Homebrew::NumPorts() const
{
return (exitPort != NULL ? 1 : 0)
+ (stdOutPort != NULL ? 1 : 0)
+ (stdErrPort != NULL ? 1 : 0);
}
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("", on)
#endif
NES_PEEK_A(Homebrew,Exit)
{
return exitPort->Peek( address );
}
NES_POKE_D(Homebrew,Exit)
{
std::exit( data );
}
NES_PEEK_A(Homebrew,StdOut)
{
return stdOutPort->Peek( address );
}
NES_POKE_D(Homebrew,StdOut)
{
std::cout << (static_cast<unsigned char>(data & 0xFF));
if (data == '\n')
std::cout << std::flush;
}
NES_PEEK_A(Homebrew,StdErr)
{
return stdErrPort->Peek( address );
}
NES_POKE_D(Homebrew,StdErr)
{
std::cerr << (static_cast<unsigned char>(data & 0xFF));
if (data == '\n')
std::cerr << std::flush;
}
Result Homebrew::ActivateExitPort()
{
if (exitSet && exitPort == NULL)
{
exitPort = cpu.Link
(
exitAddress,
Cpu::LEVEL_HIGH,
this,
&Homebrew::Peek_Exit,
&Homebrew::Poke_Exit
);
return RESULT_OK;
}
else
return RESULT_NOP;
}
Result Homebrew::ActivateStdOutPort()
{
if (stdOutSet && stdOutPort == NULL)
{
stdOutPort = cpu.Link
(
stdOutAddress,
Cpu::LEVEL_HIGH,
this,
&Homebrew::Peek_StdOut,
&Homebrew::Poke_StdOut
);
return RESULT_OK;
}
else
return RESULT_NOP;
}
Result Homebrew::ActivateStdErrPort()
{
if (stdErrSet && stdErrPort == NULL)
{
stdErrPort = cpu.Link
(
stdErrAddress,
Cpu::LEVEL_HIGH,
this,
&Homebrew::Peek_StdErr,
&Homebrew::Poke_StdErr
);
return RESULT_OK;
}
else
return RESULT_NOP;
}
}
}

View file

@ -0,0 +1,93 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2018-2018 Phil Smith
//
// This file is part of Nestopia.
//
// Nestopia 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.
//
// Nestopia 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 Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#ifndef NST_HOMEBREW_H
#define NST_HOMEBREW_H
#ifndef NST_VECTOR_H
#include "NstVector.hpp"
#endif
#ifdef NST_PRAGMA_ONCE
#pragma once
#endif
namespace Nes
{
namespace Core
{
class Homebrew
{
public:
explicit Homebrew(Cpu&);
~Homebrew();
void Reset();
void ClearPorts();
Result SetExitPort (word,bool);
Result ClearExitPort ();
Result SetStdOutPort (word,bool);
Result ClearStdOutPort ();
Result SetStdErrPort (word,bool);
Result ClearStdErrPort ();
dword NumPorts () const;
private:
NES_DECL_PEEK( Exit );
NES_DECL_POKE( Exit );
NES_DECL_PEEK( StdOut );
NES_DECL_POKE( StdOut );
NES_DECL_PEEK( StdErr );
NES_DECL_POKE( StdErr );
Result ActivateExitPort ();
Result ActivateStdOutPort ();
Result ActivateStdErrPort ();
Cpu& cpu;
word exitAddress;
ibool exitSet;
const Io::Port* exitPort;
word stdOutAddress;
ibool stdOutSet;
const Io::Port* stdOutPort;
word stdErrAddress;
ibool stdErrSet;
const Io::Port* stdErrPort;
};
}
}
#endif

View file

@ -3,6 +3,7 @@
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
// Copyright (C) 2018-2018 Phil Smith
//
// This file is part of Nestopia.
//
@ -25,6 +26,7 @@
#include "NstMachine.hpp"
#include "NstCartridge.hpp"
#include "NstCheats.hpp"
#include "NstHomebrew.hpp"
#include "NstNsf.hpp"
#include "NstImageDatabase.hpp"
#include "input/NstInpDevice.hpp"
@ -49,6 +51,7 @@ namespace Nes
expPort (new Input::Device( cpu )),
image (NULL),
cheats (NULL),
homebrew (NULL),
imageDatabase (NULL),
ppu (cpu)
{
@ -60,6 +63,7 @@ namespace Nes
delete imageDatabase;
delete cheats;
delete homebrew;
delete expPort;
for (uint ports=extPort->NumPorts(), i=0; i < ports; ++i)
@ -294,6 +298,9 @@ namespace Nes
if (cheats)
cheats->Reset();
if (homebrew)
homebrew->Reset();
tracker.Reset();
}
else
@ -513,7 +520,7 @@ namespace Nes
cpu.ExecuteFrame( sound );
ppu.EndFrame();
renderer.bgColor = ppu.output.bgColor;
if (video)

View file

@ -3,6 +3,7 @@
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
// Copyright (C) 2018-2018 Phil Smith
//
// This file is part of Nestopia.
//
@ -58,6 +59,7 @@ namespace Nes
class Image;
class Cheats;
class Homebrew;
class ImageDatabase;
class Machine
@ -128,6 +130,7 @@ namespace Nes
Input::Device* expPort;
Image* image;
Cheats* cheats;
Homebrew* homebrew;
ImageDatabase* imageDatabase;
Tracker tracker;
Ppu ppu;

View file

@ -0,0 +1,225 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2018-2018 Phil Smith
//
// This file is part of Nestopia.
//
// Nestopia 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.
//
// Nestopia 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 Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#include <new>
#include "../NstMachine.hpp"
#include "../NstHomebrew.hpp"
#include "NstApiHomebrew.hpp"
#include "NstApiMachine.hpp"
namespace Nes
{
namespace Api
{
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("s", on)
#endif
Result Homebrew::SetExitPort(ushort address) throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
try
{
if (emulator.homebrew == NULL)
emulator.homebrew = new Core::Homebrew( emulator.cpu );
return emulator.tracker.TryResync
(
emulator.homebrew->SetExitPort
(
address,
emulator.Is(Machine::GAME)
),
true
);
}
catch (const std::bad_alloc&)
{
return RESULT_ERR_OUT_OF_MEMORY;
}
catch (...)
{
return RESULT_ERR_GENERIC;
}
}
Result Homebrew::ClearExitPort() throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
if (!emulator.homebrew)
return RESULT_ERR_INVALID_PARAM;
const Result result = emulator.tracker.TryResync
(
emulator.homebrew->ClearExitPort(),
true
);
if (!emulator.homebrew->NumPorts())
{
delete emulator.homebrew;
emulator.homebrew = NULL;
}
return result;
}
Result Homebrew::SetStdOutPort(ushort address) throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
try
{
if (emulator.homebrew == NULL)
emulator.homebrew = new Core::Homebrew( emulator.cpu );
return emulator.tracker.TryResync
(
emulator.homebrew->SetStdOutPort
(
address,
emulator.Is(Machine::GAME)
),
true
);
}
catch (const std::bad_alloc&)
{
return RESULT_ERR_OUT_OF_MEMORY;
}
catch (...)
{
return RESULT_ERR_GENERIC;
}
}
Result Homebrew::ClearStdOutPort() throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
if (!emulator.homebrew)
return RESULT_ERR_INVALID_PARAM;
const Result result = emulator.tracker.TryResync
(
emulator.homebrew->ClearStdOutPort(),
true
);
if (!emulator.homebrew->NumPorts())
{
delete emulator.homebrew;
emulator.homebrew = NULL;
}
return result;
}
Result Homebrew::SetStdErrPort(ushort address) throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
try
{
if (emulator.homebrew == NULL)
emulator.homebrew = new Core::Homebrew( emulator.cpu );
return emulator.tracker.TryResync
(
emulator.homebrew->SetStdErrPort
(
address,
emulator.Is(Machine::GAME)
),
true
);
}
catch (const std::bad_alloc&)
{
return RESULT_ERR_OUT_OF_MEMORY;
}
catch (...)
{
return RESULT_ERR_GENERIC;
}
}
Result Homebrew::ClearStdErrPort() throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
if (!emulator.homebrew)
return RESULT_ERR_INVALID_PARAM;
const Result result = emulator.tracker.TryResync
(
emulator.homebrew->ClearStdErrPort(),
true
);
if (!emulator.homebrew->NumPorts())
{
delete emulator.homebrew;
emulator.homebrew = NULL;
}
return result;
}
ulong Homebrew::NumPorts() const throw()
{
return emulator.homebrew ? emulator.homebrew->NumPorts() : 0;
}
Result Homebrew::ClearPorts() throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;
if (!emulator.homebrew)
return RESULT_NOP;
if (emulator.homebrew->NumPorts())
emulator.tracker.Resync( true );
delete emulator.homebrew;
emulator.homebrew = NULL;
return RESULT_OK;
}
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("", on)
#endif
}
}

View file

@ -0,0 +1,131 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2018-2018 Phil Smith
//
// This file is part of Nestopia.
//
// Nestopia 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.
//
// Nestopia 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 Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#ifndef NST_API_HOMEBREW_H
#define NST_API_HOMEBREW_H
#include "NstApi.hpp"
#ifdef NST_PRAGMA_ONCE
#pragma once
#endif
#if NST_ICC >= 810
#pragma warning( push )
#pragma warning( disable : 444 )
#elif NST_MSVC >= 1200
#pragma warning( push )
#pragma warning( disable : 4512 )
#endif
namespace Nes
{
namespace Api
{
/**
* Homebrew interface.
*/
class Homebrew : public Base
{
public:
/**
* Interface constructor.
*
* @param instance emulator instance
*/
template<typename T>
Homebrew(T& instance)
: Base(instance) {}
/**
* Sets the exit port.
*
* @param address exit port address,
* any previous exit port will be removed
* @return result code
*/
Result SetExitPort(ushort address) throw();
/**
* Removes the exit port.
*
* @return result code
*/
Result ClearExitPort() throw();
/**
* Sets the standard out port.
*
* @param address standard out port address,
* any previous standard out port will be removed
* @return result code
*/
Result SetStdOutPort(ushort address) throw();
/**
* Removes the standard out port.
*
* @return result code
*/
Result ClearStdOutPort() throw();
/**
* Sets the standard error port.
*
* @param address standard error port address,
* any previous standard error port will be removed
* @return result code
*/
Result SetStdErrPort(ushort address) throw();
/**
* Removes the standard error port.
*
* @return result code
*/
Result ClearStdErrPort() throw();
/**
* Returns current number of ports.
*
* @return number
*/
ulong NumPorts() const throw();
/**
* Removes all existing ports.
*
* @return result code
*/
Result ClearPorts() throw();
};
}
}
#if NST_MSVC >= 1200 || NST_ICC >= 810
#pragma warning( pop )
#endif
#endif