Interrupt status atomic operations.

This commit is contained in:
Toni Wilen 2016-01-31 15:48:57 +02:00
parent c048b0284c
commit 0cc79925fa
7 changed files with 64 additions and 44 deletions

View File

@ -558,14 +558,14 @@ void a2065_hsync_handler (void)
void rethink_a2065 (void)
{
bool was = (uae_int_requested & 4) != 0;
uae_int_requested &= ~4;
atomic_and(&uae_int_requested, ~4);
if (!configured)
return;
csr[0] &= ~CSR0_INTR;
if (csr[0] & (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)) {
uae_int_requested |= 4;
atomic_or(&uae_int_requested, 4);
if (!was && log_a2065 > 2)
write_log(_T("A2065 +IRQ\n"));
}

View File

@ -33,7 +33,9 @@
#include "scsi.h"
#include "cpummu030.h"
// 00F83B7C 3.1 ROM expansion board diagrom
// ROM expansion board diagrom call
// 00F83B7C 3.1 A4000
// 00F83C96 3.1 A1200
#define PPC_IRQ_DEBUG 0
#define CPUBOARD_IO_LOG 0
@ -886,15 +888,15 @@ void cpuboard_rethink(void)
if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
INTREQ_0(0x8000 | 0x0008);
if (currprefs.cachesize)
uae_int_requested |= 0x010000;
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))) {
INTREQ_0(0x8000 | 0x0008);
if (currprefs.cachesize)
uae_int_requested |= 0x010000;
atomic_or(&uae_int_requested, 0x010000);
uae_ppc_wakeup_main();
} else {
uae_int_requested &= ~0x010000;
atomic_and(&uae_int_requested, ~0x010000);
}
check_ppc_int_lvl();
ppc_interrupt(intlev());

View File

@ -4979,6 +4979,31 @@ STATIC_INLINE int use_eventmode (uae_u16 v)
return 0;
}
void rethink_uae_int(void)
{
bool irq2 = false;
bool irq6 = false;
if (uae_int_requested) {
if (uae_int_requested & 0xff00)
irq6 = true;
if (uae_int_requested & 0x00ff)
irq2 = true;
}
{
extern void bsdsock_fake_int_handler(void);
extern int volatile bsd_int_requested;
if (bsd_int_requested)
bsdsock_fake_int_handler();
}
uae_u16 mask = (irq6 ? 0x2000 : 0) | (irq2 ? 0x0008 : 0);
if (mask)
INTREQ_0(0x8000 | mask);
}
static void rethink_intreq (void)
{
serial_check_irq ();
@ -5280,7 +5305,7 @@ static void BPLCON0 (int hpos, uae_u16 v)
v &= ~0x00F1;
else if (! (currprefs.chipset_mask & CSMASK_AGA))
v &= ~0x00B0;
v &= ~(0x0080 | 0x0020);
v &= ~0x0080;
#if SPRBORDER
v |= 1;
@ -8179,25 +8204,7 @@ static void hsync_handler_post (bool onvsync)
reset_decisions ();
}
if (uae_int_requested) {
if (uae_int_requested & 0xff00)
INTREQ(0x8000 | 0x2000);
if (uae_int_requested & 0x00ff)
INTREQ(0x8000 | 0x0008);
}
{
if (uaenet_int_requested || (uaenet_vsync_requested && vpos == 10)) {
INTREQ (0x8000 | 0x0008);
}
}
{
extern void bsdsock_fake_int_handler (void);
extern int volatile bsd_int_requested;
if (bsd_int_requested)
bsdsock_fake_int_handler ();
}
rethink_uae_int();
/* Default to no bitplane DMA overriding sprite DMA */
plfstrt_sprite = 0xff;

View File

@ -71,6 +71,7 @@ STATIC_INLINE int dmaen (unsigned int dmamask)
#define SPCFLAG_COPPER 4
#define SPCFLAG_INT 8
#define SPCFLAG_BRK 16
#define SPCFLAG_UAEINT 32
#define SPCFLAG_TRACE 64
#define SPCFLAG_DOTRACE 128
#define SPCFLAG_DOINT 256 /* arg, JIT fails without this.. */
@ -89,11 +90,12 @@ extern uae_u16 adkcon;
extern unsigned int joy0dir, joy1dir;
extern int joy0button, joy1button;
extern void INTREQ (uae_u16);
extern bool INTREQ_0 (uae_u16);
extern void INTREQ_f (uae_u16);
extern void send_interrupt (int num, int delay);
extern uae_u16 INTREQR (void);
extern void INTREQ(uae_u16);
extern bool INTREQ_0(uae_u16);
extern void INTREQ_f(uae_u16);
extern void send_interrupt(int num, int delay);
extern void rethink_uae_int(void);
extern uae_u16 INTREQR(void);
/* maximums for statically allocated tables */
#ifdef UAE_MINI

View File

@ -3439,19 +3439,19 @@ static void do_trace (void)
static void check_uae_int_request(void)
{
if (uae_int_requested || uaenet_int_requested) {
if (uae_int_requested) {
bool irq = false;
if ((uae_int_requested & 0x00ff) || uaenet_int_requested) {
INTREQ_f(0x8000 | 0x0008);
if (uae_int_requested & 0x00ff) {
INTREQ_0(0x8000 | 0x0008);
irq = true;
}
if (uae_int_requested & 0xff00) {
INTREQ_f(0x8000 | 0x2000);
INTREQ_0(0x8000 | 0x2000);
irq = true;
}
if (uae_int_requested & 0xff0000) {
if (!cpuboard_is_ppcboard_irq())
uae_int_requested &= ~0x010000;
atomic_and(&uae_int_requested, ~0x010000);
}
if (irq)
set_special(SPCFLAG_INT);
@ -3569,6 +3569,9 @@ static bool haltloop(void)
ovpos = vpos;
while (ovpos == vpos) {
x_do_cycles(8 * CYCLE_UNIT);
unset_special(SPCFLAG_UAEINT);
check_uae_int_request();
ppc_interrupt(intlev());
uae_ppc_execute_check();
if (regs.spcflags & SPCFLAG_COPPER)
do_copper();
@ -3673,6 +3676,7 @@ static int do_specialties (int cycles)
if (regs.spcflags & SPCFLAG_CHECK) {
if (regs.halted) {
unset_special(SPCFLAG_CHECK);
if (haltloop())
return 1;
}
@ -3829,6 +3833,11 @@ static int do_specialties (int cycles)
if (regs.spcflags & SPCFLAG_TRACE)
do_trace ();
if (regs.spcflags & SPCFLAG_UAEINT) {
check_uae_int_request();
unset_special(SPCFLAG_UAEINT);
}
if (m68k_interrupt_delay) {
if (time_for_interrupt ()) {
do_interrupt (regs.ipl);
@ -4401,7 +4410,7 @@ void exec_nostats (void)
#endif
}
if (end_block(r->opcode) || r->spcflags || uae_int_requested || uaenet_int_requested)
if (end_block(r->opcode) || r->spcflags || uae_int_requested)
return; /* We will deal with the spcflags in the caller */
}
}
@ -4440,7 +4449,7 @@ void execute_normal (void)
total_cycles += cpu_cycles;
pc_hist[blocklen].specmem = special_mem;
blocklen++;
if (end_block (r->opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested || uaenet_int_requested) {
if (end_block (r->opcode) || blocklen >= MAXRUN || r->spcflags || uae_int_requested) {
compile_block (pc_hist, blocklen, total_cycles);
return; /* We will deal with the spcflags in the caller */
}

View File

@ -138,7 +138,7 @@ void pci_free(void)
for (int i = 0; i < MAX_PCI_BOARDS; i++) {
hsyncs[i] = NULL;
}
uae_int_requested &= ~(0x10 | 0x100);
atomic_and(&uae_int_requested, ~(0x10 | 0x100));
}
void pci_reset(void)
{
@ -155,7 +155,7 @@ void pci_hsync(void)
void pci_rethink(void)
{
uae_int_requested &= ~(0x10 | 0x100);
atomic_and(&uae_int_requested, ~(0x10 | 0x100));
for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
struct pci_bridge *pcib = bridges[i];
if (!pcib)
@ -173,7 +173,7 @@ void pci_rethink(void)
}
}
if (pcib->irq & pcib->intena) {
uae_int_requested |= pcib->intreq_mask;
atomic_or(&uae_int_requested, pcib->intreq_mask);
}
}
}

View File

@ -269,9 +269,9 @@ static void codec_stop(void)
void sndboard_rethink(void)
{
struct toccata_data *data = &toccata;
uae_int_requested &= ~0x200;
atomic_and(&uae_int_requested, ~0x200);
if (data->toccata_irq)
uae_int_requested |= 0x200;
atomic_or(&uae_int_requested, 0x200);
}
static void sndboard_process_capture(void)
@ -638,7 +638,7 @@ void sndboard_free(void)
{
struct toccata_data *data = &toccata;
data->toccata_irq = 0;
uae_int_requested &= ~0x200;
atomic_and(&uae_int_requested, ~0x200);
}
void sndboard_reset(void)