mirror of
https://github.com/dingusdev/dingusppc.git
synced 2026-04-25 19:18:34 +00:00
machinegazelle: Use specified DIMM sizes.
Previously, only the total size of all DIMMs was used. For example, four 8 MB DIMMs would behave as a single 32 MB DIMM. This change forces handling of the individual DIMM sizes. We currently do not emulate shuffling of 4MB pages. For example, the data of the first page of bank 1 does not move if you move it to a different page. The important parts of this algorithm are: 1) DIMM sizes can be determined. 2) The final memory allocation will be a single contiguous block.
This commit is contained in:
+51
-11
@@ -75,12 +75,15 @@ void PsxCtrl::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int siz
|
||||
case PsxReg::Flash_Config:
|
||||
this->flash_cfg = value;
|
||||
break;
|
||||
case PsxReg::Page1_Mapping:
|
||||
case PsxReg::Page2_Mapping:
|
||||
case PsxReg::Page3_Mapping:
|
||||
case PsxReg::Page4_Mapping:
|
||||
case PsxReg::Page5_Mapping:
|
||||
this->pages_cfg[(offset >> 3) - PsxReg::Page1_Mapping] = value;
|
||||
case PsxReg::Page_Mappings_1:
|
||||
case PsxReg::Page_Mappings_2:
|
||||
case PsxReg::Page_Mappings_3:
|
||||
case PsxReg::Page_Mappings_4:
|
||||
case PsxReg::Page_Mappings_5:
|
||||
LOG_F(INFO, "PSX: write Page Mappings %d @%02x.%c = %0*x",
|
||||
(offset >> 3) - PsxReg::Page_Mappings_1 + 1, offset, SIZE_ARG(size), size * 2, value);
|
||||
this->pages_cfg[(offset >> 3) - PsxReg::Page_Mappings_1] = value;
|
||||
this->map_phys_ram();
|
||||
break;
|
||||
default:
|
||||
LOG_F(WARNING, "PSX: write to unsupported/read-only control register at 0x%X", offset);
|
||||
@@ -96,12 +99,11 @@ void PsxCtrl::insert_ram_dimm(int slot_num, uint32_t capacity)
|
||||
switch (capacity) {
|
||||
case 0:
|
||||
break;
|
||||
case DRAM_CAP_2MB:
|
||||
case DRAM_CAP_4MB:
|
||||
case DRAM_CAP_8MB:
|
||||
case DRAM_CAP_16MB:
|
||||
case DRAM_CAP_32MB:
|
||||
this->bank_sizes[slot_num] = capacity;
|
||||
this->bank_size[slot_num] = capacity;
|
||||
break;
|
||||
default:
|
||||
ABORT_F("PSX: unsupported DRAM capacity %d", capacity);
|
||||
@@ -111,13 +113,51 @@ void PsxCtrl::insert_ram_dimm(int slot_num, uint32_t capacity)
|
||||
void PsxCtrl::map_phys_ram()
|
||||
{
|
||||
uint32_t total_ram = 0;
|
||||
uint32_t bank_size_remaining[5];
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
total_ram += this->bank_sizes[i];
|
||||
bank_size_remaining[i] = this->bank_size[i];
|
||||
total_ram += this->bank_size[i];
|
||||
}
|
||||
|
||||
if (!add_ram_region(0x00000000, total_ram)) {
|
||||
ABORT_F("PSX: could not allocate RAM storage");
|
||||
if (!this->dram_ptr) {
|
||||
this->dram_ptr = std::unique_ptr<uint8_t[]> (new uint8_t[total_ram]()); /* () intializer clears the memory to zero */
|
||||
if (!this->dram_ptr) {
|
||||
ABORT_F("%s: could not allocate RAM storage", this->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ram_map.erase(std::remove_if(ram_map.begin(), ram_map.end(),
|
||||
[this](AddressMapEntry *entry) {
|
||||
delete this->remove_region(entry);
|
||||
return true;
|
||||
}
|
||||
), ram_map.end());
|
||||
|
||||
uint32_t ram_offset = -1;
|
||||
uint32_t mem_start = 0;
|
||||
for (int page = 0; page < 41; page++) {
|
||||
int bank = page >= 40 ? 8 : (this->pages_cfg[page / 8] >> ((page % 8) * 4)) & 15;
|
||||
//LOG_F(INFO, "page:%02d bank:%d", page, bank);
|
||||
if ((ram_offset == -1) == (bank < 5 && bank_size_remaining[bank] > 0)) {
|
||||
if (ram_offset == -1) {
|
||||
ram_offset = page * DRAM_CAP_4MB;
|
||||
//LOG_F(INFO, "ram_offset:%08x", ram_offset);
|
||||
} else {
|
||||
uint32_t mem_size = page * DRAM_CAP_4MB - ram_offset;
|
||||
AddressMapEntry *entry = this->add_ram_region(ram_offset, mem_size, &dram_ptr[mem_start]);
|
||||
mem_start += mem_size;
|
||||
ram_offset = -1;
|
||||
if (entry) {
|
||||
ram_map.push_back(entry);
|
||||
} else {
|
||||
ABORT_F("%s: could not allocate RAM storage", this->name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ram_offset != -1) {
|
||||
bank_size_remaining[bank] -= DRAM_CAP_4MB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,11 +40,11 @@ namespace PsxReg {
|
||||
DRAM_Config = 4,
|
||||
DRAM_Refresh = 5,
|
||||
Flash_Config = 6,
|
||||
Page1_Mapping = 8,
|
||||
Page2_Mapping = 9,
|
||||
Page3_Mapping = 10,
|
||||
Page4_Mapping = 11,
|
||||
Page5_Mapping = 12,
|
||||
Page_Mappings_1 = 8,
|
||||
Page_Mappings_2 = 9,
|
||||
Page_Mappings_3 = 10,
|
||||
Page_Mappings_4 = 11,
|
||||
Page_Mappings_5 = 12,
|
||||
Bus_Timeout = 13
|
||||
};
|
||||
} // namespace PsxReg
|
||||
@@ -81,8 +81,10 @@ private:
|
||||
uint32_t dram_cfg;
|
||||
uint32_t dram_refresh;
|
||||
uint32_t flash_cfg;
|
||||
uint32_t pages_cfg[5];
|
||||
uint32_t bank_sizes[5] = {};
|
||||
uint32_t pages_cfg[5] = {0x88888888,0x88888888,0x88888888,0x88888888,0x88888888};
|
||||
uint32_t bank_size[5] = {};
|
||||
std::unique_ptr<uint8_t[]> dram_ptr = nullptr;
|
||||
std::vector<AddressMapEntry*> ram_map;
|
||||
};
|
||||
|
||||
#endif // PSX_MEMCTRL_H
|
||||
|
||||
@@ -90,9 +90,6 @@ int MachineGazelle::initialize(const std::string &id) {
|
||||
psx_obj->insert_ram_dimm(3, GET_INT_PROP("rambank4_size") * DRAM_CAP_1MB);
|
||||
psx_obj->insert_ram_dimm(4, GET_INT_PROP("rambank5_size") * DRAM_CAP_1MB);
|
||||
|
||||
// allocate and map physical RAM
|
||||
psx_obj->map_phys_ram();
|
||||
|
||||
// configure CPU clocks
|
||||
uint64_t bus_freq = 50000000ULL;
|
||||
uint64_t timebase_freq = bus_freq / 4;
|
||||
|
||||
Reference in New Issue
Block a user