mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-21 23:29:51 +00:00
Rewrite MPC106 emualation from scratch.
From now on, ppcmemory delegates physical address translation to MPC106 on PowerMac Beige G3.
This commit is contained in:
parent
ac1f770f92
commit
2f06623c62
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
|
||||
# Ignore compiled object files
|
||||
*.o
|
||||
*.d
|
||||
|
||||
# Ignore generated executables
|
||||
dingusppc
|
||||
|
@ -5,368 +5,151 @@
|
||||
//if you want to distribute this.
|
||||
//(divingkatae#1017 on Discord)
|
||||
|
||||
//Functionality for the MPC106
|
||||
/** MPC106 (Grackle) emulation
|
||||
|
||||
Author: Max Poliakovski
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cinttypes>
|
||||
|
||||
#include "memctrlbase.h"
|
||||
#include "mmiodevice.h"
|
||||
#include "../viacuda.h"
|
||||
#include "mpc106.h"
|
||||
#include "../ppcemumain.h"
|
||||
#include "../ppcmemory.h"
|
||||
|
||||
bool mpc106_membound_change;
|
||||
bool mpc106_mem_approve; //Confirm memory transaction
|
||||
|
||||
uint32_t mpc106_address; // For fe000000 - fe00ffff
|
||||
uint32_t mpc_config_addr; // Device No. and Reg No. included
|
||||
uint32_t mpc_config_dat; // Value to write to the device
|
||||
uint32_t cust_grab_size; // Custom bit size
|
||||
|
||||
uint32_t mpc106_write_word;
|
||||
uint32_t mpc106_read_word;
|
||||
uint16_t mpc106_write_half;
|
||||
uint16_t mpc106_read_half;
|
||||
uint8_t mpc106_write_byte;
|
||||
uint8_t mpc106_read_byte;
|
||||
|
||||
uint8_t mpc106_word_custom_size;
|
||||
|
||||
//The below array is used for ROM banks
|
||||
//Top eight entries are for the starting addresses
|
||||
//Bottom eight entries are for the ending addresses
|
||||
uint32_t mpc106_memory_bounds[16] =
|
||||
MPC106::MPC106() : MemCtrlBase("Grackle")
|
||||
{
|
||||
0x00000, 0x00000, 0x00000, 0x00000,
|
||||
0x00000, 0x00000, 0x00000, 0x00000,
|
||||
0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF,
|
||||
0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF,
|
||||
};
|
||||
|
||||
//Entries are organized like so...
|
||||
|
||||
//ROM Banks 0-3 (ext. starting address) (starting address) (0x00000)
|
||||
//ROM Banks 4-7 (ext. starting address) (starting address) (0x00000)
|
||||
//ROM Banks 0-3 (ext. ending address) ( ending address) (0x00000)
|
||||
//ROM Banks 4-7 (ext. ending address) ( ending address) (0x00000)
|
||||
|
||||
void mpc106_init(){
|
||||
mpc_config_addr = 0;
|
||||
mpc_config_dat = 0;
|
||||
|
||||
//Initialize Vendor & Device IDs
|
||||
machine_fexxxx_mem[0x00] = 0x57;
|
||||
machine_fexxxx_mem[0x01] = 0x10;
|
||||
|
||||
machine_fexxxx_mem[0x02] = 0x02;
|
||||
|
||||
//PCI command + status
|
||||
machine_fexxxx_mem[0x04] = 0x06;
|
||||
machine_fexxxx_mem[0x06] = 0x80;
|
||||
|
||||
machine_fexxxx_mem[0x0B] = 0x06;
|
||||
machine_fexxxx_mem[0x0C] = 0x08;
|
||||
|
||||
machine_fexxxx_mem[0x73] = 0xCD;
|
||||
|
||||
machine_fexxxx_mem[0xA8] = 0x10;
|
||||
machine_fexxxx_mem[0xA9] = 0x00;
|
||||
machine_fexxxx_mem[0xAA] = 0x00;
|
||||
machine_fexxxx_mem[0xAB] = 0xFF;
|
||||
|
||||
machine_fexxxx_mem[0xAC] = 0x0C;
|
||||
machine_fexxxx_mem[0xAD] = 0x06;
|
||||
machine_fexxxx_mem[0xAE] = 0x0C;
|
||||
machine_fexxxx_mem[0xAF] = 0x00;
|
||||
|
||||
machine_fexxxx_mem[0xBA] = 0x04;
|
||||
machine_fexxxx_mem[0xC0] = 0x01;
|
||||
|
||||
machine_fexxxx_mem[0xE0] = 0x42;
|
||||
machine_fexxxx_mem[0xE1] = 0x00;
|
||||
machine_fexxxx_mem[0xE2] = 0xFF;
|
||||
machine_fexxxx_mem[0xE3] = 0x0F;
|
||||
|
||||
machine_fexxxx_mem[0xF0] = 0x00;
|
||||
machine_fexxxx_mem[0xF1] = 0x00;
|
||||
machine_fexxxx_mem[0xF2] = 0x02;
|
||||
machine_fexxxx_mem[0xF3] = 0xFF;
|
||||
|
||||
machine_fexxxx_mem[0xF4] = 0x03;
|
||||
machine_fexxxx_mem[0xF5] = 0x00;
|
||||
machine_fexxxx_mem[0xF6] = 0x00;
|
||||
machine_fexxxx_mem[0xF7] = 0x00;
|
||||
|
||||
machine_fexxxx_mem[0xFC] = 0x00;
|
||||
machine_fexxxx_mem[0xFD] = 0x00;
|
||||
machine_fexxxx_mem[0xFE] = 0x10;
|
||||
machine_fexxxx_mem[0xFF] = 0x00;
|
||||
|
||||
mpc106_mem_approve = false;
|
||||
mpc106_word_custom_size = 0;
|
||||
/* add memory mapped I/O region for MPC106 registers */
|
||||
add_mmio_region(0xFEC00000, 0x300000, this);
|
||||
}
|
||||
|
||||
uint32_t mpc106_write_device(uint32_t device_addr, uint32_t insert_to_device, uint8_t bit_length){
|
||||
//Write to the specified device - Invoked when a write is made to 0xFEExxxxx.
|
||||
//device_addr is what's stored in 0xFEC00CF8 (The MPG106/Grackle's CONFIG_ADDR Register).
|
||||
MPC106::~MPC106()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t reg_num = (device_addr & 0x07FC) >> 2;
|
||||
uint32_t dev_num = (device_addr & 0xF800) >> 11;
|
||||
uint32_t MPC106::read(uint32_t offset, int size)
|
||||
{
|
||||
if (offset >= 0x200000) {
|
||||
if (this->config_addr & 0x80) // process only if bit E (enable) is set
|
||||
return pci_read(size);
|
||||
}
|
||||
|
||||
switch(dev_num){
|
||||
case 0:
|
||||
//Device 0 is reserved to the grackle by default
|
||||
mpc106_address = reg_num;
|
||||
mpc106_write(insert_to_device);
|
||||
break;
|
||||
case 16:
|
||||
case 17:
|
||||
via_cuda_address = (reg_num << 9) + (dev_num << 12) + 0x3000000;
|
||||
via_write_byte = (uint8_t)insert_to_device;
|
||||
via_cuda_write();
|
||||
break;
|
||||
/* FIXME: reading from CONFIG_ADDR is ignored for now */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MPC106::write(uint32_t offset, uint32_t value, int size)
|
||||
{
|
||||
if (offset < 0x200000) {
|
||||
this->config_addr = value;
|
||||
} else {
|
||||
if (this->config_addr & 0x80) // process only if bit E (enable) is set
|
||||
return pci_write(value, size);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t MPC106::pci_read(uint32_t size)
|
||||
{
|
||||
int bus_num, dev_num, fun_num, reg_num;
|
||||
|
||||
bus_num = (this->config_addr >> 8) & 0xFF;
|
||||
if (bus_num) {
|
||||
std::cout << this->name << " err: read attempt from non-local PCI bus, "
|
||||
<< "config_addr = " << std::hex << this->config_addr << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_num = (this->config_addr >> 19) & 0x1F;
|
||||
fun_num = (this->config_addr >> 16) & 0x07;
|
||||
reg_num = (this->config_addr >> 24) & 0xFC;
|
||||
|
||||
if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself
|
||||
return myself_read(reg_num, size);
|
||||
} else {
|
||||
std::cout << this->name << " err: reading from device " << dev_num
|
||||
<< " not supported yet" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t mpc106_read_device(uint32_t device_addr, uint8_t bit_length){
|
||||
//Read to the specified device - Invoked when a read is made to 0xFEExxxxx.
|
||||
//device_addr is what's stored in 0xFEC00CF8 (The MPG106/Grackle's CONFIG_ADDR Register).
|
||||
void MPC106::pci_write(uint32_t value, uint32_t size)
|
||||
{
|
||||
int bus_num, dev_num, fun_num, reg_num;
|
||||
|
||||
uint32_t reg_num = (device_addr & 0x07FC) >> 2;
|
||||
uint32_t dev_num = (device_addr & 0xF800) >> 11;
|
||||
bus_num = (this->config_addr >> 8) & 0xFF;
|
||||
if (bus_num) {
|
||||
std::cout << this->name << " err: write attempt to non-local PCI bus, "
|
||||
<< "config_addr = " << std::hex << this->config_addr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t grab_value = 0;
|
||||
dev_num = (this->config_addr >> 19) & 0x1F;
|
||||
fun_num = (this->config_addr >> 16) & 0x07;
|
||||
reg_num = (this->config_addr >> 24) & 0xFC;
|
||||
|
||||
switch(dev_num){
|
||||
case 0:
|
||||
//Device 0 is reserved to the grackle by default
|
||||
mpc106_address = reg_num;
|
||||
mpc106_read();
|
||||
grab_value = mpc106_read_word;
|
||||
if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself
|
||||
myself_write(reg_num, value, size);
|
||||
} else {
|
||||
std::cout << this->name << " err: writing to device " << dev_num
|
||||
<< " not supported yet" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t MPC106::myself_read(int reg_num, uint32_t size)
|
||||
{
|
||||
#ifdef MPC106_DEBUG
|
||||
printf("read from Grackle register %08X\n", reg_num);
|
||||
#endif
|
||||
|
||||
switch(size) {
|
||||
case 1:
|
||||
return this->my_pci_cfg_hdr[reg_num];
|
||||
break;
|
||||
case 16:
|
||||
case 17:
|
||||
via_cuda_address = (reg_num << 8) + (dev_num << 12) + 0x3000000;
|
||||
via_cuda_read();
|
||||
grab_value = (uint32_t)via_read_byte;
|
||||
case 2:
|
||||
return READ_WORD_BE(&this->my_pci_cfg_hdr[reg_num]);
|
||||
break;
|
||||
}
|
||||
|
||||
return grab_value;
|
||||
}
|
||||
|
||||
bool mpc106_check_membound(uint32_t attempted_address){
|
||||
uint32_t mem_address_begin;
|
||||
uint32_t mem_address_end;
|
||||
for (int get_rom_bank = 0; get_rom_bank < 8; get_rom_bank++){
|
||||
mem_address_begin = mpc106_memory_bounds[get_rom_bank];
|
||||
mem_address_end = mpc106_memory_bounds[get_rom_bank + 8];
|
||||
if ((attempted_address >= mem_address_begin) & (attempted_address <= mem_address_end)){
|
||||
uint8_t is_valid = (machine_fexxxx_mem[0xA0] >> get_rom_bank) & 0x01;
|
||||
if (is_valid == 0){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void mpc106_set_membound_begin(uint8_t bound_area){
|
||||
uint32_t bcheck_area = 0x80 + bound_area;
|
||||
uint32_t newbound = machine_fexxxx_mem[bcheck_area];
|
||||
uint32_t bound_entry = bound_area % 8;
|
||||
uint32_t change_entry = mpc106_memory_bounds[bound_entry];
|
||||
change_entry &= 0xfffff;
|
||||
change_entry = newbound << 20;
|
||||
mpc106_memory_bounds[bound_entry] = change_entry;
|
||||
}
|
||||
|
||||
void mpc106_set_membound_extbegin(uint8_t bound_area){
|
||||
uint32_t bcheck_area = 0x88 + bound_area;
|
||||
uint32_t newbound = machine_fexxxx_mem[bcheck_area];
|
||||
uint32_t bound_entry = bound_area % 8;
|
||||
uint32_t change_entry = mpc106_memory_bounds[bound_entry];
|
||||
change_entry &= 0x0fffffff;
|
||||
change_entry = (newbound & 0x3) << 28;
|
||||
mpc106_memory_bounds[bound_entry] = change_entry;
|
||||
}
|
||||
|
||||
void mpc106_set_membound_end(uint8_t bound_area){
|
||||
uint32_t bcheck_area = 0x90 + bound_area;
|
||||
uint32_t newbound = machine_fexxxx_mem[bcheck_area];
|
||||
uint32_t bound_entry = (bound_area % 8) + 8;
|
||||
uint32_t change_entry = mpc106_memory_bounds[bound_entry];
|
||||
change_entry &= 0xfffff;
|
||||
change_entry = newbound << 20;
|
||||
mpc106_memory_bounds[bound_entry] = change_entry;
|
||||
}
|
||||
|
||||
void mpc106_set_membound_extend(uint8_t bound_area){
|
||||
uint32_t bcheck_area = 0x98 + bound_area;
|
||||
uint32_t newbound = machine_fexxxx_mem[bcheck_area];
|
||||
uint32_t bound_entry = (bound_area % 8) + 8;
|
||||
uint32_t change_entry = mpc106_memory_bounds[bound_entry];
|
||||
change_entry &= 0x0fffffff;
|
||||
change_entry = (newbound & 0x3) << 28;
|
||||
mpc106_memory_bounds[bound_entry] = change_entry;
|
||||
}
|
||||
|
||||
void mpc106_read(){
|
||||
|
||||
uint8_t read_length = 4;
|
||||
|
||||
|
||||
if ((mpc106_address >= 0x80) | (mpc106_address < 0xA0)){
|
||||
mpc106_membound_change = true;
|
||||
read_length = mpc106_word_custom_size;
|
||||
}
|
||||
else{
|
||||
switch (mpc106_address){
|
||||
case 0x8:
|
||||
case 0x9:
|
||||
case 0xA:
|
||||
case 0xB:
|
||||
case 0xC:
|
||||
case 0xD:
|
||||
case 0xE:
|
||||
case 0xF:
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
case 0x3E:
|
||||
case 0x3F:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0xA0:
|
||||
case 0xA3:
|
||||
read_length = 1;
|
||||
case 4:
|
||||
return READ_DWORD_BE(&this->my_pci_cfg_hdr[reg_num]);
|
||||
break;
|
||||
case 0x0:
|
||||
case 0x2:
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
case 0x70:
|
||||
read_length = 2;
|
||||
default:
|
||||
std::cout << "MPC106 read error: invalid size parameter " << size
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MPC106::myself_write(int reg_num, uint32_t value, uint32_t size)
|
||||
{
|
||||
#ifdef MPC106_DEBUG
|
||||
printf("write %08X to Grackle register %08X\n", value, reg_num);
|
||||
#endif
|
||||
|
||||
// FIXME: implement write-protection for read-only registers
|
||||
switch(size) {
|
||||
case 1:
|
||||
this->my_pci_cfg_hdr[reg_num] = value & 0xFF;
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF4:
|
||||
case 0xF8:
|
||||
case 0xFC:
|
||||
read_length = 4;
|
||||
default: //Avoid writing into reserved areas
|
||||
read_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(read_length){
|
||||
case 1:
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address]);
|
||||
break;
|
||||
case 2:
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address++]);
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address]) << 8;
|
||||
break;
|
||||
case 4:
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address++]);
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address++]) << 8;
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address++]) << 16;
|
||||
mpc106_read_word |= (grab_macmem_ptr[mpc106_address]) << 24;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mpc106_write(uint32_t write_word){
|
||||
|
||||
uint8_t write_length = 4;
|
||||
|
||||
if ((mpc106_address >= 0x80) | (mpc106_address < 0xA0)){
|
||||
mpc106_membound_change = true;
|
||||
write_length = mpc106_word_custom_size;
|
||||
}
|
||||
else{
|
||||
switch (mpc106_address){
|
||||
case 0x70:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0xA0:
|
||||
case 0xA3:
|
||||
write_length = 1;
|
||||
break;
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
write_length = 2;
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF4:
|
||||
case 0xF8:
|
||||
case 0xFC:
|
||||
write_length = 4;
|
||||
default: //Avoid writing into reserved areas
|
||||
write_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mpc106_membound_change){
|
||||
switch(write_length){
|
||||
case 1:
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word) & 0xFF);
|
||||
break;
|
||||
case 2:
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word) & 0xFF);
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word >> 8) & 0xFF);
|
||||
break;
|
||||
case 4:
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word) & 0xFF);
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word >> 8) & 0xFF);
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word >> 16) & 0xFF);
|
||||
change_membound_time();
|
||||
grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word >> 24) & 0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
switch(write_length){
|
||||
case 1:
|
||||
grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word) & 0xFF);
|
||||
break;
|
||||
case 2:
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word) & 0xFF);
|
||||
grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word >> 8) & 0xFF);
|
||||
break;
|
||||
case 4:
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word) & 0xFF);
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word >> 8) & 0xFF);
|
||||
grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word >> 16) & 0xFF);
|
||||
grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word >> 24) & 0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void change_membound_time(){
|
||||
if (mpc106_address < 0x88){
|
||||
mpc106_set_membound_begin(mpc106_address);
|
||||
mpc106_membound_change = false;
|
||||
}
|
||||
else if (mpc106_address < 0x90){
|
||||
mpc106_set_membound_extbegin(mpc106_address);
|
||||
mpc106_membound_change = false;
|
||||
}
|
||||
else if (mpc106_address < 0x98){
|
||||
mpc106_set_membound_end(mpc106_address);
|
||||
mpc106_membound_change = false;
|
||||
}
|
||||
else if (mpc106_address < 0xA0){
|
||||
mpc106_set_membound_extend(mpc106_address);
|
||||
mpc106_membound_change = false;
|
||||
case 2:
|
||||
this->my_pci_cfg_hdr[reg_num] = (value >> 8) & 0xFF;
|
||||
this->my_pci_cfg_hdr[reg_num+1] = value & 0xFF;
|
||||
break;
|
||||
case 4:
|
||||
this->my_pci_cfg_hdr[reg_num] = (value >> 24) & 0xFF;
|
||||
this->my_pci_cfg_hdr[reg_num+1] = (value >> 16) & 0xFF;
|
||||
this->my_pci_cfg_hdr[reg_num+2] = (value >> 8) & 0xFF;
|
||||
this->my_pci_cfg_hdr[reg_num+3] = value & 0xFF;
|
||||
break;
|
||||
default:
|
||||
std::cout << "MPC106 read error: invalid size parameter " << size
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -5,34 +5,71 @@
|
||||
//if you want to distribute this.
|
||||
//(divingkatae#1017 on Discord)
|
||||
|
||||
//Functionality for the MPC106
|
||||
/** MPC106 (Grackle) emulation
|
||||
|
||||
Author: Max Poliakovski
|
||||
|
||||
Grackle IC is a combined memory and PCI controller manufactored by Motorola.
|
||||
It's the central device in the Gossamer architecture.
|
||||
Manual: https://www.nxp.com/docs/en/reference-manual/MPC106UM.pdf
|
||||
|
||||
This code emulate as much functionality as needed to run PowerMac Beige G3.
|
||||
This implies that
|
||||
- we only support address map B
|
||||
- our virtual device reports revision 4.0 as expected by machine firmware
|
||||
*/
|
||||
|
||||
#ifndef MPC106_H_
|
||||
#define MPC106_H_
|
||||
|
||||
#define mpc106_addres_map_a 1
|
||||
#define mpc106_addres_map_b 0
|
||||
#include <cinttypes>
|
||||
#include "memctrlbase.h"
|
||||
#include "mmiodevice.h"
|
||||
|
||||
extern uint32_t mpc106_address;
|
||||
extern uint32_t mpc_config_addr;
|
||||
extern uint32_t mpc_config_dat;
|
||||
|
||||
extern uint32_t mpc106_write_word;
|
||||
extern uint32_t mpc106_read_word;
|
||||
extern uint16_t mpc106_write_half;
|
||||
extern uint16_t mpc106_read_half;
|
||||
extern uint8_t mpc106_write_byte;
|
||||
extern uint8_t mpc106_read_byte;
|
||||
extern uint8_t mpc106_word_custom_size;
|
||||
class MPC106 : public MemCtrlBase, public MMIODevice
|
||||
{
|
||||
public:
|
||||
using MemCtrlBase::name;
|
||||
|
||||
extern unsigned char* mpc106_regs;
|
||||
MPC106();
|
||||
~MPC106();
|
||||
uint32_t read(uint32_t offset, int size);
|
||||
void write(uint32_t offset, uint32_t value, int size);
|
||||
|
||||
extern void change_membound_time();
|
||||
extern void mpc106_init();
|
||||
extern void mpc106_read();
|
||||
extern void mpc106_write(uint32_t write_word);
|
||||
extern uint32_t mpc106_write_device(uint32_t device_addr, uint32_t insert_to_device, uint8_t bit_length);
|
||||
extern uint32_t mpc106_read_device(uint32_t device_addr, uint8_t bit_length);
|
||||
extern bool mpc106_check_membound(uint32_t attempted_address);
|
||||
protected:
|
||||
/* PCI access */
|
||||
uint32_t pci_read(uint32_t size);
|
||||
void pci_write(uint32_t value, uint32_t size);
|
||||
|
||||
/* my own registers access */
|
||||
uint32_t myself_read(int reg_num, uint32_t size);
|
||||
void myself_write(int reg_num, uint32_t value, uint32_t size);
|
||||
|
||||
private:
|
||||
uint8_t my_pci_cfg_hdr[256] = {
|
||||
0x57, 0x10, // vendor ID: Motorola
|
||||
0x02, 0x00, // device ID: MPC106
|
||||
0x06, 0x00, // PCI command
|
||||
0x80, 0x00, // PCI status
|
||||
0x40, // revision ID: 4.0
|
||||
0x00, // standard programming
|
||||
0x00, // subclass code
|
||||
0x06, // class code
|
||||
[0x73] = 0xCD, // default value for ODCR
|
||||
[0xA8] = 0x10, 0x00, 0x00, 0xFF, // PICR1
|
||||
[0xAC] = 0x0C, 0x06, 0x0C, 0x00, // PICR2
|
||||
[0xBA] = 0x04,
|
||||
[0xC0] = 0x01,
|
||||
[0xE0] = 0x42, 0x00, 0xFF, 0x0F,
|
||||
[0xE8] = 0x20,
|
||||
[0xF0] = 0x00, 0x00, 0x02, 0xFF,
|
||||
[0xF4] = 0x03,
|
||||
[0xFC] = 0x00, 0x00, 0x10, 0x00
|
||||
};
|
||||
|
||||
uint32_t config_addr;
|
||||
//uint32_t config_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
225
main.cpp
225
main.cpp
@ -38,6 +38,33 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
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)
|
||||
};
|
||||
|
||||
|
||||
SetPRS ppc_state;
|
||||
|
||||
bool power_on = 1;
|
||||
@ -55,6 +82,7 @@ uint32_t ppc_next_instruction_address; //Used for branching, setting up the NIA
|
||||
|
||||
uint32_t return_value;
|
||||
|
||||
MemCtrlBase *mem_ctrl_instance = 0;
|
||||
|
||||
//A pointer to a pointer, used for quick movement to one of the following
|
||||
//memory areas. These are listed right below.
|
||||
@ -90,7 +118,7 @@ bool msr_es_change; //Check Endian
|
||||
uint32_t rom_file_begin; //where to start storing ROM files in memory
|
||||
uint32_t pci_io_end;
|
||||
|
||||
uint32_t rom_file_setsize;
|
||||
uint32_t rom_filesize;
|
||||
|
||||
clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly.
|
||||
|
||||
@ -397,26 +425,14 @@ int main(int argc, char **argv)
|
||||
|
||||
rom_file_begin = 0xFFF00000; //where to start storing ROM files in memory
|
||||
pci_io_end = 0x83FFFFFF;
|
||||
rom_file_setsize = 0x400000;
|
||||
rom_filesize = 0x400000;
|
||||
|
||||
//Init virtual CPU.
|
||||
reg_init();
|
||||
|
||||
/**
|
||||
uint16_t test_endianness = 0x1234;
|
||||
|
||||
//Test for endianess before beginning
|
||||
uint8_t grab_result = (uint8_t) (test_endianness >> 8);
|
||||
endian_switch endis;
|
||||
|
||||
//Special case for little-endian machines
|
||||
switch(unsigned(grab_result)){
|
||||
case 18:
|
||||
endis = little_end;
|
||||
break;
|
||||
default:
|
||||
endis = big_end;
|
||||
}
|
||||
**/
|
||||
//0xFFF00100 is where the reset vector is.
|
||||
//In other words, begin executing code here.
|
||||
ppc_state.ppc_pc = 0xFFF00100;
|
||||
|
||||
uint32_t opcode_entered = 0; //used for testing opcodes in playground
|
||||
|
||||
@ -431,38 +447,25 @@ int main(int argc, char **argv)
|
||||
romFile.open("rom.bin", ios::in|ios::binary);
|
||||
|
||||
if (romFile.fail()){
|
||||
cerr << "rom.bin not present. Creating it right now. Please restart this program.\n";
|
||||
std::ofstream outfile ("rom.bin", ios::binary);
|
||||
|
||||
outfile << "Testing!" << std::endl;
|
||||
|
||||
outfile.close();
|
||||
cerr << "rom.bin not present. Please provide an appropriate ROM file"
|
||||
<< "and restart this program.\n";
|
||||
|
||||
romFile.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Allocate memory for ROM, RAM, and I/O.
|
||||
//Calculate and validate ROM file size.
|
||||
romFile.seekg(0, romFile.end);
|
||||
rom_file_setsize = romFile.tellg();
|
||||
printf("Rom SIZE: %d \n", rom_file_setsize);
|
||||
rom_filesize = romFile.tellg();
|
||||
printf("Rom SIZE: %d \n", rom_filesize);
|
||||
romFile.seekg (0, romFile.beg);
|
||||
|
||||
/**
|
||||
Allocate memory wisely.
|
||||
if (rom_filesize != 0x400000){
|
||||
cerr << "Unsupported ROM File size. Expected size is 4 megabytes.\n";
|
||||
romFile.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
Corresponds (mostly) to the follow memory patterns seen in
|
||||
https://www.nxp.com/docs/en/reference-manual/MPC106UM.pdf
|
||||
|
||||
machine_sysram_mem - 0x00000000 to 0x7FFFFFFF
|
||||
machine_upperiocontrol_mem - 0x80000000 to 0x807FFFFF
|
||||
machine_iocontrolcdma_mem - 0x80800000 to 0x80FFFFFF
|
||||
machine_loweriocontrol_mem - 0x81000000 to 0xBF7FFFFF
|
||||
machine_interruptack_mem - 0xBFFFFFF0 to 0xBFFFFFFF
|
||||
machine_iocontrolmem_mem - 0xC0000000 to 0xFFBFFFFF
|
||||
machine_sysrom_mem - 0xFFC00000 to 0xFFFFFFFF
|
||||
**/
|
||||
|
||||
//grab_disk_buf = (unsigned char*) calloc (32768, 1);
|
||||
machine_sysram_mem = (unsigned char*) calloc (67108864, 1);
|
||||
machine_sysconfig_mem = (unsigned char*) calloc (2048, 1);
|
||||
machine_upperiocontrol_mem = (unsigned char*) calloc (8388608, 1);
|
||||
@ -476,7 +479,7 @@ int main(int argc, char **argv)
|
||||
machine_feexxx_mem = (unsigned char*) calloc (4096, 1);
|
||||
machine_ff00xx_mem = (unsigned char*) calloc (4096, 1);
|
||||
machine_ff80xx_mem = (unsigned char*) calloc (1048576, 1);
|
||||
machine_sysrom_mem = (unsigned char*) calloc (rom_file_setsize, 1);
|
||||
machine_sysrom_mem = (unsigned char*) calloc (rom_filesize, 1);
|
||||
|
||||
memset(machine_sysram_mem, 0x0, 67108864);
|
||||
memset(machine_sysconfig_mem, 0x0, 2048);
|
||||
@ -492,19 +495,10 @@ int main(int argc, char **argv)
|
||||
memset(machine_ff80xx_mem, 0x0, 1048576);
|
||||
|
||||
grab_sysram_size = sizeof(machine_sysram_mem);
|
||||
grab_sysrom_size = rom_file_setsize;
|
||||
grab_sysrom_size = rom_filesize;
|
||||
|
||||
//Sanity checks - Prevent the input files being too small or too big.
|
||||
//Also prevent the ROM area from overflow.
|
||||
if (grab_sysrom_size < 0x100000){
|
||||
cerr << "ROM File is too small. Must be at least 1 megabyte.\n";
|
||||
return 1;
|
||||
}
|
||||
else if (grab_sysrom_size > 0x400000){
|
||||
cerr << "ROM File is too big. Must be no more than 4 megabytes.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ram_size_set < 0x800000){
|
||||
cerr << "The RAM size must be at least 8 MB to function.\n";
|
||||
return 1;
|
||||
@ -516,41 +510,11 @@ int main(int argc, char **argv)
|
||||
|
||||
rom_file_begin = 0xFFFFFFFF - grab_sysrom_size + 1;
|
||||
|
||||
/**
|
||||
Test for PowerPC Mac ROMS
|
||||
|
||||
Starting at 0x30D064 (0x30C064 in older ROMS), there is a boot
|
||||
identifier string in the ROM. This helps a lot to determine which
|
||||
setup is to by used.
|
||||
**/
|
||||
char * memPPCBlock = new char[5];
|
||||
|
||||
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 ", "Power Mac G1 or WGS"}, //(Unknown)
|
||||
{"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)
|
||||
};
|
||||
|
||||
char configGrab = 0;
|
||||
uint32_t configInfoOffset = 0;
|
||||
|
||||
if (grab_sysrom_size == 0x400000){
|
||||
|
||||
romFile.seekg (0x300082, ios::beg); //This is where the place to get the offset is
|
||||
romFile.get(configGrab); //just one byte to determine where the identifier string is
|
||||
romFile.get(configGrab); //just one byte to determine ConfigInfo location
|
||||
configInfoOffset = (uint32_t)(configGrab & 0xff);
|
||||
|
||||
if (configInfoOffset == 0xC0){
|
||||
@ -558,8 +522,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
uint32_t configInfoAddr = 0x300000 + (configInfoOffset << 8) + 0x69; //address to check the identifier string
|
||||
char memPPCBlock[5]; //First four chars are enough to distinguish between codenames
|
||||
romFile.seekg (configInfoAddr, ios::beg);
|
||||
romFile.read(memPPCBlock, sizeof(uint32_t)); //Only four chars needed to distinguish between codenames
|
||||
romFile.read(memPPCBlock, 4);
|
||||
memPPCBlock[4] = 0;
|
||||
uint32_t rom_id = (memPPCBlock[0] << 24) | (memPPCBlock[1] << 16) | (memPPCBlock[2] << 8) | memPPCBlock[3];
|
||||
|
||||
std::string string_test = std::string(memPPCBlock);
|
||||
|
||||
@ -571,58 +538,35 @@ int main(int argc, char **argv)
|
||||
if (string_test.compare(redo_me) == 0){
|
||||
cout << "The machine is identified as..." << iter->second << endl;
|
||||
romFile.seekg (0x0, ios::beg);
|
||||
|
||||
//This is where the first real instruction is in the ROM
|
||||
//0xFFF00000 - 0xFFF02FFF is for the exception table,
|
||||
//which is stored in all PPC ROMs here, btw.
|
||||
|
||||
//0xFFF00100 is where the reset vector is.
|
||||
//In other words, begin executing code here.
|
||||
|
||||
ppc_state.ppc_pc = 0xFFF00100;//Please don't move this from here.
|
||||
//A strange bug will happen where this will prevent proper branching
|
||||
mpc106_init();
|
||||
mac_serial_init();
|
||||
mac_swim3_init();
|
||||
via_cuda_init();
|
||||
openpic_init();
|
||||
break;
|
||||
}
|
||||
else{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
switch(rom_id) {
|
||||
case 0x476F7373:
|
||||
cout << "Initialize Gossamer hardware...";
|
||||
mem_ctrl_instance = new MPC106();
|
||||
if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000) ||
|
||||
!mem_ctrl_instance->add_ram_region(0x00000000, 0x800000)) {
|
||||
cout << "failure!\n" << endl;
|
||||
delete(mem_ctrl_instance);
|
||||
romFile.close();
|
||||
return 1;
|
||||
}
|
||||
cout << "done" << endl;
|
||||
break;
|
||||
default:
|
||||
cout << "This machine not supported yet." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Copy the contents of the IO data and the ROM to memory appropriate locations.
|
||||
//Read ROM file content and transfer it to the dedicated ROM region
|
||||
romFile.read ((char *)machine_sysrom_mem,grab_sysrom_size);
|
||||
|
||||
/*
|
||||
//Open the Disk File.
|
||||
uint64_t disk_file_setsize = 0;
|
||||
ifstream diskFile;
|
||||
|
||||
diskFile.open("disk.img", ios::in|ios::binary);
|
||||
|
||||
if (diskFile){
|
||||
diskFile.seekg(0, romFile.end);
|
||||
disk_file_setsize = romFile.tellg();
|
||||
diskFile.seekg(0, romFile.beg);
|
||||
|
||||
if (disk_file_setsize % 32678 != 0){
|
||||
cout << "WARNING - Disk file has improper offsets. Make sure the disk image has even 32 KB sectors." << endl;
|
||||
}
|
||||
else{
|
||||
//Copy the contents of the IO data and the ROM to memory appropriate locations.
|
||||
diskFile.read ((char *)machine_sysram_mem,(sizeof(uint8_t)*0x8000));
|
||||
disk_inserted = 1;
|
||||
disk_offset = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
disk_inserted = 0;
|
||||
}
|
||||
*/
|
||||
mem_ctrl_instance->set_data(0xFFC00000, machine_sysrom_mem, rom_filesize);
|
||||
romFile.close();
|
||||
|
||||
clock_test_begin = clock();
|
||||
|
||||
@ -641,29 +585,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else if ((checker=="1")|(checker=="realtime")|(checker=="/realtime")|(checker=="-realtime")){
|
||||
execute_interpreter();
|
||||
/*
|
||||
if (disk_inserted){
|
||||
if (disk_word == 32768){
|
||||
if (disk_offset < disk_file_setsize){
|
||||
disk_offset += 32768;
|
||||
diskFile.seekg(disk_offset, romFile.beg);
|
||||
char *ptr = ((char*)machine_iocontrolmem_mem + (0xF3008000 % 0x4000000));
|
||||
diskFile.read (ptr,(sizeof(uint8_t)*0x8000));
|
||||
disk_word = 0;
|
||||
}
|
||||
else{
|
||||
disk_offset = 0;
|
||||
diskFile.seekg(0, romFile.beg);
|
||||
char *ptr = ((char*)machine_iocontrolmem_mem + (0xF3008000 % 0x4000000));
|
||||
diskFile.read (ptr,(sizeof(uint8_t)*0x8000));
|
||||
disk_word = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
disk_word += 4;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if ((checker=="e")|(checker=="loadelf")|(checker=="/loadelf")|(checker=="-loadelf")){
|
||||
ifstream elfFile;
|
||||
@ -864,7 +785,7 @@ int main(int argc, char **argv)
|
||||
std::cout << "playground - Mess around with and opcodes. " << endl;
|
||||
}
|
||||
|
||||
romFile.close();
|
||||
delete(mem_ctrl_instance);
|
||||
|
||||
//Free memory after the emulation is completed.
|
||||
free(machine_sysram_mem);
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "devices/memctrlbase.h"
|
||||
|
||||
//Uncomment this to help debug the emulator further
|
||||
//#define EXHAUSTIVE_DEBUG 1
|
||||
|
||||
@ -96,7 +98,7 @@ extern uint32_t ram_size_set;
|
||||
extern uint32_t rom_file_begin; //where to start storing ROM files in memory
|
||||
extern uint32_t pci_io_end;
|
||||
|
||||
extern uint32_t rom_file_setsize;
|
||||
extern uint32_t rom_filesize;
|
||||
|
||||
//Additional steps to prevent overflow?
|
||||
extern int32_t add_result;
|
||||
@ -220,6 +222,8 @@ void ppc_tbr_update();
|
||||
void ppc_exception_handler(uint32_t exception_type, uint32_t handle_args);
|
||||
|
||||
//MEMORY DECLARATIONS
|
||||
extern MemCtrlBase *mem_ctrl_instance;
|
||||
|
||||
extern unsigned char * machine_sysram_mem;
|
||||
extern unsigned char * machine_sysconfig_mem;
|
||||
//Mapped to 0x68000000 - extern unsigned char * machine_68kemu_mem;
|
||||
|
584
ppcmemory.cpp
584
ppcmemory.cpp
@ -20,6 +20,8 @@
|
||||
#include "ppcemumain.h"
|
||||
#include "ppcmemory.h"
|
||||
#include "openpic.h"
|
||||
#include "devices/memctrlbase.h"
|
||||
#include "devices/mmiodevice.h"
|
||||
#include "devices/mpc106.h"
|
||||
#include "davbus.h"
|
||||
|
||||
@ -94,76 +96,70 @@ void msr_status_update(){
|
||||
msr_dr_test = (ppc_state.ppc_msr >> 4) & 1;
|
||||
}
|
||||
|
||||
inline void ppc_set_cur_instruction(uint32_t mem_index)
|
||||
static inline void ppc_set_cur_instruction(unsigned char *ptr, uint32_t offset)
|
||||
{
|
||||
ppc_cur_instruction = (grab_macmem_ptr[mem_index] << 24) |
|
||||
(grab_macmem_ptr[mem_index+1] << 16) |
|
||||
(grab_macmem_ptr[mem_index+2] << 8) |
|
||||
grab_macmem_ptr[mem_index+3];
|
||||
ppc_cur_instruction = (ptr[offset] << 24) | (ptr[offset+1] << 16) |
|
||||
(ptr[offset+2] << 8) | ptr[offset+3];
|
||||
}
|
||||
|
||||
void ppc_set_return_val(uint32_t mem_index, int num_size)
|
||||
static inline void ppc_set_return_val(unsigned char *ptr, uint32_t offset,
|
||||
int num_size)
|
||||
{
|
||||
//Put the final result in return_value here
|
||||
//This is what gets put back into the register
|
||||
|
||||
if (ppc_state.ppc_msr & 1) { /* little-endian byte ordering */
|
||||
if (num_size == 1) { // BYTE
|
||||
return_value = grab_macmem_ptr[mem_index];
|
||||
return_value = ptr[offset];
|
||||
}
|
||||
else if (num_size == 2) { // WORD
|
||||
return_value = grab_macmem_ptr[mem_index] |
|
||||
(grab_macmem_ptr[mem_index+1] << 8);
|
||||
return_value = ptr[offset] | (ptr[offset+1] << 8);
|
||||
}
|
||||
else if (num_size == 4) { // DWORD
|
||||
return_value = grab_macmem_ptr[mem_index] |
|
||||
(grab_macmem_ptr[mem_index+1] << 8) |
|
||||
(grab_macmem_ptr[mem_index+2] << 16) |
|
||||
(grab_macmem_ptr[mem_index+3] << 24);
|
||||
return_value = ptr[offset] | (ptr[offset+1] << 8) |
|
||||
(ptr[offset+2] << 16) | (ptr[offset+3] << 24);
|
||||
}
|
||||
} else { /* big-endian byte ordering */
|
||||
if (num_size == 1) { // BYTE
|
||||
return_value = grab_macmem_ptr[mem_index];
|
||||
return_value = ptr[offset];
|
||||
}
|
||||
else if (num_size == 2) { // WORD
|
||||
return_value = (grab_macmem_ptr[mem_index] << 8) |
|
||||
grab_macmem_ptr[mem_index+1];
|
||||
return_value = (ptr[offset] << 8) | ptr[offset+1];
|
||||
}
|
||||
else if (num_size == 4) { // DWORD
|
||||
return_value = (grab_macmem_ptr[mem_index] << 24) |
|
||||
(grab_macmem_ptr[mem_index+1] << 16) |
|
||||
(grab_macmem_ptr[mem_index+2] << 8) |
|
||||
grab_macmem_ptr[mem_index+3];
|
||||
return_value = (ptr[offset] << 24) | (ptr[offset+1] << 16) |
|
||||
(ptr[offset+2] << 8) | ptr[offset+3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ppc_memstore_value(uint32_t value_insert, uint32_t mem_index, int num_size)
|
||||
static inline void ppc_memstore_value(unsigned char *ptr, uint32_t value,
|
||||
uint32_t offset, int num_size)
|
||||
{
|
||||
if (ppc_state.ppc_msr & 1) { /* little-endian byte ordering */
|
||||
if (num_size >= 1) { // BYTE
|
||||
grab_macmem_ptr[mem_index] = value_insert & 0xFF;
|
||||
ptr[offset] = value & 0xFF;
|
||||
}
|
||||
if (num_size >= 2) { // WORD
|
||||
grab_macmem_ptr[mem_index+1] = (value_insert >> 8) & 0xFF;
|
||||
ptr[offset+1] = (value >> 8) & 0xFF;
|
||||
}
|
||||
if (num_size == 4) { // DWORD
|
||||
grab_macmem_ptr[mem_index+2] = (value_insert >> 16) & 0xFF;
|
||||
grab_macmem_ptr[mem_index+3] = (value_insert >> 24) & 0xFF;
|
||||
ptr[offset+2] = (value >> 16) & 0xFF;
|
||||
ptr[offset+3] = (value >> 24) & 0xFF;
|
||||
}
|
||||
} else { /* big-endian byte ordering */
|
||||
if (num_size == 1) { // BYTE
|
||||
grab_macmem_ptr[mem_index] = value_insert & 0xFF;
|
||||
ptr[offset] = value & 0xFF;
|
||||
}
|
||||
else if (num_size == 2) { // WORD
|
||||
grab_macmem_ptr[mem_index] = (value_insert >> 8) & 0xFF;
|
||||
grab_macmem_ptr[mem_index+1] = value_insert & 0xFF;
|
||||
ptr[offset] = (value >> 8) & 0xFF;
|
||||
ptr[offset+1] = value & 0xFF;
|
||||
}
|
||||
else if (num_size == 4) { // DWORD
|
||||
grab_macmem_ptr[mem_index] = (value_insert >> 24) & 0xFF;
|
||||
grab_macmem_ptr[mem_index+1] = (value_insert >> 16) & 0xFF;
|
||||
grab_macmem_ptr[mem_index+2] = (value_insert >> 8) & 0xFF;
|
||||
grab_macmem_ptr[mem_index+3] = value_insert & 0xFF;
|
||||
ptr[offset] = (value >> 24) & 0xFF;
|
||||
ptr[offset+1] = (value >> 16) & 0xFF;
|
||||
ptr[offset+2] = (value >> 8) & 0xFF;
|
||||
ptr[offset+3] = value & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,7 +278,7 @@ void get_pointer_pteg1(uint32_t address_grab){
|
||||
}
|
||||
}
|
||||
else{
|
||||
pte_word1 = address_grab % rom_file_setsize;
|
||||
pte_word1 = address_grab % rom_filesize;
|
||||
grab_pteg1_ptr = machine_sysrom_mem;
|
||||
}
|
||||
}
|
||||
@ -359,7 +355,7 @@ void get_pointer_pteg2(uint32_t address_grab){
|
||||
}
|
||||
}
|
||||
else{
|
||||
pte_word2 = address_grab % rom_file_setsize;
|
||||
pte_word2 = address_grab % rom_filesize;
|
||||
grab_pteg2_ptr = machine_sysrom_mem;
|
||||
}
|
||||
}
|
||||
@ -561,465 +557,101 @@ uint32_t ppc_mmu_addr_translate(uint32_t la, uint32_t access_type)
|
||||
}
|
||||
|
||||
|
||||
/** Insert a value into memory from a register. */
|
||||
void address_quickinsert_translate(uint32_t value_insert, uint32_t address_grab,
|
||||
uint8_t num_bytes)
|
||||
uint32_t write_last_pa_start = 0;
|
||||
uint32_t write_last_pa_end = 0;
|
||||
unsigned char *write_last_ptr = 0;
|
||||
|
||||
void address_quickinsert_translate(uint32_t value, uint32_t addr, uint8_t num_bytes)
|
||||
{
|
||||
uint32_t storage_area = 0;
|
||||
|
||||
printf("Inserting into address %x with %x \n", address_grab, value_insert);
|
||||
|
||||
// data address translation if enabled
|
||||
if (ppc_state.ppc_msr & 0x10) {
|
||||
printf("DATA RELOCATION GO! - INSERTING \n");
|
||||
|
||||
address_grab = ppc_mmu_addr_translate(address_grab, 0);
|
||||
}
|
||||
|
||||
//regular grabbing
|
||||
if (address_grab < 0x80000000){
|
||||
if (mpc106_check_membound(address_grab)){
|
||||
if (address_grab > 0x03ffffff){ //for debug purposes
|
||||
storage_area = address_grab;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
else if ((address_grab >= 0x40000000) && (address_grab < 0x40400000)){
|
||||
if (is_nubus){
|
||||
storage_area = address_grab % rom_file_setsize;
|
||||
grab_macmem_ptr = machine_sysrom_mem;
|
||||
ppc_memstore_value(value_insert, storage_area, num_bytes);
|
||||
return;
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((address_grab >= 0x5fffe000) && (address_grab <= 0x5fffffff)){
|
||||
storage_area = address_grab % 0x2000;
|
||||
grab_macmem_ptr = machine_sysconfig_mem;
|
||||
}
|
||||
else{
|
||||
storage_area = address_grab % 0x04000000;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
}
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (address_grab < 0x80800000){
|
||||
storage_area = address_grab % 0x800000;
|
||||
if (address_grab == 0x80000CF8){
|
||||
storage_area = 0x0CF8; //CONFIG_ADDR
|
||||
value_insert = rev_endian32(value_insert);
|
||||
grab_macmem_ptr = machine_fecxxx_mem;
|
||||
uint32_t reg_num = (value_insert & 0x07FC) >> 2;
|
||||
uint32_t dev_num = (value_insert & 0xF800) >> 11;
|
||||
printf("ADDRESS SET FOR GRACKLE: ");
|
||||
printf("Device Number: %d ", dev_num);
|
||||
printf("Hex Register Number: %x \n", reg_num);
|
||||
mpc106_address = value_insert;
|
||||
}
|
||||
else{
|
||||
grab_macmem_ptr = machine_upperiocontrol_mem;
|
||||
}
|
||||
|
||||
|
||||
if ((address_grab >= 0x80040000) && (address_grab < 0x80080000)){
|
||||
openpic_address = address_grab - 0x80000000;
|
||||
openpic_read_word = value_insert;
|
||||
openpic_read();
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
}
|
||||
else if (address_grab < 0x81000000){
|
||||
if (address_grab > 0x83FFFFFF){
|
||||
return;
|
||||
}
|
||||
storage_area = address_grab;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_iocontrolcdma_mem;
|
||||
}
|
||||
else if (address_grab < 0xBF800000){
|
||||
storage_area = address_grab % 33554432;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_loweriocontrol_mem;
|
||||
}
|
||||
else if (address_grab < 0xC0000000){
|
||||
storage_area = address_grab % 16;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_interruptack_mem;
|
||||
}
|
||||
else if (address_grab < 0xF0000000){
|
||||
printf("Invalid Memory Attempt: %x \n", address_grab);
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xF8000000){
|
||||
storage_area = address_grab % 67108864;
|
||||
if ((address_grab >= 0xF3013000) && (address_grab < 0xF3013040)){
|
||||
mac_serial_address = storage_area;
|
||||
serial_write_byte = (uint8_t)value_insert;
|
||||
printf("Writing byte to Serial address %x ... %x \n", address_grab, via_write_byte);
|
||||
mac_serial_write();
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3014000) && (address_grab < 0xF3015000)){
|
||||
davbus_address = storage_area;
|
||||
davbus_write_word = value_insert;
|
||||
printf("\nWriting to DAVBus: %x \n", return_value);
|
||||
davbus_write();
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3015000) && (address_grab < 0xF3016000)){
|
||||
mac_swim3_address = storage_area;
|
||||
swim3_write_byte = (uint8_t)value_insert;
|
||||
printf("Writing byte to SWIM3 address %x ... %x \n", address_grab, swim3_write_byte);
|
||||
mac_swim3_write();
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3016000) && (address_grab < 0xF3018000)){
|
||||
via_cuda_address = storage_area;
|
||||
via_write_byte = (uint8_t)value_insert;
|
||||
printf("Writing byte to CUDA address %x ... %x \n", address_grab, via_write_byte);
|
||||
via_cuda_write();
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3040000) && (address_grab < 0xF3080000)){
|
||||
openpic_address = storage_area - 0x3000000;
|
||||
openpic_write_word = value_insert;
|
||||
printf("Writing byte to OpenPIC address %x ... %x \n", address_grab, openpic_write_word);
|
||||
openpic_write();
|
||||
return;
|
||||
}
|
||||
else if (address_grab > 0xF3FFFFFF){
|
||||
printf("Uncharted territory: %x", address_grab);
|
||||
return;
|
||||
}
|
||||
grab_macmem_ptr = machine_iocontrolmem_mem;
|
||||
}
|
||||
else if (address_grab < rom_file_begin){
|
||||
//Get back to this! (weeny1)
|
||||
|
||||
if (address_grab < 0xFE000000){
|
||||
storage_area = address_grab % 4096;
|
||||
grab_macmem_ptr = machine_f8xxxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFEC00000){
|
||||
mpc106_address = address_grab % 65536;
|
||||
mpc106_write(value_insert);
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xFEE00000){
|
||||
storage_area = 0x0CF8; //CONFIG_ADDR
|
||||
grab_macmem_ptr = machine_fecxxx_mem;
|
||||
value_insert = rev_endian32(value_insert);
|
||||
uint32_t reg_num = (value_insert & 0x07FC) >> 2;
|
||||
uint32_t dev_num = (value_insert & 0xF800) >> 11;
|
||||
printf("ADDRESS SET FOR GRACKLE \n");
|
||||
printf("Device Number: %d ", dev_num);
|
||||
printf("Hex Register Number: %x \n", reg_num);
|
||||
mpc_config_addr = value_insert;
|
||||
}
|
||||
else if (address_grab < 0xFF000000){
|
||||
storage_area = 0x0CFC; //CONFIG_DATA
|
||||
mpc106_word_custom_size = num_bytes;
|
||||
mpc106_write_device(mpc_config_addr, value_insert, num_bytes);
|
||||
grab_macmem_ptr = machine_feexxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFF800000){
|
||||
storage_area = address_grab % 4096;
|
||||
grab_macmem_ptr = machine_ff00xx_mem;
|
||||
}
|
||||
else{
|
||||
storage_area = (address_grab % 1048576) + 0x400000;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
}
|
||||
else{
|
||||
storage_area = address_grab % rom_file_setsize;
|
||||
grab_macmem_ptr = machine_sysrom_mem;
|
||||
}
|
||||
|
||||
ppc_memstore_value(value_insert, storage_area, num_bytes);
|
||||
}
|
||||
|
||||
/** Grab a value from memory into a register */
|
||||
void address_quickgrab_translate(uint32_t address_grab, uint8_t num_bytes)
|
||||
{
|
||||
uint32_t storage_area = 0;
|
||||
|
||||
//printf("Grabbing from address %x \n", address_grab);
|
||||
|
||||
return_value = 0; //reset this before going into the real fun.
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.ppc_msr & 0x10) {
|
||||
printf("DATA RELOCATION GO! - GRABBING \n");
|
||||
|
||||
address_grab = ppc_mmu_addr_translate(address_grab, 0);
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
if (address_grab >= 0xFFC00000){
|
||||
//printf("Charting ROM Area: %x \n", address_grab);
|
||||
storage_area = address_grab % rom_file_setsize;
|
||||
grab_macmem_ptr = machine_sysrom_mem;
|
||||
ppc_set_return_val(storage_area, num_bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
//regular grabbing
|
||||
else if (address_grab < 0x80000000){
|
||||
if ((address_grab >= 0x40000000) && (address_grab < 0x40400000) && is_nubus){
|
||||
storage_area = address_grab % rom_file_setsize;
|
||||
grab_macmem_ptr = machine_sysrom_mem;
|
||||
ppc_set_return_val(storage_area, num_bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mpc106_check_membound(address_grab)){
|
||||
if (address_grab > 0x03ffffff){ //for debug purposes
|
||||
storage_area = address_grab;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
if (addr >= write_last_pa_start && addr <= write_last_pa_end) {
|
||||
ppc_memstore_value(write_last_ptr, value, addr - write_last_pa_start, num_bytes);
|
||||
} else {
|
||||
AddressMapEntry *entry = mem_ctrl_instance->find_range(addr);
|
||||
if (entry) {
|
||||
if (entry->type & RT_RAM) {
|
||||
write_last_pa_start = entry->start;
|
||||
write_last_pa_end = entry->end;
|
||||
write_last_ptr = entry->mem_ptr;
|
||||
ppc_memstore_value(write_last_ptr, value, addr - entry->start, num_bytes);
|
||||
} else if (entry->type & RT_MMIO) {
|
||||
entry->devobj->write(addr - entry->start, value, num_bytes);
|
||||
} else {
|
||||
printf("Please check your address map!\n");
|
||||
}
|
||||
else if ((address_grab >= 0x40000000) && (address_grab < 0x40400000)){
|
||||
storage_area = address_grab;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
else if ((address_grab >= 0x5fffe000) && (address_grab <= 0x5fffffff)){
|
||||
storage_area = address_grab % 0x2000;
|
||||
grab_macmem_ptr = machine_sysconfig_mem;
|
||||
}
|
||||
else{
|
||||
return_value = (num_bytes == 1)?0xFF:(num_bytes == 2)?0xFFFF:0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else{
|
||||
//The address is not within the ROM banks
|
||||
return_value = (num_bytes == 1)?0xFF:(num_bytes == 2)?0xFFFF:0xFFFFFFFF;
|
||||
return;
|
||||
} else {
|
||||
printf("WARNING: write attempt to unmapped memory at 0x%08X!\n", addr);
|
||||
}
|
||||
}
|
||||
else if (address_grab < 0x80800000){
|
||||
if ((address_grab >= 0x80040000) && (address_grab < 0x80080000)){
|
||||
openpic_address = address_grab - 0x80000000;
|
||||
openpic_write();
|
||||
return_value = openpic_write_word;
|
||||
return;
|
||||
}
|
||||
|
||||
storage_area = address_grab % 0x800000;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_upperiocontrol_mem;
|
||||
}
|
||||
else if (address_grab < 0x81000000){
|
||||
storage_area = address_grab;
|
||||
if (address_grab > 0x83FFFFFF){
|
||||
return_value = (num_bytes == 1)?0xFF:(num_bytes == 2)?0xFFFF:0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_iocontrolcdma_mem;
|
||||
}
|
||||
else if (address_grab < 0xBF800000){
|
||||
storage_area = address_grab % 33554432;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_loweriocontrol_mem;
|
||||
}
|
||||
else if (address_grab < 0xC0000000){
|
||||
storage_area = address_grab % 16;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
grab_macmem_ptr = machine_interruptack_mem;
|
||||
}
|
||||
else if (address_grab < 0xF0000000){
|
||||
return_value = (num_bytes == 1)?0xFF:(num_bytes == 2)?0xFFFF:0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xF8000000){
|
||||
storage_area = address_grab % 67108864;
|
||||
if ((address_grab >= 0xF3013000) && (address_grab < 0xF3013040)){
|
||||
mac_serial_address = storage_area;
|
||||
mac_serial_read();
|
||||
return_value = serial_read_byte;
|
||||
printf("\n Read from Serial: %x \n", return_value);
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3014000) && (address_grab < 0xF3015000)){
|
||||
davbus_address = storage_area;
|
||||
davbus_read();
|
||||
return_value = davbus_read_word;
|
||||
printf("\n Read from DAVBus: %x \n", return_value);
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3015000) && (address_grab < 0xF3016000)){
|
||||
mac_swim3_address = storage_area;
|
||||
mac_swim3_read();
|
||||
return_value = swim3_read_byte;
|
||||
printf("\n Read from Swim3: %x \n", return_value);
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3016000) && (address_grab < 0xF3018000)){
|
||||
via_cuda_address = storage_area;
|
||||
via_cuda_read();
|
||||
return_value = via_read_byte;
|
||||
printf("\n Read from CUDA: %x \n", return_value);
|
||||
return;
|
||||
}
|
||||
else if ((address_grab >= 0xF3040000) && (address_grab < 0xF3080000)){
|
||||
openpic_address = storage_area - 0x3000000;
|
||||
openpic_read();
|
||||
return_value = openpic_write_word;
|
||||
return;
|
||||
}
|
||||
else if (address_grab > 0xF3FFFFFF){
|
||||
return_value = (num_bytes == 1)?0xFF:(num_bytes == 2)?0xFFFF:0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
grab_macmem_ptr = machine_iocontrolmem_mem;
|
||||
}
|
||||
else if (address_grab < rom_file_begin){
|
||||
//Get back to this! (weeny1)
|
||||
if (address_grab < 0xFE000000){
|
||||
storage_area = address_grab % 4096;
|
||||
grab_macmem_ptr = machine_f8xxxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFEC00000){
|
||||
mpc106_address = address_grab % 65536;
|
||||
mpc106_read();
|
||||
return_value = mpc106_read_word;
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xFEE00000){
|
||||
return_value = (num_bytes == 1)? (mpc106_address & 0xFF):(num_bytes == 2)?(mpc106_address & 0xFFFF):mpc106_address;
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xFF000000){
|
||||
mpc106_word_custom_size = num_bytes;
|
||||
return_value = mpc106_read_device(mpc_config_addr, num_bytes);
|
||||
return_value = rev_endian32(return_value);
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xFF800000){
|
||||
storage_area = address_grab % 4096;
|
||||
grab_macmem_ptr = machine_ff00xx_mem;
|
||||
}
|
||||
else{
|
||||
storage_area = (address_grab % 1048576) + 0x400000;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
}
|
||||
|
||||
ppc_set_return_val(storage_area, num_bytes);
|
||||
|
||||
}
|
||||
|
||||
void quickinstruction_translate(uint32_t address_grab)
|
||||
|
||||
uint32_t read_last_pa_start = 0;
|
||||
uint32_t read_last_pa_end = 0;
|
||||
unsigned char *read_last_ptr = 0;
|
||||
|
||||
/** Grab a value from memory into a register */
|
||||
void address_quickgrab_translate(uint32_t addr, uint8_t num_bytes)
|
||||
{
|
||||
uint32_t storage_area = 0;
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.ppc_msr & 0x10) {
|
||||
//printf("DATA RELOCATION GO! - GRABBING \n");
|
||||
|
||||
return_value = 0; //reset this before going into the real fun.
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
if (addr >= read_last_pa_start && addr <= read_last_pa_end) {
|
||||
ppc_set_return_val(read_last_ptr, addr - read_last_pa_start, num_bytes);
|
||||
} else {
|
||||
AddressMapEntry *entry = mem_ctrl_instance->find_range(addr);
|
||||
if (entry) {
|
||||
if (entry->type & (RT_ROM | RT_RAM)) {
|
||||
read_last_pa_start = entry->start;
|
||||
read_last_pa_end = entry->end;
|
||||
read_last_ptr = entry->mem_ptr;
|
||||
ppc_set_return_val(read_last_ptr, addr - entry->start, num_bytes);
|
||||
} else if (entry->type & RT_MMIO) {
|
||||
return_value = entry->devobj->read(addr - entry->start, num_bytes);
|
||||
} else {
|
||||
printf("Please check your address map!\n");
|
||||
}
|
||||
} else {
|
||||
printf("WARNING: read attempt from unmapped memory at 0x%08X!\n", addr);
|
||||
|
||||
/* reading from unmapped memory will return unmapped value */
|
||||
for (return_value = 0xFF; --num_bytes > 0;)
|
||||
return_value = (return_value << 8) | 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t exec_last_pa_start = 0;
|
||||
uint32_t exec_last_pa_end = 0;
|
||||
unsigned char *exec_last_ptr = 0;
|
||||
|
||||
void quickinstruction_translate(uint32_t addr)
|
||||
{
|
||||
/* instruction address translation if enabled */
|
||||
if (ppc_state.ppc_msr & 0x20) {
|
||||
printf("INSTRUCTION RELOCATION GO! \n");
|
||||
|
||||
address_grab = ppc_mmu_instr_translate(address_grab);
|
||||
addr = ppc_mmu_instr_translate(addr);
|
||||
}
|
||||
|
||||
//grab opcode from memory area
|
||||
if (address_grab >= 0xFFC00000){
|
||||
storage_area = address_grab % rom_file_setsize;
|
||||
grab_macmem_ptr = machine_sysrom_mem;
|
||||
ppc_set_cur_instruction(storage_area);
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0x80000000){
|
||||
if (address_grab < 0x040000000){ //for debug purposes
|
||||
storage_area = address_grab;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
else if ((address_grab >= 0x40000000) && (address_grab < 0x40400000)){
|
||||
if (is_nubus){
|
||||
storage_area = address_grab % rom_file_setsize;
|
||||
grab_macmem_ptr = machine_sysrom_mem;
|
||||
ppc_set_cur_instruction(storage_area);
|
||||
return;
|
||||
}
|
||||
else{
|
||||
storage_area = address_grab;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
}
|
||||
else if ((address_grab >= 0x5fffe000) && (address_grab <= 0x5fffffff)){
|
||||
storage_area = address_grab % 0x2000;
|
||||
grab_macmem_ptr = machine_sysconfig_mem;
|
||||
}
|
||||
else{
|
||||
storage_area = address_grab % 0x04000000;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
printf("Uncharted territory: %x \n", address_grab);
|
||||
if (addr >= exec_last_pa_start && addr <= exec_last_pa_end) {
|
||||
ppc_set_cur_instruction(exec_last_ptr, addr - exec_last_pa_start);
|
||||
} else {
|
||||
AddressMapEntry *entry = mem_ctrl_instance->find_range(addr);
|
||||
if (entry && entry->type & (RT_ROM | RT_RAM)) {
|
||||
exec_last_pa_start = entry->start;
|
||||
exec_last_pa_end = entry->end;
|
||||
exec_last_ptr = entry->mem_ptr;
|
||||
ppc_set_cur_instruction(exec_last_ptr, addr - exec_last_pa_start);
|
||||
} else {
|
||||
printf("WARNING: attempt to execute code at %08X!\n", addr);
|
||||
}
|
||||
}
|
||||
else if (address_grab < 0x80800000){
|
||||
storage_area = address_grab % 0x800000;
|
||||
grab_macmem_ptr = machine_upperiocontrol_mem;
|
||||
|
||||
}
|
||||
else if (address_grab < 0x81000000){
|
||||
storage_area = address_grab % 0x800000;
|
||||
grab_macmem_ptr = machine_iocontrolcdma_mem;
|
||||
|
||||
}
|
||||
else if (address_grab < 0xBF80000){
|
||||
storage_area = address_grab % 33554432;
|
||||
grab_macmem_ptr = machine_loweriocontrol_mem;
|
||||
|
||||
}
|
||||
else if (address_grab < 0xC0000000){
|
||||
storage_area = address_grab % 16;
|
||||
grab_macmem_ptr = machine_interruptack_mem;
|
||||
|
||||
}
|
||||
else if (address_grab < 0xF0000000){
|
||||
printf("Invalid Memory Attempt: %x \n", address_grab);
|
||||
return;
|
||||
}
|
||||
else if (address_grab < 0xF8000000){
|
||||
storage_area = address_grab % 67108864;
|
||||
grab_macmem_ptr = machine_iocontrolmem_mem;
|
||||
|
||||
}
|
||||
else if (address_grab < rom_file_begin){
|
||||
//Get back to this! (weeny1)
|
||||
|
||||
if (address_grab < 0xFE000000){
|
||||
storage_area = address_grab % 4096;
|
||||
grab_macmem_ptr = machine_f8xxxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFEC00000){
|
||||
storage_area = address_grab % 65536;
|
||||
grab_macmem_ptr = machine_fexxxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFEE00000){
|
||||
storage_area = 0x0CF8; //CONFIG_ADDR
|
||||
grab_macmem_ptr = machine_fecxxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFF000000){
|
||||
storage_area = 0x0CFC; //CONFIG_DATA
|
||||
grab_macmem_ptr = machine_feexxx_mem;
|
||||
}
|
||||
else if (address_grab < 0xFF800000){
|
||||
storage_area = address_grab % 4096;
|
||||
grab_macmem_ptr = machine_ff00xx_mem;
|
||||
}
|
||||
else{
|
||||
storage_area = (address_grab % 1048576) + 0x400000;
|
||||
grab_macmem_ptr = machine_sysram_mem;
|
||||
}
|
||||
}
|
||||
|
||||
ppc_set_cur_instruction(storage_area);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user