#include "debug.h"
#include "calc.h"
#include "gfxboard.h"
+#include "cpuboard.h"
#include "luascript.h"
static int config_newfilesystem;
decode_rom_ident (p->a4091romident2, sizeof p->a4091romident2 / sizeof (TCHAR), p->a4091romident2, ROMTYPE_A4091BOOT);
return 1;
}
+ if (cfgfile_string (option, value, _T("cpuboard_rom"), p->acceleratorromident, sizeof p->acceleratorromident / sizeof (TCHAR))) {
+ decode_rom_ident (p->acceleratorromident, sizeof p->acceleratorromident / sizeof (TCHAR), p->acceleratorromident, ROMTYPE_CPUBOARD);
+ return 1;
+ }
+ if (cfgfile_string (option, value, _T("cpuboard_ext_rom"), p->acceleratorextromident, sizeof p->acceleratorextromident / sizeof (TCHAR))) {
+ decode_rom_ident (p->acceleratorextromident, sizeof p->acceleratorextromident / sizeof (TCHAR), p->acceleratorextromident, ROMTYPE_CPUBOARDEXT);
+ return 1;
+ }
if (cfgfile_string (option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
return 1;
return 1;
}
+int built_in_cpuboard_prefs(struct uae_prefs *p)
+{
+ int roms[2], roms2[2];
+
+ roms[0] = -1;
+ roms[1] = -1;
+ roms2[0] = -1;
+ roms2[1] = -1;
+
+ switch(p->cpuboard_type)
+ {
+ case BOARD_BLIZZARD_1230_IV_SCSI:
+ roms2[0] = 94;
+ case BOARD_BLIZZARD_1230_IV:
+ roms[0] = 89;
+ break;
+ case BOARD_BLIZZARD_1260_SCSI:
+ roms2[0] = 94;
+ case BOARD_BLIZZARD_1260:
+ roms[0] = 90;
+ break;
+ case BOARD_BLIZZARD_2060:
+ roms[0] = 92;
+ break;
+ case BOARD_WARPENGINE_A4000:
+ roms[0] = 93;
+ break;
+ case BOARD_CSMK1:
+ roms[0] = p->cpu_model == 68040 ? 95 : 101;
+ break;
+ case BOARD_CSMK2:
+ roms[0] = 96;
+ break;
+ case BOARD_CSMK3:
+ roms[0] = 97;
+ break;
+ case BOARD_CSPPC:
+ roms[0] = 98;
+ break;
+ case BOARD_BLIZZARDPPC:
+ roms[0] = p->cpu_model == 68040 ? 99 : 100;
+ break;
+ }
+ p->acceleratorromfile[0] = 0;
+ p->acceleratorextromfile[0] = 0;
+ if (!configure_rom(p, roms, 0))
+ return 0;
+ if (!configure_rom(p, roms2, 0))
+ return 0;
+ return 1;
+}
+
void set_config_changed (void)
{
config_changed = 1;
#define BPPC_MAPROM_OFF 0x13
#define BPPC_UNLOCK_FLASH 0x92
#define BPPC_LOCK_FLASH 0x93
-#define BPPC_MAGIC_UNLOCK 0x42
+#define BPPC_MAGIC_UNLOCK_VALUE 0x42
/* bit definitions */
#define P5_SET_CLEAR 0x80
/* REQ_RESET 0x00 */
+// 0x10/0x08/0x04 only work if P5_SELF_RESET is cleared
#define P5_PPC_RESET 0x10
#define P5_M68K_RESET 0x08
#define P5_AMIGA_RESET 0x04
if (cpuboard_size <= 2 * 524288)
return;
if (maprom_state) {
- write_log(_T("BPPC MAP ROM On\n"));
map_banks(&blizzardmaprom2_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
} else {
- write_log(_T("BPPC MAP ROM Off\n"));
map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
}
}
{
if (a3000hmem_bank.allocated <= 2 * 524288)
return;
- write_log(_T("CSMK3 MAP ROM On\n"));
- if (!(io_reg[CSIII_REG_SHADOW] & P5_SHADOW) && is_ppc())
+ if (maprom_state && is_ppc())
map_banks(&blizzardmaprom2_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
else
map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
v &= ~0x10;
} else if (reg == CSIII_REG_SHADOW) {
v |= 0x08;
+ } else if (reg == CSIII_REG_RESET) {
+ v &= 0x1f;
}
#if CPUBOARD_IO_LOG > 0
if (reg != CSIII_REG_IRQ || CPUBOARD_IO_LOG > 2)
if (bank == 0) {
addr &= 0xff;
if (is_blizzardppc()) {
- if (addr == BPPC_UNLOCK_FLASH && v == BPPC_MAGIC_UNLOCK) {
+ if (addr == BPPC_UNLOCK_FLASH && v == BPPC_MAGIC_UNLOCK_VALUE) {
flash_unlocked = 1;
write_log(_T("BPPC: flash unlocked\n"));
} else if (addr == BPPC_LOCK_FLASH) {
if (v & 0x80)
io_reg[CSIII_REG_LOCK] |= 2;
}
- if (is_blizzardppc())
- return;
if ((io_reg[CSIII_REG_LOCK] & 0x70) != P5_MAGIC3)
return;
}
write_log(_T("CS: SCSI reset\n"));
map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x60000 >> 16, 0);
}
- if (!(regval & P5_AMIGA_RESET)) {
- uae_reset(0, 0);
- write_log(_T("CS: Amiga Reset\n"));
- io_reg[addr] |= P5_AMIGA_RESET;
- }
if ((oldval & P5_PPC_RESET) && !(regval & P5_PPC_RESET)) {
uae_ppc_cpu_stop();
} else if (!(oldval & P5_PPC_RESET) && (regval & P5_PPC_RESET)) {
cpu_halt(-1);
}
}
+ if (!(io_reg[CSIII_REG_SHADOW] & P5_SELF_RESET)) {
+ if (!(regval & P5_AMIGA_RESET)) {
+ uae_reset(0, 0);
+ write_log(_T("CS: Amiga Reset\n"));
+ io_reg[addr] |= P5_AMIGA_RESET;
+ }
+ } else {
+ io_reg[CSIII_REG_RESET] &= ~P5_AMIGA_RESET;
+ io_reg[CSIII_REG_RESET] |= oldval & P5_AMIGA_RESET;
+ }
} else if (addr == CSIII_REG_IPL_EMU) {
#if CPUBOARD_IRQ_LOG > 0
regval &= ~P5_M68k_IPL_MASK;
} else if (addr == CSIII_REG_SHADOW) {
if (is_csmk3() && ((oldval ^ regval) & 1)) {
maprom_state = (regval & 1) ? 0 : 1;
+ write_log(_T("CyberStorm MAPROM = %d\n"), maprom_state);
cyberstorm_copymaprom();
cyberstorm_maprom();
}
map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x40000 >> 16, 0);
map_banks(&blizzardio_bank, 0xf50000 >> 16, (3 * 65536) >> 16, 0);
cyberstorm_maprom();
- if (!(io_reg[CSIII_REG_SHADOW] & P5_SHADOW))
- cyberstorm_copymaprom();
}
if (is_csmk2()) {
map_banks(&blizzardio_bank, 0x88000000 >> 16, 65536 >> 16, 0);
blizzardram_bank.start = BLIZZARD_RAM_ALIAS_BASE;
blizzardram_bank.allocated = cpuboard_size;
blizzardram_bank.mask = blizzardram_bank.allocated - 1;
+ blizzardram_bank.startmask = BLIZZARD_RAM_BASE;
blizzardram_nojit_bank.start = blizzardram_bank.start;
blizzardram_nojit_bank.allocated = blizzardram_bank.allocated;
blizzardram_nojit_bank.mask = blizzardram_bank.mask;
+ blizzardram_nojit_bank.startmask = blizzardram_bank.startmask;
blizzard_jit = 0 && BLIZZARD_RAM_BASE + blizzardram_bank.allocated <= max_z3fastmem && currprefs.jit_direct_compatible_memory;
blizzardf0_bank.start = 0x00f00000;
blizzardf0_bank.allocated = 65536;
blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
-
mapped_malloc(&blizzardf0_bank);
blizzardea_bank.allocated = 2 * 65536;
- blizzardea_bank.mask = blizzardea_bank.allocated - 1;
+ blizzardea_bank.mask = 65535 - 1;
mapped_malloc(&blizzardea_bank);
blizzardmaprom_bank.allocated = 524288;
- mapped_malloc(&blizzardmaprom_bank);
blizzardmaprom_bank.start = 0x07f80000;
blizzardmaprom_bank.mask = 524288 - 1;
blizzardmaprom_bank_mapped = true;
+ mapped_malloc(&blizzardmaprom_bank);
} else if (is_csmk2() || is_blizzard2060()) {
if (maprom_state)
blizzard_copymaprom();
} else if (is_csmk3()) {
- if (!(io_reg[CSIII_REG_SHADOW] & P5_SHADOW))
+ if (maprom_state)
cyberstorm_copymaprom();
}
return true;
return false;
}
+bool cpuboard_blizzardram(struct uae_prefs *p)
+{
+ switch (p->cpuboard_type)
+ {
+ case BOARD_BLIZZARD_1230_IV:
+ case BOARD_BLIZZARD_1260:
+ case BOARD_BLIZZARDPPC:
+ return true;
+ }
+ return false;
+}
+
static void fixserial(uae_u8 *rom, int size)
{
uae_u8 value1 = rom[16];
uae_u32 serialnum = 0x1234;
char serial[10];
+#if 0
+ return;
+#endif
+
if (currprefs.cpuboard_type == BOARD_BLIZZARDPPC) {
value1 = 'I';
value2 = 'D';
f = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
}
}
+ if (f)
+ write_log(_T("Accelerator board flash file '%s' loaded.\n"), name);
return f;
}
const TCHAR *defaultromname = NULL;
const TCHAR *romname = currprefs.acceleratorromfile;
bool isflashrom = false;
+ struct romdata *rd = NULL;
roms[0] = -1;
roms[1] = -1;
case BOARD_WARPENGINE_A4000:
return &expamem_null;
case BOARD_CSMK1:
- roms[0] = 95;
+ roms[0] = currprefs.cpu_model == 68040 ? 95 : 101;
isflashrom = true;
break;
case BOARD_CSMK2:
isflashrom = true;
break;
case BOARD_BLIZZARDPPC:
- roms[0] = 99;
+ roms[0] = currprefs.cpu_model == 68040 ? 99 : 100;
isflashrom = true;
break;
default:
}
struct romlist *rl = getromlistbyids(roms);
- if (!rl)
- return &expamem_null;
- defaultromname = rl->rd->defaultfilename;
- if (rl && !isflashrom) {
- autoconfig_rom = read_rom(rl->rd);
+ if (!rl) {
+ rd = getromlistbyidsallroms(roms);
+ if (!rd)
+ return &expamem_null;
+ } else {
+ rd = rl->rd;
}
-
- if (isflashrom) {
+ defaultromname = rd->defaultfilename;
+ if (rl && !isflashrom) {
+ autoconfig_rom = zfile_fopen(romname, _T("rb"));
+ if (!autoconfig_rom)
+ autoconfig_rom = read_rom(rl->rd);
+ } else if (isflashrom) {
autoconfig_rom = flashfile_open(romname);
if (!autoconfig_rom) {
- autoconfig_rom = flashfile_open(rl->path);
+ if (rl)
+ autoconfig_rom = flashfile_open(rl->path);
if (!autoconfig_rom)
autoconfig_rom = flashfile_open(defaultromname);
}
blizzardea_bank.baseaddr[i * 2 + 0] = b;
}
} else if (is_csmk1()) {
- f0rom_size = 131072;
- earom_size = 65536;
+ earom_size = 131072;
+ f0rom_size = 65536;
for (int i = 0; i < 32768; i++) {
uae_u8 b = 0xff;
zfile_fread(&b, 1, 1, autoconfig_rom);
zfile_fclose(autoconfig_rom);
if (f0rom_size)
- map_banks(&blizzardf0_bank, 0xf00000 >> 16, 262144 >> 16, 0);
+ map_banks(&blizzardf0_bank, 0xf00000 >> 16, f0rom_size >> 16, 0);
if (!autoconf)
return &expamem_null;
return &blizzarde8_bank;
extern void cpuboard_vsync(void);
extern void cpuboard_rethink(void);
extern bool cpuboard_08000000(struct uae_prefs *p);
+extern bool cpuboard_blizzardram(struct uae_prefs *p);
extern bool is_ppc_cpu(struct uae_prefs *);
extern bool ppc_interrupt(int new_m68k_ipl);
extern void cfgfile_addcfgparam (TCHAR *);
extern int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck);
extern int built_in_chipset_prefs (struct uae_prefs *p);
+extern int built_in_cpuboard_prefs(struct uae_prefs *p);
extern int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max);
extern int cfgfile_configuration_change (int);
extern void fixup_prefs_dimensions (struct uae_prefs *prefs);
extern void getromname (const struct romdata*, TCHAR*);
extern struct romdata *getromdatabyname (const TCHAR*);
extern struct romlist *getromlistbyids (const int *ids);
+extern struct romdata *getromlistbyidsallroms (const int *ids);
extern void romwarning(const int *ids);
extern struct romlist *getromlistbyromdata (const struct romdata *rd);
extern void romlist_add (const TCHAR *path, struct romdata *rd);
x_do_cycles_post = do_cycles_post;
} else {
x_prefetch = NULL;
- x_get_ilong = get_iilong;
- x_get_iword = get_iiword;
- x_get_ibyte = get_iibyte;
- x_next_iword = next_iiword;
- x_next_ilong = next_iilong;
+ x_get_ilong = get_dilong;
+ x_get_iword = get_diword;
+ x_get_ibyte = get_dibyte;
+ x_next_iword = next_diword;
+ x_next_ilong = next_dilong;
x_put_long = put_long;
x_put_word = put_word;
x_put_byte = put_byte;
for (;;) {
r->instruction_pc = m68k_getpc ();
+
+// if (r->instruction_pc >= 0x01000000)
+// activate_debugger();
+
uae_u16 opcode = x_get_iword(0);
count_instr (opcode);
void exception2_fake (uaecptr addr)
{
+ if (regs.halted)
+ return;
write_log (_T("delayed exception2!\n"));
regs.panic_pc = m68k_getpc ();
regs.panic_addr = addr;
}
z3offset = 0;
- if ((changed_prefs.z3fastmem_start == 0x10000000 || changed_prefs.z3fastmem_start == 0x40000000) && !changed_prefs.force_0x10000000_z3) {
+ if ((changed_prefs.z3fastmem_start == 0x10000000 || changed_prefs.z3fastmem_start == 0x40000000) && !changed_prefs.force_0x10000000_z3 && !cpuboard_blizzardram(&changed_prefs)) {
if (natmem_size > 0x40000000 && natmem_size - 0x40000000 >= (totalsize - 0x10000000 - ((changed_prefs.z3chipmem_size + align) & ~align)) && changed_prefs.z3chipmem_size <= 512 * 1024 * 1024) {
changed_prefs.z3fastmem_start = currprefs.z3fastmem_start = 0x40000000;
z3offset += 0x40000000 - 0x10000000 - ((changed_prefs.z3chipmem_size + align) & ~align);
CONTROL "More compatible [] More compatible but slower FPU emulation.",IDC_COMPATIBLE_FPU,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,259,117,10
CONTROL "Unimplemented FPU emu [] Emulate FPU unimplemented instructions",IDC_FPU_UNIMPLEMENTED,
- "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,277,116,10
+ "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,272,116,10
GROUPBOX "Advanced JIT Settings",IDC_STATIC,136,188,258,99
RTEXT "Cache size:",IDC_STATIC,143,207,66,10,SS_CENTERIMAGE
CONTROL "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,212,201,115,20
CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,243,234,68,11
CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,315,234,72,10
CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,315,248,72,10
- CONTROL "PPC [] Automatically configure CyberStorm PPC or Blizzard PPC setup.",IDC_CPU_PPC,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,169,118,10
+ CONTROL "PPC [] Automatically configure CyberStorm PPC or Blizzard PPC setup.",IDC_CPU_PPC,
+ "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,169,118,10
END
IDD_FLOPPY DIALOGEX 0, 0, 396, 261
BEGIN
IDD_KICKSTART, DIALOG
BEGIN
- BOTTOMMARGIN, 243
+ BOTTOMMARGIN, 275
END
IDD_DISPLAY, DIALOG
#define LANG_DLL_FULL_VERSION_MATCH 1
#if WINUAEPUBLICBETA
-#define WINUAEBETA _T("10")
+#define WINUAEBETA _T("11")
#else
#define WINUAEBETA _T("")
#endif
-#define WINUAEDATE MAKEBD(2014, 8, 10)
+#define WINUAEDATE MAKEBD(2014, 8, 16)
//#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition")
} else if (workprefs.ppc_mode == 2) {
workprefs.ppc_mode = 0;
}
+ built_in_cpuboard_prefs(&workprefs);
enable_for_memorydlg(hDlg);
}
break;
{
case WM_INITDIALOG:
{
- int ids[] = { IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_A2091ROMFILE, IDC_A4091ROMFILE, -1 };
+ int ids[] = { IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_A2091ROMFILE, IDC_A4091ROMFILE, IDC_CPUBOARDROMFILE, IDC_CPUBOARDEXTROMFILE, -1 };
pages[KICKSTART_ID] = hDlg;
currentpage = KICKSTART_ID;
init_kickstart (hDlg);
case IDC_CARTFILE:
case IDC_A2091ROMFILE:
case IDC_A4091ROMFILE:
+ case IDC_CPUBOARDROMFILE:
+ case IDC_CPUBOARDEXTROMFILE:
values_from_kickstartdlg (hDlg);
break;
}
-1,
IDD_INPUT, IDC_INPUTDEVICE, IDC_INPUTLIST, IDC_INPUTAMIGA,
-1,
- IDD_KICKSTART, IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_FLASHFILE, IDC_RTCFILE, IDC_A2091ROMFILE, IDC_A4091ROMFILE,
+ IDD_KICKSTART, IDC_ROMFILE, IDC_ROMFILE2, IDC_CARTFILE, IDC_FLASHFILE, IDC_RTCFILE, IDC_A2091ROMFILE, IDC_A4091ROMFILE, IDC_CPUBOARDROMFILE, IDC_CPUBOARDEXTROMFILE,
-1,
IDD_LOADSAVE, IDC_CONFIGTREE, IDC_EDITNAME, IDC_EDITDESCRIPTION, IDC_CONFIGLINK, IDC_EDITPATH,
-1,
- restore only single input target to default.
+Beta 11:
+
+- P5_AMIGA_RESET CSMK3/CSPPC/BPPC bit can be only changed if P5_SELF_RESET is cleared first.
+- Never use normal Z3 autoconfig mapping if Blizzard board is emulated to reduce address space
+ conflicts with Blizzard RAM mirror at 0x48000000. Note that this is impossible config, there is no
+ way to have any Z3 boards with BPPC in real world.
+- Blizzard PPC rom name renamed to blizzardppc_060.rom and added blizzardppc_040.rom. 68040 and 68060
+ variants have different (and incompatible) flash rom contents.
+- 68000 + no cycle exact and no "more compatible" used wrong memory access method. (b9)
+- RTD instruction was set as 68000 compatible (should be 68010+). Incorrect since the beginning.
+- Accelerator board ROM select menus didn't select anything.
+- Added full CyberStorm MK1 image ($F00000 ROM code is 68060-only), added another 68040 compatible ROM
+ that simulates boards with boot rom jumper disabled or boot rom chip removed. (Original non-flash based
+ boards had separate ROM chip for boot and diag ROMs and boot was only installed if CPU was 68060)
+- CyberStorm MK1 SCSI works again.
+- Automatically update accelerator board ROM settings when board type is changed in GUI.
+- PPC BAT register handling fixed (Technically not emulation bug but OS bug, PPC documentation says
+ '... BEPI and BRPN fields must have at least as many low-order zeros as there are ones in BL.', BEPI and BRPN
+ needs to be masked with BL instead of trusting software doing as documentation says..)
+- Added missing PearPC divwu, divwuo, addco, subfco PPC instructions. (Variants of already existing
+ instructions).
+
+Last two updates allows AmigaOS 4.1 Classic to boot.
+
+OS4 note: If you enable Z3 RTG board, it must be mapped at real Z3 space (0x40000000+), "JIT Direct compatible
+Z3 memory mapping" must be unticked or you must have large enough host address space (=64-bit Windows). OS4 resets
+the system and autoconfigures all boards, m68k hacks can't work. (NetBSD and Linux work because they read board
+config data from AOS expansion.library before taking over the system)
+
+Next topic:
+
+PearPC CPU emulator is a dead-end. Missing instructions, only partially emulated instructions, no support
+for integer overflows, division by zero, illegal instruction exceptions and so on.. (Which means any buggy or
+badly behaving program can crash the emulator or hang or crash emulated operating system). It did its job, allowed
+easy and quick PPC emulation test. It would not have happened with any other more complex ores.
+
+It seems most compatible PPC CPU emulation is in QEMU. Dolphin only have experimental MMU support which is not
+supported in JIT modes. But QEMU is complex, very complex..
+
+What does this mean? It means all PPC CPU related bugs will be ignored until PPC CPU emulator core is replaced
+(timeframe: unknown. Not going to happen without help.), only exception is bugs that didn't exist in b10.
+
Beta 10:
-- Added CyberStormI/II/II/PPC and Blizzard PPC flash rom images to rom scanner, name based detection only.
+- Added CyberStormI/II/III/PPC and Blizzard PPC flash rom images to rom scanner, name based detection only.
(Remember to click ROM rescan button) Now opens usual ROM missing dialog when flash rom image can't be opened.
- Added GUI support for manual accelerator board ROM image selection.
- NCR53C770 emulation spurious interrupt fix.
// update XER flags
PPC_ALU_ERR("addcox unimplemented\n");
}
+
+/*
+ * addcox Add Carrying with Overflow
+ * .522 ***** TW
+ */
+void ppc_opc_addco()
+{
+ int rD, rA, rB;
+ PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
+ uint32 a = gCPU.gpr[rA];
+ gCPU.gpr[rD] = a + gCPU.gpr[rB];
+ if (gCPU.current_opc & PPC_OPC_Rc) {
+ // update cr0 flags
+ ppc_update_cr0(gCPU.gpr[rD]);
+ }
+}
+
+
/*
* addex Add Extended
* .424
if (!gCPU.gpr[rB]) {
PPC_ALU_WARN("division by zero @%08x\n", gCPU.pc);
SINGLESTEP("");
+ return;
}
sint32 a = gCPU.gpr[rA];
sint32 b = gCPU.gpr[rB];
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
if (!gCPU.gpr[rB]) {
PPC_ALU_ERR("division by zero\n");
+ return;
}
sint32 a = gCPU.gpr[rA];
sint32 b = gCPU.gpr[rB];
if (!gCPU.gpr[rB]) {
PPC_ALU_WARN("division by zero @%08x\n", gCPU.pc);
SINGLESTEP("");
+ return;
}
gCPU.gpr[rD] = gCPU.gpr[rA] / gCPU.gpr[rB];
if (gCPU.current_opc & PPC_OPC_Rc) {
int rD, rA, rB;
PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
if (!gCPU.gpr[rB]) {
-// PPC_ALU_ERR("division by zero\n");
+ PPC_ALU_ERR("division by zero\n");
+ return;
}
gCPU.gpr[rD] = gCPU.gpr[rA] / gCPU.gpr[rB];
if (gCPU.current_opc & PPC_OPC_Rc) {
PPC_ALU_ERR("divwuox unimplemented\n");
}
+/*
+ * divwuo Divide Word Unsigned with Overflow
+ * .971 ***** TW
+ */
+void ppc_opc_divwuo()
+{
+ int rD, rA, rB;
+ PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
+ if (!gCPU.gpr[rB]) {
+ PPC_ALU_ERR("division by zero\n");
+ return;
+ }
+ gCPU.gpr[rD] = gCPU.gpr[rA] / gCPU.gpr[rB];
+ if (gCPU.current_opc & PPC_OPC_Rc) {
+ // update cr0 flags
+ ppc_update_cr0(gCPU.gpr[rD]);
+ }
+}
+
+/*
+ * divwo Divide Word with Overflow
+ * .1003 ***** TW
+ */
+void ppc_opc_divwo()
+{
+ int rD, rA, rB;
+ PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
+ if (!gCPU.gpr[rB]) {
+ PPC_ALU_ERR("division by zero\n");
+ return;
+ }
+ sint32 a = gCPU.gpr[rA];
+ sint32 b = gCPU.gpr[rB];
+ gCPU.gpr[rD] = a / b;
+ if (gCPU.current_opc & PPC_OPC_Rc) {
+ // update cr0 flags
+ ppc_update_cr0(gCPU.gpr[rD]);
+ }
+}
+
/*
* eqvx Equivalent
* .480
}
}
+/*
+ * mullwo Multiply Low Word with Overflow
+ * .747 ***** TW
+ */
+void ppc_opc_mullwo()
+{
+ int rD, rA, rB;
+ PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
+ gCPU.gpr[rD] = gCPU.gpr[rA] * gCPU.gpr[rB];
+ if (gCPU.current_opc & PPC_OPC_Rc) {
+ // update cr0 flags
+ ppc_update_cr0(gCPU.gpr[rD]);
+ }
+}
+
/*
* nandx NAND
* .600
// update XER flags
PPC_ALU_ERR("subfcox unimplemented\n");
}
+
+/*
+ * subfcox Subtract From Carrying with Overflow
+ * .520 ***** TW
+ */
+void ppc_opc_subfco()
+{
+ int rD, rA, rB;
+ PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
+ uint32 a = gCPU.gpr[rA];
+ uint32 b = gCPU.gpr[rB];
+ gCPU.gpr[rD] = ~a + b + 1;
+ if (gCPU.current_opc & PPC_OPC_Rc) {
+ // update cr0 flags
+ ppc_update_cr0(gCPU.gpr[rD]);
+ }
+}
+
/*
* subfex Subtract From Extended
* .668
void ppc_opc_addis();
void ppc_opc_addmex();
void ppc_opc_addzex();
+void ppc_opc_addco(); // TW
void ppc_opc_andx();
void ppc_opc_andcx();
void ppc_opc_divwx();
void ppc_opc_divwux();
+void ppc_opc_divwo(); // TW
+void ppc_opc_divwuo(); // TW
void ppc_opc_eqvx();
void ppc_opc_mulhwux();
void ppc_opc_mulli();
void ppc_opc_mullwx();
+void ppc_opc_mullwo(); // TW
void ppc_opc_nandx();
void ppc_opc_subfic();
void ppc_opc_subfmex();
void ppc_opc_subfzex();
+void ppc_opc_subfco(); // TW
void ppc_opc_xorx();
void ppc_opc_xori();
}
static uint ops = 0;
+static int ppc_trace;
void ppc_cpu_run_single(int count)
{
gCPU.effective_code_page = gCPU.pc & ~0xfff;
continue;
}
- //ht_printf("%08x %04x\n", gCPU.pc, gCPU.current_opc);
+ if (ppc_trace)
+ ht_printf("%08x %04x\n", gCPU.pc, gCPU.current_opc);
ppc_exec_opc();
ops++;
gCPU.ptb++;
// uint32 j=0;
// ppc_read_effective_word(0xc046b2f8, j);
- ht_printf("@%08x (%u ops) pdec: %08x lr: %08x\n", gCPU.pc, ops, gCPU.pdec, gCPU.lr);
+ //ht_printf("@%08x (%u ops) pdec: %08x lr: %08x\n", gCPU.pc, ops, gCPU.pdec, gCPU.lr);
#if 0
extern uint32 PIC_enable_low;
extern uint32 PIC_enable_high;
return gCPU.pvr;
}
+#if 0
void ppc_cpu_map_framebuffer(uint32 pa, uint32 ea)
{
// use BAT for framebuffer
gCPU.dbat_bl17[0] = ~(BATU_BL(gCPU.dbatu[0])<<17);
gCPU.dbatl[0] = pa;
}
+#endif
void ppc_set_singlestep_v(bool v, const char *file, int line, const char *format, ...)
{
memset(&gCPU, 0, sizeof gCPU);
gCPU.pvr = pvr; //gConfig->getConfigInt(CPU_KEY_PVR);
gCPU.hid[1] = 0x80000000;
- gCPU.msr = 1 << MSR_IP;
+ gCPU.msr = MSR_IP;
ppc_dec_init();
// initialize srs (mostly for prom)
- for (int i=0; i<16; i++) {
- gCPU.sr[i] = 0x2aa*i;
- }
+// for (int i=0; i<16; i++) {
+// gCPU.sr[i] = 0x2aa*i;
+// }
sys_create_mutex(&exception_mutex);
PPC_CPU_WARN("You are using the generic CPU!\n");
ppc_opc_table_group2[983] = ppc_opc_stfiwx;
ppc_opc_table_group2[1014] = ppc_opc_dcbz;
+ // missing variants (TW)
+ ppc_opc_table_group2[520] = ppc_opc_subfco;
+ ppc_opc_table_group2[522] = ppc_opc_addco;
+ ppc_opc_table_group2[747] = ppc_opc_mullwo;
+ ppc_opc_table_group2[971] = ppc_opc_divwuo;
+ ppc_opc_table_group2[1003] = ppc_opc_divwo;
+
if ((ppc_cpu_get_pvr(0) & 0xffff0000) == 0x000c0000) {
/* Added for Altivec support */
ppc_opc_table_group2[6] = ppc_opc_lvsl;
return false;
}
ppc_mmu_tlb_invalidate();
- if (1 || (gCPU.msr & MSR_IP))
+ // MSR_IP: 0=0x000xxxxx 1=0xfffxxxxx
+ if (gCPU.msr & MSR_IP)
type |= 0xfff00000;
- gCPU.msr = 0;
+ // MSR_IP is not cleared when exception starts (was wrong in original PearPC)
+ gCPU.msr &= MSR_IP;
gCPU.npc = type;
return true;
}
inline int FASTCALL ppc_effective_to_physical(uint32 addr, int flags, uint32 &result)
{
+ static int lastibatcnt;
+ static int lastdbatcnt;
+
if (flags & PPC_MMU_CODE) {
if (!(gCPU.msr & MSR_IR)) {
result = addr;
uint32 batu = (gCPU.msr & MSR_PR ? BATU_Vp : BATU_Vs);
- for (int i=0; i<4; i++) {
- uint32 bl17 = gCPU.ibat_bl17[i];
- uint32 addr2 = addr & (bl17 | 0xf001ffff);
- if (BATU_BEPI(addr2) == BATU_BEPI(gCPU.ibatu[i])) {
+ for (int ii=0; ii<4; ii++) {
+ int i = lastibatcnt;
+ uint32 bl17 = gCPU.ibat_bl17[i] | 0xf001ffff;
+ uint32 addr2 = addr & bl17;
+ uint32 addr3 = gCPU.ibatu[i] & bl17;
+ if (BATU_BEPI(addr2) == BATU_BEPI(addr3)) {
// bat applies to this address
if (gCPU.ibatu[i] & batu) {
// bat entry valid
uint32 offset = BAT_EA_OFFSET(addr);
uint32 page = BAT_EA_11(addr);
- page &= ~bl17;
- page |= BATL_BRPN(gCPU.ibatl[i]);
+ page &= ~gCPU.ibat_bl17[i];
+ page |= BATL_BRPN(gCPU.ibatl[i] & bl17);
// fixme: check access rights
result = page | offset;
return PPC_MMU_OK;
}
}
+ lastibatcnt++;
+ lastibatcnt &= 3;
}
} else {
if (!(gCPU.msr & MSR_DR)) {
uint32 batu = (gCPU.msr & MSR_PR ? BATU_Vp : BATU_Vs);
- for (int i=0; i<4; i++) {
- uint32 bl17 = gCPU.dbat_bl17[i];
- uint32 addr2 = addr & (bl17 | 0xf001ffff);
- if (BATU_BEPI(addr2) == BATU_BEPI(gCPU.dbatu[i])) {
+ for (int ii=0; ii<4; ii++) {
+ int i = lastdbatcnt;
+ uint32 bl17 = gCPU.dbat_bl17[i] | 0xf001ffff;
+ uint32 addr2 = addr & bl17;
+ uint32 addr3 = gCPU.dbatu[i] & bl17;
+ if (BATU_BEPI(addr2) == BATU_BEPI(addr3)) {
// bat applies to this address
if (gCPU.dbatu[i] & batu) {
// bat entry valid
uint32 offset = BAT_EA_OFFSET(addr);
uint32 page = BAT_EA_11(addr);
- page &= ~bl17;
- page |= BATL_BRPN(gCPU.dbatl[i]);
+ page &= ~gCPU.dbat_bl17[i];
+ page |= BATL_BRPN(gCPU.dbatl[i] & bl17);
// fixme: check access rights
result = page | offset;
return PPC_MMU_OK;
}
}
+ lastdbatcnt++;
+ lastdbatcnt &= 3;
}
}
void ppc_opc_mcrxr()
{
gCPU.xer = 0; //no, this is not correct
- //PPC_OPC_ERR("mcrxr unimplemented.\n");
+ PPC_OPC_ERR("mcrxr unimplemented.\n");
}
/*
* mfcr Move from Condition Register
static void uae_ppc_cpu_reset(void)
{
if (!ppc_init_done) {
+ write_log(_T("PPC: Hard reset\n"));
ppc_cpu_init(currprefs.cpuboard_type == BOARD_BLIZZARDPPC ? BLIZZPPC_PVR : CSPPC_PVR);
ppc_init_done = true;
}
+ write_log(_T("PPC: Init\n"));
ppc_cpu_set_pc(0, 0xfff00100);
ppc_cycle_count = 2000;
ppc_state = PPC_STATE_ACTIVE;
uae_ppc_poll_queue();
}
read_comm_pipe_u32_blocking(&ppcreturn);
+ ppc_state = PPC_STATE_STOP;
write_log(_T("PPC stopped.\n"));
}
}
static char * simm(int val, int hex, int s)
{
static char out[16];
+ hex = 1;
if( ((val >= -256) && (val <= 256)) && !hex) sprintf(out, "%i", val);
else
{
return s->vga.cr[s->vga.cr_index];
case 0x26: // Attribute Controller Index Readback (R)
return s->vga.ar_index & 0x3f;
+ case 0x3f:
+ return 0; // Miscellaneous video control
break;
default:
#ifdef DEBUG_CIRRUS
return NULL;
}
-#define NEXT_ROM_ID 100
+#define NEXT_ROM_ID 102
static struct romheader romheaders[] = {
{ _T("Freezer Cartridges"), 1 },
{ _T("Warp Engine A4000 ROM"), 0, 0, 0, 0, _T("WARPENGINE\0WARPENGINEA4000\0"), 32768, 93, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
0x4deb574a, 0x6e6c95ff,0xe8448391,0xd36c5b68,0xc9065cb0,0x702a7d27 },
- { _T("CyberStorm MK I"), 0, 0, 0, 0, _T("CSMKI\0"), 65536, 95, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
- 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1.rom") },
+ { _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
+ 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") },
+ { _T("CyberStorm MK I 68060"), 0, 0, 0, 0, _T("CSMKI\0"), 65536, 101, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
+ 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_060.rom") },
{ _T("CyberStorm MK II"), 0, 0, 0, 0, _T("CSMKII\0"), 131072, 96, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk2.rom") },
{ _T("CyberStorm MK III"), 0, 0, 0, 0, _T("CSMKIII\0"), 131072, 97, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk3.rom") },
{ _T("CyberStorm PPC"), 0, 0, 0, 0, _T("CSPPC\0"), 131072, 98, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
0, 0, 0, 0, 0, 0, NULL, _T("cyberstormppc.rom") },
- { _T("Blizzard PPC"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 99, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
- 0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc.rom") },
+ { _T("Blizzard PPC 68040"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 99, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
+ 0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_040.rom") },
+ { _T("Blizzard PPC 68060"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 100, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
+ 0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_060.rom") },
{ _T("Picasso IV ROM"), 7, 4, 7, 4, _T("PIV\0"), 131072, 91, 0, 0, ROMTYPE_PIV, 0, 0, NULL,
0xa8133e7e, 0xcafafb91,0x6f16b9f3,0xec9b49aa,0x4b40eb4e,0xeceb5b5b },
{
int i = 0;
while (roms[i].name) {
- if (notcrc32(roms[i].crc32) && roms[i].size >= size && roms[i].defaultfilename && !_tcsicmp(roms[i].defaultfilename, name)) {
+ if (notcrc32(roms[i].crc32) && size >= roms[i].size && roms[i].defaultfilename && !_tcsicmp(roms[i].defaultfilename, name)) {
return &roms[i];
}
i++;
ret = checkromdata (sha1, size, ROMTYPE_AR);
memcpy (rom, tmp, 4);
}
- }
+ }//9
xfree (tmpbuf);
return ret;
}
return NULL;
}
+struct romdata *getromlistbyidsallroms (const int *ids)
+{
+ struct romdata *rd;
+ int i;
+
+ i = 0;
+ while (ids[i] >= 0) {
+ rd = getromdatabyid (ids[i]);
+ if (rd)
+ return rd;
+ i++;
+ }
+ return NULL;
+}
+
void romwarning (const int *ids)
{
int i, exp;
TCHAR *path = 0;
int i;
+ if (rom[0] < 0)
+ return 1;
i = 0;
while (rom[i] >= 0) {
rd = getromdatabyid (rom[i]);
_tcscpy (p->romextfile, path);
if (rd->type & (ROMTYPE_CD32CART | ROMTYPE_ARCADIAGAME | ROMTYPE_HRTMON | ROMTYPE_XPOWER | ROMTYPE_NORDIC | ROMTYPE_AR | ROMTYPE_SUPERIV))
_tcscpy (p->cartfile, path);
+ if (rd->type & ROMTYPE_CPUBOARD)
+ _tcscpy (p->acceleratorromfile, path);
+ if (rd->type & ROMTYPE_CPUBOARDEXT)
+ _tcscpy (p->acceleratorextromfile, path);
return 1;
}
idle = 0;
on = 1;
if (gui_data.cpu_halted < 0) {
- on_rgb = 0xcc0000;
+ on_rgb = 0x000000;
num1 = 16; // PPC
num2 = 16;
num3 = 10;
- 0 0 8
0100 1110 0111 0011:002:XNZVC:-----:00: RTE
- 1 9 18
-0100 1110 0111 0100:000:?????:?????:10: RTD #1
+0100 1110 0111 0100:100:?????:?????:10: RTD #1
- 2 0 10
0100 1110 0111 0101:000:-----:-----:00: RTS
- 1 0 9