if (mask & (CSR0_BABL | CSR0_MISS | CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IDON))
csr[0] |= CSR0_INTR;
if ((csr[0] & (CSR0_INTR | CSR0_INEA)) == (CSR0_INTR | CSR0_INEA)) {
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_A2065, 0, false);
if (log_a2065 > 2)
write_log(_T("7990 +IRQ\n"));
}
rc->unitdata = scsi;
scsi->rc = rc;
scsi->self_ptr = wd;
+ scsi->id = i;
*wd = scsi;
return scsi;
}
if (scsi_units[i]) {
int irq = isirq(scsi_units[i]);
if (irq & 1)
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_WD, i, false);
if (irq & 2)
- safe_interrupt_set(0x2000);
+ safe_interrupt_set(IRQ_SOURCE_WD, i, true);
#if DEBUG > 2 || A3000_DEBUG > 2
write_log (_T("Interrupt_RETHINK:%d\n"), irq);
#endif
{
struct wd_chip_state *wd = &wds->wc;
if (wd->intmask) {
- safe_interrupt_set(wd->intmask);
+ safe_interrupt_set(IRQ_SOURCE_WD, wds->id, (wd->intmask & 0x2000) != 0);
wd->intmask = 0;
}
if (wd->auxstatus & ASR_INT)
#include "flashrom.h"
#include "debug.h"
#include "rommgr.h"
+#include "devices.h"
#define AKIKO_DEBUG_IO 1
#define AKIKO_DEBUG_IO_CMD 1
static void irq (void)
{
- if (!(intreq & 8)) {
- safe_interrupt_set(0x0008);
- }
+ safe_interrupt_set(IRQ_SOURCE_CD32CDTV, 0, false);
}
/*
#include "debug.h"
#include "custom.h"
#include "audio.h"
+#include "devices.h"
#include "threaddep/thread.h"
#include "cda_play.h"
static void do_irq(void)
{
- if (!(intreq & 8)) {
- safe_interrupt_set(0x0008);
- }
+ safe_interrupt_set(IRQ_SOURCE_CD32CDTV, 1, false);
}
static bool l64111_checkint(bool enabled)
#include "uae.h"
#include "savestate.h"
#include "scsi.h"
+#include "devices.h"
/* DMAC CNTR bits. */
#define CNTR_TCEN (1<<7)
static void INT2 (void)
{
- if (!(intreq & 8)) {
- safe_interrupt_set(0x0008);
- }
+ safe_interrupt_set(IRQ_SOURCE_CD32CDTV, 0, false);
cd_led ^= LED_CD_ACTIVE2;
}
#include "uae.h"
#include "custom.h"
#include "rommgr.h"
+#include "devices.h"
#if CDTVCR_4510_EMULATION
static void init_65c02(void);
void rethink_cdtvcr(void)
{
if ((cdtvcr_4510_ram[CDTVCR_INTREQ] & cdtvcr_4510_ram[CDTVCR_INTENA]) && !cdtvcr_4510_ram[CDTVCR_INTDISABLE]) {
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_CD32CDTV, 0, false);
cd_led ^= LED_CD_ACTIVE2;
}
}
#include "rommgr.h"
#include "scsi.h"
#include "rtc.h"
+#include "devices.h"
#define CIAA_DEBUG_R 0
#define CIAA_DEBUG_W 0
static void ICR (uae_u32 data)
{
- safe_interrupt_set(data);
+ safe_interrupt_set(IRQ_SOURCE_CIA, 0, (data & 0x2000) != 0);
}
static void ICRA (uae_u32 data)
{
if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_CPUBOARD, 0, false);
if (currprefs.cachesize)
atomic_or(&uae_int_requested, 0x010000);
uae_ppc_wakeup_main();
} else if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_CPUBOARD, 1, false);
if (currprefs.cachesize)
atomic_or(&uae_int_requested, 0x010000);
uae_ppc_wakeup_main();
map_banks_nojitdirect(&blizzardmaprom_bank, blizzardmaprom_bank.start >> 16, 524288 >> 16, 0);
}
-void cyberstorm_mk3_ppc_irq_setonly(int level)
+void cyberstorm_mk3_ppc_irq_setonly(int id, int level)
{
if (level)
io_reg[CSIII_REG_IRQ] &= ~P5_IRQ_SCSI;
else
io_reg[CSIII_REG_IRQ] |= P5_IRQ_SCSI;
}
-void cyberstorm_mk3_ppc_irq(int level)
+void cyberstorm_mk3_ppc_irq(int id, int level)
{
- cyberstorm_mk3_ppc_irq_setonly(level);
+ cyberstorm_mk3_ppc_irq_setonly(id, level);
devices_rethink_all(cpuboard_rethink);
}
else
io_reg[CSIII_REG_IRQ] |= P5_IRQ_SCSI;
}
-void blizzardppc_irq(int level)
+void blizzardppc_irq(int id, int level)
{
blizzardppc_irq_setonly(level);
devices_rethink_all(cpuboard_rethink);
if (bsd_int_requested)
bsdsock_fake_int_handler();
}
-
- uae_u16 mask = (irq6 ? 0x2000 : 0) | (irq2 ? 0x0008 : 0);
- if (mask)
- safe_interrupt_set(mask);
+ if (irq6)
+ safe_interrupt_set(IRQ_SOURCE_UAE, 0, true);
+ if (irq2)
+ safe_interrupt_set(IRQ_SOURCE_UAE, 0, false);
}
static void rethink_intreq (void)
void devices_rethink_all(void func(void))
{
- if (ppc_state || 0) {
- devices_rethink();
- } else {
- func();
- }
+ func();
}
// these really should be dynamically allocated..
void devices_rethink(void)
{
- safe_interrupt_clear_all();
rethink_cias ();
#ifdef A2065
rethink_a2065 ();
if (currprefs.cs_ide == IDE_A4000) {
gayle_irq |= checkgayleideirq ();
- if ((gayle_irq & GAYLE_IRQ_IDE) && !(intreq & 0x0008))
- safe_interrupt_set(0x0008);
+ if ((gayle_irq & GAYLE_IRQ_IDE))
+ safe_interrupt_set(IRQ_SOURCE_GAYLE, 0, false);
return;
}
else
lev2 = 1;
}
- if (lev2 && !(intreq & 0x0008))
- safe_interrupt_set(0x0008);
- if (lev6 && !(intreq & 0x2000))
- safe_interrupt_set(0x2000);
+ if (lev2)
+ safe_interrupt_set(IRQ_SOURCE_GAYLE, 0, false);
+ if (lev6)
+ safe_interrupt_set(IRQ_SOURCE_GAYLE, 0, true);
}
static void gayle_cs_change (uae_u8 mask, int onoff)
x86_doirq(ide_boards[i] == x86_at_ide_board[0] ? 14 : 15);
}
} else {
- irq |= ide_rethink(ide_boards[i], false);
+ if (ide_rethink(ide_boards[i], false))
+ safe_interrupt_set(IRQ_SOURCE_IDE, i, false);
}
}
- if (irq) {
- safe_interrupt_set(0x0008);
- }
}
void idecontroller_hsync(void)
};
struct wd_state {
+ int id;
bool enabled;
int configured;
bool autoconfig;
extern int REGPARAM3 cyberstorm_scsi_ram_check(uaecptr addr, uae_u32 size) REGPARAM;
extern uae_u8 *REGPARAM3 cyberstorm_scsi_ram_xlate(uaecptr addr) REGPARAM;
-void cyberstorm_mk3_ppc_irq(int level);
-void blizzardppc_irq(int level);
-void cyberstorm_mk3_ppc_irq_setonly(int level);
-void blizzardppc_irq_setonly(int level);
+void cyberstorm_mk3_ppc_irq(int id, int level);
+void blizzardppc_irq(int id, int level);
+void cyberstorm_mk3_ppc_irq_setonly(int id, int level);
+void blizzardppc_irq_setonly(int id, int level);
#define BOARD_MEMORY_Z2 1
#define BOARD_MEMORY_Z3 2
void devices_pause(void);
void devices_unpause(void);
+#define IRQ_SOURCE_PCI 0
+#define IRQ_SOURCE_SOUND 1
+#define IRQ_SOURCE_NE2000 2
+#define IRQ_SOURCE_A2065 3
+#define IRQ_SOURCE_NCR 4
+#define IRQ_SOURCE_NCR9X 5
+#define IRQ_SOURCE_CPUBOARD 6
+#define IRQ_SOURCE_UAE 7
+#define IRQ_SOURCE_SCSI 8
+#define IRQ_SOURCE_WD 9
+#define IRQ_SOURCE_X86 10
+#define IRQ_SOURCE_GAYLE 11
+#define IRQ_SOURCE_CIA 12
+#define IRQ_SOURCE_CD32CDTV 13
+#define IRQ_SOURCE_IDE 14
+#define IRQ_SOURCE_MAX 15
+
#endif /* UAE_DEVICES_H */
void ncr815_io_bput_wildfire(uaecptr addr, uae_u32 v);
uae_u32 ncr815_io_bget_wildfire(uaecptr addr);
-void wildfire_ncr815_irq(int v);
+void wildfire_ncr815_irq(int id, int v);
extern addrbank ncr_bank_cyberstorm;
extern addrbank ncr_bank_generic;
extern int cpucycleunit;
extern int m68k_pc_indirect;
-extern void safe_interrupt_set(uae_u32 v);
-extern void safe_interrupt_clear_all(void);
+extern void safe_interrupt_set(int, int, bool);
STATIC_INLINE void set_special_exter(uae_u32 x)
{
#define UVAL64(a) (a ## ul)
#endif
-void atomic_and(volatile uae_atomic *p, uae_u32 v);
-void atomic_or(volatile uae_atomic *p, uae_u32 v);
+uae_atomic atomic_and(volatile uae_atomic *p, uae_u32 v);
+uae_atomic atomic_or(volatile uae_atomic *p, uae_u32 v);
uae_atomic atomic_inc(volatile uae_atomic *p);
uae_atomic atomic_dec(volatile uae_atomic *p);
uae_u32 atomic_bit_test_and_reset(volatile uae_atomic *p, uae_u32 v);
extern void getfilepart (TCHAR *out, int size, const TCHAR *path);
extern uae_u32 getlocaltime (void);
extern bool isguiactive(void);
+extern bool is_mainthread(void);
extern int quit_program;
extern bool console_emulation;
{
for (int i = 0; ncr_units[i]; i++) {
if (ncr_units[i]->boardirq) {
- if (ncr_units[i]->irq6)
- safe_interrupt_set(0x2000);
- else
- safe_interrupt_set(0x0008);
- return;
+ safe_interrupt_set(IRQ_SOURCE_NCR9X, i, ncr_units[i]->irq6);
}
}
}
#include "qemuvga/scsi/scsi.h"
#include "autoconf.h"
#include "gui.h"
+#include "devices.h"
#define BOARD_SIZE 16777216
#define IO_MASK 0xff
struct ncr_state
{
+ int id;
bool newncr;
DeviceState devobject;
SCSIDevice *scsid[8];
int io_start, io_end;
addrbank *bank;
bool irq;
- void (*irq_func)(int);
+ void (*irq_func)(int, int);
struct romconfig *rc;
struct ncr_state **self_ptr;
};
static struct ncr_state *ncra4091[MAX_DUPLICATE_EXPANSION_BOARDS];
static struct ncr_state *ncr_wildfire;
-static void set_irq2(int level)
+static void set_irq2(int id, int level)
{
if (level)
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_NCR, 0, false);
}
void ncr_rethink(void)
{
for (int i = 0; ncr_units[i]; i++) {
if (ncr_units[i] != ncr_cs && ncr_units[i]->irq)
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_NCR, i + 1, false);
}
if (ncr_cs && ncr_cs->irq)
- cyberstorm_mk3_ppc_irq_setonly(1);
+ cyberstorm_mk3_ppc_irq_setonly(0, 1);
}
/* 720+ */
{
struct ncr_state *ncr = (struct ncr_state*)pci_dev;
ncr->irq = level != 0;
- ncr->irq_func(ncr->irq);
+ ncr->irq_func(ncr->id, ncr->irq);
}
void scsi_req_continue(SCSIRequest *req)
{
struct ncr_state *ncr = (struct ncr_state*)pci_dev;
ncr->irq = level != 0;
- ncr->irq_func(ncr->irq);
+ ncr->irq_func(ncr->id, ncr->irq);
}
void scsi710_req_continue(SCSIRequest *req)
#include "threaddep/thread.h"
#include "x86.h"
#include "bsdsocket.h"
+#include "devices.h"
#ifdef JIT
#include "jit/compemu.h"
#include <signal.h>
bool m68k_interrupt_delay;
static bool m68k_reset_delay;
+static volatile uae_atomic uae_interrupt;
+static volatile uae_atomic uae_interrupts2[IRQ_SOURCE_MAX];
+static volatile uae_atomic uae_interrupts6[IRQ_SOURCE_MAX];
+
static int cacheisets04060, cacheisets04060mask, cacheitag04060mask;
static int cachedsets04060, cachedsets04060mask, cachedtag04060mask;
regs.spcflags = 0;
m68k_reset_delay = 0;
regs.ipl = regs.ipl_pin = 0;
+ for (int i = 0; i < IRQ_SOURCE_MAX; i++) {
+ uae_interrupts2[i] = 0;
+ uae_interrupts6[i] = 0;
+ uae_interrupt = 0;
+ }
#ifdef SAVESTATE
if (isrestore ()) {
static void check_uae_int_request(void)
{
+ bool irq2 = false;
+ bool irq6 = false;
+ if (atomic_and(&uae_interrupt, 0)) {
+ for (int i = 0; i < IRQ_SOURCE_MAX; i++) {
+ if (!irq2 && uae_interrupts2[i]) {
+ uae_atomic v = atomic_and(&uae_interrupts2[i], 0);
+ if (v) {
+ INTREQ_f(0x8000 | 0x0008);
+ irq2 = true;
+ }
+ }
+ if (!irq6 && uae_interrupts6[i]) {
+ uae_atomic v = atomic_and(&uae_interrupts6[i], 0);
+ if (v) {
+ INTREQ_f(0x8000 | 0x2000);
+ irq6 = true;
+ }
+ }
+ }
+ }
if (uae_int_requested) {
- bool irq = false;
- if (uae_int_requested & 0x00ff) {
+ if (!irq2 && (uae_int_requested & 0x00ff)) {
INTREQ_f(0x8000 | 0x0008);
- irq = true;
+ irq2 = true;
}
- if (uae_int_requested & 0xff00) {
+ if (!irq6 && (uae_int_requested & 0xff00)) {
INTREQ_f(0x8000 | 0x2000);
- irq = true;
+ irq6 = true;
}
if (uae_int_requested & 0xff0000) {
if (!cpuboard_is_ppcboard_irq()) {
atomic_and(&uae_int_requested, ~0x010000);
}
}
- if (irq) {
- doint();
- }
+ }
+ if (irq2 || irq6) {
+ doint();
}
}
-/* 0x0010 = generic expansion level 2
- * 0x1000 = generic expansion level 6
- */
-void safe_interrupt_clear_all(void)
-{
- atomic_and(&uae_int_requested, ~(0x0010 | 0x1000));
-}
-
-void safe_interrupt_set(uae_u32 v)
+void safe_interrupt_set(int num, int id, bool i6)
{
- if (ppc_state || 0) {
+ if (!is_mainthread()) {
set_special_exter(SPCFLAG_UAEINT);
- if (v & 0x0008)
- atomic_or(&uae_int_requested, 0x0010);
- if (v & 0x2000)
- atomic_or(&uae_int_requested, 0x1000);
+ volatile uae_atomic *p;
+ if (i6)
+ p = &uae_interrupts6[num];
+ else
+ p = &uae_interrupts2[num];
+ atomic_or(p, 1 << id);
+ atomic_or(&uae_interrupt, 1);
} else {
+ uae_u16 v = i6 ? 0x2000 : 0x0008;
if (currprefs.cpu_cycle_exact || (!(intreq & v) && !currprefs.cpu_cycle_exact)) {
INTREQ_0(0x8000 | v);
}
if (s[1] == '!') {
*v = _tstol(s + 2);
} else {
- TCHAR *endptr;
*v = asmgetval(s + 1);
}
return imm;
}
}
-void atomic_and(volatile uae_atomic *p, uae_u32 v)
+uae_atomic atomic_and(volatile uae_atomic *p, uae_u32 v)
{
- _InterlockedAnd(p, v);
+ return _InterlockedAnd(p, v);
}
-void atomic_or(volatile uae_atomic *p, uae_u32 v)
+uae_atomic atomic_or(volatile uae_atomic *p, uae_u32 v)
{
- _InterlockedOr(p, v);
+ return _InterlockedOr(p, v);
}
void atomic_set(volatile uae_atomic *p, uae_u32 v)
{
static HWND hwndNextViewer;
HANDLE AVTask;
static int all_events_disabled;
+static int mainthreadid;
TCHAR VersionStr[256];
TCHAR BetaStr[64];
return nats;
}
+bool is_mainthread(void)
+{
+ return GetCurrentThreadId() == mainthreadid;
+}
+
typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD);
#ifndef NDEBUG
GetProcessAffinityMask (GetCurrentProcess (), &original_affinity, &sys_aff);
thread = GetCurrentThread ();
+ mainthreadid = GetCurrentThreadId();
//original_affinity = SetThreadAffinityMask(thread, 1);
fpucontrol = _controlfp (0, 0) & (_MCW_IC | _MCW_RC | _MCW_PC);
_tzset ();
for (int i = 0; i < MAX_PCI_BOARDS; i++) {
hsyncs[i] = NULL;
}
- atomic_and(&uae_int_requested, ~(0x10 | 0x100));
}
void pci_reset(void)
{
const struct pci_config *c = pcibs->board->config;
if (c->interruptpin) {
if ((pcibs->config_data[5] & (1 << 3)) && !(pcibs->config_data[6] & (1 << (10 - 8)))) {
- pcib->irq |= 1 << (c->interruptpin - 1);
+ uae_u8 irq = 1 << (c->interruptpin - 1);;
+ pcib->irq |= irq;
+ if (irq & pcib->intena) {
+ safe_interrupt_set(IRQ_SOURCE_PCI, i, (pcib->intreq_mask & 0x2000) != 0);
+ }
}
}
}
}
- if (pcib->irq & pcib->intena) {
- safe_interrupt_set(pcib->intreq_mask);
- }
}
}
// Wildfire
-void wildfire_ncr815_irq(int v)
+void wildfire_ncr815_irq(int id, int v)
{
struct pci_board_state *pcibs = &bridges[PCI_BRIDGE_WILDFIRE]->boards[0];
set_pci_irq(bridges[PCI_BRIDGE_WILDFIRE], pcibs, v != 0);
if (!ne->ariadne2_board_state)
return;
if (ne->ariadne2_irq) {
- if (ne->level6)
- safe_interrupt_set(0x2000);
- else
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_NE2000, 0, ne->level6);
}
}
if (soft_scsi_devices[i] == x86_hd_data) {
x86_doirq(5);
} else {
- if (soft_scsi_devices[i]->level6)
- safe_interrupt_set(0x2000);
- else
- safe_interrupt_set(0x0008);
- return;
+ safe_interrupt_set(IRQ_SOURCE_SCSI, i, soft_scsi_devices[i]->level6);
}
}
}
void sndboard_rethink(void)
{
- bool irq = false;
if (toccata[0].enabled) {
struct toccata_data *data = &toccata[0];
- irq = data->toccata_irq != 0;
+ bool irq = data->toccata_irq != 0;
+ if (irq) {
+ safe_interrupt_set(IRQ_SOURCE_SOUND, 0, true);
+ }
}
if (uaesndboard[0].enabled) {
- irq |= uaesnd_rethink();
- }
- if (irq) {
- safe_interrupt_set(0x2000);
- //atomic_or(&uae_int_requested, 0x200);
- //set_special_exter(SPCFLAG_UAEINT);
- } else {
- //atomic_and(&uae_int_requested, ~0x200);
+ bool irq = uaesnd_rethink();
+ if (irq) {
+ safe_interrupt_set(IRQ_SOURCE_SOUND, 1, true);
+ }
}
}
uae_u8 intena = xb->amiga_io[IO_INTERRUPT_MASK];
uae_u8 status = intreq & ~intena;
if (status)
- safe_interrupt_set(0x0008);
+ safe_interrupt_set(IRQ_SOURCE_X86, 0, false);
}
}