mirror of
https://github.com/cmosher01/Epple-II.git
synced 2025-01-15 18:30:43 +00:00
fixes #12
This commit is contained in:
parent
617bad3e51
commit
348f85e391
@ -11,6 +11,8 @@
|
||||
|
||||
|
||||
|
||||
cpu epple2
|
||||
|
||||
# standard 48K RAM with mixed chip brands
|
||||
motherboard ram E MM5290 MM5290 MM5290 MK4116 MM5290 MM5290 MM5290 MK4116
|
||||
motherboard strap E 16K 8000
|
||||
|
16
conf/epple2.visual6502.conf.in
Normal file
16
conf/epple2.visual6502.conf.in
Normal file
@ -0,0 +1,16 @@
|
||||
# Use the Visual 6502 emulation algorithm (from http://www.visual6502.org/).
|
||||
# WARNING: this is EXTREMELY SLOW
|
||||
|
||||
|
||||
|
||||
cpu visual6502
|
||||
|
||||
|
||||
|
||||
motherboard ram E MM5290 MM5290 MM5290 MK4116 MM5290 MM5290 MM5290 MK4116
|
||||
motherboard strap E 16K 8000
|
||||
motherboard ram D MM5290 MM5290 MK4116 MK4116 MM5290 MK4116 MM5290 MCM4116
|
||||
motherboard strap D 16K 4000
|
||||
motherboard ram C MK4116 MK4116 MM5290 MM5290 MM5290 MM5290 MM5290 MM5290
|
||||
motherboard strap C 16K 0000
|
||||
import motherboard rom 2C00 ${LIBDIR}/epple2/system/epple2sys.a65
|
@ -121,6 +121,26 @@ strap c 4K 0000
|
||||
|
||||
|
||||
|
||||
#### cpu
|
||||
|
||||
The `cpu` command chooses which CPU emulator to run with.
|
||||
|
||||
``` conf
|
||||
cpu epple2
|
||||
```
|
||||
|
||||
Valid values are:
|
||||
|
||||
`epple2` The standard, faster, albeit less accurate, high-level emulator. Works for 99.99% of known cases.
|
||||
This is the default value, used when the `cpu` command is not present.
|
||||
|
||||
`visual6502` The emulator based on the algorithm and transistor circuitry from http://www.visual6502.org/.
|
||||
WARNING: this emulator is *extremely slow*, but absolutely 100% accurate to the original MOS6502.
|
||||
|
||||
Note: the CPU cannot be changed in the user interface, only in the configuration file.
|
||||
|
||||
|
||||
|
||||
#### import
|
||||
|
||||
The `import` command imports a binary image file into the emulated Apple's ROMs.
|
||||
|
@ -72,17 +72,9 @@ add_executable(epple2 ${sources})
|
||||
|
||||
find_package(SDL2 CONFIG)
|
||||
message(STATUS "SDL2_INCLUDE_DIRS: ${SDL2_INCLUDE_DIRS}")
|
||||
message(STATUS "SDL2_LIBRARIES: ${SDL2_LIBRARIES}")
|
||||
target_include_directories(epple2 PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||
message(STATUS "SDL2_LIBRARIES: ${SDL2_LIBRARIES}")
|
||||
target_link_libraries(epple2 ${SDL2_LIBRARIES})
|
||||
|
||||
target_compile_features(epple2 PRIVATE cxx_std_17)
|
||||
target_compile_definitions(epple2 PRIVATE ETCDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SYSCONFDIR}")
|
||||
|
||||
option(USE_EMU "Use http://www.visual6502.org/ CPU (will run slowly)")
|
||||
if (USE_EMU)
|
||||
message(STATUS "USE_EMU")
|
||||
target_compile_definitions(epple2 PRIVATE USE_EMU)
|
||||
# target_compile_definitions(epple2 PRIVATE TRACESEG)
|
||||
target_compile_definitions(epple2 PRIVATE TRACEREG)
|
||||
endif()
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* File: Emu6502.h
|
||||
* Author: Christopher
|
||||
*
|
||||
@ -8,6 +8,7 @@
|
||||
#ifndef EMU6502_H
|
||||
#define EMU6502_H
|
||||
|
||||
#include "abstractcpu.h"
|
||||
#include "Cpu6502Helper.h"
|
||||
#include "Cpu6502.h"
|
||||
#include "Trace.h"
|
||||
@ -19,7 +20,7 @@
|
||||
|
||||
class AddressBus;
|
||||
|
||||
class Emu6502 {
|
||||
class Emu6502 : public AbstractCpu {
|
||||
public:
|
||||
|
||||
Emu6502(std::istream& transistors, AddressBus& mem) : tn(transistors, segs, transes), c(tn), trace(segs, transes, c), cpu(mem, trace, c), cpuhelper(cpu, c) {
|
||||
|
29
src/abstractcpu.h
Normal file
29
src/abstractcpu.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
epple2
|
||||
Copyright (C) 2008 by Christopher A. Mosher <cmosher01@gmail.com>
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ABSTRACTCPU_H
|
||||
#define ABSTRACTCPU_H
|
||||
|
||||
class AbstractCpu {
|
||||
public:
|
||||
virtual ~AbstractCpu() {};
|
||||
virtual void powerOn() = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual void tick() = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -48,12 +48,8 @@ Apple2::Apple2(KeypressQueue& keypresses, PaddleButtonStates& paddleButtonStates
|
||||
addressBus(gui,revision,ram,rom,kbd,videoMode,paddles,paddleButtonStates,speaker,cassetteIn,cassetteOut,slts),
|
||||
picgen(tv,videoMode,revision),
|
||||
video(videoMode,addressBus,picgen,textRows),
|
||||
#ifdef USE_EMU
|
||||
transistors("transistors"),
|
||||
cpu(transistors,addressBus),
|
||||
#else
|
||||
cpu(addressBus),
|
||||
#endif
|
||||
transistors("transistors"),
|
||||
cpu(NULL),
|
||||
powerUpReset(*this),
|
||||
revision(1)
|
||||
{
|
||||
@ -63,9 +59,22 @@ Apple2::~Apple2()
|
||||
{
|
||||
}
|
||||
|
||||
void Apple2::useEpple2Cpu() {
|
||||
if (this->cpu == NULL) {
|
||||
std::cout << "Using fast Epple2 CPU emulator" << std::endl;
|
||||
this->cpu = new CPU(this->addressBus);
|
||||
}
|
||||
}
|
||||
|
||||
void Apple2::useVisual6502Cpu() {
|
||||
if (this->cpu == NULL) {
|
||||
std::cout << "Using http://www.visual6502.org/ CPU emulation (which will be slow)." << std::endl;
|
||||
this->cpu = new Emu6502(this->transistors, this->addressBus);
|
||||
}
|
||||
}
|
||||
|
||||
void Apple2::tick() {
|
||||
this->cpu.tick();
|
||||
this->cpu->tick();
|
||||
this->slts.tick();
|
||||
this->video.tick();
|
||||
this->paddles.tick();
|
||||
@ -81,7 +90,7 @@ void Apple2::tick() {
|
||||
void Apple2::powerOn()
|
||||
{
|
||||
this->ram.powerOn();
|
||||
this->cpu.powerOn();
|
||||
this->cpu->powerOn();
|
||||
this->videoMode.powerOn();
|
||||
this->video.powerOn();
|
||||
this->picgen.powerOn();
|
||||
@ -95,6 +104,6 @@ void Apple2::powerOff()
|
||||
|
||||
void Apple2::reset()
|
||||
{
|
||||
this->cpu.reset();
|
||||
this->cpu->reset();
|
||||
this->slts.reset();
|
||||
}
|
||||
|
12
src/apple2.h
12
src/apple2.h
@ -28,6 +28,7 @@
|
||||
#include "picturegenerator.h"
|
||||
#include "textcharacters.h"
|
||||
#include "video.h"
|
||||
#include "abstractcpu.h"
|
||||
#include "cpu.h"
|
||||
#include "paddles.h"
|
||||
#include "paddlebuttonstates.h"
|
||||
@ -56,12 +57,8 @@ class Apple2 : public Timable
|
||||
PictureGenerator picgen;
|
||||
TextCharacters textRows;
|
||||
Video video;
|
||||
#ifdef USE_EMU
|
||||
std::ifstream transistors;
|
||||
Emu6502 cpu;
|
||||
#else
|
||||
CPU cpu;
|
||||
#endif
|
||||
std::ifstream transistors;
|
||||
AbstractCpu* cpu;
|
||||
PowerUpReset powerUpReset;
|
||||
int revision;
|
||||
|
||||
@ -69,6 +66,9 @@ public:
|
||||
Apple2(KeypressQueue& keypresses, PaddleButtonStates& paddleButtonStates, AnalogTV& tv, HyperMode& fhyper, KeyboardBufferMode& buffered, ScreenImage& gui);
|
||||
~Apple2();
|
||||
|
||||
void useEpple2Cpu();
|
||||
void useVisual6502Cpu();
|
||||
|
||||
void powerOn();
|
||||
void powerOff();
|
||||
void reset();
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
#include "configep2.h"
|
||||
|
||||
#include "apple2.h"
|
||||
#include "memory.h"
|
||||
#include "memoryrandomaccess.h"
|
||||
#include "slots.h"
|
||||
@ -93,14 +94,8 @@ static void trim(std::string& str)
|
||||
}
|
||||
}
|
||||
|
||||
void Config::parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
||||
void Config::parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Apple2* apple2)
|
||||
{
|
||||
#ifdef USE_EMU
|
||||
std::cout << "Running with http://www.visual6502.org/ CPU emulation (which will be slow)." << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
std::ifstream* pConfig;
|
||||
|
||||
std::string path(this->file_path);
|
||||
@ -192,7 +187,7 @@ void Config::parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revis
|
||||
trim(line);
|
||||
if (!line.empty())
|
||||
{
|
||||
parseLine(line,ram,rom,slts,revision,gui,cassetteIn,cassetteOut);
|
||||
parseLine(line,ram,rom,slts,revision,gui,cassetteIn,cassetteOut,apple2);
|
||||
}
|
||||
std::getline(*pConfig,line);
|
||||
}
|
||||
@ -201,11 +196,11 @@ void Config::parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revis
|
||||
|
||||
// TODO: make sure there is no more than ONE stdin and/or ONE stdout card
|
||||
}
|
||||
void Config::parseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
||||
void Config::parseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Apple2* apple2)
|
||||
{
|
||||
try
|
||||
{
|
||||
tryParseLine(line,ram,rom,slts,revision,gui,cassetteIn,cassetteOut);
|
||||
tryParseLine(line,ram,rom,slts,revision,gui,cassetteIn,cassetteOut,apple2);
|
||||
}
|
||||
catch (const ConfigException& err)
|
||||
{
|
||||
@ -220,7 +215,7 @@ static std::string filter_row(const std::string &row) {
|
||||
return std::string(1, static_cast<char>(std::toupper(row[0])));
|
||||
}
|
||||
|
||||
void Config::tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut)
|
||||
void Config::tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Apple2* apple2)
|
||||
{
|
||||
std::istringstream tok(line);
|
||||
|
||||
@ -456,10 +451,28 @@ void Config::tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memo
|
||||
throw ConfigException("error: unknown cassette command: "+cas);
|
||||
}
|
||||
}
|
||||
else if (cmd == "cpu")
|
||||
{
|
||||
std::string cpu;
|
||||
tok >> cpu;
|
||||
if (apple2 != NULL) {
|
||||
if (cpu == "epple2") {
|
||||
apple2->useEpple2Cpu();
|
||||
} else if (cpu == "visual6502") {
|
||||
apple2->useVisual6502Cpu();
|
||||
} else {
|
||||
throw ConfigException("invalid value for cpu command: "+cpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ConfigException("Invalid command: "+cmd);
|
||||
}
|
||||
|
||||
if (apple2 != NULL) {
|
||||
apple2->useEpple2Cpu(); // set default CPU
|
||||
}
|
||||
}
|
||||
|
||||
void Config::loadDisk(Slots& slts, int slot, int drive, const std::string& fnib)
|
||||
|
@ -25,6 +25,7 @@ class Slots;
|
||||
class ScreenImage;
|
||||
class CassetteIn;
|
||||
class CassetteOut;
|
||||
class Apple2;
|
||||
|
||||
class ConfigException {
|
||||
public:
|
||||
@ -41,14 +42,14 @@ private:
|
||||
static void unloadDisk(Slots& slts, int slot, int drive);
|
||||
static void saveDisk(Slots& slts, int slot, int drive);
|
||||
static void insertCard(const std::string& cardType, int slot, Slots& slts, ScreenImage& gui, std::istringstream& tok);
|
||||
static void tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
||||
static void tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Apple2* apple2);
|
||||
|
||||
public:
|
||||
Config(const std::string& file_path);
|
||||
~Config();
|
||||
|
||||
void parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
||||
static void parseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut);
|
||||
void parse(MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Apple2* apple2);
|
||||
static void parseLine(const std::string& line, MemoryRandomAccess& ram, Memory& rom, Slots& slts, int& revision, ScreenImage& gui, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Apple2* apple2);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,10 +18,11 @@
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#include "abstractcpu.h"
|
||||
class AddressBus;
|
||||
#include <istream>
|
||||
|
||||
class CPU
|
||||
{
|
||||
class CPU : public AbstractCpu {
|
||||
private:
|
||||
enum { MEMORY_LIM = 1 << 0x10 };
|
||||
enum { IRQ_VECTOR = MEMORY_LIM-2 }; // or BRK
|
||||
@ -43,7 +44,7 @@ private:
|
||||
bool pendingIRQ;
|
||||
bool pendingNMI;
|
||||
bool pendingReset;
|
||||
|
||||
|
||||
bool started;
|
||||
|
||||
unsigned char a;
|
||||
@ -205,7 +206,7 @@ private:
|
||||
|
||||
public:
|
||||
CPU(AddressBus& addressBus);
|
||||
~CPU();
|
||||
virtual ~CPU();
|
||||
|
||||
void powerOn();
|
||||
void reset();
|
||||
|
@ -72,7 +72,7 @@ void Emulator::powerOffComputer() {
|
||||
}
|
||||
|
||||
void Emulator::config(Config& cfg) {
|
||||
cfg.parse(this->apple2.ram, this->apple2.rom, this->apple2.slts, this->apple2.revision, this->screenImage, this->apple2.cassetteIn, this->apple2.cassetteOut);
|
||||
cfg.parse(this->apple2.ram, this->apple2.rom, this->apple2.slts, this->apple2.revision, this->screenImage, this->apple2.cassetteIn, this->apple2.cassetteOut, &this->apple2);
|
||||
this->apple2.ram.dump_config();
|
||||
}
|
||||
|
||||
@ -444,7 +444,7 @@ void Emulator::processCommand() {
|
||||
return;
|
||||
}
|
||||
|
||||
Config::parseLine(cmdline, this->apple2.ram, this->apple2.rom, this->apple2.slts, this->apple2.revision, this->screenImage, this->apple2.cassetteIn, this->apple2.cassetteOut);
|
||||
Config::parseLine(cmdline, this->apple2.ram, this->apple2.rom, this->apple2.slts, this->apple2.revision, this->screenImage, this->apple2.cassetteIn, this->apple2.cassetteOut, NULL);
|
||||
cmdline.erase(cmdline.begin(), cmdline.end());
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ class Emulator
|
||||
void dispatchKeyUp(const SDL_KeyboardEvent& keyEvent);
|
||||
void cmdKey(const SDL_KeyboardEvent& keyEvent);
|
||||
void processCommand();
|
||||
bool isSafeToQuit();
|
||||
bool isSafeToQuit();
|
||||
|
||||
public:
|
||||
Emulator();
|
||||
|
@ -44,9 +44,5 @@ void PowerUpReset::tick()
|
||||
|
||||
void PowerUpReset::powerOn()
|
||||
{
|
||||
#ifdef USE_EMU
|
||||
this->pendingTicks = 99; // TODO REMOVE THIS
|
||||
#else
|
||||
this->pendingTicks = (int)(E2Const::AVG_CPU_HZ*.3); // U.A.II, p. 7-15
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user