From 1c360841f6bb78377f9d9c13edef8798e15efd91 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 7 Aug 2019 20:25:30 +0200 Subject: [PATCH] Define and connect basic PowerMac 6100 hardware. --- main.cpp | 6 +++++ makefile | 9 ++++--- pmac6100hw.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ pmac6100hw.h | 45 ++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 pmac6100hw.cpp create mode 100644 pmac6100hw.h diff --git a/main.cpp b/main.cpp index 0971a97..9458fff 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,7 @@ #include "mpc106.h" #include "openpic.h" #include "debugger.h" +#include "pmac6100hw.h" //#include #define max_16b_int 65535 @@ -596,6 +597,8 @@ int main(int argc, char **argv) //Copy the contents of the IO data and the ROM to memory appropriate locations. romFile.read ((char *)machine_sysrom_mem,grab_sysrom_size); + if (is_nubus) + pmac6100_init(); /* //Open the Disk File. @@ -867,6 +870,9 @@ int main(int argc, char **argv) romFile.close(); //Free memory after the emulation is completed. + if (machine_phys_map) + delete(machine_phys_map); + free(machine_sysram_mem); free(machine_upperiocontrol_mem); free(machine_iocontrolcdma_mem); diff --git a/makefile b/makefile index f727ef8..7552238 100644 --- a/makefile +++ b/makefile @@ -1,11 +1,11 @@ OBJS = main.o macioserial.o macscsi.o macswim3.o mpc106.o openpic.o poweropcodes.o \ ppcfpopcodes.o ppcgekkoopcodes.o ppcmemory.o ppcopcodes.o viacuda.o davbus.o \ - debugger.o addressmap.o + debugger.o addressmap.o pmac6100hw.o SOURCE = main.cpp macioserial.cpp macscsi.cpp macswim3.cpp mpc106.cpp openpic.cpp \ poweropcodes.cpp ppcfpopcodes.cpp ppcgekkoopcodes.cpp ppcmemory.cpp \ - ppcopcodes.cpp viacuda.cpp davbus.cpp debugger.cpp addressmap.cpp + ppcopcodes.cpp viacuda.cpp davbus.cpp debugger.cpp addressmap.cpp pmac6100hw.cpp HEADER = macioserial.h macscsi.h macswim3.h mpc106.h openpic.h ppcemumain.h ppcmemory.h \ - viacuda.h debugger.h addressmap.h + viacuda.h debugger.h addressmap.h pmac6100hw.h OUT = dingusppc CC = g++ FLAGS = -g -c -Wall -std=c++11 @@ -59,5 +59,8 @@ debugger.o: debugger.cpp addressmap.o: addressmap.cpp $(CC) $(FLAGS) addressmap.cpp +pmac6100hw.o: pmac6100hw.cpp + $(CC) $(FLAGS) pmac6100hw.cpp + clean: rm -f $(OBJS) $(OUT) diff --git a/pmac6100hw.cpp b/pmac6100hw.cpp new file mode 100644 index 0000000..1dc313f --- /dev/null +++ b/pmac6100hw.cpp @@ -0,0 +1,71 @@ +#include +#include "ppcemumain.h" +#include "pmac6100hw.h" +#include "addressmap.h" + + +/** ======== High-speed memory controller (HMC) implementation ======== */ +HMC::HMC() +{ + this->config_reg = 0ULL; + this->bit_pos = 0; +} + +uint32_t HMC::read(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 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; + } +} + + +/** Initialize Power Macintosh 6100 hardware. */ +void pmac6100_init() +{ + AddressMapEntry entry; + + machine_phys_map = new AddressMap(); + + /* add ROM and its mirror */ + entry = {0xFFC00000, 0xFFFFFFFF, 0, RT_ROM, 0, machine_sysrom_mem}; + machine_phys_map->add(entry); + + entry = {0x40000000, 0x403FFFFF, 0, RT_MIRROR | RT_ROM, 0, machine_sysrom_mem}; + machine_phys_map->add(entry); + + /* add soldered on-board RAM. FIXME: do it properly using memory objects */ + entry = {0x00000000, 0x007FFFFF, 0, RT_RAM, 0, machine_sysram_mem}; + machine_phys_map->add(entry); + + /* this machine has two SIMM slots, each of them can hold max. 128 MB RAM */ + /* SIMM slot 2 physical range: 0x08000000 - 0x0FFFFFFF */ + /* SIMM slot 1 physical range: 0x10000000 - 0x17FFFFFF */ + /* TODO: make those SIMM slots end-user configurable */ + + /* add high-speed memory controller I/O space */ + entry = {0x50F40000, 0x50F4FFFF, 0, RT_MMIO, new HMC()}; + machine_phys_map->add(entry); + + /* add read-only machine identification register */ + entry = {0x5FFFFFFC, 0x5FFFFFFF, 0, RT_MMIO, new CPUID(PM6100)}; + machine_phys_map->add(entry); + + printf("Machine initialization completed.\n"); +} diff --git a/pmac6100hw.h b/pmac6100hw.h new file mode 100644 index 0000000..baeaaa1 --- /dev/null +++ b/pmac6100hw.h @@ -0,0 +1,45 @@ +#ifndef PMAC_6100_HW_H +#define PMAC_6100_HW_H + +#include +#include "mmiodevice.h" + +/** Some Power macintosh IDs stored in the CPUID register */ +enum PMACID { + PM6100 = 0x3010, /* PowerMac 6100 */ + PM7100 = 0x3012, /* PowerMac 7100 */ + PM8100 = 0x3013, /* PowerMac 8100 */ +}; + + +/** ======== High-speed memory controller (HMC) ======== */ +class HMC : public MMIODevice { +public: + HMC(); + ~HMC() = default; + uint32_t read(uint32_t offset, int size); + void write(uint32_t offset, uint32_t value, int size); + +private: + int bit_pos; + uint64_t config_reg; +}; + + +/** CPUID is a read-only register containing machine identification (see PMACID) */ +class CPUID : public MMIODevice { +public: + CPUID(const uint32_t id) { + this->cpuid = (0xA55A << 16) | (id & 0xFFFF); }; + ~CPUID() = default; + uint32_t read(uint32_t offset, int size) { + return (cpuid >> (3 - (offset & 3)) * 8) & 0xFF; }; + void write(uint32_t offset, uint32_t value, int size) {}; /* not writable */ + +private: + uint32_t cpuid; +}; + +void pmac6100_init(void); + +#endif /* PMAC_6100_HW_H */