Near-Midnight Update - July 18, 2019

- Added a check for NuBus Macs, providing a mirror to the ROM
- Very slightly optimized ROM accesses for instructions and reads
- Some slight OpenPIC fixes
- Removed unused variables and slightly improved code readability
- Changed readme + boot-up help to reflect on newly added debugger

More changes will be added soon.
This commit is contained in:
dingusdev 2019-07-18 23:31:16 -07:00 committed by GitHub
parent e909d48ee6
commit e091fedb38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 294 additions and 195 deletions

View File

@ -17,23 +17,23 @@ There are a few command line arguments one can enter when starting the program.
-fuzzer
Processor fuzzer, very unfinished
Processor fuzzer, very unfinished.
-realtime
Run the emulator in runtime
Run the emulator in runtime.
-loadelf
Load an ELF file into memory
Load an ELF file into memory.
-stepi
-debugger
Execute a single opcode
Enter the interactive debugger.
-stepp
Execute a page of opcodes (256 instructions at a time)
Execute a page of opcodes (256 instructions at a time).
-playground

View File

@ -43,6 +43,8 @@
</Compiler>
<Unit filename="davbus.cpp" />
<Unit filename="davbus.h" />
<Unit filename="debugger.cpp" />
<Unit filename="debugger.h" />
<Unit filename="macioserial.cpp" />
<Unit filename="macioserial.h" />
<Unit filename="macscsi.cpp" />

View File

@ -41,6 +41,7 @@ using namespace std;
SetPRS ppc_state;
bool power_on = 1;
bool is_nubus = 0;
bool grab_branch;
bool grab_exception;
@ -51,12 +52,9 @@ uint32_t ppc_cur_instruction; //Current instruction for the PPC
uint32_t ppc_effective_address;
uint32_t ppc_real_address;
uint32_t ppc_next_instruction_address; //Used for branching, setting up the NIA
uint32_t temp_address; //used for determining where memory ends up.
uint32_t return_value;
uint32_t pc_return_value;
//A pointer to a pointer, used for quick movement to one of the following
//memory areas. These are listed right below.
@ -555,6 +553,11 @@ int main(int argc, char **argv)
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
configInfoOffset = (uint32_t)(configGrab & 0xff);
if (configInfoOffset == 0xC0){
is_nubus = 1;
}
uint32_t configInfoAddr = 0x300000 + (configInfoOffset << 8) + 0x69; //address to check the identifier string
romFile.seekg (configInfoAddr, ios::beg);
romFile.read(memPPCBlock, sizeof(uint32_t)); //Only four chars needed to distinguish between codenames
@ -859,12 +862,10 @@ int main(int argc, char **argv)
std::cout << " " << endl;
std::cout << "realtime - Run the emulator in real-time. " << endl;
std::cout << "loadelf - Load an ELF file to run from RAM. " << endl;
std::cout << "until - Runs until hitting a specified address. " << endl;
std::cout << "debugger - Enter the interactive debugger. " << endl;
std::cout << "fuzzer - Test every single PPC opcode. " << endl;
std::cout << "stepi - Execute a single opcode per key press. " << endl;
std::cout << "stepp - Execute a page of opcodes per key press." << endl;
std::cout << "playground - Mess around with and opcodes. " << endl;
//std::cout << "disas - NOT YET IMPLEMENTED " << endl;
}
romFile.close();

View File

@ -15,6 +15,7 @@
uint32_t openpic_address;
uint32_t openpic_write_word;
uint32_t openpic_read_word;
uint32_t openpic_prev_address;
bool openpic_int_go;
@ -29,17 +30,27 @@ bool openpic_int_go;
//Taken from FreeBSD source code
void openpic_init(){
for (int i = 0x40004; i < 0x7FFFF; i++){
machine_upperiocontrol_mem[0x40000] = 0x14;
machine_upperiocontrol_mem[0x40001] = 0x10;
machine_upperiocontrol_mem[0x40002] = 0x46;
machine_upperiocontrol_mem[0x40003] = 0x00;
machine_upperiocontrol_mem[0x40007] = 0x02;
for (int i = 0x41004; i < 0x7FFFF; i++){
if (i % 16 == 0){
i += 4;
}
machine_upperiocontrol_mem[i] = 0xFF;
}
machine_upperiocontrol_mem[0x40080] = 0x6B;
machine_upperiocontrol_mem[0x40081] = 0x10;
machine_upperiocontrol_mem[0x40082] = 0x10;
machine_upperiocontrol_mem[0x40083] = 0x00;
machine_upperiocontrol_mem[0x41000] = 0x02;
machine_upperiocontrol_mem[0x41002] = 0x80;
machine_upperiocontrol_mem[0x41080] = 0x14;
machine_upperiocontrol_mem[0x41081] = 0x46;
machine_upperiocontrol_mem[0x41090] = 0x01;
machine_upperiocontrol_mem[0x410E0] = 0xFF;
}
void openpic_read(){
@ -65,12 +76,50 @@ void openpic_write(){
openpic_address = (openpic_address % 0x8000) + 0x60000;
}
machine_upperiocontrol_mem[openpic_address++] = (uint8_t)(openpic_write_word);
machine_upperiocontrol_mem[openpic_address++] = (uint8_t)((openpic_write_word) >> 8);
machine_upperiocontrol_mem[openpic_address++] = (uint8_t)((openpic_write_word) >> 16);
machine_upperiocontrol_mem[openpic_address] = (uint8_t)((openpic_write_word) >> 24);
switch(openpic_address){
//Make sure we don't touch any of the following read-only regs
case 0x41000:
case 0x41080:
case 0x41100:
case 0x41140:
case 0x41180:
case 0x411C0:
case 0x600A0:
case 0x600B0:
case 0x610A0:
case 0x610B0:
case 0x620A0:
case 0x620B0:
case 0x630A0:
case 0x630B0:
return;
default:
if (openpic_address == openpic_prev_address){
return;
}
else{
openpic_prev_address = openpic_address;
}
machine_upperiocontrol_mem[openpic_address++] = (uint8_t)(openpic_write_word);
machine_upperiocontrol_mem[openpic_address++] = (uint8_t)((openpic_write_word) >> 8);
machine_upperiocontrol_mem[openpic_address++] = (uint8_t)((openpic_write_word) >> 16);
machine_upperiocontrol_mem[openpic_address] = (uint8_t)((openpic_write_word) >> 24);
break;
}
switch (op_interrupt_check){
case 0x40:
printf("IPI 0 stuff goes here! \n");
break;
case 0x50:
printf("IPI 1 stuff goes here! \n");
break;
case 0x60:
printf("IPI 2 stuff goes here! \n");
break;
case 0x70:
printf("IPI 3 stuff goes here! \n");
break;
case 0x80:
printf("Task Priority Reg stuff goes here! \n");
break;

View File

@ -214,22 +214,22 @@ void power_lscbx(){
if (match_found == false){
switch(shift_amount){
case 0:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0x00FFFFFF) | (return_value << 24);
ppc_store_result_regd();
break;
case 1:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFF00FFFF) | (return_value << 16);
ppc_store_result_regd();
break;
case 2:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFFFF00FF) | (return_value << 8);
ppc_store_result_regd();
break;
case 3:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFFFFFF00) | return_value;
ppc_store_result_regd();
break;

View File

@ -84,8 +84,6 @@ SUPERVISOR MODEL
extern uint32_t return_value; //used for loading from memory
extern uint32_t pc_return_value; //used for getting instructions
extern uint32_t opcode_value; //used for interpreting opcodes
extern uint32_t ram_size_set;
@ -154,20 +152,18 @@ extern bool grab_branch;
extern bool grab_exception;
extern bool grab_return;
extern bool is_nubus; //For early Power Mac Emulation
extern bool is_601; //For PowerPC 601 Emulation
extern bool is_gekko; //For GameCube Emulation
extern bool is_altivec; //For Altivec Emulation
extern bool is_64bit; //For PowerPC G5 Emulation
//uint64_t virtual_address;
//Important Addressing Integers
extern uint64_t ppc_virtual_address; //It's 52 bits
extern uint32_t ppc_cur_instruction;
extern uint32_t ppc_effective_address;
extern uint32_t ppc_real_address;
extern uint32_t ppc_next_instruction_address;
extern uint32_t temp_address; //used for determining where memory ends up.
//Function prototypes
void reg_init();

View File

@ -849,7 +849,7 @@ void ppc_lfs(){
ppc_grab_regsfpdia();
grab_d = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
ppc_effective_address = (reg_a == 0)?grab_d:ppc_result_a + grab_d;
address_quickgrab_translate(ppc_effective_address, ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result64_d = (uint64_t)return_value;
ppc_store_dfpresult();
}
@ -859,7 +859,7 @@ void ppc_lfsu(){
ppc_grab_regsfpdia();
grab_d = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
ppc_effective_address = (reg_a == 0)?grab_d:ppc_result_a + grab_d;
address_quickgrab_translate(ppc_effective_address, ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result64_d = (uint64_t)return_value;
ppc_result_a = ppc_effective_address;
ppc_store_dfpresult();
@ -869,7 +869,7 @@ void ppc_lfsu(){
void ppc_lfsx(){
ppc_grab_regsfpdiab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:ppc_result_a + ppc_result_b;
address_quickgrab_translate(ppc_effective_address, ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result64_d = (uint64_t)return_value;
ppc_store_dfpresult();
}
@ -878,7 +878,7 @@ void ppc_lfsx(){
void ppc_lfsux(){
ppc_grab_regsfpdiab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:ppc_result_a + ppc_result_b;
address_quickgrab_translate(ppc_effective_address, ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result64_d = (uint64_t)return_value;
ppc_result_a = ppc_effective_address;
ppc_store_dfpresult();
@ -889,9 +889,9 @@ void ppc_lfd(){
ppc_grab_regsfpdia();
grab_d = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
ppc_effective_address = (reg_a == 0)?grab_d:ppc_result_a + grab_d;
address_quickgrab_translate(ppc_effective_address, ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate(ppc_effective_address, 4);
uint64_t combine_result1 = (uint64_t)(return_value);
address_quickgrab_translate((ppc_effective_address + 4), ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate((ppc_effective_address + 4), 4);
uint64_t combine_result2 = (uint64_t)(return_value);
ppc_result64_d = (combine_result1 << 32) | combine_result2;
ppc_store_dfpresult();
@ -902,9 +902,9 @@ void ppc_lfdu(){
ppc_grab_regsfpdia();
grab_d = (int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF));
ppc_effective_address = (reg_a == 0)?grab_d:ppc_result_a + grab_d;
address_quickgrab_translate(ppc_effective_address, ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate(ppc_effective_address, 4);
uint64_t combine_result1 = (uint64_t)(return_value);
address_quickgrab_translate((ppc_effective_address + 4), ppc_state.ppc_fpr[reg_d], 4);
address_quickgrab_translate((ppc_effective_address + 4), 4);
uint64_t combine_result2 = (uint64_t)(return_value);
ppc_result64_d = (combine_result1 << 32) | combine_result2;
ppc_store_dfpresult();

View File

@ -24,7 +24,6 @@
#include "davbus.h"
std::vector<uint32_t> pte_storage;
uint64_t ppc_virtual_address; //It's 52 bits, but 64 bits more than covers the range needed.
uint32_t bat_srch;
uint32_t bepi_chk;
@ -109,6 +108,87 @@ void msr_status_update(){
msr_dr_test = (ppc_state.ppc_msr >> 4) & 1;
}
void ppc_set_cur_instruction(uint32_t mem_index){
ppc_cur_instruction += (grab_macmem_ptr[mem_index]) << 24;
++mem_index;
ppc_cur_instruction += (grab_macmem_ptr[mem_index]) << 16;
++mem_index;
ppc_cur_instruction += (grab_macmem_ptr[mem_index]) << 8;
++mem_index;
ppc_cur_instruction += (grab_macmem_ptr[(mem_index)]);
}
void ppc_set_return_val(uint32_t mem_index, uint8_t bit_num){
//Put the final result in return_value here
//This is what gets put back into the register
switch (ppc_state.ppc_msr & 0x1){
case 0:
if (bit_num == 1){
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index]));
}
else if (bit_num == 2){
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) << 8;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index]));
}
else if (bit_num == 4){
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) << 24;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) << 16;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) << 8;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index]));
}
break;
case 1:
if (bit_num == 1){
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index]));
}
else if (bit_num == 2){
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) ;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index])) << 8;
}
else if (bit_num == 4){
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) ;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) << 8;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index++])) << 16;
return_value |= ((uint32_t)(grab_macmem_ptr[mem_index])) << 24;
}
}
}
void ppc_memstore_value(uint32_t value_insert, uint32_t mem_index, uint8_t bit_num){
switch (ppc_state.ppc_msr & 0x1){
case 0:
if (bit_num == 1){
grab_macmem_ptr[mem_index] = (uint8_t)value_insert;
}
else if (bit_num == 2){
grab_macmem_ptr[mem_index++] = (uint8_t)(value_insert >> 8);
grab_macmem_ptr[mem_index] = (uint8_t)value_insert;
}
else if (bit_num == 4){
grab_macmem_ptr[mem_index++] = (uint8_t)(value_insert >> 24);
grab_macmem_ptr[mem_index++] = (uint8_t)(value_insert >> 16);
grab_macmem_ptr[mem_index++] = (uint8_t)(value_insert >> 8);
grab_macmem_ptr[mem_index] = (uint8_t)value_insert;
}
break;
case 1:
if (bit_num == 1){
grab_macmem_ptr[mem_index] = (uint8_t)value_insert;
}
else if (bit_num == 2){
grab_macmem_ptr[mem_index++] = (uint8_t)value_insert;
grab_macmem_ptr[mem_index] = (uint8_t)(value_insert >> 8);
}
else if (bit_num == 4){
grab_macmem_ptr[mem_index++] = (uint8_t)value_insert;
grab_macmem_ptr[mem_index++] = (uint8_t)(value_insert >> 8);
grab_macmem_ptr[mem_index++] = (uint8_t)(value_insert >> 16);
grab_macmem_ptr[mem_index] = (uint8_t)(value_insert >> 24);
}
break;
}
}
void ibat_update(){
uint8_t tlb_place = 0;
uint32_t ref_area = 0;
@ -425,7 +505,7 @@ void pteg_translate(uint32_t address_grab){
secondary_pteg_check.join();
}
void address_quickinsert_translate(uint32_t address_grab, uint32_t value_insert, uint8_t bit_num){
void address_quickinsert_translate(uint32_t value_insert, uint32_t address_grab, uint8_t bit_num){
//Insert a value into memory from a register
printf("Inserting into address %x with %x \n", address_grab, value_insert);
@ -484,6 +564,17 @@ void address_quickinsert_translate(uint32_t address_grab, uint32_t value_insert,
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, bit_num);
return;
}
else{
return;
}
}
else if ((address_grab >= 0x5fffe000) && (address_grab <= 0x5fffffff)){
storage_area = address_grab % 0x2000;
grab_macmem_ptr = machine_sysconfig_mem;
@ -633,41 +724,10 @@ void address_quickinsert_translate(uint32_t address_grab, uint32_t value_insert,
grab_macmem_ptr = machine_sysrom_mem;
}
switch (ppc_state.ppc_msr & 0x1){
case 0:
if (bit_num == 1){
grab_macmem_ptr[storage_area] = (uint8_t)value_insert;
}
else if (bit_num == 2){
grab_macmem_ptr[storage_area++] = (uint8_t)(value_insert >> 8);
grab_macmem_ptr[storage_area] = (uint8_t)value_insert;
}
else if (bit_num == 4){
grab_macmem_ptr[storage_area++] = (uint8_t)(value_insert >> 24);
grab_macmem_ptr[storage_area++] = (uint8_t)(value_insert >> 16);
grab_macmem_ptr[storage_area++] = (uint8_t)(value_insert >> 8);
grab_macmem_ptr[storage_area] = (uint8_t)value_insert;
}
break;
case 1:
if (bit_num == 1){
grab_macmem_ptr[storage_area] = (uint8_t)value_insert;
}
else if (bit_num == 2){
grab_macmem_ptr[storage_area++] = (uint8_t)value_insert;
grab_macmem_ptr[storage_area] = (uint8_t)(value_insert >> 8);
}
else if (bit_num == 4){
grab_macmem_ptr[storage_area++] = (uint8_t)value_insert;
grab_macmem_ptr[storage_area++] = (uint8_t)(value_insert >> 8);
grab_macmem_ptr[storage_area++] = (uint8_t)(value_insert >> 16);
grab_macmem_ptr[storage_area] = (uint8_t)(value_insert >> 24);
}
break;
}
ppc_memstore_value(value_insert, storage_area, bit_num);
}
void address_quickgrab_translate(uint32_t address_grab, uint32_t value_extract, uint8_t bit_num){
void address_quickgrab_translate(uint32_t address_grab, uint8_t bit_num){
//Grab a value from memory into a register
printf("Grabbing from address %x \n", address_grab);
@ -721,13 +781,33 @@ void address_quickgrab_translate(uint32_t address_grab, uint32_t value_extract,
}
}
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, bit_num);
return;
}
//regular grabbing
if (address_grab < 0x80000000){
else 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_set_return_val(storage_area, bit_num);
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;
@ -851,45 +931,9 @@ void address_quickgrab_translate(uint32_t address_grab, uint32_t value_extract,
grab_macmem_ptr = machine_sysram_mem;
}
}
else{
printf("Charting ROM Area: %x \n", address_grab);
storage_area = address_grab % rom_file_setsize;
grab_macmem_ptr = machine_sysrom_mem;
}
//Put the final result in return_value here
//This is what gets put back into the register
switch (ppc_state.ppc_msr & 0x1){
case 0:
if (bit_num == 1){
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area]));
}
else if (bit_num == 2){
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) << 8;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area]));
}
else if (bit_num == 4){
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) << 24;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) << 16;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) << 8;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area]));
}
break;
case 1:
if (bit_num == 1){
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area]));
}
else if (bit_num == 2){
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) ;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area])) << 8;
}
else if (bit_num == 4){
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) ;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) << 8;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area++])) << 16;
return_value |= ((uint32_t)(grab_macmem_ptr[storage_area])) << 24;
}
}
ppc_set_return_val(storage_area, bit_num);
}
void quickinstruction_translate(uint32_t address_grab){
@ -947,11 +991,29 @@ void quickinstruction_translate(uint32_t address_grab){
}
//grab opcode from memory area
if (address_grab < 0x80000000){
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;
@ -1018,18 +1080,7 @@ void quickinstruction_translate(uint32_t address_grab){
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_cur_instruction += (grab_macmem_ptr[storage_area]) << 24;
++storage_area;
ppc_cur_instruction += (grab_macmem_ptr[storage_area]) << 16;
++storage_area;
ppc_cur_instruction += (grab_macmem_ptr[storage_area]) << 8;
++storage_area;
ppc_cur_instruction += (grab_macmem_ptr[(storage_area)]);
ppc_set_cur_instruction(storage_area);
}

View File

@ -35,8 +35,8 @@ extern void dbat_update();
extern void msr_status_update();
extern void address_quickinsert_translate(uint32_t address_grab, uint32_t value_insert, uint8_t bit_num);
extern void address_quickgrab_translate(uint32_t address_grab, uint32_t value_extract, uint8_t bit_num);
extern void address_quickinsert_translate(uint32_t value_insert, uint32_t address_grab, uint8_t bit_num);
extern void address_quickgrab_translate(uint32_t address_grab, uint8_t bit_num);
extern void quickinstruction_translate(uint32_t address_grab);
#endif // PPCMEMORY_H

View File

@ -397,38 +397,38 @@ void ppc_adde(){
void ppc_addedot(){
ppc_grab_regsdab();
uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000;
ppc_result_d = ppc_result_a + ppc_result_b + grab_xer;
ppc_changecrf0(ppc_result_d);
if (((ppc_result_b + grab_xer) < ppc_result_b) || (ppc_result_d < ppc_result_a)){
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
ppc_state.ppc_spr[1] &= 0xDFFFFFFF;
}
ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
void ppc_addeo(){
ppc_grab_regsdab();
uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000;
ppc_setsoov(ppc_result_a, ppc_result_b + grab_xer);
ppc_result_d = ppc_result_a + ppc_result_b + grab_xer;
if (((ppc_result_b + grab_xer) < ppc_result_b) || (ppc_result_d < ppc_result_a)){
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
ppc_state.ppc_spr[1] &= 0xDFFFFFFF;
}
ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
void ppc_addeodot(){
ppc_grab_regsdab();
uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000;
ppc_setsoov(ppc_result_a, ppc_result_b + grab_xer);
ppc_result_d = ppc_result_a + ppc_result_b + grab_xer;
if (((ppc_result_b + grab_xer) < ppc_result_b) || (ppc_result_d < ppc_result_a)){
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_setsoov(ppc_result_a, (ppc_result_b + xer_ca));
ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -440,9 +440,9 @@ void ppc_addeodot(){
void ppc_addme(){
ppc_grab_regsda();
uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000;
ppc_result_d = ppc_result_a + grab_xer - 1;
if ((grab_xer - 1) > ~ppc_result_a){
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = ppc_result_a + xer_ca - 1;
if (((xer_ca - 1) < 0xFFFFFFFF) | (ppc_result_d < ppc_result_a)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -453,9 +453,9 @@ void ppc_addme(){
void ppc_addmedot(){
ppc_grab_regsda();
uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000;
ppc_result_d = ppc_result_a + grab_xer - 1;
if ((grab_xer - 1) > ~ppc_result_a){
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = ppc_result_a + xer_ca - 1;
if (((xer_ca - 1) < 0xFFFFFFFF) | (ppc_result_d < ppc_result_a)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -467,10 +467,10 @@ void ppc_addmedot(){
void ppc_addmeo(){
ppc_grab_regsda();
uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000;
ppc_setsoov(ppc_result_a, grab_xer);
ppc_result_d = ppc_result_a + grab_xer - 1;
if ((grab_xer - 1) > ~ppc_result_a){
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_setsoov(ppc_result_a, xer_ca);
ppc_result_d = ppc_result_a + xer_ca - 1;
if (((xer_ca - 1) < 0xFFFFFFFF) | (ppc_result_d < ppc_result_a)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -481,11 +481,11 @@ void ppc_addmeo(){
void ppc_addmeodot(){
ppc_grab_regsda();
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
ppc_setsoov(ppc_result_a, grab_xer);
ppc_result_d = ppc_result_a + grab_xer - 1;
uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000);
ppc_setsoov(ppc_result_a, xer_ca);
ppc_result_d = ppc_result_a + xer_ca - 1;
ppc_changecrf0(ppc_result_d);
if ((grab_xer - 1) > ~ppc_result_a){
if (((xer_ca - 1) < 0xFFFFFFFF) | (ppc_result_d < ppc_result_a)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -498,7 +498,7 @@ void ppc_addze(){
ppc_grab_regsda();
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = ppc_result_a + grab_xer;
if (grab_xer > ~ppc_result_a){
if (ppc_result_d < ppc_result_a){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -511,7 +511,7 @@ void ppc_addzedot(){
ppc_grab_regsda();
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = ppc_result_a + grab_xer;
if (grab_xer > ~ppc_result_a){
if (ppc_result_d < ppc_result_a){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -526,7 +526,7 @@ void ppc_addzeo(){
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
ppc_setsoov(ppc_result_a, grab_xer);
ppc_result_d = ppc_result_a + grab_xer;
if (grab_xer > ~ppc_result_a){
if (ppc_result_d < ppc_result_a){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -540,7 +540,7 @@ void ppc_addzeodot(){
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
ppc_setsoov(ppc_result_a, grab_xer);
ppc_result_d = ppc_result_a + grab_xer;
if (grab_xer > ~ppc_result_a){
if (ppc_result_d < ppc_result_a){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -586,7 +586,7 @@ void ppc_subfc(){
ppc_grab_regsdab();
not_this = ~ppc_result_a;
ppc_result_d = not_this + ppc_result_b + 1;
if (ppc_result_d < (not_this + 1)){
if (ppc_result_d <= not_this){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -600,7 +600,7 @@ void ppc_subfcdot(){
ppc_grab_regsdab();
not_this = ~ppc_result_a;
ppc_result_d = not_this + ppc_result_b + 1;
if (ppc_result_d < (not_this + 1)){
if (ppc_result_d <= not_this){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -616,7 +616,7 @@ void ppc_subfco(){
ppc_setsoov(ppc_result_a, ppc_result_b);
not_this = ~ppc_result_a;
ppc_result_d = not_this + ppc_result_b + 1;
if (ppc_result_d < (not_this + 1)){
if (ppc_result_d <= not_this){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -631,7 +631,7 @@ void ppc_subfcodot(){
ppc_setsoov(ppc_result_a, ppc_result_b);
not_this = ~ppc_result_a;
ppc_result_d = not_this + ppc_result_b + 1;
if (ppc_result_d < (not_this + 1)){
if (ppc_result_d <= not_this){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -660,7 +660,7 @@ void ppc_subfe(){
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
not_this = ~ppc_result_a;
ppc_result_d = not_this + ppc_result_b + (ppc_state.ppc_spr[1] & 0x20000000);
if (ppc_result_d < (not_this + grab_xer)){
if (ppc_result_d <= (not_this + grab_xer)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -675,7 +675,7 @@ void ppc_subfedot(){
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
not_this = ~ppc_result_a;
ppc_result_d = not_this + ppc_result_b + grab_xer;
if (ppc_result_d < (not_this + grab_xer)){
if (ppc_result_d <= (not_this + grab_xer)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -707,7 +707,7 @@ void ppc_subfmedot(){
not_this = ~ppc_result_a;
uint32_t grab_xer = (ppc_state.ppc_spr[1] & 0x20000000);
ppc_result_d = not_this + grab_xer - 1;
if (ppc_result_d < (not_this + grab_xer)){
if (ppc_result_d <= (not_this + grab_xer)){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -722,7 +722,7 @@ void ppc_subfze(){
ppc_grab_regsda();
not_this = ~ppc_result_a;
ppc_result_d = not_this + (ppc_state.ppc_spr[1] & 0x20000000);
if (ppc_result_d < not_this){
if (ppc_result_d <= not_this){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -736,7 +736,7 @@ void ppc_subfzedot(){
ppc_grab_regsda();
not_this = ~ppc_result_a;
ppc_result_d = not_this + (ppc_state.ppc_spr[1] & 0x20000000);
if (ppc_result_d < not_this){
if (ppc_result_d <= not_this){
ppc_state.ppc_spr[1] |= 0x20000000;
}
else{
@ -2043,7 +2043,7 @@ void ppc_lbz(){
ppc_grab_regsda();
grab_d = (uint32_t)((int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)));
ppc_effective_address = (reg_a == 0)?grab_d:(ppc_result_a + grab_d);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
//printf("LBZ Storage Area: %x \n",ppc_effective_address);
ppc_result_d = return_value;
return_value = 0;
@ -2059,7 +2059,7 @@ void ppc_lbzu(){
else{
ppc_expection_handler(0x0700, 0x20000);
}
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = return_value;
return_value = 0;
ppc_result_a = ppc_effective_address;
@ -2070,7 +2070,7 @@ void ppc_lbzu(){
void ppc_lbzx(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
address_quickgrab_translate((ppc_effective_address), ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2084,7 +2084,7 @@ void ppc_lbzux(){
else{
ppc_expection_handler(0x0700, 0x20000);
}
address_quickgrab_translate((ppc_effective_address), ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = return_value;
return_value = 0;
ppc_result_a = ppc_effective_address;
@ -2097,7 +2097,7 @@ void ppc_lhz(){
ppc_grab_regsda();
grab_d = (uint32_t)((int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)));
ppc_effective_address = (reg_a == 0)?grab_d:(ppc_result_a + grab_d);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2107,7 +2107,7 @@ void ppc_lhzu(){
ppc_grab_regsda();
grab_d = (uint32_t)((int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)));
ppc_effective_address = ppc_result_a + grab_d;
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
ppc_result_d = return_value;
return_value = 0;
ppc_result_a = ppc_effective_address;
@ -2118,7 +2118,7 @@ void ppc_lhzu(){
void ppc_lhzx(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
address_quickgrab_translate((ppc_effective_address), ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2127,7 +2127,7 @@ void ppc_lhzx(){
void ppc_lhzux(){
ppc_grab_regsdab();
ppc_effective_address = ppc_result_a + ppc_result_b;
address_quickgrab_translate((ppc_effective_address), ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
ppc_result_d = return_value;
return_value = 0;
ppc_result_a = ppc_effective_address;
@ -2139,7 +2139,7 @@ void ppc_lha(){
ppc_grab_regsda();
grab_d = (uint32_t)((int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)));
ppc_effective_address = (reg_a == 0)?grab_d:(uint32_t)(ppc_result_a + grab_d);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
uint16_t go_this = (uint16_t)return_value;
if (go_this & 0x8000){
ppc_result_d = 0xFFFF0000 | (uint32_t)return_value;
@ -2156,7 +2156,7 @@ void ppc_lhau(){
ppc_grab_regsda();
grab_d = (uint32_t)((int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)));
ppc_effective_address = (reg_a == 0)?grab_d:(uint32_t)(ppc_result_a + grab_d);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
uint16_t go_this = (uint16_t)return_value;
if (go_this & 0x8000){
ppc_result_d = 0xFFFF0000 | (uint32_t)return_value;
@ -2174,7 +2174,7 @@ void ppc_lhau(){
void ppc_lhaux(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
uint16_t go_this = (uint16_t)return_value;
if (go_this & 0x8000){
ppc_result_d = 0xFFFF0000 | (uint32_t)return_value;
@ -2192,7 +2192,7 @@ void ppc_lhaux(){
void ppc_lhax(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
uint16_t go_this = (uint16_t)return_value;
if (go_this & 0x8000){
ppc_result_d = 0xFFFF0000 | (uint32_t)return_value;
@ -2208,7 +2208,7 @@ void ppc_lhax(){
void ppc_lhbrx(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 2);
address_quickgrab_translate(ppc_effective_address, 2);
ppc_result_d = (uint32_t)(rev_endian16((uint16_t)ppc_result_d));
return_value = 0;
ppc_store_result_regd();
@ -2218,7 +2218,7 @@ void ppc_lwz(){
ppc_grab_regsda();
grab_d = (uint32_t)((int32_t)((int16_t)(ppc_cur_instruction & 0xFFFF)));
ppc_effective_address = (reg_a == 0)?grab_d:(ppc_result_a + grab_d);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2228,7 +2228,7 @@ void ppc_lwbrx(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
printf("LWBRX Storage Area: %x \n",ppc_effective_address);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result_d = rev_endian32(return_value);
return_value = 0;
ppc_store_result_regd();
@ -2243,7 +2243,7 @@ void ppc_lwzu(){
else{
ppc_expection_handler(0x0700, 0x20000);
}
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2254,7 +2254,7 @@ void ppc_lwzu(){
void ppc_lwzx(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2268,7 +2268,7 @@ void ppc_lwzux(){
else{
ppc_expection_handler(0x0700, 0x20000);
}
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result_d = return_value;
return_value = 0;
ppc_result_a = ppc_effective_address;
@ -2281,7 +2281,7 @@ void ppc_lwarx(){
ppc_grab_regsdab();
ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b);
ppc_state.ppc_reserve = true;
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_result_d = return_value;
return_value = 0;
ppc_store_result_regd();
@ -2293,7 +2293,7 @@ void ppc_lmw(){
ppc_effective_address = (reg_a == 0)?grab_d:(ppc_result_a + grab_d);
//How many words to load in memory - using a do-while for this
do{
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 4);
address_quickgrab_translate(ppc_effective_address, 4);
ppc_state.ppc_gpr[reg_d] = return_value;
return_value = 0;
ppc_effective_address +=4;
@ -2312,25 +2312,25 @@ void ppc_lswi(){
while (grab_inb > 0){
switch(shift_times){
case 0:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_state.ppc_gpr[reg_d] = (ppc_result_d & 0x00FFFFFF) | (return_value << 24);
ppc_store_result_regd();
return_value = 0;
break;
case 1:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFF00FFFF) | (return_value << 16);
ppc_store_result_regd();
return_value = 0;
break;
case 2:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFFFF00FF) | (return_value << 8);
ppc_store_result_regd();
return_value = 0;
break;
case 3:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFFFFFF00) | return_value;
ppc_store_result_regd();
return_value = 0;
@ -2366,25 +2366,25 @@ void ppc_lswx(){
while (grab_inb > 0){
switch(shift_times){
case 0:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0x00FFFFFF) | (return_value << 24);
ppc_store_result_regd();
return_value = 0;
break;
case 1:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFF00FFFF) | (return_value << 16);
ppc_store_result_regd();
return_value = 0;
break;
case 2:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFFFF00FF) | (return_value << 8);
ppc_store_result_regd();
return_value = 0;
break;
case 3:
address_quickgrab_translate(ppc_effective_address, ppc_result_d, 1);
address_quickgrab_translate(ppc_effective_address, 1);
ppc_result_d = (ppc_result_d & 0xFFFFFF00) | return_value;
ppc_store_result_regd();
return_value = 0;