2020-02-28 16:04:28 +00:00
|
|
|
/*
|
|
|
|
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/>.
|
|
|
|
*/
|
2019-07-02 02:15:33 +00:00
|
|
|
|
|
|
|
//The main runfile - main.cpp
|
|
|
|
//This is where the magic begins
|
|
|
|
|
2020-02-24 03:59:10 +00:00
|
|
|
#include <thirdparty/loguru.hpp>
|
2019-07-02 02:15:33 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <map>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cinttypes>
|
|
|
|
#include <array>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <fstream>
|
|
|
|
#include <stdexcept>
|
2019-12-27 19:10:36 +00:00
|
|
|
#include "ppcemu.h"
|
2019-12-27 19:00:53 +00:00
|
|
|
#include "ppcmmu.h"
|
2020-01-06 02:46:23 +00:00
|
|
|
#include "memreadwrite.h"
|
2019-08-18 23:34:24 +00:00
|
|
|
#include "devices/mpc106.h"
|
2019-12-14 12:48:54 +00:00
|
|
|
#include "debugger/debugger.h"
|
2019-10-14 15:38:47 +00:00
|
|
|
#include "devices/machineid.h"
|
2019-08-23 21:34:19 +00:00
|
|
|
#include "devices/macio.h"
|
|
|
|
#include "devices/mpc106.h"
|
2019-07-02 02:15:33 +00:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2019-08-21 06:33:01 +00:00
|
|
|
/**
|
|
|
|
Power Macintosh ROM identification string
|
|
|
|
|
|
|
|
is located in the ConfigInfo structure starting at 0x30D064 (PCI Macs)
|
|
|
|
or 0x30C064 (Nubus Macs). This helps a lot to determine which
|
|
|
|
hardware is to be used.
|
|
|
|
*/
|
|
|
|
static const map<string,string> PPCMac_ROMIdentity = { //Codename Abbreviation for...
|
|
|
|
{"Alch", "Performa 6400"}, //Alchemy
|
|
|
|
{"Come", "PowerBook 2400"}, //Comet
|
|
|
|
{"Cord", "Power Mac 5200/6200 series"}, //Cordyceps
|
|
|
|
{"Gaze", "Power Mac 6500"}, //Gazelle
|
|
|
|
{"Goss", "Power Mac G3 Beige"}, //Gossamer
|
|
|
|
{"GRX ", "PowerBook G3 Wallstreet"}, //(Unknown)
|
|
|
|
{"Hoop", "PowerBook 3400"}, //Hooper
|
|
|
|
{"PBX ", "PowerBook Pre-G3"}, //(Unknown)
|
|
|
|
{"PDM ", "Nubus Power Mac or WGS"}, //Piltdown Man (6100/7100/8100)
|
|
|
|
{"Pip ", "Pippin... uh... yeah..."}, //Pippin
|
|
|
|
{"Powe", "Generic Power Mac"}, //PowerMac?
|
|
|
|
{"Spar", "20th Anniversay Mac, you lucky thing."}, //Spartacus
|
|
|
|
{"Tanz", "Power Mac 4400"}, //Tanzania
|
|
|
|
{"TNT ", "Power Mac 7xxxx/8xxx series"}, //Trinitrotoluene :-)
|
|
|
|
{"Zanz", "A complete engima."}, //Zanzibar (mentioned in Sheepshaver's code, but no match to any known ROM)
|
|
|
|
{"????", "A clone, perhaps?"} //N/A (Placeholder ID)
|
|
|
|
};
|
|
|
|
|
2019-08-23 21:34:19 +00:00
|
|
|
HeathrowIC *heathrow = 0;
|
2019-10-14 15:38:47 +00:00
|
|
|
GossamerID *machine_id;
|
2019-07-02 02:15:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
|
2019-07-12 05:27:14 +00:00
|
|
|
std::cout << "DingusPPC - Prototype 5bf4 (7/14/2019) " << endl;
|
2019-07-02 02:15:33 +00:00
|
|
|
std::cout << "Written by divingkatae, (c) 2019. " << endl;
|
|
|
|
std::cout << "This is not intended for general use. " << endl;
|
|
|
|
std::cout << "Use at your own discretion. " << endl;
|
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
if (argc > 1) {
|
|
|
|
string checker = argv[1];
|
|
|
|
cout << checker << endl;
|
2020-02-24 03:59:10 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
if ((checker == "1") || (checker == "realtime") || \
|
|
|
|
(checker == "-realtime") || (checker == "/realtime")) {
|
|
|
|
loguru::g_stderr_verbosity = loguru::Verbosity_OFF;
|
2020-02-28 01:41:02 +00:00
|
|
|
loguru::g_preamble_date = false;
|
|
|
|
loguru::g_preamble_time = false;
|
|
|
|
loguru::g_preamble_thread = false;
|
2020-02-27 02:51:07 +00:00
|
|
|
loguru::init(argc, argv);
|
|
|
|
loguru::add_file("dingusppc.log", loguru::Append, 0);
|
|
|
|
//Replace the above line with this for maximum debugging detail:
|
|
|
|
//loguru::add_file("dingusppc.log", loguru::Append, loguru::Verbosity_MAX);
|
|
|
|
}
|
|
|
|
else if ((checker == "debugger") || (checker == "/debugger") ||
|
|
|
|
(checker == "-debugger")) {
|
|
|
|
loguru::g_stderr_verbosity = 0;
|
2020-02-28 01:41:02 +00:00
|
|
|
loguru::g_preamble_date = false;
|
|
|
|
loguru::g_preamble_time = false;
|
|
|
|
loguru::g_preamble_thread = false;
|
|
|
|
loguru::init(argc, argv);
|
2020-02-27 02:51:07 +00:00
|
|
|
}
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
uint32_t rom_filesize;
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
/* Init virtual CPU and request MPC750 CPU aka G3 */
|
|
|
|
ppc_cpu_init(PPC_VER::MPC750);
|
2019-07-02 02:15:33 +00:00
|
|
|
|
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
LOG_F(INFO, "Checking for ROM file");
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
//Open the ROM File.
|
|
|
|
ifstream romFile;
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
romFile.open("rom.bin", ios::in|ios::binary);
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
if (romFile.fail()){
|
|
|
|
cerr << "rom.bin not present. Please provide an appropriate ROM file"
|
|
|
|
<< " and restart this program.\n";
|
2019-07-19 06:31:16 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
romFile.close();
|
|
|
|
return 1;
|
|
|
|
}
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
//Calculate and validate ROM file size.
|
|
|
|
romFile.seekg(0, romFile.end);
|
|
|
|
rom_filesize = (uint32_t) romFile.tellg();
|
|
|
|
LOG_F(INFO, "Rom SIZE: %d \n", rom_filesize);
|
|
|
|
romFile.seekg (0, romFile.beg);
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
if (rom_filesize != 0x400000){
|
|
|
|
cerr << "Unsupported ROM File size. Expected size is 4 megabytes.\n";
|
|
|
|
romFile.close();
|
|
|
|
return 1;
|
|
|
|
}
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
char configGrab = 0;
|
|
|
|
uint32_t configInfoOffset = 0;
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
romFile.seekg (0x300082, ios::beg); //This is where the place to get the offset is
|
|
|
|
romFile.get(configGrab); //just one byte to determine ConfigInfo location
|
|
|
|
configInfoOffset = (uint32_t)(configGrab & 0xff);
|
|
|
|
|
|
|
|
uint32_t configInfoAddr = 0x300000 + (configInfoOffset << 8) + 0x69; //address to check the identifier string
|
2020-02-28 04:03:01 +00:00
|
|
|
char memPPCBlock[5] = { 0 }; //First four chars are enough to distinguish between codenames
|
2020-02-27 02:51:07 +00:00
|
|
|
romFile.seekg (configInfoAddr, ios::beg);
|
|
|
|
romFile.read(memPPCBlock, 4);
|
|
|
|
memPPCBlock[4] = 0;
|
|
|
|
uint32_t rom_id = READ_DWORD_BE_A(memPPCBlock);
|
|
|
|
|
|
|
|
std::string string_test = std::string(memPPCBlock);
|
|
|
|
|
|
|
|
//Just auto-iterate through the list
|
|
|
|
for (auto iter = PPCMac_ROMIdentity.begin(); iter != PPCMac_ROMIdentity.end(); ){
|
|
|
|
|
|
|
|
string redo_me = iter->first;
|
|
|
|
|
|
|
|
if (string_test.compare(redo_me) == 0){
|
|
|
|
const char* check_me = iter->second.c_str();
|
|
|
|
LOG_F(INFO, "The machine is identified as... %s \n", check_me);
|
|
|
|
romFile.seekg (0x0, ios::beg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
iter++;
|
|
|
|
}
|
2019-07-02 04:54:12 +00:00
|
|
|
}
|
2019-07-02 02:15:33 +00:00
|
|
|
|
2019-08-21 06:33:01 +00:00
|
|
|
switch(rom_id) {
|
2020-02-27 02:51:07 +00:00
|
|
|
case 0x476F7373: {
|
|
|
|
LOG_F(INFO, "Initialize Gossamer hardware... \n");
|
|
|
|
MPC106 *mpc106 = new MPC106();
|
|
|
|
mem_ctrl_instance = mpc106;
|
|
|
|
if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000)) {
|
|
|
|
LOG_F(ERROR, "Failed to Gossamer hardware... \n");
|
|
|
|
delete(mem_ctrl_instance);
|
|
|
|
romFile.close();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
machine_id = new GossamerID(0x3d8c);
|
|
|
|
mpc106->add_mmio_region(0xFF000004, 4096, machine_id);
|
|
|
|
|
|
|
|
heathrow = new HeathrowIC();
|
|
|
|
mpc106->pci_register_device(16, heathrow);
|
2020-02-27 04:43:19 +00:00
|
|
|
LOG_F(INFO, "Initialization complete. \n");
|
2019-08-23 21:34:19 +00:00
|
|
|
}
|
2020-02-27 02:51:07 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
LOG_F(INFO, "This machine not supported yet. \n");
|
|
|
|
return 1;
|
2019-07-02 02:15:33 +00:00
|
|
|
}
|
2019-08-21 06:33:01 +00:00
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
/* Read ROM file content and transfer it to the dedicated ROM region */
|
|
|
|
unsigned char *sysrom_mem = new unsigned char[rom_filesize];
|
|
|
|
romFile.read ((char *)sysrom_mem, rom_filesize);
|
|
|
|
mem_ctrl_instance->set_data(0xFFC00000, sysrom_mem, rom_filesize);
|
|
|
|
romFile.close();
|
|
|
|
delete[] sysrom_mem;
|
2019-07-02 02:15:33 +00:00
|
|
|
|
|
|
|
|
2020-02-27 02:51:07 +00:00
|
|
|
if ((checker == "1") || (checker == "realtime") || \
|
|
|
|
(checker == "-realtime") || (checker == "/realtime")) {
|
2019-12-28 01:49:58 +00:00
|
|
|
ppc_exec();
|
2020-01-28 01:20:18 +00:00
|
|
|
} else if ((checker == "debugger") || (checker == "/debugger") ||
|
|
|
|
(checker == "-debugger")) {
|
2019-07-17 13:24:34 +00:00
|
|
|
enter_debugger();
|
2019-07-02 02:15:33 +00:00
|
|
|
}
|
|
|
|
}
|
2020-01-28 01:20:18 +00:00
|
|
|
else {
|
2020-02-28 01:41:02 +00:00
|
|
|
std::cout << " " << endl;
|
2019-07-07 06:10:32 +00:00
|
|
|
std::cout << "Please enter one of the following commands when " << endl;
|
|
|
|
std::cout << "booting up DingusPPC... " << endl;
|
2020-02-28 01:41:02 +00:00
|
|
|
std::cout << " " << endl;
|
|
|
|
std::cout << " " << endl;
|
2019-07-07 06:10:32 +00:00
|
|
|
std::cout << "realtime - Run the emulator in real-time. " << endl;
|
2019-07-19 06:31:16 +00:00
|
|
|
std::cout << "debugger - Enter the interactive debugger. " << endl;
|
2019-07-02 02:15:33 +00:00
|
|
|
}
|
|
|
|
|
2020-01-28 01:20:18 +00:00
|
|
|
/* Free memory after the emulation is completed. */
|
2019-08-23 21:34:19 +00:00
|
|
|
delete(heathrow);
|
2019-10-14 15:38:47 +00:00
|
|
|
delete(machine_id);
|
2019-08-21 06:33:01 +00:00
|
|
|
delete(mem_ctrl_instance);
|
2019-07-02 02:15:33 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|