diff --git a/README.md b/README.md index 986ca27..e33ee4a 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,9 @@ Future versions will include SDL 2 as a requirement. ## Intended Minimum Requirements - Windows 7 or newer (64-bit), Linux 4.4 or newer, Mac OS X 10.9 or newer (64-bit) -- 2 GB of RAM - Intel Core 2 Duo or better +- 2 GB of RAM +- 2 GB of Hard Disk Space - Graphics Card with a minimum resolution of 800*600 ## Compiler Requirements diff --git a/macioserial.cpp b/macioserial.cpp index a3c7f1c..5961ccd 100644 --- a/macioserial.cpp +++ b/macioserial.cpp @@ -17,6 +17,8 @@ uint32_t mac_serial_address; uint8_t serial_write_byte; uint8_t serial_read_byte; +bool w7_prime; + void mac_serial_init(){ machine_iocontrolmem_mem[0x3013004] = 0x04; machine_iocontrolmem_mem[0x3013009] = 0xC0; @@ -31,11 +33,70 @@ void mac_serial_read(){ if (mac_serial_address >=0x3013020){ mac_serial_address -= 0x20; } - machine_iocontrolmem_mem[mac_serial_address] = serial_read_byte; + + if (w7_prime){ + if (((machine_iocontrolmem_mem[0x301301F] >> 2) & 0x1) & ((machine_iocontrolmem_mem[0x3013007] >> 6) & 0x1)){ + switch(mac_serial_address){ + case 0x14: case 0x15: + serial_read_byte = machine_iocontrolmem_mem[(mac_serial_address - 0x10)]; + break; + case 0x19: + serial_read_byte = machine_iocontrolmem_mem[0x3]; + break; + case 0x1B: + serial_read_byte = machine_iocontrolmem_mem[0x10]; + break; + case 0x1E: + serial_read_byte = machine_iocontrolmem_mem[0x07]; + break; + default: + serial_read_byte = machine_iocontrolmem_mem[mac_serial_address]; + break; + } + } + } + else{ + if ((machine_iocontrolmem_mem[0x301300F] >> 2) & 0x1){ + switch(mac_serial_address){ + case 0x14: case 0x15: + serial_read_byte = machine_iocontrolmem_mem[(mac_serial_address - 4)]; + break; + case 0x19: case 0x1B: + serial_read_byte = machine_iocontrolmem_mem[(mac_serial_address + 4)]; + break; + default: + serial_read_byte = machine_iocontrolmem_mem[mac_serial_address]; + break; + } + } + else { + switch(mac_serial_address){ + case 0x14: case 0x15: case 0x16: case 0x17: + serial_read_byte = machine_iocontrolmem_mem[(mac_serial_address - 4)]; + case 0x19: case 0x1B: + serial_read_byte = machine_iocontrolmem_mem[(mac_serial_address + 4)]; + break; + default: + serial_read_byte = machine_iocontrolmem_mem[mac_serial_address]; + break; + } + } + } } + void mac_serial_write(){ if (mac_serial_address >=0x3013020){ mac_serial_address -= 0x20; } - serial_write_byte = machine_iocontrolmem_mem[mac_serial_address]; + machine_iocontrolmem_mem[mac_serial_address] = serial_write_byte; + + if ((machine_iocontrolmem_mem[0x0F]) & 0x1){ + w7_prime = true; + } + else{ + w7_prime = false; + } + + machine_iocontrolmem_mem[(mac_serial_address + 0x10)] = machine_iocontrolmem_mem[mac_serial_address]; + } diff --git a/mpc106.cpp b/mpc106.cpp index 2edd2a1..e4ea06f 100644 --- a/mpc106.cpp +++ b/mpc106.cpp @@ -15,11 +15,13 @@ #include "ppcemumain.h" #include "ppcmemory.h" -bool mpc106_address_map; +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; @@ -28,6 +30,26 @@ 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] = +{ +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; @@ -58,21 +80,12 @@ void mpc106_init(){ machine_fexxxx_mem[0xAF] = 0x00; machine_fexxxx_mem[0xBA] = 0x04; + machine_fexxxx_mem[0xC0] = 0x01; - machine_fexxxx_mem[0xAC] = 0x0C; - machine_fexxxx_mem[0xAD] = 0x06; - machine_fexxxx_mem[0xAE] = 0x0C; - machine_fexxxx_mem[0xAF] = 0x00; - - machine_fexxxx_mem[0xAC] = 0x0C; - machine_fexxxx_mem[0xAD] = 0x06; - machine_fexxxx_mem[0xAE] = 0x0C; - machine_fexxxx_mem[0xAF] = 0x00; - - machine_fexxxx_mem[0xAC] = 0x0C; - machine_fexxxx_mem[0xAD] = 0x06; - machine_fexxxx_mem[0xAE] = 0x0C; - machine_fexxxx_mem[0xAF] = 0x00; + 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; @@ -88,6 +101,9 @@ void mpc106_init(){ machine_fexxxx_mem[0xFD] = 0x00; machine_fexxxx_mem[0xFE] = 0x10; machine_fexxxx_mem[0xFF] = 0x00; + + mpc106_mem_approve = false; + mpc106_word_custom_size = 0; } uint32_t mpc106_write_device(uint32_t device_addr, uint32_t insert_to_device, uint8_t bit_length){ @@ -141,10 +157,73 @@ uint32_t mpc106_read_device(uint32_t device_addr, uint8_t bit_length){ 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: @@ -171,14 +250,6 @@ void mpc106_read(){ case 0x70: read_length = 2; break; - case 0x80: - case 0x84: - case 0x88: - case 0x8C: - case 0x90: - case 0x94: - case 0x98: - case 0x9C: case 0xF0: case 0xF4: case 0xF8: @@ -187,6 +258,7 @@ void mpc106_read(){ default: //Avoid writing into reserved areas read_length = 0; } + } switch(read_length){ case 1: @@ -210,57 +282,91 @@ void mpc106_write(uint32_t write_word){ uint8_t write_length = 4; - 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 0x80: - case 0x84: - case 0x88: - case 0x8C: - case 0x90: - case 0x94: - case 0x98: - case 0x9C: - case 0xF0: - case 0xF4: - case 0xF8: - case 0xFC: - write_length = 4; - default: //Avoid writing into reserved areas - write_length = 0; + 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; + } } - 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: - if ((mpc106_address == 0x88) | (mpc106_address == 0x8C) | (mpc106_address == 0x98) | (mpc106_address == 0x9C)){ - grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word) & 0x03); - grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word >> 8) & 0x03); - grab_macmem_ptr[mpc106_address++] |= (uint8_t)((mpc106_read_word >> 16) & 0x03); - grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word >> 24) & 0x03); + if (mpc106_membound_change){ + switch(write_length){ + case 1: + change_membound_time(); + grab_macmem_ptr[mpc106_address] |= (uint8_t)((mpc106_read_word) & 0xFF); break; - } - else{ + 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; } } diff --git a/mpc106.h b/mpc106.h index 69302b0..91c96f5 100644 --- a/mpc106.h +++ b/mpc106.h @@ -23,12 +23,16 @@ 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; + extern unsigned char* mpc106_regs; +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); #endif diff --git a/openpic.cpp b/openpic.cpp index 551410e..aca3cd7 100644 --- a/openpic.cpp +++ b/openpic.cpp @@ -16,6 +16,18 @@ uint32_t openpic_address; uint32_t openpic_write_word; uint32_t openpic_read_word; +bool openpic_int_go; + +//OPENPIC ADDRESS MAP goes like this... + +//(Assuming that it's placed at 0x80040000 +//Per Processor Registers [private access] 0x40000 - 0x40fff +//Global registers 0x41000 - 0x4ffff +//Interrupt Source Configuration Registers 0x50000 - 0x5ffff +//Per Processor Registers [global access] 0x60000 - 0x7ffff + +//Taken from FreeBSD source code + void openpic_init(){ for (int i = 0x40004; i < 0x7FFFF; i++){ if (i % 16 == 0){ @@ -23,18 +35,53 @@ void openpic_init(){ } 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; } void openpic_read(){ + if (openpic_address > 0x60000){ + openpic_address = (openpic_address % 0x8000) + 0x60000; + } + openpic_read_word = (uint32_t)(machine_upperiocontrol_mem[openpic_address++]); openpic_read_word = (uint32_t)((machine_upperiocontrol_mem[openpic_address++]) << 8); openpic_read_word = (uint32_t)((machine_upperiocontrol_mem[openpic_address++]) << 16); openpic_read_word = (uint32_t)((machine_upperiocontrol_mem[openpic_address]) << 24); + } void openpic_write(){ + //Max of 128 interrupts per processor + //Each interrupt line takes up 0x8000 bytes + + uint32_t op_interrupt_check = (openpic_address & 0xFF); + + //We have only one processor + if (openpic_address > 0x60000){ + 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 (op_interrupt_check){ + case 0x80: + printf("Task Priority Reg stuff goes here! \n"); + break; + case 0x90: + printf("WHOAMI stuff goes here! \n"); + break; + case 0xA0: + openpic_int_go = true; + break; + case 0xB0: + openpic_int_go = false; + break; + } } diff --git a/ppcmemory.cpp b/ppcmemory.cpp index 953608f..3be30fa 100644 --- a/ppcmemory.cpp +++ b/ppcmemory.cpp @@ -479,18 +479,23 @@ void address_quickinsert_translate(uint32_t address_grab, uint32_t value_insert, //regular grabbing if (address_grab < 0x80000000){ - if (address_grab > 0x03ffffff){ //for debug purposes - 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; + 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 >= 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{ - storage_area = address_grab % 0x04000000; - grab_macmem_ptr = machine_sysram_mem; - printf("Uncharted territory: %x \n", address_grab); + return; } } else if (address_grab < 0x80800000){ @@ -610,6 +615,7 @@ void address_quickinsert_translate(uint32_t address_grab, uint32_t value_insert, } else if (address_grab < 0xFF000000){ storage_area = 0x0CFC; //CONFIG_DATA + mpc106_word_custom_size = bit_num; mpc106_write_device(mpc_config_addr, value_insert, bit_num); grab_macmem_ptr = machine_feexxx_mem; } @@ -717,15 +723,22 @@ void address_quickgrab_translate(uint32_t address_grab, uint32_t value_extract, //regular grabbing if (address_grab < 0x80000000){ - if (address_grab > 0x03ffffff){ //for debug purposes - 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; + 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 >= 0x5fffe000) && (address_grab <= 0x5fffffff)){ + storage_area = address_grab % 0x2000; + grab_macmem_ptr = machine_sysconfig_mem; + } + else{ + return_value = (bit_num == 1)?0xFF:(bit_num == 2)?0xFFFF:0xFFFFFFFF; + return; + } } else{ + //The address is not within the ROM banks return_value = (bit_num == 1)?0xFF:(bit_num == 2)?0xFFFF:0xFFFFFFFF; return; } @@ -824,6 +837,7 @@ void address_quickgrab_translate(uint32_t address_grab, uint32_t value_extract, return; } else if (address_grab < 0xFF000000){ + mpc106_word_custom_size = bit_num; return_value = mpc106_read_device(mpc_config_addr, bit_num); return_value = rev_endian32(return_value); return; @@ -1011,8 +1025,11 @@ void quickinstruction_translate(uint32_t address_grab){ grab_macmem_ptr = machine_sysrom_mem; } - ppc_cur_instruction += (grab_macmem_ptr[(storage_area++)]) << 24; - ppc_cur_instruction += (grab_macmem_ptr[(storage_area++)]) << 16; - ppc_cur_instruction += (grab_macmem_ptr[(storage_area++)]) << 8; + 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)]); }