{
if (!configured)
return;
+ bool wasintr = (csr[0] & CSR0_INTR) != 0;
csr[0] &= ~CSR0_INTR;
uae_u16 mask = csr[0];
if (AM79C960)
csr[0] |= CSR0_INTR;
if ((csr[0] & (CSR0_INTR | CSR0_INEA)) == (CSR0_INTR | CSR0_INEA)) {
safe_interrupt_set(IRQ_SOURCE_A2065, 0, false);
- if (log_a2065 > 2)
+ if (log_a2065 > 1 && !wasintr) {
write_log(_T("7990 +IRQ\n"));
- }
- if (log_a2065) {
- write_log(_T("7990 -IRQ\n"));
+ }
+ } else if (wasintr) {
+ if (log_a2065 > 1) {
+ write_log(_T("7990 -IRQ\n"));
+ }
}
}
receive_buffer_size[receive_buffer_write] = len;
receive_buffer_write = nextwrite;
uae_sem_post(&receive_sem);
+ device_add_main_thread_callback(receive_queue_drain);
}
static int getfunc (void *devv, uae_u8 *d, int *len)
uae_u16 t;
if (log_a2065 > 2)
- write_log (_T("7990_CHIPWPUT: CSR%d=%04X PC=%08X\n"), rap, v & 0xffff, M68K_GETPC);
+ write_log(_T("7990_CHIPWPUT: CSR%d=%04X PC=%08X\n"), rap, v & 0xffff, M68K_GETPC);
switch (rap)
{
- case 0:
+ case 0:
csr[0] &= ~CSR0_INEA; csr[0] |= v & CSR0_INEA;
// bit = 1 -> set, bit = 0 -> nop
t = v & (CSR0_INIT | CSR0_STRT | CSR0_STOP | CSR0_TDMD);
csr[0] = CSR0_STOP;
if (log_a2065)
- write_log (_T("7990: STOP. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
+ write_log(_T("7990: STOP. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
csr[3] = 0;
dbyteswap = 0;
if (!(am_mode & MODE_DRX))
csr[0] |= CSR0_RXON;
if ((csr[0] & CSR0_INIT) && !(oreg & CSR0_INIT)) {
- chip_init ();
+ chip_init();
csr[0] |= CSR0_IDON;
am_initialized = 1;
if (log_a2065)
- write_log (_T("7990: INIT+START. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
+ write_log(_T("7990: INIT+START. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
}
if (log_a2065)
- write_log (_T("7990: START. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
-
+ write_log(_T("7990: START. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
+
} else if ((csr[0] & CSR0_INIT) && !(oreg & CSR0_INIT) && (oreg & CSR0_STOP)) {
- chip_init ();
+ chip_init();
csr[0] |= CSR0_IDON;
csr[0] &= ~(CSR0_RXON | CSR0_TXON | CSR0_STOP);
am_initialized = 1;
csr[3] = 0;
if (log_a2065)
- write_log (_T("7990: INIT. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
+ write_log(_T("7990: INIT. %04X -> %04X -> %04X\n"), oreg, v, csr[0]);
}
if ((csr[0] & CSR0_STRT)) {
devices_rethink_all(rethink_a2065);
break;
- case 1:
+ case 1:
if (csr[0] & 4) {
csr[1] = v;
csr[1] &= ~1;
}
break;
- case 2:
+ case 2:
if (csr[0] & 4) {
csr[2] = v;
csr[2] &= 0x00ff;
}
break;
- case 3:
+ case 3:
+ // interrupt masks
if ((csr[0] & 4) || AM79C960) {
csr[3] = v;
- if (AM79C960)
+ if (AM79C960) {
csr[3] &= 0x4000 | 0x1000 | 0x800 | 0x400 | 0x200 | 0x100 | 0x10 | 8;
- else
+ } else {
csr[3] &= 7;
+ }
}
dbyteswap = 0;
- /*
- * Some drivers set this but only work if no byteswapping
- * is done. Weird..
- * dbyteswap = (csr[3] & CSR3_BSWP) ? 1 : 0;
- */
+ if (!AM79C960) {
+ dbyteswap = (csr[3] & CSR3_BSWP) ? 1 : 0;
+ }
break;
- // Am79C960 extra
+ // Am79C960 extra
- // interrupt masks
- case 4:
- v &= ~(0x80 | 0x40);
- break;
// logical address filter
case 8:
am_ladrf &= 0x0000ffffffffffff;
#include "devices.h"
#include "options.h"
+#include "uae.h"
#include "threaddep/thread.h"
#include "memory.h"
#include "audio.h"
}
}
+static uae_sem_t thread_sema;
static int device_configs_cnt;
static DEVICE_VOID device_configs[MAX_DEVICE_ITEMS];
static int device_vsync_pre_cnt;
static int device_resets_cnt;
static DEVICE_INT device_resets[MAX_DEVICE_ITEMS];
static bool device_reset_done[MAX_DEVICE_ITEMS];
+static int device_callbacks_cnt;
+static DEVICE_VOID device_callbacks[MAX_DEVICE_ITEMS];
+
+void device_call_main_thread_callbacks(void)
+{
+ uae_sem_wait(&thread_sema);
+ DEVICE_VOID device_callbacks_tmp[MAX_DEVICE_ITEMS];
+ int device_callbacks_cnt_tmp = device_callbacks_cnt;
+ memcpy(device_callbacks_tmp, device_callbacks, sizeof(DEVICE_VOID) * device_callbacks_cnt);
+ device_callbacks_cnt = 0;
+ uae_sem_post(&thread_sema);
+ execute_device_items(device_callbacks_tmp, device_callbacks_cnt_tmp);
+}
+
+// queues function for execution from main thread if called from another thread
+void device_add_main_thread_callback(DEVICE_VOID p)
+{
+ if (is_mainthread()) {
+ p();
+ } else {
+ uae_sem_wait(&thread_sema);
+ add_device_item(device_callbacks, &device_callbacks_cnt, p);
+ set_special(SPCFLAG_CALLBACK);
+ uae_sem_post(&thread_sema);
+ }
+}
static void reset_device_items(void)
{
keymcu_reset();
keymcu2_reset();
keymcu3_reset();
+
+ uae_sem_wait(&thread_sema);
+ device_callbacks_cnt = 0;
+ uae_sem_post(&thread_sema);
+
uae_int_requested = 0;
}
SDL_Quit();
#endif
machdep_free();
+
+ if (thread_sema) {
+ uae_sem_destroy(&thread_sema);
+ thread_sema = NULL;
+ }
}
void virtualdevice_init (void)
{
+ if (!thread_sema) {
+ uae_sem_init(&thread_sema, 0, 1);
+ }
+
reset_device_items();
#ifdef CD32
void device_add_reset(DEVICE_INT p);
void device_add_reset_imm(DEVICE_INT p);
void device_add_exit(DEVICE_VOID p, DEVICE_VOID p2);
+void device_add_main_thread_callback(DEVICE_VOID p);
+void device_call_main_thread_callbacks(void);
#define IRQ_SOURCE_PCI 0
#define IRQ_SOURCE_SOUND 1
extern void safe_interrupt_set(int, int, bool);
-#define SPCFLAG_CPUINRESET 2
-#define SPCFLAG_CPU_SLOW 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.. */
-#define SPCFLAG_BLTNASTY 512
-#define SPCFLAG_EXEC 1024
-#define SPCFLAG_ACTION_REPLAY 2048
-#define SPCFLAG_TRAP 4096 /* enforcer-hack */
-#define SPCFLAG_MODE_CHANGE 8192
+#define SPCFLAG_CPUINRESET 0x000002
+#define SPCFLAG_CPU_SLOW 0x000004
+#define SPCFLAG_INT 0x000008
+#define SPCFLAG_BRK 0x000010
+#define SPCFLAG_UAEINT 0x000020
+#define SPCFLAG_TRACE 0x000040
+#define SPCFLAG_DOTRACE 0x000080
+#define SPCFLAG_DOINT 0x000100 /* arg, JIT fails without this.. */
+#define SPCFLAG_BLTNASTY 0x000200
+#define SPCFLAG_EXEC 0x000400
+#define SPCFLAG_ACTION_REPLAY 0x000800
+#define SPCFLAG_TRAP 0x001000 /* enforcer-hack */
+#define SPCFLAG_MODE_CHANGE 0x002000
#ifdef JIT
-#define SPCFLAG_END_COMPILE 16384
+#define SPCFLAG_END_COMPILE 0x004000
#endif
-#define SPCFLAG_CHECK 32768
-#define SPCFLAG_MMURESTART 65536
+#define SPCFLAG_CHECK 0x008000
+#define SPCFLAG_MMURESTART 0x010000
+#define SPCFLAG_CALLBACK 0x020000
STATIC_INLINE void set_special_exter(uae_u32 x)
{
ppc_interrupt(intlev());
uae_ppc_execute_check();
#endif
+ if (regs.spcflags & SPCFLAG_CALLBACK) {
+ unset_special(SPCFLAG_CALLBACK);
+ device_call_main_thread_callbacks();
+ }
if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) {
if (regs.spcflags & SPCFLAG_BRK) {
unset_special(SPCFLAG_BRK);
ppc_interrupt(intlev());
uae_ppc_execute_check();
#endif
+ if (regs.spcflags & SPCFLAG_CALLBACK) {
+ unset_special(SPCFLAG_CALLBACK);
+ device_call_main_thread_callbacks();
+ }
+
if (event_wait)
break;
frame_time_t d = read_processor_time() - rpt_end;
if (spcflags & SPCFLAG_MODE_CHANGE)
return 1;
+ if (spcflags & SPCFLAG_CALLBACK) {
+ unset_special(SPCFLAG_CALLBACK);
+ device_call_main_thread_callbacks();
+ }
+
while (spcflags & SPCFLAG_CPUINRESET) {
cpu_halt_clear();
x_do_cycles(4 * CYCLE_UNIT);
extern addrbank *thread_mem_banks[MEMORY_BANKS];
+static bool is_cpu_thread(void)
+{
+ return cpu_thread_tid == uae_thread_get_id();
+}
+
uae_u32 process_cpu_indirect_memory_read(uae_u32 addr, int size)
{
// Do direct access if call is from filesystem etc thread
- if (cpu_thread_tid != uae_thread_get_id()) {
+ if (!is_cpu_thread()) {
uae_u32 data = 0;
addrbank *ab = thread_mem_banks[bankindex(addr)];
switch (size)
void process_cpu_indirect_memory_write(uae_u32 addr, uae_u32 data, int size)
{
- if (cpu_thread_tid != uae_thread_get_id()) {
+ if (!is_cpu_thread()) {
addrbank *ab = thread_mem_banks[bankindex(addr)];
switch (size)
{
static void custom_reset_cpu(bool hardreset, bool keyboardreset)
{
#ifdef WITH_THREADED_CPU
- if (cpu_thread_tid != uae_thread_get_id()) {
+ if (!is_cpu_thread()) {
custom_reset(hardreset, keyboardreset);
return;
}
struct regstruct *r = ®s;
cpu_thread_tid = uae_thread_get_id();
-
cpu_thread_active = 1;
while (!exit) {
TRY(prb)
currprefs.cpu_model < 68020 ? m68k_run_2_000 : m68k_run_2_020;
run_func();
+
+ cpu_thread_tid = 0;
}
void m68k_go (int may_quit)