mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
Merge branch 'machine-pdm'.
This commit is contained in:
commit
d2cd43fcb1
70
devices/hmc.cpp
Normal file
70
devices/hmc.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-20 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** Highspeed Memory Controller emulation.
|
||||
|
||||
Author: Max Poliakovski
|
||||
*/
|
||||
|
||||
#include "hmc.h"
|
||||
|
||||
HMC::HMC() : MemCtrlBase()
|
||||
{
|
||||
this->name = "Highspeed Memory Controller";
|
||||
|
||||
/* add memory mapped I/O region for the HMC control register */
|
||||
add_mmio_region(0x50F40000, 0xFFFF, this);
|
||||
|
||||
this->config_reg = 0ULL;
|
||||
this->bit_pos = 0;
|
||||
}
|
||||
|
||||
bool HMC::supports_type(HWCompType type) {
|
||||
if (type == HWCompType::MEM_CTRL || type == HWCompType::MMIO_DEV) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HMC::read(uint32_t reg_start, uint32_t offset, int size)
|
||||
{
|
||||
if (!offset)
|
||||
return !!(this->config_reg & (1ULL << this->bit_pos++));
|
||||
else
|
||||
return 0; /* FIXME: what should be returned for invalid offsets? */
|
||||
}
|
||||
|
||||
void HMC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
|
||||
{
|
||||
uint64_t bit;
|
||||
|
||||
switch(offset) {
|
||||
case 0:
|
||||
bit = 1ULL << this->bit_pos++;
|
||||
this->config_reg = (value & 1) ? this->config_reg | bit :
|
||||
this->config_reg & ~bit;
|
||||
break;
|
||||
case 8: /* writing to HMCBase + 8 resets internal bit position */
|
||||
this->bit_pos = 0;
|
||||
break;
|
||||
}
|
||||
}
|
54
devices/hmc.h
Normal file
54
devices/hmc.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-20 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** Highspeed Memory Controller emulation.
|
||||
|
||||
Author: Max Poliakovski
|
||||
|
||||
Highspeed Memory Controller (HMC) is a custom memory
|
||||
and L2 cache controller designed especially for the
|
||||
first generation of the PowerMacintosh computer.
|
||||
*/
|
||||
|
||||
#ifndef HMC_H
|
||||
#define HMC_H
|
||||
|
||||
#include "hwcomponent.h"
|
||||
#include "memctrlbase.h"
|
||||
#include "mmiodevice.h"
|
||||
|
||||
class HMC : public MemCtrlBase, public MMIODevice {
|
||||
public:
|
||||
HMC();
|
||||
~HMC() = default;
|
||||
|
||||
bool supports_type(HWCompType type);
|
||||
|
||||
/* MMIODevice methods */
|
||||
uint32_t read(uint32_t reg_start, uint32_t offset, int size);
|
||||
void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
|
||||
|
||||
private:
|
||||
int bit_pos;
|
||||
uint64_t config_reg;
|
||||
};
|
||||
|
||||
#endif // HMC_H
|
@ -36,6 +36,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <thirdparty/loguru/loguru.hpp>
|
||||
|
||||
@ -76,6 +77,13 @@ static const PropMap GossamerSettings = {
|
||||
new IntProperty( 2, vector<uint32_t>({2, 4, 6}))},
|
||||
};
|
||||
|
||||
static const PropMap PDMSettings = {
|
||||
{"rambank1_size",
|
||||
new IntProperty(0, vector<uint32_t>({0, 8, 16, 32, 64, 128}))},
|
||||
{"rambank2_size",
|
||||
new IntProperty(0, vector<uint32_t>({0, 8, 16, 32, 64, 128}))},
|
||||
};
|
||||
|
||||
static const map<string, string> PropHelp = {
|
||||
{"rambank1_size", "specifies RAM bank 1 size in MB"},
|
||||
{"rambank2_size", "specifies RAM bank 2 size in MB"},
|
||||
@ -83,8 +91,9 @@ static const map<string, string> PropHelp = {
|
||||
{"gfxmem_size", "specifies video memory size in MB"},
|
||||
};
|
||||
|
||||
static const map<string, tuple<PropMap, function<int(void)>, string>> machines = {
|
||||
{"pmg3", {GossamerSettings, create_gossamer, "Power Macintosh G3 (Beige)"}},
|
||||
static const map<string, tuple<PropMap, function<int(string&)>, string>> machines = {
|
||||
{"pm6100", {PDMSettings, create_pdm, "PowerMacintosh 6100"}},
|
||||
{"pmg3", {GossamerSettings, create_gossamer, "Power Macintosh G3 (Beige)"}},
|
||||
};
|
||||
|
||||
string machine_name_from_rom(string& rom_filepath) {
|
||||
@ -267,7 +276,7 @@ int create_machine_for_id(string& id, string& rom_filepath) {
|
||||
auto machine = machines.at(id);
|
||||
|
||||
/* build machine and load boot ROM */
|
||||
if (get<1>(machine)() < 0 || load_boot_rom(rom_filepath) < 0) {
|
||||
if (get<1>(machine)(id) < 0 || load_boot_rom(rom_filepath) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} catch(out_of_range ex) {
|
||||
|
@ -42,6 +42,7 @@ void list_machines(void);
|
||||
void list_properties(void);
|
||||
|
||||
/* Machine-specific factory functions. */
|
||||
int create_gossamer(void);
|
||||
int create_gossamer(string& id);
|
||||
int create_pdm(string& id);
|
||||
|
||||
#endif /* MACHINE_FACTORY_H */
|
||||
|
@ -35,6 +35,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "machinebase.h"
|
||||
#include "machineproperties.h"
|
||||
#include <thirdparty/loguru/loguru.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
static void setup_ram_slot(std::string name, int i2c_addr, int capacity_megs) {
|
||||
@ -51,7 +52,7 @@ static void setup_ram_slot(std::string name, int i2c_addr, int capacity_megs) {
|
||||
}
|
||||
|
||||
|
||||
int create_gossamer() {
|
||||
int create_gossamer(std::string& id) {
|
||||
if (gMachineObj) {
|
||||
LOG_F(ERROR, "Global machine object not empty!");
|
||||
return -1;
|
||||
|
74
machines/machinepdm.cpp
Normal file
74
machines/machinepdm.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-20 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file Construct a PDM-style PowerMacintosh machine.
|
||||
|
||||
Author: Max Poliakovski
|
||||
*/
|
||||
|
||||
#include "cpu/ppc/ppcemu.h"
|
||||
#include "devices/hmc.h"
|
||||
#include "machinebase.h"
|
||||
#include "machineproperties.h"
|
||||
#include <string>
|
||||
|
||||
int create_pdm(std::string& id) {
|
||||
if (gMachineObj) {
|
||||
LOG_F(ERROR, "PDM Factory: global machine object not empty!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_F(INFO, "Initializing the %s hardware...", id.c_str());
|
||||
|
||||
/* initialize the global machine object */
|
||||
gMachineObj.reset(new MachineBase("PDM"));
|
||||
|
||||
/* register HMC memory controller */
|
||||
gMachineObj->add_component("HMC", new HMC);
|
||||
|
||||
/* get raw pointer to HMC object */
|
||||
HMC* hmc_obj = dynamic_cast<HMC*>(gMachineObj->get_comp_by_name("HMC"));
|
||||
|
||||
/* allocate ROM region */
|
||||
if (!hmc_obj->add_rom_region(0x40000000, 0x400000)) {
|
||||
LOG_F(ERROR, "Could not allocate ROM region!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mirror ROM to 0xFFC00000 for a PowerPC CPU to start */
|
||||
if (!hmc_obj->add_mem_mirror(0xFFC00000, 0x40000000)) {
|
||||
LOG_F(ERROR, "Could not create ROM mirror!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* add 8MB of soldered on-board RAM */
|
||||
if (!hmc_obj->add_ram_region(0x00000000, 0x800000)) {
|
||||
LOG_F(ERROR, "Could not allocate built-in RAM region!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Init virtual CPU and request MPC601 */
|
||||
ppc_cpu_init(hmc_obj, PPC_VER::MPC601);
|
||||
|
||||
LOG_F(INFO, "Initialization completed.\n");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user