void calltrap (uae_u32 n)
{
- dw (0xA000 + n);
+ dw(0xA000 + n);
}
void org (uae_u32 a)
static uae_u16 l64111intmask[2], l64111intstatus[2];
#define L64111_CHANNEL_BUFFERS 128
-static uae_u16 io_reg;
+static uae_u16 mpeg_io_reg;
static mpeg2dec_t *mpeg_decoder;
static const mpeg2_info_t *mpeg_info;
static void l64111_setvolume(void)
{
int volume = 32768;
- if (l64111_regs[A_CONTROL2] & (1 << 5) || (io_reg & IO_L64111_MUTE))
+ if (l64111_regs[A_CONTROL2] & (1 << 5) || (mpeg_io_reg & IO_L64111_MUTE))
volume = 0;
if (!pcmaudio)
return;
if (addr != 0)
return;
write_log(_T("FMV: IO=%04x\n"), v);
- io_reg = v;
+ mpeg_io_reg = v;
l64111_setvolume();
- cd32_fmv_state((io_reg & IO_CL450_VIDEO) ? 1 : 0);
+ cd32_fmv_state((mpeg_io_reg & IO_CL450_VIDEO) ? 1 : 0);
}
static uae_u32 REGPARAM2 fmv_wget (uaecptr addr)
_T("qemu"),
NULL
};
+static const TCHAR *ppc_cpu_idle[] = {
+ _T("disabled"),
+ _T("1"),
+ _T("2"),
+ _T("3"),
+ _T("4"),
+ _T("5"),
+ _T("6"),
+ _T("7"),
+ _T("8"),
+ _T("9"),
+ _T("max"),
+ NULL
+};
static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 };
cfgfile_write (f, _T("fpu_model"), _T("%d"), p->fpu_model);
if (p->mmu_model)
cfgfile_write (f, _T("mmu_model"), _T("%d"), p->mmu_model);
- if (p->ppc_mode)
- cfgfile_write_str(f, _T("ppc_model"), p->ppc_mode == 1 ? _T("automatic") : _T("manual"));
+ if (p->ppc_mode) {
+ cfgfile_write_str(f, _T("ppc_model"), p->ppc_model[0] ? p->ppc_model : (p->ppc_mode == 1 ? _T("automatic") : _T("manual")));
+ cfgfile_write_str(f, _T("ppc_cpu_idle"), ppc_cpu_idle[p->ppc_cpu_idle]);
+ }
cfgfile_write_bool (f, _T("cpu_compatible"), p->cpu_compatible);
cfgfile_write_bool (f, _T("cpu_24bit_addressing"), p->address_space_24);
/* do not reorder end */
return 1;
if (cfgfile_string(option, value, _T("ppc_model"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
p->ppc_mode = 0;
- if (!_tcsicmp(tmpbuf, _T("automatic")))
+ p->ppc_model[0] = 0;
+ if (!_tcsicmp(tmpbuf, _T("automatic"))) {
p->ppc_mode = 1;
- else if (!_tcsicmp(tmpbuf, _T("manual")))
+ } else if (!_tcsicmp(tmpbuf, _T("manual"))) {
p->ppc_mode = 2;
+ } else {
+ if (tmpbuf[0] && _tcslen(tmpbuf) < sizeof(p->ppc_model) / sizeof(TCHAR)) {
+ _tcscpy(p->ppc_model, tmpbuf);
+ p->ppc_mode = 2;
+ }
+ }
return 1;
}
+ if (cfgfile_strval(option, value, _T("ppc_cpu_idle"), &p->ppc_cpu_idle, ppc_cpu_idle, 0))
+ return 1;
/* old-style CPU configuration */
if (cfgfile_string (option, value, _T("cpu_type"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
// 0x04
#define P5_IRQ_PPC_1 0x08
#define P5_IRQ_PPC_2 0x10
-// 0x20
+#define P5_IRQ_PPC_3 0x20 // MOS sets this bit
// 0x40 always cleared
/* REG_WAITSTATE 0x10 */
// 0x20
// 0x10 always cleared
// 0x08
-// 0x04
+// 0x04 // MOS sets this bit
#define P5_ENABLE_IPL 0x02
#define P5_INT_MASTER 0x01 // 1=m68k gets interrupts, 0=ppc gets interrupts.
static void check_ppc_int_lvl(void)
{
- uae_u8 ipl;
- uae_u8 il;
if (!(io_reg[CSIII_REG_INT] & P5_ENABLE_IPL)) {
- ipl = (~io_reg[CSIII_REG_IPL_EMU]) & P5_PPC_IPL_MASK;
+ uae_u8 ipl = (~io_reg[CSIII_REG_IPL_EMU]) & P5_PPC_IPL_MASK;
if (ipl < 7) {
- il = (~io_reg[CSIII_REG_INT_LVL]) & 0x7f;
+ uae_u8 il = (~io_reg[CSIII_REG_INT_LVL]) & 0x7f;
if (il) {
for (int i = ipl; i < 7; i++) {
if (il & (1 << i)) {
bool ppc_interrupt(int new_m68k_ipl)
{
- uae_u8 ppcipl;
bool m68kint = (io_reg[CSIII_REG_INT] & P5_INT_MASTER) != 0;
bool active = (io_reg[CSIII_REG_IPL_EMU] & P5_DISABLE_INT) == 0;
bool iplemu = (io_reg[CSIII_REG_INT] & P5_ENABLE_IPL) == 0;
+ uae_u8 ppcipl = (~io_reg[CSIII_REG_IPL_EMU]) & P5_PPC_IPL_MASK;
if (!active)
return false;
if (new_m68k_ipl < 0)
new_m68k_ipl = 0;
- ppcipl = (io_reg[CSIII_REG_IPL_EMU] ^ 7) & 7;
+
+ //bool xirq = !(io_reg[CSIII_REG_IRQ] & P5_IRQ_PPC_2) && (io_reg[CSIII_REG_IRQ] & P5_IRQ_PPC_3);
if (!m68kint && iplemu && active) {
if (new_m68k_ipl > ppcipl) {
return m68kint;
}
-
static bool is_blizzard(void)
{
return currprefs.cpuboard_type == BOARD_BLIZZARD_1230_IV || currprefs.cpuboard_type == BOARD_BLIZZARD_1230_IV_SCSI ||
static addrbank blizzardf0_bank = {
blizzardf0_lget, blizzardf0_wget, blizzardf0_bget,
blizzardf0_lput, blizzardf0_wput, blizzardf0_bput,
- blizzardf0_xlate, blizzardf0_check, NULL, _T("rom_f0"), _T("CPUBoard F00000"),
+ blizzardf0_xlate, blizzardf0_check, NULL, _T("rom_f0_ppc"), _T("CPUBoard F00000"),
blizzardf0_lget, blizzardf0_wget, ABFLAG_ROM
};
protect_roms(false);
memcpy(dst, src, 524288);
protect_roms(true);
+ set_roms_modified();
}
static void cyberstorm_copymaprom(void)
{
protect_roms(false);
memcpy(dst, src, 524288);
protect_roms(true);
+ set_roms_modified();
}
}
static void cyberstormmk2_copymaprom(void)
protect_roms(false);
memcpy(dst, src, 524288);
protect_roms(true);
+ set_roms_modified();
}
}
static void cyberstormmk1_copymaprom(void)
protect_roms(false);
memcpy(dst, src, 524288);
protect_roms(true);
+ set_roms_modified();
}
}
if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
INTREQ(0x8000 | 0x0008);
}
+ check_ppc_int_lvl();
ppc_interrupt(intlev());
}
}
if ((regval & P5_PPC_IPL_MASK) != (oldval & P5_PPC_IPL_MASK))
write_log(_T("CS: PPC IPL %02x\n"), (~regval) & P5_PPC_IPL_MASK);
#endif
- check_ppc_int_lvl();
} else if (addr == CSIII_REG_INT) {
#if CPUBOARD_IRQ_LOG > 0
if ((regval & P5_INT_MASTER) != (oldval & P5_INT_MASTER))
if ((regval & P5_ENABLE_IPL) != (oldval & P5_ENABLE_IPL))
write_log(_T("CS: IPL state: %s\n"), (regval & P5_ENABLE_IPL) ? _T("disabled") : _T("enabled"));
#endif
- check_ppc_int_lvl();
} else if (addr == CSIII_REG_INT_LVL) {
#if CPUBOARD_IRQ_LOG > 0
if (regval != oldval)
write_log(_T("CS: interrupt level: %02x\n"), regval);
#endif
- check_ppc_int_lvl();
} else if (addr == CSIII_REG_SHADOW) {
if (is_csmk3() && ((oldval ^ regval) & 1)) {
maprom_state = (regval & 1) ? 0 : 1;
}
}
+void cpuboard_hsync(void)
+{
+ // we should call check_ppc_int_lvl() immediately
+ // after PPC CPU's interrupt flag is cleared but this
+ // should be fast enough for now
+ if (is_csmk3() || is_blizzardppc()) {
+ check_ppc_int_lvl();
+ }
+}
+
void cpuboard_vsync(void)
{
if (delayed_rom_protect <= 0)
}
}
-void cpuboard_reset(bool hardreset)
+void cpuboard_reset(void)
{
+ bool hardreset = is_hardreset();
if (is_blizzard() || is_blizzardppc())
canbang = 0;
configured = false;
void cpuboard_clear(void)
{
+ if (blizzardmaprom_bank.baseaddr)
+ memset(blizzardmaprom_bank.baseaddr, 0, 524288);
+ if (blizzardmaprom2_bank.baseaddr)
+ memset(blizzardmaprom2_bank.baseaddr, 0, 524288);
+ if (is_csmk3()) // SCSI RAM
+ memset(blizzardf0_bank.baseaddr + 0x40000, 0, 0x10000);
}
bool is_ppc_cpu(struct uae_prefs *p)
now = read_processor_time ();
if (extraframewait && !currprefs.turbo_emulation)
- sleep_millis_main (extraframewait);
+ cpu_sleep_millis(extraframewait);
adjust = (int)now - (int)curr_time;
int adjustx = adjust;
if ((int)vsyncwaittime - (int)curr_time <= 0 || (int)vsyncwaittime - (int)curr_time > 2 * vsynctimebase)
break;
rtg_vsynccheck ();
- sleep_millis_main (1);
+ cpu_sleep_millis(1);
}
} else {
curr_time = read_processor_time ();
if (v >= -4)
break;
rtg_vsynccheck ();
- sleep_millis_main (2);
+ cpu_sleep_millis(2);
}
curr_time = start = read_processor_time ();
while (rpt_vsync (clockadjust) < 0)
#endif
#ifdef WITH_PPC
uae_ppc_hsync_handler();
+ cpuboard_hsync();
#endif
DISK_hsync ();
if (currprefs.produce_sound)
frame_time_t rpt = read_processor_time ();
// sleep if more than 2ms "free" time
while (!vsync_isdone () && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) {
- sleep_millis_main (1);
+ cpu_sleep_millis(1);
rpt = read_processor_time ();
//write_log (_T("*"));
}
long max_cycles_to_next_event;
long cycles_to_hsync_event;
unsigned long start_cycles;
+bool event_wait;
frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime;
int vsynctimebase;
if (v > vsynctimebase || v < -vsynctimebase) {
v = 0;
}
- if (v < 0 && v2 < 0) {
+ if (v < 0 && v2 < 0 && event_wait) {
+
#ifdef WITH_PPC
if (ppc_state) {
if (is_syncline == 1) {
- uae_ppc_execute_quick(0);
+ uae_ppc_execute_check();
} else {
- uae_ppc_execute_quick(1);
+ uae_ppc_execute_quick();
}
}
-
#endif
if (currprefs.cachesize)
pissoff = pissoff_value;
} else if (is_syncline < 0) {
int rpt = read_processor_time ();
int v = rpt - is_syncline_end;
- if (v < 0) {
+ if (v < 0 && event_wait) {
+
#ifdef WITH_PPC
if (ppc_state) {
- uae_ppc_execute_quick(0);
+ uae_ppc_execute_check();
}
#endif
if (currprefs.cachesize)
#include "debug.h"
#include "gayle.h"
#include "cpuboard.h"
+#include "uae/ppc.h"
#define MAX_EXPANSION_BOARDS 11
uae_u32 expamem_z2_size;
static uae_u32 expamem_board_size;
static uae_u32 expamem_board_pointer;
+static bool z3hack_override;
+
+void set_expamem_z3_hack_override(bool overridenoz3hack)
+{
+ z3hack_override = overridenoz3hack;
+}
bool expamem_z3hack(struct uae_prefs *p)
{
+ if (z3hack_override)
+ return false;
+#ifdef WITH_PPC
+ if (regs.halted && ppc_state)
+ return false;
+#endif
return p->jit_direct_compatible_memory || cpuboard_blizzardram(p);
}
if (expamem_z3_sum < 0x10000000) {
expamem_z3_sum = currprefs.z3autoconfig_start;
- if (currprefs.mbresmem_high_size == 128 * 1024 * 1024)
- expamem_z3_sum += 16 * 1024 * 1024;
+ if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024 && expamem_z3_sum == 0x10000000)
+ expamem_z3_sum += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
if (!expamem_z3hack(&currprefs))
expamem_z3_sum = 0x40000000;
if (expamem_z3_sum == 0x10000000) {
z3chipmem_bank.start = 0x10000000;
z3fastmem_bank.start = currprefs.z3autoconfig_start;
- if (currprefs.mbresmem_high_size == 128 * 1024 * 1024)
- z3chipmem_bank.start += 16 * 1024 * 1024;
+ if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024)
+ z3chipmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
if (!expamem_z3hack(&currprefs))
z3fastmem_bank.start = 0x40000000;
- if (currprefs.cpuboard_type == BOARD_WARPENGINE_A4000) {
- z3fastmem_bank.start += 0x01000000;
- z3fastmem_bank.start = expansion_startaddress(z3fastmem_bank.start, currprefs.z3fastmem_size);
+ if (z3fastmem_bank.start == 0x40000000) {
+ if (currprefs.cpuboard_type == BOARD_WARPENGINE_A4000) {
+ z3fastmem_bank.start += 0x01000000;
+ z3fastmem_bank.start = expansion_startaddress(z3fastmem_bank.start, currprefs.z3fastmem_size);
+ }
}
if (z3fastmem_bank.start == 0x10000000) {
- if (currprefs.mbresmem_high_size == 128 * 1024 * 1024)
- z3fastmem_bank.start += 16 * 1024 * 1024;
+ if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024)
+ z3fastmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
z3fastmem_bank.start += currprefs.z3chipmem_size;
}
z3fastmem2_bank.start = z3fastmem_bank.start + currprefs.z3fastmem_size;
extern addrbank *cpuboard_autoconfig_init(void);
extern bool cpuboard_maprom(void);
extern void cpuboard_map(void);
-extern void cpuboard_reset(bool);
+extern void cpuboard_reset(void);
extern void cpuboard_cleanup(void);
extern void cpuboard_init(void);
extern void cpuboard_clear(void);
extern void cpuboard_vsync(void);
+extern void cpuboard_hsync(void);
extern void cpuboard_rethink(void);
extern bool cpuboard_08000000(struct uae_prefs *p);
extern bool cpuboard_blizzardram(struct uae_prefs *p);
extern unsigned long int vsync_cycles;
extern unsigned long start_cycles;
extern int event2_count;
+extern bool event_wait;
extern void compute_vsynctime (void);
extern void init_eventtab (void);
extern void expamem_next (addrbank *mapped, addrbank *next);
extern void expamem_shutup (addrbank *mapped);
extern bool expamem_z3hack(struct uae_prefs*);
+extern void set_expamem_z3_hack_override(bool);
extern uaecptr expamem_z3_pointer, expamem_z2_pointer;
extern uae_u32 expamem_z3_size, expamem_z2_size;
extern void memory_hardreset (int);
extern void memory_clear (void);
extern void free_fastmemory (int);
+extern void set_roms_modified (void);
#define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
#define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
extern void m68k_do_rte (void);
extern void protect_roms (bool);
extern void unprotect_maprom (void);
+extern bool is_hardreset(void);
extern void mmu_op (uae_u32, uae_u32);
extern void mmu_op30 (uaecptr, uae_u32, uae_u16, uaecptr);
extern void m68k_reset (void);
extern void cpureset (void);
extern void cpu_halt (int id);
+extern void cpu_sleep_millis(int ms);
extern void fill_prefetch (void);
extern void fill_prefetch_020 (void);
bool uaeserial;
int catweasel;
int cpu_idle;
+ int ppc_cpu_idle;
bool cpu_cycle_exact;
int cpu_clock_multiplier;
int cpu_frequency;
int fpu_model;
int fpu_revision;
int ppc_mode;
+ TCHAR ppc_model[32];
bool cpu_compatible;
bool int_no_unimplemented;
bool fpu_no_unimplemented;
void uae_ppc_wakeup(void);
void ppc_map_banks(uae_u32, uae_u32, const TCHAR*, void*, bool);
-void uae_ppc_execute_quick(int linetype);
+void uae_ppc_execute_quick(void);
+void uae_ppc_execute_check(void);
void uae_ppc_spinlock_reset(void);
void uae_ppc_spinlock_get(void);
void uae_ppc_spinlock_release(void);
}
}
+static bool inputdevice_handle_inputcode_immediate(int code, int state)
+{
+ switch(code)
+ {
+ case AKS_ENTERDEBUGGER:
+ activate_debugger ();
+ return true;
+ }
+ return false;
+}
+
void inputdevice_add_inputcode (int code, int state)
{
}
for (int i = 0; i < MAX_PENDING_EVENTS; i++) {
if (inputcode_pending[i] == 0) {
- inputcode_pending[i] = code;
- inputcode_pending_state[i] = state;
+ if (!inputdevice_handle_inputcode_immediate(code, state)) {
+ inputcode_pending[i] = code;
+ inputcode_pending_state[i] = state;
+ }
return;
}
}
if (p->cpu_cycle_exact)
p->cpu_compatible = true;
- if (p->cpuboard_type && !p->comptrustbyte) {
- error_log(_T("JIT direct is not compatible with emulated accelerator boards."));
+ if (cpuboard_blizzardram(p) && !p->comptrustbyte) {
+ error_log(_T("JIT direct is not compatible with emulated Blizzard accelerator boards."));
p->comptrustbyte = 1;
p->comptrustlong = 1;
p->comptrustlong = 1;
#endif
if (p->maprom && !p->address_space_24)
p->maprom = 0x0f000000;
- if (((p->maprom & 0xff000000) && p->address_space_24) || (p->maprom && p->mbresmem_high_size == 0x08000000)) {
+ if (((p->maprom & 0xff000000) && p->address_space_24) || (p->maprom && p->mbresmem_high_size >= 0x08000000)) {
p->maprom = 0x00e00000;
}
if (p->tod_hack && p->cs_ciaatod == 0)
init_eventtab ();
#ifdef WITH_PPC
- uae_ppc_reset(false);
+ uae_ppc_reset(is_hardreset());
#endif
#ifdef PICASSO96
picasso_reset ();
int special_mem;
#endif
static int mem_hardreset;
+static bool roms_modified;
#define FLASHEMU 0
if (!decode_rom (mem, size, cr, i))
return 0;
}
- if (currprefs.cs_a1000ram) {
+ if (currprefs.cs_a1000ram && i < ROM_SIZE_256) {
int off = 0;
- a1000_bootrom = xcalloc (uae_u8, ROM_SIZE_256);
+ if (!a1000_bootrom)
+ a1000_bootrom = xcalloc (uae_u8, ROM_SIZE_256);
while (off + i < ROM_SIZE_256) {
memcpy (a1000_bootrom + off, kickmem_bank.baseaddr, i);
off += i;
currprefs.cs_ide = changed_prefs.cs_ide;
currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev;
currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev;
- cpuboard_reset(mem_hardreset > 2);
+ cpuboard_reset();
gayleorfatgary = (currprefs.chipset_mask & CSMASK_AGA) || currprefs.cs_pcmcia || currprefs.cs_ide > 0 || currprefs.cs_mbdmac;
allocate_memory ();
chipmem_setindirect ();
- if (mem_hardreset > 1
+ if (mem_hardreset > 1 || ((roms_modified || a1000_bootrom) && is_hardreset())
|| _tcscmp (currprefs.romfile, changed_prefs.romfile) != 0
|| _tcscmp (currprefs.romextfile, changed_prefs.romextfile) != 0)
{
+ roms_modified = false;
protect_roms (false);
write_log (_T("ROM loader.. (%s)\n"), currprefs.romfile);
kickstart_rom = 1;
memset (kickmem_bank.baseaddr, 0, ROM_SIZE_512);
_tcscpy (currprefs.romfile, _T("<none>"));
currprefs.romextfile[0] = 0;
- cpuboard_reset(0);
+ cpuboard_reset();
#ifdef ACTION_REPLAY
action_replay_unload (0);
#endif
}
+void set_roms_modified(void)
+{
+ roms_modified = true;
+}
+
void memory_hardreset (int mode)
{
if (mode + 1 > mem_hardreset)
return;
currprefs.cpu_idle = changed_prefs.cpu_idle;
+ currprefs.ppc_cpu_idle = changed_prefs.ppc_cpu_idle;
currprefs.reset_delay = changed_prefs.reset_delay;
if (check_prefs_changed_cpu2()) {
}
}
+void cpu_sleep_millis(int ms)
+{
+#ifdef WITH_PPC
+ int state = ppc_state;
+ if (state)
+ uae_ppc_spinlock_release();
+#endif
+ sleep_millis_main(ms);
+#ifdef WITH_PPC
+ if (state)
+ uae_ppc_spinlock_get();
+#endif
+}
+
+#define PPC_HALTLOOP_SCANLINES 25
+// ppc_cpu_idle
+// 0 = busy
+// 1-9 = wait, levels
+// 10 = max wait
static bool haltloop(void)
{
- while (regs.halted) {
- if (regs.halted >= 0) {
+ if (regs.halted < 0) {
+
+ int vsynctimeline = vsynctimebase / (maxvpos_display + 1);
+ int rpt_end = 0;
+ int ovpos = vpos;
+
+ while (regs.halted) {
+ int lines;
+
+ if (currprefs.ppc_cpu_idle) {
+
+ int maxlines = 100 - (currprefs.ppc_cpu_idle - 1) * 10;
+ int i;
+
+ int rpt_scanline = read_processor_time();
+
+ event_wait = false;
+ for (i = 0; i < ev_max; i++) {
+ if (i == ev_hsync)
+ continue;
+ if (i == ev_audio)
+ continue;
+ if (!eventtab[i].active)
+ continue;
+ if (eventtab[i].evtime - currcycle < maxlines * maxhpos * CYCLE_UNIT)
+ break;
+ }
+ if (currprefs.ppc_cpu_idle >= 10 || (i == ev_max && vpos > 0 && vpos < maxvpos - maxlines)) {
+ cpu_sleep_millis(1);
+ }
+
+ lines = (read_processor_time() - rpt_scanline) / vsynctimeline + 1;
+
+ } else {
+
+ event_wait = true;
+ lines = 0;
+
+ }
+
+ while (lines-- >= 0) {
+ ovpos = vpos;
+ while (ovpos == vpos) {
+ x_do_cycles(4 * CYCLE_UNIT);
+ if (regs.spcflags) {
+ if (regs.spcflags & SPCFLAG_COPPER)
+ do_copper();
+ if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))
+ return true;
+ }
+ }
+ }
+
+#ifdef WITH_PPC
+ if (regs.halted < 0)
+ uae_ppc_emulate();
+#endif
+
+ }
+
+ } else {
+
+ while (regs.halted) {
static int prevvpos;
if (vpos == 0 && prevvpos) {
prevvpos = 0;
- sleep_millis_main(8);
+ cpu_sleep_millis(8);
}
if (vpos)
prevvpos = 1;
x_do_cycles(8 * CYCLE_UNIT);
- } else {
- x_do_cycles(32 * CYCLE_UNIT);
- }
- if (regs.spcflags & SPCFLAG_COPPER)
- do_copper();
-
-#ifdef WITH_PPC
- if (regs.halted < 0)
- uae_ppc_emulate();
-#endif
+ if (regs.spcflags & SPCFLAG_COPPER)
+ do_copper();
- if (regs.spcflags) {
- if ((regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)))
- return true;
+ if (regs.spcflags) {
+ if ((regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)))
+ return true;
+ }
}
}
+
return false;
}
if (ppc_state) {
if (uae_ppc_poll_check_halt())
return true;
+ uae_ppc_execute_check();
}
#endif
}
unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
#ifdef WITH_PPC
bool m68kint = true;
- if (ppc_state)
+ if (ppc_state) {
m68kint = ppc_interrupt(intr);
+ }
if (m68kint) {
#endif
if (intr > 0 && intr > regs.intmask)
}
#ifdef WITH_PPC
- if (ppc_state)
+ if (ppc_state) {
+ uae_ppc_execute_check();
uae_ppc_poll_check_halt();
+ }
#endif
if (!uae_int_requested && !uaenet_int_requested && currprefs.cpu_idle && currprefs.m68k_speed != 0 && (regs.spcflags & SPCFLAG_STOP)
#endif
if (sleepcnt < 0) {
sleepcnt = IDLETIME / 2;
- sleep_millis_main (1);
+ cpu_sleep_millis(1);
}
}
}
Exception (2);
}
+static bool cpu_hardreset;
+
+bool is_hardreset(void)
+{
+ return cpu_hardreset;
+}
+
+
void m68k_go (int may_quit)
{
int hardboot = 1;
inprec_startup ();
if (quit_program > 0) {
- int hardreset = (quit_program == UAE_RESET_HARD ? 1 : 0) | hardboot;
+ int restored = 0;
bool kbreset = quit_program == UAE_RESET_KEYBOARD;
+ cpu_hardreset = ((quit_program == UAE_RESET_HARD ? 1 : 0) | hardboot) != 0;
+
if (quit_program == UAE_QUIT)
break;
- int restored = 0;
hsync_counter = 0;
vsync_counter = 0;
savestate_rewind ();
#endif
set_cycles (start_cycles);
- custom_reset (hardreset != 0, kbreset);
- m68k_reset2 (hardreset != 0);
- if (hardreset) {
+ custom_reset (cpu_hardreset != 0, kbreset);
+ m68k_reset2 (cpu_hardreset != 0);
+ if (cpu_hardreset) {
memory_clear ();
write_log (_T("hardreset, memory cleared\n"));
}
+ cpu_hardreset = false;
#ifdef SAVESTATE
/* We may have been restoring state, but we're done now. */
if (isrestore ()) {
startup = 0;
if (regs.halted) {
cpu_halt (regs.halted);
+ if (regs.halted < 0)
+ haltloop();
continue;
}
#if 0
}
#endif
+ event_wait = true;
unset_special(SPCFLAG_MODE_CHANGE);
run_func();
}
}
}
if (!natmem_offset_allocated) {
+ DWORD vaflags = MEM_RESERVE | MEM_WRITE_WATCH;
+ if (!os_vista)
+ vaflags |= MEM_TOP_DOWN;
for (;;) {
- natmem_offset_allocated = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE | MEM_WRITE_WATCH | MEM_TOP_DOWN, PAGE_READWRITE);
+ natmem_offset_allocated = (uae_u8*)VirtualAlloc (NULL, natmem_size, vaflags, PAGE_READWRITE);
if (natmem_offset_allocated)
break;
natmem_size -= 128 * 1024 * 1024;
if (!natmem_size) {
write_log (_T("Can't allocate 257M of virtual address space!?\n"));
natmem_size = 17 * 1024 * 1024;
- natmem_offset_allocated = (uae_u8*)VirtualAlloc (NULL, natmem_size, MEM_RESERVE | MEM_WRITE_WATCH | MEM_TOP_DOWN, PAGE_READWRITE);
+ natmem_offset_allocated = (uae_u8*)VirtualAlloc (NULL, natmem_size, vaflags, PAGE_READWRITE);
if (!natmem_size) {
write_log (_T("Can't allocate 17M of virtual address space!? Something is seriously wrong\n"));
return false;
z3size = 0;
othersize = 0;
size = 0x1000000;
- startbarrier = changed_prefs.mbresmem_high_size == 128 * 1024 * 1024 ? 16 * 1024 * 1024 : 0;
+ startbarrier = changed_prefs.mbresmem_high_size >= 128 * 1024 * 1024 ? (changed_prefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024 : 0;
z3rtgmem_size = gfxboard_is_z3 (changed_prefs.rtgmem_type) ? changed_prefs.rtgmem_size : 0;
if (changed_prefs.cpu_model >= 68020)
size = 0x10000000;
}
}
+ set_expamem_z3_hack_override(false);
z3offset = 0;
if ((changed_prefs.z3autoconfig_start == 0x10000000 || changed_prefs.z3autoconfig_start == 0x40000000) && !changed_prefs.force_0x10000000_z3 && !cpuboard_blizzardram(&changed_prefs)) {
if (1 && natmem_size > 0x40000000 && natmem_size - 0x40000000 >= (totalsize - 0x10000000 - ((changed_prefs.z3chipmem_size + align) & ~align)) && changed_prefs.z3chipmem_size <= 512 * 1024 * 1024) {
z3offset += 0x40000000 - 0x10000000 - ((changed_prefs.z3chipmem_size + align) & ~align);
if (currprefs.cpuboard_type == BOARD_WARPENGINE_A4000)
z3offset += 0x01000000;
+ set_expamem_z3_hack_override(true);
+ startbarrier = 0;
+ write_log(_T("Z3 autoconfig option automatically disabled\n"));
} else {
changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = 0x10000000;
}
p96base_offset = getz2rtgaddr (changed_prefs.rtgmem_size);
}
if (p96base_offset) {
- if (expamem_z3hack(&changed_prefs)) {
+ if (changed_prefs.jit_direct_compatible_memory) {
p96mem_offset = natmem_offset + p96base_offset;
} else {
// calculate Z3 alignment (argh, I thought only Z2 needed this..)
shmaddr=natmem_offset + 0xf00000;
got = TRUE;
readonly = TRUE;
+ } else if(!_tcscmp (shmids[shmid].name, _T("rom_f0_ppc"))) {
+ // this is flash and also contains IO
+ shmaddr=natmem_offset + 0xf00000;
+ got = TRUE;
+ readonly = FALSE;
} else if (!_tcscmp(shmids[shmid].name, _T("rtarea"))) {
shmaddr = natmem_offset + rtarea_base;
got = TRUE;
#define IDC_8BIT 1230
#define IDC_CPU_PPC 1230
#define IDC_16BIT 1231
+#define IDC_PPC_CPUIDLE 1231
#define IDC_11KHZ 1232
#define IDC_22KHZ 1233
#define IDC_44KHZ 1234
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
GROUPBOX "CPU",IDC_STATIC,1,1,129,184,BS_LEFT
- CONTROL "68000",IDC_CPU0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,15,63,10
- CONTROL "68010",IDC_CPU1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,29,63,10
- CONTROL "68020",IDC_CPU2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,42,63,10
- CONTROL "68030",IDC_CPU3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,56,63,10
- CONTROL "68040",IDC_CPU4,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,70,63,10
- CONTROL "68060",IDC_CPU5,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,84,63,10
- CONTROL "24-bit addressing",IDC_COMPATIBLE24,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,101,119,12
+ CONTROL "68000",IDC_CPU0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,19,63,10
+ CONTROL "68010",IDC_CPU1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,33,63,10
+ CONTROL "68020",IDC_CPU2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,46,63,10
+ CONTROL "68030",IDC_CPU3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,60,63,10
+ CONTROL "68040",IDC_CPU4,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,74,63,10
+ CONTROL "68060",IDC_CPU5,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,88,63,10
+ CONTROL "24-bit addressing",IDC_COMPATIBLE24,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,108,119,12
CONTROL "More compatible [] 68000: emulate prefetch. 68020+: emulate prefetch partially. More compatible but slower.",IDC_COMPATIBLE,
- "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,115,118,11
+ "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,121,118,11
CONTROL "JIT [] Enable just-in-time CPU emulator. Significantly increases the speed of the CPU emulation. Requires 68020 or higher CPU.",IDC_JITENABLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,128,120,11
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,135,120,11
CONTROL "MMU [] 68030, 68040 and 68060 MMU emulation. Not compatible with JIT.",IDC_MMUENABLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,142,120,11
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,148,120,11
CONTROL "Unimplemented CPU emu [] Emulate 68060 unimplemented integer instructions",IDC_CPU_UNIMPLEMENTED,
- "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,156,118,10
- GROUPBOX "CPU Emulation Speed",IDC_STATIC,136,3,258,111
- CONTROL "Fastest possible",IDC_CS_HOST,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,143,24,195,10
+ "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,161,118,10
+ GROUPBOX "CPU Emulation Speed",IDC_STATIC,136,3,258,95
+ CONTROL "Fastest possible",IDC_CS_HOST,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,143,19,195,10
CONTROL "Approximate A500/A1200 or cycle-exact",IDC_CS_68000,
- "Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,143,38,195,10
- CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,142,62,192,20
- RTEXT "CPU Speed",IDC_STATIC,141,90,55,9,SS_CENTERIMAGE
- EDITTEXT IDC_CPUTEXT,204,89,30,12,ES_CENTER | ES_READONLY
- RTEXT "CPU Idle",IDC_STATIC,239,90,62,9
- CONTROL "",IDC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,308,85,69,21
- GROUPBOX "Cycle-exact CPU Emulation Speed",IDC_STATIC,136,121,258,64
- RTEXT "CPU Frequency",IDC_STATIC,139,145,67,10,SS_CENTERIMAGE
- COMBOBOX IDC_CPU_FREQUENCY,215,144,89,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- EDITTEXT IDC_CPU_FREQUENCY2,312,143,70,15
- GROUPBOX "FPU",IDC_STATIC,1,188,129,99,BS_LEFT
+ "Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,143,33,195,10
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,142,50,192,20
+ RTEXT "CPU Speed",IDC_STATIC,141,77,55,9,SS_CENTERIMAGE
+ EDITTEXT IDC_CPUTEXT,204,76,30,12,ES_CENTER | ES_READONLY
+ RTEXT "CPU Idle",IDC_STATIC,239,77,62,9
+ CONTROL "",IDC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,308,72,69,21
+ GROUPBOX "Cycle-exact CPU Emulation Speed",IDC_STATIC,136,100,258,42
+ RTEXT "CPU Frequency",IDC_STATIC,139,121,67,10,SS_CENTERIMAGE
+ COMBOBOX IDC_CPU_FREQUENCY,215,120,89,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_CPU_FREQUENCY2,312,119,70,15
+ GROUPBOX "FPU",IDC_STATIC,1,188,129,101,BS_LEFT
CONTROL "None",IDC_FPU0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,202,87,10
CONTROL "68881",IDC_FPU1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,216,87,10
CONTROL "68882",IDC_FPU2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,229,87,10
"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,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
- EDITTEXT IDC_CACHETEXT,331,206,30,12,ES_CENTER | ES_READONLY
- CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,234,84,11
- CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,248,84,11
- CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,262,84,11
- 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
+ GROUPBOX "Advanced JIT Settings",IDC_STATIC,136,209,258,80
+ RTEXT "Cache size:",IDC_STATIC,143,225,66,10,SS_CENTERIMAGE
+ CONTROL "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,212,219,115,20
+ EDITTEXT IDC_CACHETEXT,331,224,30,12,ES_CENTER | ES_READONLY
+ CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,244,84,11
+ CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,258,84,11
+ CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,272,84,11
+ CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,313,244,68,11
+ CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,313,261,72,10
+ CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,313,275,72,10
+ CONTROL "PPC CPU emulation (Blizzard PPC / CyberStorm PPC) [] Automatically configure CyberStorm PPC or Blizzard PPC setup.",IDC_CPU_PPC,
+ "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,145,161,236,10
+ GROUPBOX "PPC CPU options",IDC_STATIC,136,144,258,62
+ RTEXT "Stopped M68K CPU idle mode",IDC_STATIC,180,183,121,9
+ CONTROL "",IDC_PPC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,308,177,69,21
END
IDD_FLOPPY DIALOGEX 0, 0, 396, 261
if (!newname)
return NULL;
for (round = 0; round < 6; round++) {
- TCHAR s[MAX_DPATH];
+ TCHAR s[MAX_DPATH], dir[MAX_DPATH], dir2[MAX_DPATH];
_tcscpy (newname, name);
#ifdef CPU_64_BIT
switch(round)
#endif
get_plugin_path (s, sizeof s / sizeof (TCHAR), NULL);
_tcscat (s, newname);
+ GetDllDirectory(sizeof(dir2) / sizeof TCHAR, dir2);
+ getpathpart(dir, sizeof(dir) / sizeof TCHAR, s);
+ stripslashes(dir);
+ if (dir[0])
+ SetDllDirectory(dir);
m = LoadLibrary (s);
LLError (m ,s);
- if (m)
+ if (m) {
+ if (dir2[0])
+ SetDllDirectory(dir2);
goto end;
+ }
m = LoadLibrary (newname);
LLError (m, newname);
+ if (dir2[0])
+ SetDllDirectory(dir2);
if (m)
goto end;
#ifndef CPU_64_BIT
#define LANG_DLL_FULL_VERSION_MATCH 1
#if WINUAEPUBLICBETA
-#define WINUAEBETA _T("16")
+#define WINUAEBETA _T("17")
#else
#define WINUAEBETA _T("")
#endif
-#define WINUAEDATE MAKEBD(2014, 9, 13)
+#define WINUAEDATE MAKEBD(2014, 9, 21)
//#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition")
((rtgz3size + sizealign) & ~sizealign);
if (cfgfile_board_enabled(&currprefs.a4091rom))
size += 2 * 16 * 1024 * 1024;
- if (changed_prefs.mbresmem_high_size == 128 * 1024 * 1024 && (size || workprefs.z3chipmem_size))
- size += 16 * 1024 * 1024;
+ if (changed_prefs.mbresmem_high_size >= 128 * 1024 * 1024 && (size || workprefs.z3chipmem_size))
+ size += (changed_prefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
if (natmem_size > 0x40000000)
z3size = natmem_size - 0x40000000;
else
//ew (hDlg, IDC_CS_68000, !workprefs.cpu_cycle_exact);
//ew (hDlg, IDC_CS_ADJUSTABLE, !workprefs.cpu_cycle_exact);
ew (hDlg, IDC_CPUIDLE, workprefs.m68k_speed != 0 ? TRUE : FALSE);
+ ew (hDlg, IDC_PPC_CPUIDLE, workprefs.ppc_mode != 0);
#if !defined(CPUEMU_0) || defined(CPUEMU_68000_ONLY)
ew (hDlg, IDC_CPU1, FALSE);
ew (hDlg, IDC_CPU2, FALSE);
CheckDlgButton (hDlg, IDC_FPU_UNIMPLEMENTED, !workprefs.fpu_no_unimplemented || workprefs.cachesize);
CheckDlgButton (hDlg, IDC_CPU_UNIMPLEMENTED, !workprefs.int_no_unimplemented || workprefs.cachesize);
SendDlgItemMessage (hDlg, IDC_CPUIDLE, TBM_SETPOS, TRUE, workprefs.cpu_idle == 0 ? 0 : 12 - workprefs.cpu_idle / 15);
+ SendDlgItemMessage (hDlg, IDC_PPC_CPUIDLE, TBM_SETPOS, TRUE, workprefs.ppc_cpu_idle);
cpu = (workprefs.cpu_model - 68000) / 10;
if (cpu >= 5)
cpu--;
workprefs.cpu_idle = SendMessage (GetDlgItem (hDlg, IDC_CPUIDLE), TBM_GETPOS, 0, 0);
if (workprefs.cpu_idle > 0)
workprefs.cpu_idle = (12 - workprefs.cpu_idle) * 15;
+ workprefs.ppc_cpu_idle = SendMessage (GetDlgItem (hDlg, IDC_PPC_CPUIDLE), TBM_GETPOS, 0, 0);
if (pages[KICKSTART_ID])
SendMessage (pages[KICKSTART_ID], WM_USER, 0, 0);
SendDlgItemMessage (hDlg, IDC_CACHE, TBM_SETPAGESIZE, 0, 1);
SendDlgItemMessage (hDlg, IDC_CPUIDLE, TBM_SETRANGE, TRUE, MAKELONG (0, 10));
SendDlgItemMessage (hDlg, IDC_CPUIDLE, TBM_SETPAGESIZE, 0, 1);
+ SendDlgItemMessage (hDlg, IDC_PPC_CPUIDLE, TBM_SETRANGE, TRUE, MAKELONG (0, 10));
+ SendDlgItemMessage (hDlg, IDC_PPC_CPUIDLE, TBM_SETPAGESIZE, 0, 1);
SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage (hDlg, IDC_CPU_FREQUENCY, CB_ADDSTRING, 0, (LPARAM)_T("1x"));
- restore only single input target to default.
+Beta 17:
+
+- Hard reset now forces reload of KS ROM if maprom is active, previously map rom mapped image
+ was still in use after hard reset.
+- Fixed some more Z3 autoconfig bugs introduced in recent betas autoconfig updates.
+- Only add VirtualAlloc() MEM_TOP_DOWN flag when OS is XP. For some unknown reason with MEM_TOP_DOWN my system
+ suddenly started giving less address space than without it..
+- A1000 with full KS ROM configured (instead of A1000 boot strap ROM) didn't boot since b9.
+- Reset didn't clear QEMU PPC JIT translation buffer, fixes mysterious hangs after reset.
+- Added main thread sleep option slider to GUI, reduces CPU usage when M68K is stopped and only PPC is active.
+- PPC CPU model can be manually configured using ppc_model=<name> config entry. Can be any QEMU supported
+ PPC CPU model name string. (Model strings are in qemu source file target-ppc/cpu-models.c)
+- Automatically disable m68k JIT autoconfig hack if only PPC CPU is active when autoconfig starts after reset.
+- Fixed WarpOS (possible PowerUP too) semi-random program hang caused by lost PPC interrupt(s).
+- Allow m68k JIT direct with accelerator board if board is not Blizzard model (no Blizzard memory aliases)
+ CyberStorm PPC + m68k JIT direct at least seems to work, no guarantees.
+
+Important:
+
+- QEMU PPC libraries are now loaded from <winuae path>\plugins\qemu\. Old location is not supported
+ anymore. Move all qemu dependency libraries and qemu-uae.dll to new path.
+
+
Beta 16:
- GUI (and log) showed wrong size for very large drives (>1T). Visual problem only.
- PPC CPU HID1 set to more correct value, detected CPU clock is not same as bus clock anymore.
- QEMU TCG (JIT) buffer was too small, real world PPC programs run now much faster.
+NOTE: Reset when PPC CPU is active still does not work 100% correctly.
+
Beta 15:
- "ROM disabled" A2091/A590 ROM option was not visible (b14)
enable chip ID read mode.
- PPC IO access completely rewritten, most IO areas are now directly accessible and only special regions
- (custom chipset and CIA require locking. Very slow IO message passing system is completely gone.
+ (custom chipset and CIA) require locking. Very slow IO message passing system is completely gone.
- QEMU PPC core support. Read separate notes!
Beta 14:
#include "uae/ppc.h"
/* The qemu-uae major version must match this */
-#define QEMU_UAE_VERSION_MAJOR 1
+#define QEMU_UAE_VERSION_MAJOR 2
/* The qemu-uae minor version must be at least this */
-#define QEMU_UAE_VERSION_MINOR 2
+#define QEMU_UAE_VERSION_MINOR 0
+#define SPINLOCK_DEBUG 0
#define PPC_ACCESS_LOG 0
#define PPC_DEBUG_ADDR_FROM 0x000000
#define TRACE(format, ...) write_log(_T("PPC: ") format, ## __VA_ARGS__)
+#ifdef WINUAE
+#define QEMU_LIBRARY_PATH _T("qemu\\qemu-uae.dll")
+#else
+#define QEMU_LIBRARY_PATH _T("qemu-uae.dll")
+#endif
+
+#if SPINLOCK_DEBUG
+static volatile int spinlock_cnt;
+#endif
+
+static volatile bool ppc_spinlock_waiting;
#ifdef _WIN32
#define CRITICAL_SECTION_SPIN_COUNT 5000
-static CRITICAL_SECTION ppc_cs;
+static CRITICAL_SECTION ppc_cs1, ppc_cs2;
static bool ppc_cs_initialized;
#else
#include <glib.h>
void uae_ppc_spinlock_get(void)
{
#ifdef _WIN32
- EnterCriticalSection(&ppc_cs);
+ EnterCriticalSection(&ppc_cs2);
+ ppc_spinlock_waiting = true;
+ EnterCriticalSection(&ppc_cs1);
+ ppc_spinlock_waiting = false;
+ LeaveCriticalSection(&ppc_cs2);
#else
g_mutex_lock(&mutex);
#endif
+#if SPINLOCK_DEBUG
+ if (spinlock_cnt != 0)
+ write_log(_T("uae_ppc_spinlock_get %d!\n"), spinlock_cnt);
+ spinlock_cnt++;
+#endif
}
void uae_ppc_spinlock_release(void)
{
+#if SPINLOCK_DEBUG
+ if (spinlock_cnt != 1)
+ write_log(_T("uae_ppc_spinlock_release %d!\n"), spinlock_cnt);
+ spinlock_cnt--;
+#endif
#ifdef _WIN32
- LeaveCriticalSection(&ppc_cs);
+ LeaveCriticalSection(&ppc_cs1);
#else
g_mutex_unlock(&mutex);
#endif
static void uae_ppc_spinlock_create(void)
{
+#if SPINLOCK_DEBUG
+ write_log(_T("uae_ppc_spinlock_create\n"));
+#endif
#ifdef _WIN32
- if (ppc_cs_initialized)
- DeleteCriticalSection(&ppc_cs);
- InitializeCriticalSectionAndSpinCount(&ppc_cs, CRITICAL_SECTION_SPIN_COUNT);
+ if (ppc_cs_initialized) {
+ DeleteCriticalSection(&ppc_cs1);
+ DeleteCriticalSection(&ppc_cs2);
+ }
+ InitializeCriticalSectionAndSpinCount(&ppc_cs1, CRITICAL_SECTION_SPIN_COUNT);
+ InitializeCriticalSectionAndSpinCount(&ppc_cs2, CRITICAL_SECTION_SPIN_COUNT);
#else
+#endif
+#if SPINLOCK_DEBUG
+ spinlock_cnt = 0;
#endif
ppc_cs_initialized = true;
}
write_log(_T("PPC: Loading QEmu implementation\n"));
memset(&impl, 0, sizeof(impl));
- UAE_DLHANDLE handle = uae_dlopen(_T("qemu-uae.dll"));
+ UAE_DLHANDLE handle = uae_dlopen(QEMU_LIBRARY_PATH);
if (!handle) {
gui_message(_T("PPC: Error loading qemu-uae library\n"));
return false;
void ppc_map_banks(uae_u32 start, uae_u32 size, const TCHAR *name, void *addr, bool remove)
{
- if (ppc_state == PPC_STATE_INACTIVE)
+ if (ppc_state == PPC_STATE_INACTIVE || !impl.map_memory)
return;
PPCMemoryRegion r;
r.start = start;
const TCHAR *model;
uint32_t hid1;
- /* Set default CPU model based on accelerator board */
+ if (currprefs.ppc_model[0]) {
+ /* Override PPC CPU model. See qemu/target-ppc/cpu-models.c for
+ * a list of valid CPU model identifiers */
+ model = currprefs.ppc_model;
+ } else {
+ /* Set default CPU model based on accelerator board */
+ if (currprefs.cpuboard_type == BOARD_BLIZZARDPPC) {
+ model = _T("603ev");
+ } else {
+ model = _T("604e");
+ }
+ }
if (currprefs.cpuboard_type == BOARD_BLIZZARDPPC) {
- model = _T("603ev");
hid1 = 0xc0000000; // 4x
} else {
- model = _T("604e");
hid1 = 0xa0000000; // 4x
}
- /* Override PPC CPU model. See qemu/target-ppc/cpu-models.c for
- * a list of valid CPU model identifiers */
-#if 0
- // FIXME: if ppc_model is overridden in currprefs, point to option
- if (currprefs.ppc_model[0]) {
- model = currprefs.ppc_model
- }
-#endif
-
if (impl.init) {
char *models = ua(model);
impl.init(models, hid1);
return NULL;
}
-void uae_ppc_execute_quick(int linetype)
+void uae_ppc_execute_check(void)
{
- if (linetype == 0) {
+ if (ppc_spinlock_waiting) {
uae_ppc_spinlock_release();
- read_processor_time(); // tiny delay..
- read_processor_time();
- uae_ppc_spinlock_get();
- } else {
- uae_ppc_spinlock_release();
- sleep_millis(1);
uae_ppc_spinlock_get();
}
}
+void uae_ppc_execute_quick()
+{
+ uae_ppc_spinlock_release();
+ sleep_millis_main(1);
+ uae_ppc_spinlock_get();
+}
+
void uae_ppc_emulate(void)
{
if (using_pearpc()) {
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
-#if PPC_ACCESS_LOG > 0
+#if PPC_ACCESS_LOG > 0 && PPC_ACCESS_LOG < 2
if (!valid_address(addr, size)) {
if (addr >= PPC_DEBUG_ADDR_FROM && addr < PPC_DEBUG_ADDR_TO)
write_log(_T("PPC io write %08x = %08x %d\n"), addr, data, size);
#endif
locked = spinlock_pre(addr);
+ if (addr >= 0xdff000 && addr < 0xe00000) {
+ // shortcuts for common registers
+ if (addr == 0xdff09c) { // INTREQ
+ INTREQ_0(data);
+ size = 0;
+ }
+ }
switch (size)
{
case 4:
put_byte(addr, data);
break;
}
- if (addr == 0xdff09c || addr == 0xdff09a) {
- int lev = intlev();
- ppc_interrupt(lev);
- }
spinlock_post(locked);
#if PPC_ACCESS_LOG > 2
- write_log(_T("PPC mem write %08x = %08x %d\n"), addr, data, size);
+ write_log(_T("PPC write %08x = %08x %d\n"), addr, data, size);
#endif
return true;
*data = v;
spinlock_post(locked);
-#if PPC_ACCESS_LOG > 0
+#if PPC_ACCESS_LOG > 0 && PPC_ACCESS_LOG < 2
if (!valid_address(addr, size)) {
if (addr >= PPC_DEBUG_ADDR_FROM && addr < PPC_DEBUG_ADDR_TO && addr != 0xdff006)
write_log(_T("PPC io read %08x=%08x %d\n"), addr, v, size);
}
#endif
#if PPC_ACCESS_LOG > 2
- write_log(_T("PPC mem read %08x=%08x %d\n"), addr, v, size);
+ write_log(_T("PPC read %08x=%08x %d\n"), addr, v, size);
#endif
return true;
}
if (!ppc_thread_running) {
write_log(_T("Starting PPC thread.\n"));
ppc_thread_running = true;
- uae_start_thread(_T("ppc"), ppc_thread, NULL, NULL);
+ uae_start_thread(NULL, ppc_thread, NULL, NULL);
} else if (using_qemu()) {
write_log(_T("PPC: Thread already running, resetting\n"));
uae_ppc_cpu_reset();
void uae_ppc_reset(bool hardreset)
{
+ if (!currprefs.ppc_mode)
+ return;
TRACE(_T("uae_ppc_reset hardreset=%d\n"), hardreset);
if (using_qemu()) {
set_and_wait_for_state(PPC_CPU_STATE_PAUSED, 1);