This commit is contained in:
Toni Wilen 2023-09-17 18:00:26 +03:00
parent 61cdfc2b30
commit 0293d194fc
13 changed files with 3103 additions and 2 deletions

View File

@ -45,6 +45,7 @@
#include "cpuboard.h"
#include "rtc.h"
#include "devices.h"
#include "dsp3210/dsp_glue.h"
#define DMAC_8727_ROM_VECTOR 0x8000
#define CDMAC_ROM_VECTOR 0x2000
@ -3625,6 +3626,12 @@ static void mbdmac_write_word (struct wd_state *wd, uae_u32 addr, uae_u32 val)
case 0x46:
wdscsi_put(&wd->wc, wd, val);
break;
case 0x5e:
case 0x80:
if (is_dsp_installed) {
dsp_write(val);
}
break;
}
}
@ -3645,6 +3652,12 @@ static void mbdmac_write_byte (struct wd_state *wd, uae_u32 addr, uae_u32 val)
case 0x47:
wdscsi_put (&wd->wc, wd, val);
break;
case 0x5f:
case 0x80:
if (is_dsp_installed) {
dsp_write(val);
}
break;
default:
if (addr & 1)
mbdmac_write_word (wd, addr, val);
@ -3711,6 +3724,12 @@ static uae_u32 mbdmac_read_word (struct wd_state *wd, uae_u32 addr)
case 0x46:
v = wdscsi_get(&wd->wc, wd);
break;
case 0x5e:
case 0x80:
if (is_dsp_installed) {
v = dsp_read();
}
break;
}
#if A3000_DEBUG_IO > 1
write_log (_T("DMAC_WREAD %08X=%04X PC=%X\n"), vaddr, v & 0xffff, M68K_GETPC);
@ -3741,6 +3760,12 @@ static uae_u32 mbdmac_read_byte (struct wd_state *wd, uae_u32 addr)
if (!(addr & 1))
v >>= 8;
break;
case 0x5f:
case 0x80:
if (is_dsp_installed) {
v = dsp_read();
}
break;
}
#if A3000_DEBUG_IO > 1
write_log (_T("DMAC_BREAD %08X=%02X PC=%X\n"), vaddr, v & 0xff, M68K_GETPC);

View File

@ -63,6 +63,7 @@
#ifdef RETROPLATFORM
#include "rp.h"
#endif
#include "dsp3210/dsp_glue.h"
#define MAX_DEVICE_ITEMS 64
@ -438,6 +439,9 @@ void devices_pause(void)
{
#ifdef WITH_PPC
uae_ppc_pause(1);
#endif
#ifdef WITH_DSP
dsp_pause(1);
#endif
blkdev_entergui();
#ifdef RETROPLATFORM
@ -455,6 +459,9 @@ void devices_unpause(void)
#endif
#ifdef WITH_PPC
uae_ppc_pause(0);
#endif
#ifdef WITH_DSP
dsp_pause(0);
#endif
pausevideograb(0);
ethernet_pause(0);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/********************************************************/
/* Initialise the DSP emulator */
/* */
/********************************************************/
void DSP_init_emu ();
/********************************************************/
/* Shut down the DSP emulator */
/* */
/********************************************************/
void DSP_shutdown_emu ();
/********************************************************/
/* Reset the DSP */
/* */
/********************************************************/
void DSP_reset();
//note this is triggered via bit 7 of 0xDD0080 going from 1 to 0
/********************************************************/
/* Trigger an interrupt level 0 */
/* */
/********************************************************/
bool DSP_int0();
bool DSP_int0_masked();
//note this is triggered via bit 0 of 0xDD0080 going from 1 to 0
/********************************************************/
/* Trigger an interrupt level 1 */
/* */
/********************************************************/
bool DSP_int1();
bool DSP_int1_masked();
//note this is triggered via bit 1 of 0xDD0080 going from 1 to 0
/********************************************************/
/* DSP has changed M68k interrupt line */
/* */
/********************************************************/
void DSP_external_interrupt(int32_t level, int32_t state);
//state is the state of the associated line, 0 triggers an M68k interrupt
//level=0 corresponds to INT2, level=1 corresponds to INT6
//this routine needs to mask interrupts
/********************************************************/
/* Execute a single DSP instruction, allowing for */
/* instruction and memory latencies */
/********************************************************/
void DSP_execute_insn ();
/********************************************************/
/* Read values from the Amiga's memory space */
/* */
/********************************************************/
uint32_t DSP_get_long_ext(uint32_t addr);
uint16_t DSP_get_short_ext(uint32_t addr);
unsigned char DSP_get_char_ext(uint32_t addr);
/********************************************************/
/* Set values in the Amiga's memory space */
/* */
/********************************************************/
void DSP_set_long_ext(uint32_t addr, uint32_t value);
void DSP_set_short_ext(uint32_t addr, uint16_t value);
void DSP_set_char_ext(uint32_t addr, unsigned char value);
extern char DSP_irsh_flag;
//Notes:
//The DSP write register is byte sized and located at 0xDD0080
//The DSP read register (which should mirror the write register)
//is long word sized and located at 0xDD005C
//
//For more details on the Amiga interface to the DSP3210, see here:
//http://www.devili.iki.fi/mirrors/haynie/research/a3000p/docs/dspprg.pdf

353
dsp3210/dsp_glue.cpp Normal file
View File

@ -0,0 +1,353 @@
#include "stdlib.h"
#include "stdint.h"
#include "dsp3210/DSP3210_emulation.h"
#include "sysconfig.h"
#include "sysdeps.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "devices.h"
#include "uae.h"
#include "autoconf.h"
#include "debug.h"
#include "newcpu.h"
#include "threaddep/thread.h"
#include "dsp_glue.h"
#define DSP_INST_COUNT_WAIT 1000
int log_dsp = 0;
static volatile uae_u8 dsp_status;
bool is_dsp_installed;
static volatile int dsp_thread_running;
static uae_sem_t reset_sem, pause_sem;
static volatile uae_atomic dsp_int;
static volatile uae_atomic dsp_int_ext;
static int dsp_int0_delay, dsp_int1_delay;
static volatile bool dsp_running;
static volatile uae_u32 dsp_inst_cnt;
static bool dsp_paused;
static bool dsp_addr_check(uint32_t addr)
{
addrbank *ab = &get_mem_bank(addr);
if ((ab->flags & ABFLAG_THREADSAFE) == 0 && ab != &dummy_bank) {
write_log("DSP accesses non-threadsafe address %08x!\n", addr);
return false;
}
return true;
}
static uint32_t safe_memory_read(uint32_t addr, int size)
{
return 0;
}
static void safe_memory_write(uint32_t addr, uint32_t data, int size)
{
}
uint32_t DSP_get_long_ext(uint32_t addr)
{
int32_t v;
if (dsp_addr_check(addr)) {
v = get_long(addr);
} else {
v = safe_memory_read(addr, 4);
}
v = _byteswap_ulong(v);
if (log_dsp) {
write_log("DSP LGET %08x = %08x\n", addr, v);
}
return v;
}
uint16_t DSP_get_short_ext(uint32_t addr)
{
uint16_t v;
if (dsp_addr_check(addr)) {
v = get_word(addr);
} else {
v = safe_memory_read(addr, 2);
}
v = _byteswap_ushort(v);
if (log_dsp) {
write_log("DSP WGET %08x = %04x\n", addr, v & 0xffff);
}
return v;
}
unsigned char DSP_get_char_ext(uint32_t addr)
{
unsigned char v;
if (dsp_addr_check(addr)) {
v = get_byte(addr);
} else {
v = safe_memory_read(addr, 1);
}
if (log_dsp) {
write_log("DSP BGET %08x = %02x\n", addr, v & 0xff);
}
return v;
}
void DSP_set_long_ext(uint32_t addr, uint32_t v)
{
v = _byteswap_ulong(v);
if (log_dsp) {
write_log("DSP LPUT %08x = %08x\n", addr, v);
}
if (dsp_addr_check(addr)) {
put_long(addr, v);
} else {
safe_memory_write(addr, v, 4);
}
}
void DSP_set_short_ext(uint32_t addr, uint16_t v)
{
v = _byteswap_ushort(v);
if (log_dsp) {
write_log("DSP WPUT %08x = %04x\n", addr, v & 0xffff);
}
if (dsp_addr_check(addr)) {
put_word(addr, v);
} else {
safe_memory_write(addr, v, 2);
}
}
void DSP_set_char_ext(uint32_t addr, unsigned char v)
{
if (log_dsp) {
write_log("DSP BPUT %08x = %02x\n", addr, v & 0xff);
}
if (dsp_addr_check(addr)) {
put_byte(addr, v);
} else {
safe_memory_write(addr, v, 1);
}
}
static void dsp_status_intx(void)
{
dsp_status &= ~(1 | 2 | 4 | 8);
dsp_status |= dsp_int;
dsp_status |= dsp_int_ext;
}
static void dsp_rethink(void)
{
dsp_status_intx();
if ((dsp_status & 0x20) && !(dsp_status & 8)) {
if (log_dsp) {
write_log("DSP INTREQ level 6\n");
}
INTREQ_0(0x8000 | 0x2000);
}
if ((dsp_status & 0x10) && !(dsp_status & 4)) {
if (log_dsp) {
write_log("DSP INTREQ level 2\n");
}
INTREQ_0(0x8000 | 0x0008);
}
}
static void dsp_reset(void)
{
dsp_int = 0x01 | 0x02;
dsp_int_ext = 0x04 | 0x08;
}
static void cpu_wait(void)
{
while (dsp_inst_cnt < DSP_INST_COUNT_WAIT && dsp_thread_running > 0) {
x_do_cycles(CYCLE_UNIT * 8);
}
}
// stop CPU for a while if DSP was not waiting for interrupt
static void dsp_do_int(int i)
{
int mask = ~(1 << i);
if (log_dsp) {
write_log("DSP INT%d\n", i);
}
// stop CPU if DSP is not waiting for interrupt
if (DSP_irsh_flag != 4) {
dsp_inst_cnt = 0;
atomic_and(&dsp_int, mask);
cpu_wait();
} else {
atomic_and(&dsp_int, mask);
}
}
void dsp_write(uae_u8 v)
{
dsp_status_intx();
if (log_dsp) {
write_log("DSP write %02x (%02x) PC=%08x\n", v, dsp_status, M68K_GETPC);
}
if (!(dsp_status & 0x80) && (v & 0x80)) {
dsp_status |= 0x80;
write_log("DSP reset released\n");
dsp_inst_cnt = 0;
uae_sem_post(&reset_sem);
cpu_wait();
write_log("DSP reset delay end\n");
} else if ((dsp_status & 0x80) && !(v & 0x80)) {
write_log("DSP reset activated\n");
dsp_status &= ~0x80;
dsp_reset();
}
if ((dsp_status & 1) && !(v & 1)) {
dsp_do_int(0);
} else if (v & 1) {
atomic_or(&dsp_int, 1);
}
if ((dsp_status & 2) && !(v & 2)) {
dsp_do_int(1);
} else if (v & 2) {
atomic_or(&dsp_int, 2);
}
dsp_status = (v & (0x40 | 0x20 | 0x10)) | (dsp_status & 0x80);
dsp_status_intx();
if (log_dsp) {
write_log("-> %02x\n", dsp_status);
}
}
uae_u8 dsp_read(void)
{
dsp_status_intx();
uae_u8 v = dsp_status;
if (log_dsp) {
write_log("DSP read %02x\n", v);
}
return v;
}
void DSP_external_interrupt(int32_t level, int32_t state)
{
int32_t mask = level ? 0x08 : 0x04;
if (state) {
if (log_dsp && !(dsp_status & mask)) {
write_log("DSP interrupt %d = %d\n", level, state);
}
atomic_and(&dsp_int_ext, ~mask);
} else {
if (log_dsp && (dsp_status & mask)) {
write_log("DSP interrupt %d = %d\n", level, state);
}
atomic_or(&dsp_int_ext, mask);
}
atomic_or(&uae_int_requested, 0x010000);
}
static void dsp_thread(void *v)
{
dsp_thread_running = 1;
DSP_init_emu();
dsp_reset();
dsp_int0_delay = 0;
dsp_int1_delay = 0;
while (dsp_thread_running > 0) {
if (!(dsp_status & 0x80)) {
uae_sem_wait(&reset_sem);
dsp_reset();
DSP_reset();
dsp_inst_cnt = 0;
}
if (dsp_paused) {
uae_sem_wait(&pause_sem);
continue;
}
if (dsp_status & 0x80) {
DSP_execute_insn();
dsp_inst_cnt++;
if (!(dsp_int & 1)) {
dsp_int0_delay++;
if (DSP_int0_masked()) {
dsp_int0_delay = 0;
if (log_dsp) {
write_log("DSP interrupt 0 masked\n");
}
}
if (dsp_int0_delay > 2) {
if (DSP_int0()) {
if (log_dsp) {
write_log(_T("DSP interrupt 0 started\n"));
}
}
atomic_or(&dsp_int, 1);
dsp_int0_delay = 0;
}
}
if (!(dsp_int & 2)) {
dsp_int1_delay++;
if (DSP_int1_masked()) {
dsp_int1_delay = 0;
if (log_dsp) {
write_log("DSP interrupt 1 masked\n");
}
}
if (dsp_int1_delay > 2) {
if (DSP_int1()) {
if (log_dsp) {
write_log(_T("DSP interrupt 1 started\n"));
}
}
atomic_or(&dsp_int, 2);
dsp_int1_delay = 0;
}
}
}
}
DSP_shutdown_emu();
dsp_status = 0;
dsp_thread_running = 0;
}
static void dsp_free(void)
{
write_log("DSP free\n");
if (dsp_thread_running > 0) {
dsp_status &= ~0x80;
dsp_thread_running = -1;
uae_sem_post(&reset_sem);
uae_sem_post(&pause_sem);
while (dsp_thread_running) {
sleep_millis(2);
}
uae_sem_destroy(&reset_sem);
}
is_dsp_installed = false;
}
bool dsp_init(struct autoconfig_info *aci)
{
aci->start = 0xdd0000;
aci->size = 0x10000;
dsp_status = 0;
dsp_reset();
dsp_status_intx();
if (aci->doinit) {
is_dsp_installed = true;
write_log("DSP init\n");
device_add_rethink(dsp_rethink);
device_add_exit(NULL, dsp_free);
uae_sem_init(&reset_sem, 0, 0);
uae_sem_init(&pause_sem, 0, 0);
uae_start_thread(NULL, dsp_thread, NULL, NULL);
}
return true;
}
void dsp_pause(int pause)
{
dsp_paused = pause;
uae_sem_post(&pause_sem);
}

7
dsp3210/dsp_glue.h Normal file
View File

@ -0,0 +1,7 @@
bool dsp_init(struct autoconfig_info *aci);
void dsp_write(uae_u8);
uae_u8 dsp_read(void);
void dsp_pause(int);
extern bool is_dsp_installed;

View File

@ -50,6 +50,7 @@
#include "sana2.h"
#include "arcadia.h"
#include "devices.h"
#include "dsp3210/dsp_glue.h"
#define CARD_FLAG_CAN_Z3 1
@ -5289,6 +5290,14 @@ const struct expansionromtype expansionroms[] = {
NULL, 0,
false, EXPANSIONTYPE_INTERNAL
},
#ifdef WITH_DSP
{
_T("dsp3210"), _T("DSP3210"), _T("AT&T"),
NULL, dsp_init, NULL, NULL, ROMTYPE_DSP3210 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
NULL, 0,
false, EXPANSIONTYPE_INTERNAL
},
#endif
/* PCI Bridgeboards */

View File

@ -36,6 +36,7 @@
#include "autoconf.h"
#include "rommgr.h"
#include "devices.h"
#include "dsp3210/dsp_glue.h"
#define PCMCIA_SRAM 1
#define PCMCIA_IDE 2
@ -475,6 +476,14 @@ static int gayle_read (uaecptr addr)
uaecptr oaddr = addr;
uae_u32 v = 0;
int got = 0;
if (is_dsp_installed) {
uaecptr daddr = addr & 0xffff;
if (daddr == 0x5f || daddr == 0x80) {
v = dsp_read();
return v;
}
}
if (currprefs.cs_ide == IDE_A600A1200) {
if ((addr & 0xA0000) != 0xA0000)
return 0;
@ -513,9 +522,17 @@ static void gayle_write (uaecptr addr, int val)
{
uaecptr oaddr = addr;
int got = 0;
if (is_dsp_installed) {
uaecptr daddr = addr & 0xffff;
if (daddr == 0x5f || daddr == 0x80) {
dsp_write(val);
}
}
if (currprefs.cs_ide == IDE_A600A1200) {
if ((addr & 0xA0000) != 0xA0000)
if ((addr & 0xA0000) != 0xA0000) {
return;
}
}
addr &= 0xffff;
if (currprefs.cs_pcmcia) {
@ -540,7 +557,6 @@ static void gayle_write (uaecptr addr, int val)
write_log (_T("PCMCIA CONFIG WRITE %08X=%02X PC=%08X\n"), oaddr, (uae_u32)val & 0xff, M68K_GETPC);
}
}
if (GAYLE_LOG)
write_log (_T("GAYLE_WRITE %08X=%02X PC=%08X\n"), oaddr, (uae_u32)val & 0xff, M68K_GETPC);
if (!got)

View File

@ -206,6 +206,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size);
#define ROMTYPE_DEVHD 0x0010008c
#define ROMTYPE_CSMK1SCSI 0x0010008d
#define ROMTYPE_GVPA1208 0x0010008e
#define ROMTYPE_DSP3210 0x0010008f
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000

View File

@ -117,6 +117,7 @@
#define WITH_SOFTFLOAT
#define FLOPPYBRIDGE
#define WITH_MIDIEMU
#define WITH_DSP
#else

View File

@ -125,6 +125,7 @@ extern int log_a2065, a2065_promiscuous, log_ethernet;
extern int rawinput_enabled_hid, rawinput_log;
extern int log_filesys;
extern int forcedframelatency;
extern int log_dsp;
int log_scsi;
int log_net;
int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay;
@ -6774,6 +6775,10 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
log_rp = 3;
return 1;
}
if (!_tcscmp(arg, _T("dsplog"))) {
log_dsp = 1;
return 1;
}
if (!_tcscmp(arg, _T("nomultidisplay"))) {
return 1;
}

View File

@ -1327,6 +1327,8 @@
<ClCompile Include="..\..\devices.cpp" />
<ClCompile Include="..\..\disasm.cpp" />
<ClCompile Include="..\..\dlopen.cpp" />
<ClCompile Include="..\..\dsp3210\DSP3210_emulation.cpp" />
<ClCompile Include="..\..\dsp3210\dsp_glue.cpp" />
<ClCompile Include="..\..\ethernet.cpp" />
<ClCompile Include="..\..\events.cpp" />
<ClCompile Include="..\..\flashrom.cpp" />

View File

@ -74,6 +74,9 @@
<UniqueIdentifier>{5c4c971a-37b6-4c1e-82f1-d225ebb12808}</UniqueIdentifier>
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
</Filter>
<Filter Include="dsp3210">
<UniqueIdentifier>{6f046035-4e6d-4038-a65f-d789a89ee702}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\ahidsound_dsonly.cpp">
@ -991,6 +994,12 @@
<ClCompile Include="..\..\midiemu.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\dsp3210\DSP3210_emulation.cpp">
<Filter>dsp3210</Filter>
</ClCompile>
<ClCompile Include="..\..\dsp3210\dsp_glue.cpp">
<Filter>dsp3210</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">