mirror of https://github.com/xemu-project/xemu.git
kill wut
This commit is contained in:
parent
537edc85f3
commit
8d029a7c2e
|
@ -20,8 +20,9 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dsp_cpu.h"
|
||||
#include "dsp_disasm.h"
|
||||
|
@ -29,6 +30,8 @@
|
|||
|
||||
#include "dsp.h"
|
||||
|
||||
/* Defines */
|
||||
#define BITMASK(x) ((1<<(x))-1)
|
||||
#define ARRAYSIZE(x) (int)(sizeof(x)/sizeof(x[0]))
|
||||
|
||||
#define DEBUG 0
|
||||
|
@ -38,23 +41,18 @@
|
|||
#define DPRINTF(a)
|
||||
#endif
|
||||
|
||||
static const char* x_ext_memory_addr_name[] = {
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"PBC", "PCC", "PBDDR", "PCDDR", "PBD", "PCD", "", "",
|
||||
"HCR", "HSR", "", "HRX/HTX", "CRA", "CRB", "SSISR/TSR", "RX/TX",
|
||||
"SCR", "SSR", "SCCR", "STXA", "SRX/STX", "SRX/STX", "SRX/STX", "",
|
||||
"", "", "", "", "", "", "BCR", "IPR"
|
||||
};
|
||||
|
||||
static int32_t save_cycles;
|
||||
|
||||
static void dsp_trigger_host_interrupt(void) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the DSP emulation
|
||||
*/
|
||||
void dsp_init(void)
|
||||
{
|
||||
dsp_core_init(NULL); //DSP_TriggerHostInterrupt
|
||||
dsp_core_init(dsp_trigger_host_interrupt);
|
||||
dsp56k_init_cpu();
|
||||
save_cycles = 0;
|
||||
}
|
||||
|
@ -110,7 +108,7 @@ void dsp_run(int nHostCycles)
|
|||
/**
|
||||
* Get DSP program counter (for debugging)
|
||||
*/
|
||||
uint16_t dsp_get_pc(void)
|
||||
uint32_t dsp_get_pc(void)
|
||||
{
|
||||
return dsp_core.pc;
|
||||
}
|
||||
|
@ -118,7 +116,7 @@ uint16_t dsp_get_pc(void)
|
|||
/**
|
||||
* Get next DSP PC without output (for debugging)
|
||||
*/
|
||||
uint16_t dsp_get_next_pc(uint16_t pc)
|
||||
uint32_t dsp_get_next_pc(uint32_t pc)
|
||||
{
|
||||
/* code is reduced copy from dsp56k_execute_one_disasm_instruction() */
|
||||
dsp_core_t dsp_core_save;
|
||||
|
@ -152,9 +150,9 @@ uint16_t dsp_get_instr_cycles(void)
|
|||
/**
|
||||
* Disassemble DSP code between given addresses, return next PC address
|
||||
*/
|
||||
uint16_t dsp_disasm_address(FILE *out, uint16_t lowerAdr, uint16_t UpperAdr)
|
||||
uint32_t dsp_disasm_address(FILE *out, uint32_t lowerAdr, uint32_t UpperAdr)
|
||||
{
|
||||
uint16_t dsp_pc;
|
||||
uint32_t dsp_pc;
|
||||
|
||||
for (dsp_pc=lowerAdr; dsp_pc<=UpperAdr; dsp_pc++) {
|
||||
dsp_pc += dsp56k_execute_one_disasm_instruction(out, dsp_pc);
|
||||
|
@ -172,77 +170,32 @@ uint16_t dsp_disasm_address(FILE *out, uint16_t lowerAdr, uint16_t UpperAdr)
|
|||
* Return the value at given address. For valid values AND the return
|
||||
* value with BITMASK(24).
|
||||
*/
|
||||
uint32_t dsp_read_memory(uint16_t address, char space_id, const char **mem_str)
|
||||
uint32_t dsp_read_memory(uint32_t address, char space_id, const char **mem_str)
|
||||
{
|
||||
static const char *spaces[3][4] = {
|
||||
{ "X ram", "X rom", "X", "X periph" },
|
||||
{ "Y ram", "Y rom", "Y", "Y periph" },
|
||||
{ "P ram", "P ram", "P ext memory", "P ext memory" }
|
||||
};
|
||||
int idx, space;
|
||||
int space;
|
||||
|
||||
switch (space_id) {
|
||||
case 'X':
|
||||
space = DSP_SPACE_X;
|
||||
idx = 0;
|
||||
if (address >= DSP_PERIPH_BASE) {
|
||||
*mem_str = "X periph";
|
||||
} else {
|
||||
*mem_str = "X ram";
|
||||
}
|
||||
break;
|
||||
case 'Y':
|
||||
space = DSP_SPACE_Y;
|
||||
idx = 1;
|
||||
*mem_str = "Y ram";
|
||||
break;
|
||||
case 'P':
|
||||
space = DSP_SPACE_P;
|
||||
idx = 2;
|
||||
*mem_str = "P ram";
|
||||
break;
|
||||
default:
|
||||
space = DSP_SPACE_X;
|
||||
idx = 0;
|
||||
}
|
||||
address &= 0xFFFF;
|
||||
|
||||
/* Internal RAM ? */
|
||||
if (address < 0x100) {
|
||||
*mem_str = spaces[idx][0];
|
||||
return dsp_core.ramint[space][address];
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (space == DSP_SPACE_P) {
|
||||
/* Internal RAM ? */
|
||||
if (address < 0x200) {
|
||||
*mem_str = spaces[idx][0];
|
||||
return dsp_core.ramint[DSP_SPACE_P][address];
|
||||
}
|
||||
/* External RAM, mask address to available ram size */
|
||||
*mem_str = spaces[idx][2];
|
||||
return dsp_core.ramext[address & (DSP_RAMSIZE-1)];
|
||||
}
|
||||
|
||||
/* Internal ROM ? */
|
||||
if (address < 0x200) {
|
||||
if (dsp_core.registers[DSP_REG_OMR] & (1<<DSP_OMR_DE)) {
|
||||
*mem_str = spaces[idx][1];
|
||||
return dsp_core.rom[space][address];
|
||||
}
|
||||
}
|
||||
|
||||
/* Peripheral address ? */
|
||||
if (address >= 0xffc0) {
|
||||
*mem_str = spaces[idx][3];
|
||||
/* reading host/transmit regs has side-effects,
|
||||
* so just give the memory value.
|
||||
*/
|
||||
return dsp_core.periph[space][address-0xffc0];
|
||||
}
|
||||
|
||||
/* Falcon: External RAM, map X to upper 16K of matching space in Y,P */
|
||||
address &= (DSP_RAMSIZE>>1) - 1;
|
||||
if (space == DSP_SPACE_X) {
|
||||
address += DSP_RAMSIZE>>1;
|
||||
}
|
||||
|
||||
/* Falcon: External RAM, finally map X,Y to P */
|
||||
*mem_str = spaces[idx][2];
|
||||
return dsp_core.ramext[address & (DSP_RAMSIZE-1)];
|
||||
return dsp56k_read_memory(space, address);
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,39 +203,12 @@ uint32_t dsp_read_memory(uint16_t address, char space_id, const char **mem_str)
|
|||
* Output memory values between given addresses in given DSP address space.
|
||||
* Return next DSP address value.
|
||||
*/
|
||||
uint16_t dsp_disasm_memory(uint16_t dsp_memdump_addr, uint16_t dsp_memdump_upper, char space)
|
||||
uint32_t dsp_disasm_memory(uint32_t dsp_memdump_addr, uint32_t dsp_memdump_upper, char space)
|
||||
{
|
||||
uint32_t mem, mem2, value;
|
||||
uint32_t mem, value;
|
||||
const char *mem_str;
|
||||
|
||||
for (mem = dsp_memdump_addr; mem <= dsp_memdump_upper; mem++) {
|
||||
/* special printing of host communication/transmit registers */
|
||||
if (space == 'X' && mem >= 0xffc0) {
|
||||
if (mem == 0xffeb) {
|
||||
fprintf(stderr,"X periph:%04x HTX : %06x RTX:%06x\n",
|
||||
mem, dsp_core.dsp_host_htx, dsp_core.dsp_host_rtx);
|
||||
}
|
||||
else if (mem == 0xffef) {
|
||||
fprintf(stderr,"X periph:%04x SSI TX : %06x SSI RX:%06x\n",
|
||||
mem, dsp_core.ssi.transmit_value, dsp_core.ssi.received_value);
|
||||
}
|
||||
else {
|
||||
value = dsp_read_memory(mem, space, &mem_str);
|
||||
fprintf(stderr,"%s:%04x %06x\t%s\n", mem_str, mem, value, x_ext_memory_addr_name[mem-0xffc0]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* special printing of X & Y external RAM values */
|
||||
if ((space == 'X' || space == 'Y') &&
|
||||
mem >= 0x200 && mem < 0xffc0) {
|
||||
mem2 = mem & ((DSP_RAMSIZE>>1)-1);
|
||||
if (space == 'X') {
|
||||
mem2 += (DSP_RAMSIZE>>1);
|
||||
}
|
||||
fprintf(stderr,"%c:%04x (P:%04x): %06x\n", space,
|
||||
mem, mem2, dsp_core.ramext[mem2 & (DSP_RAMSIZE-1)]);
|
||||
continue;
|
||||
}
|
||||
value = dsp_read_memory(mem, space, &mem_str);
|
||||
fprintf(stderr,"%s:%04x %06x\n", mem_str, mem, value);
|
||||
}
|
||||
|
@ -303,14 +229,14 @@ void dsp_info(uint32_t dummy)
|
|||
for (i = 0; i < ARRAYSIZE(stackname); i++) {
|
||||
fprintf(stderr, "- %s stack:", stackname[i]);
|
||||
for (j = 0; j < ARRAYSIZE(dsp_core.stack[0]); j++) {
|
||||
fprintf(stderr, " %04hx", dsp_core.stack[i][j]);
|
||||
fprintf(stderr, " %04x", dsp_core.stack[i][j]);
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
fprintf(stderr, "- Interrupt IPL:");
|
||||
for (i = 0; i < ARRAYSIZE(dsp_core.interrupt_ipl); i++) {
|
||||
fprintf(stderr, " %04hx", dsp_core.interrupt_ipl[i]);
|
||||
fprintf(stderr, " %04x", dsp_core.interrupt_ipl[i]);
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
|
||||
|
@ -319,12 +245,6 @@ void dsp_info(uint32_t dummy)
|
|||
fprintf(stderr, " %04hx", dsp_core.interrupt_isPending[i]);
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
|
||||
fprintf(stderr, "- Hostport:");
|
||||
for (i = 0; i < ARRAYSIZE(dsp_core.hostport); i++) {
|
||||
fprintf(stderr, " %02x", dsp_core.hostport[i]);
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -413,7 +333,7 @@ int dsp_get_register_address(const char *regname, uint32_t **addr, uint32_t *mas
|
|||
{ "OMR", &dsp_core.registers[DSP_REG_OMR], 32, 0x5f },
|
||||
|
||||
/* 16-bit program counter */
|
||||
{ "PC", (uint32_t*)(&dsp_core.pc), 16, BITMASK(16) },
|
||||
{ "PC", (uint32_t*)(&dsp_core.pc), 24, BITMASK(24) },
|
||||
|
||||
/* 16-bit DSP R (address) registers */
|
||||
{ "R0", &dsp_core.registers[DSP_REG_R0], 32, BITMASK(16) },
|
||||
|
|
|
@ -34,12 +34,12 @@ void dsp_reset(void);
|
|||
void dsp_run(int nHostCycles);
|
||||
|
||||
/* Dsp Debugger commands */
|
||||
uint16_t dsp_get_pc(void);
|
||||
uint16_t dsp_get_next_pc(uint16_t pc);
|
||||
uint32_t dsp_get_pc(void);
|
||||
uint32_t dsp_get_next_pc(uint32_t pc);
|
||||
uint16_t dsp_get_instr_cycles(void);
|
||||
uint32_t dsp_read_memory(uint16_t addr, char space, const char **mem_str);
|
||||
uint16_t dsp_disasm_memory(uint16_t dsp_memdump_addr, uint16_t dsp_memdump_upper, char space);
|
||||
uint16_t dsp_disasm_address(FILE *out, uint16_t lowerAdr, uint16_t UpperAdr);
|
||||
uint32_t dsp_read_memory(uint32_t addr, char space, const char **mem_str);
|
||||
uint32_t dsp_disasm_memory(uint32_t dsp_memdump_addr, uint32_t dsp_memdump_upper, char space);
|
||||
uint32_t dsp_disasm_address(FILE *out, uint32_t lowerAdr, uint32_t UpperAdr);
|
||||
void dsp_info(uint32_t dummy);
|
||||
void dsp_print_registers(void);
|
||||
int dsp_get_register_address(const char *arg, uint32_t **addr, uint32_t *mask);
|
||||
|
|
|
@ -29,15 +29,9 @@
|
|||
|
||||
#include "dsp_core.h"
|
||||
|
||||
|
||||
|
||||
/*--- the DSP core itself ---*/
|
||||
dsp_core_t dsp_core;
|
||||
|
||||
/*--- Functions prototypes ---*/
|
||||
static void dsp_core_dsp2host(void);
|
||||
static void dsp_core_host2dsp(void);
|
||||
|
||||
static void (*dsp_host_interrupt)(void); /* Function to trigger host interrupt */
|
||||
|
||||
#define DPRINTF(s, ...) fprintf(stderr, s, ## __VA_ARGS__)
|
||||
|
@ -45,77 +39,10 @@ static void (*dsp_host_interrupt)(void); /* Function to trigger host interrupt
|
|||
/* Init DSP emulation */
|
||||
void dsp_core_init(void (*host_interrupt)(void))
|
||||
{
|
||||
int i;
|
||||
|
||||
DPRINTF("Dsp: core init\n");
|
||||
|
||||
dsp_host_interrupt = host_interrupt;
|
||||
memset(&dsp_core, 0, sizeof(dsp_core_t));
|
||||
|
||||
/* Initialize Y:rom[0x0100-0x01ff] with a sin table */
|
||||
for (i=0;i<256;i++) {
|
||||
float src = (((float) i)*M_PI)/128.0;
|
||||
int32_t dest = (int32_t) (sin(src) * 8388608.0); /* 1<<23 */
|
||||
if (dest>8388607) {
|
||||
dest = 8388607;
|
||||
} else if (dest<-8388608) {
|
||||
dest = -8388608;
|
||||
}
|
||||
dsp_core.rom[DSP_SPACE_Y][0x100+i]=dest & 0x00ffffff;
|
||||
}
|
||||
|
||||
/* Initialize X:rom[0x0100-0x017f] with a mu-law table */
|
||||
{
|
||||
const uint16_t mulaw_base[8]={
|
||||
0x7d7c, 0x3e7c, 0x1efc, 0x0f3c, 0x075c, 0x036c, 0x0174, 0x0078
|
||||
};
|
||||
|
||||
uint32_t position = 0x0100;
|
||||
uint32_t offset = 0x040000;
|
||||
|
||||
for(i=0;i<8;i++) {
|
||||
int j;
|
||||
uint32_t value = mulaw_base[i]<<8;
|
||||
|
||||
for (j=0;j<16;j++) {
|
||||
dsp_core.rom[DSP_SPACE_X][position++]=value;
|
||||
value -= offset;
|
||||
}
|
||||
|
||||
offset >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize X:rom[0x0180-0x01ff] with a a-law table */
|
||||
{
|
||||
const int32_t multiply_base[8]={
|
||||
0x1580, 0x0ac0, 0x5600, 0x2b00,
|
||||
0x1580, 0x0058, 0x0560, 0x02b0
|
||||
};
|
||||
const int32_t multiply_col[4]={0x10, 0x01, 0x04, 0x02};
|
||||
const int32_t multiply_line[4]={0x40, 0x04, 0x10, 0x08};
|
||||
const int32_t base_values[4]={0, -1, 2, 1};
|
||||
uint32_t pos=0x0180;
|
||||
|
||||
for (i=0;i<8;i++) {
|
||||
int32_t alawbase, j;
|
||||
|
||||
alawbase = multiply_base[i]<<8;
|
||||
for (j=0;j<4;j++) {
|
||||
int32_t alawbase1, k;
|
||||
|
||||
alawbase1 = alawbase + ((base_values[j]*multiply_line[i & 3])<<12);
|
||||
|
||||
for (k=0;k<4;k++) {
|
||||
int32_t alawbase2;
|
||||
|
||||
alawbase2 = alawbase1 + ((base_values[k]*multiply_col[i & 3])<<12);
|
||||
|
||||
dsp_core.rom[DSP_SPACE_X][pos++]=alawbase2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Shutdown DSP emulation */
|
||||
|
@ -134,13 +61,11 @@ void dsp_core_reset(void)
|
|||
dsp_core_shutdown();
|
||||
|
||||
/* Memory */
|
||||
memset((void*)dsp_core.periph, 0, sizeof(dsp_core.periph));
|
||||
memset(dsp_core.periph, 0, sizeof(dsp_core.periph));
|
||||
memset(dsp_core.stack, 0, sizeof(dsp_core.stack));
|
||||
memset(dsp_core.registers, 0, sizeof(dsp_core.registers));
|
||||
dsp_core.dsp_host_rtx = 0;
|
||||
dsp_core.dsp_host_htx = 0;
|
||||
|
||||
dsp_core.bootstrap_pos = 0;
|
||||
// dsp_core.dsp_host_rtx = 0;
|
||||
// dsp_core.dsp_host_htx = 0;
|
||||
|
||||
/* Registers */
|
||||
dsp_core.pc = 0x0000;
|
||||
|
@ -163,29 +88,9 @@ void dsp_core_reset(void)
|
|||
dsp_core.interrupt_ipl[i] = -1;
|
||||
}
|
||||
|
||||
/* host port init, dsp side */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR]=(1<<DSP_HOST_HSR_HTDE);
|
||||
|
||||
/* host port init, cpu side */
|
||||
dsp_core.hostport[CPU_HOST_ICR] = 0x0;
|
||||
dsp_core.hostport[CPU_HOST_CVR] = 0x12;
|
||||
dsp_core.hostport[CPU_HOST_ISR] = (1<<CPU_HOST_ISR_TRDY)|(1<<CPU_HOST_ISR_TXDE);
|
||||
dsp_core.hostport[CPU_HOST_IVR] = 0x0f;
|
||||
dsp_core.hostport[CPU_HOST_RX0] = 0x0;
|
||||
|
||||
/* SSI registers */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR]=1<<DSP_SSI_SR_TDE;
|
||||
dsp_core.ssi.waitFrameTX = 1;
|
||||
dsp_core.ssi.waitFrameRX = 1;
|
||||
dsp_core.ssi.TX = 0;
|
||||
dsp_core.ssi.RX = 0;
|
||||
dsp_core.ssi.dspPlay_handshakeMode_frame = 0;
|
||||
dsp_core_ssi_configure(DSP_SSI_CRA, 0);
|
||||
dsp_core_ssi_configure(DSP_SSI_CRB, 0);
|
||||
|
||||
/* Other hardware registers */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_IPR]=0;
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_BCR]=0xffff;
|
||||
// dsp_core.periph[DSP_SPACE_X][DSP_IPR]=0;
|
||||
// dsp_core.periph[DSP_SPACE_X][DSP_BCR]=0xffff;
|
||||
|
||||
/* Misc */
|
||||
dsp_core.loop_rep = 0;
|
||||
|
@ -194,502 +99,3 @@ void dsp_core_reset(void)
|
|||
dsp56k_init_cpu();
|
||||
}
|
||||
|
||||
/*
|
||||
SSI INTERFACE processing
|
||||
*/
|
||||
|
||||
/* Set PortC data register : send a frame order to the DMA in handshake mode */
|
||||
void dsp_core_setPortCDataRegister(uint32_t value)
|
||||
{
|
||||
/* if DSP Record is in handshake mode with DMA Play */
|
||||
if ((dsp_core.periph[DSP_SPACE_X][DSP_PCDDR] & 0x10) == 0x10) {
|
||||
if ((value & 0x10) == 0x10) {
|
||||
dsp_core.ssi.waitFrameRX = 0;
|
||||
// DSP_SsiTransmit_SC1();
|
||||
DPRINTF("Dsp record in handshake mode: SSI send SC1 to crossbar\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* if DSP Play is in handshake mode with DMA Record, high or low frame sync */
|
||||
/* to allow / disable transfer of the data */
|
||||
if ((dsp_core.periph[DSP_SPACE_X][DSP_PCDDR] & 0x20) == 0x20) {
|
||||
if ((value & 0x20) == 0x20) {
|
||||
dsp_core.ssi.dspPlay_handshakeMode_frame = 1;
|
||||
dsp_core.ssi.waitFrameTX = 0;
|
||||
DPRINTF("Dsp play in handshake mode: frame = 1\n");
|
||||
}
|
||||
else {
|
||||
dsp_core.ssi.dspPlay_handshakeMode_frame = 0;
|
||||
// DSP_SsiTransmit_SC2(0);
|
||||
DPRINTF("Dsp play in handshake mode: SSI send SC2 to crossbar, frame sync = 0\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SSI set TX register */
|
||||
void dsp_core_ssi_writeTX(uint32_t value)
|
||||
{
|
||||
/* Clear SSI TDE bit */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_TDE);
|
||||
dsp_core.ssi.TX = value;
|
||||
DPRINTF("Dsp set TX register: 0x%06x\n", value);
|
||||
|
||||
/* if DSP Play is in handshake mode with DMA Record, send frame sync */
|
||||
/* to allow transfer of the data */
|
||||
if (dsp_core.ssi.dspPlay_handshakeMode_frame) {
|
||||
// DSP_SsiTransmit_SC2(1);
|
||||
DPRINTF("Dsp play in handshake mode: SSI send SC2 to crossbar, frame sync = 1\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* SSI set TDE register (dummy write) */
|
||||
void dsp_core_ssi_writeTSR(void)
|
||||
{
|
||||
/* Dummy write : Just clear SSI TDE bit */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_TDE);
|
||||
}
|
||||
|
||||
/* SSI get RX register */
|
||||
uint32_t dsp_core_ssi_readRX(void)
|
||||
{
|
||||
/* Clear SSI RDF bit */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_RDF);
|
||||
DPRINTF("Dsp read RX register: 0x%06x\n", dsp_core.ssi.RX);
|
||||
return dsp_core.ssi.RX;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SSI receive serial clock.
|
||||
*
|
||||
*/
|
||||
void dsp_core_ssi_Receive_SC0(void)
|
||||
{
|
||||
uint32_t value, i, temp=0;
|
||||
|
||||
/* Receive data from crossbar to SSI */
|
||||
value = dsp_core.ssi.received_value;
|
||||
|
||||
/* adjust value to receive size word */
|
||||
value <<= (24 - dsp_core.ssi.cra_word_length);
|
||||
value &= 0xffffff;
|
||||
|
||||
/* if bit SHFD in CRB is set, swap received data */
|
||||
if (dsp_core.ssi.crb_shifter) {
|
||||
temp=0;
|
||||
for (i=0; i<dsp_core.ssi.cra_word_length; i++) {
|
||||
temp += value & 1;
|
||||
temp <<= 1;
|
||||
value >>= 1;
|
||||
}
|
||||
value = temp;
|
||||
}
|
||||
|
||||
DPRINTF("Dsp SSI received value from crossbar: 0x%06x\n", value);
|
||||
|
||||
if (dsp_core.ssi.crb_re && dsp_core.ssi.waitFrameRX == 0) {
|
||||
/* Send value to DSP receive */
|
||||
dsp_core.ssi.RX = value;
|
||||
|
||||
/* generate interrupt ? */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_RIE)) {
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] & (1<<DSP_SSI_SR_RDF)) {
|
||||
dsp_add_interrupt(DSP_INTER_SSI_RCV_DATA);
|
||||
} else {
|
||||
dsp_add_interrupt(DSP_INTER_SSI_RCV_DATA);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
dsp_core.ssi.RX = 0;
|
||||
}
|
||||
|
||||
/* set RDF */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= 1<<DSP_SSI_SR_RDF;
|
||||
}
|
||||
|
||||
/**
|
||||
* SSI receive SC1 bit : frame sync for receiver
|
||||
* value = 1 : beginning of a new frame
|
||||
* value = 0 : not beginning of a new frame
|
||||
*/
|
||||
void dsp_core_ssi_Receive_SC1(uint32_t value)
|
||||
{
|
||||
/* SSI runs in network mode ? */
|
||||
if (dsp_core.ssi.crb_mode) {
|
||||
if (value) {
|
||||
/* Beginning of a new frame */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_RFS);
|
||||
dsp_core.ssi.waitFrameRX = 0;
|
||||
}else{
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_RFS);
|
||||
}
|
||||
}else{
|
||||
/* SSI runs in normal mode */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_RFS);
|
||||
}
|
||||
|
||||
DPRINTF("Dsp SSI receive frame sync: 0x%01x\n", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* SSI receive SC2 bit : frame sync for transmitter
|
||||
* value = 1 : beginning of a new frame
|
||||
* value = 0 : not beginning of a new frame
|
||||
*/
|
||||
void dsp_core_ssi_Receive_SC2(uint32_t value)
|
||||
{
|
||||
/* SSI runs in network mode ? */
|
||||
if (dsp_core.ssi.crb_mode) {
|
||||
if (value) {
|
||||
/* Beginning of a new frame */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_TFS);
|
||||
dsp_core.ssi.waitFrameTX = 0;
|
||||
}else{
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_TFS);
|
||||
}
|
||||
}else{
|
||||
/* SSI runs in normal mode */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_TFS);
|
||||
}
|
||||
|
||||
DPRINTF("Dsp SSI transmit frame sync: 0x%01x\n", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* SSI transmit serial clock.
|
||||
*
|
||||
*/
|
||||
void dsp_core_ssi_Receive_SCK(void)
|
||||
{
|
||||
uint32_t value, i, temp=0;
|
||||
|
||||
value = dsp_core.ssi.TX;
|
||||
|
||||
/* Transfer data from SSI to crossbar*/
|
||||
|
||||
/* adjust value to transnmit size word */
|
||||
value >>= (24 - dsp_core.ssi.cra_word_length);
|
||||
value &= dsp_core.ssi.cra_word_mask;
|
||||
|
||||
/* if bit SHFD in CRB is set, swap data to transmit */
|
||||
if (dsp_core.ssi.crb_shifter) {
|
||||
for (i=0; i<dsp_core.ssi.cra_word_length; i++) {
|
||||
temp += value & 1;
|
||||
temp <<= 1;
|
||||
value >>= 1;
|
||||
}
|
||||
value = temp;
|
||||
}
|
||||
|
||||
DPRINTF("Dsp SSI transmit value to crossbar: 0x%06x\n", value);
|
||||
|
||||
/* Transmit the data */
|
||||
if (dsp_core.ssi.crb_te && dsp_core.ssi.waitFrameTX == 0) {
|
||||
/* Send value to crossbar */
|
||||
dsp_core.ssi.transmit_value = value;
|
||||
|
||||
/* generate interrupt ? */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_TIE)) {
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] & (1<<DSP_SSI_SR_TDE)) {
|
||||
dsp_add_interrupt(DSP_INTER_SSI_TRX_DATA);
|
||||
} else {
|
||||
dsp_add_interrupt(DSP_INTER_SSI_TRX_DATA);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
dsp_core.ssi.transmit_value = 0;
|
||||
}
|
||||
|
||||
/* set TDE */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_TDE);
|
||||
}
|
||||
|
||||
|
||||
/* SSI initialisations and state management */
|
||||
void dsp_core_ssi_configure(uint32_t address, uint32_t value)
|
||||
{
|
||||
uint32_t crb_te, crb_re;
|
||||
|
||||
switch (address) {
|
||||
case DSP_SSI_CRA:
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRA] = value;
|
||||
/* get word size for transfers */
|
||||
switch ((value>>DSP_SSI_CRA_WL0) & 3) {
|
||||
case 0:
|
||||
dsp_core.ssi.cra_word_length = 8;
|
||||
dsp_core.ssi.cra_word_mask = 0xff;
|
||||
break;
|
||||
case 1:
|
||||
dsp_core.ssi.cra_word_length = 12;
|
||||
dsp_core.ssi.cra_word_mask = 0xfff;
|
||||
break;
|
||||
case 2:
|
||||
dsp_core.ssi.cra_word_length = 16;
|
||||
dsp_core.ssi.cra_word_mask = 0xffff;
|
||||
break;
|
||||
case 3:
|
||||
dsp_core.ssi.cra_word_length = 24;
|
||||
dsp_core.ssi.cra_word_mask = 0xffffff;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINTF("Dsp SSI CRA write: 0x%06x\n", value);
|
||||
|
||||
/* Get the Frame rate divider ( 2 < value <32) */
|
||||
dsp_core.ssi.cra_frame_rate_divider = ((value >> DSP_SSI_CRA_DC0) & 0x1f)+1;
|
||||
break;
|
||||
case DSP_SSI_CRB:
|
||||
crb_te = dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_TE);
|
||||
crb_re = dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_RE);
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] = value;
|
||||
|
||||
dsp_core.ssi.crb_src_clock = (value>>DSP_SSI_CRB_SCKD) & 1;
|
||||
dsp_core.ssi.crb_shifter = (value>>DSP_SSI_CRB_SHFD) & 1;
|
||||
dsp_core.ssi.crb_synchro = (value>>DSP_SSI_CRB_SYN) & 1;
|
||||
dsp_core.ssi.crb_mode = (value>>DSP_SSI_CRB_MOD) & 1;
|
||||
dsp_core.ssi.crb_te = (value>>DSP_SSI_CRB_TE) & 1;
|
||||
dsp_core.ssi.crb_re = (value>>DSP_SSI_CRB_RE) & 1;
|
||||
dsp_core.ssi.crb_tie = (value>>DSP_SSI_CRB_TIE) & 1;
|
||||
dsp_core.ssi.crb_rie = (value>>DSP_SSI_CRB_RIE) & 1;
|
||||
|
||||
if (crb_te == 0 && dsp_core.ssi.crb_te) {
|
||||
dsp_core.ssi.waitFrameTX = 1;
|
||||
}
|
||||
if (crb_re == 0 && dsp_core.ssi.crb_re) {
|
||||
dsp_core.ssi.waitFrameRX = 1;
|
||||
}
|
||||
|
||||
DPRINTF("Dsp SSI CRB write: 0x%06x\n", value);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
HOST INTERFACE processing
|
||||
*/
|
||||
|
||||
static void dsp_core_hostport_update_trdy(void)
|
||||
{
|
||||
int trdy;
|
||||
|
||||
/* Clear/set TRDY bit */
|
||||
dsp_core.hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_TRDY);
|
||||
trdy = (dsp_core.hostport[CPU_HOST_ISR]>>CPU_HOST_ISR_TXDE)
|
||||
& ~(dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR]>>DSP_HOST_HSR_HRDF);
|
||||
dsp_core.hostport[CPU_HOST_ISR] |= (trdy & 1)<< CPU_HOST_ISR_TRDY;
|
||||
}
|
||||
|
||||
static void dsp_core_hostport_update_hreq(void)
|
||||
{
|
||||
int hreq;
|
||||
|
||||
hreq = (dsp_core.hostport[CPU_HOST_ICR] & dsp_core.hostport[CPU_HOST_ISR]) & 0x3;
|
||||
|
||||
/* Trigger host interrupt? */
|
||||
if (hreq && (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_HREQ)) == 0) {
|
||||
dsp_host_interrupt();
|
||||
}
|
||||
|
||||
/* Set HREQ bit in hostport */
|
||||
dsp_core.hostport[CPU_HOST_ISR] &= 0x7f;
|
||||
dsp_core.hostport[CPU_HOST_ISR] |= (hreq?1:0) << CPU_HOST_ISR_HREQ;
|
||||
}
|
||||
|
||||
/* Host port transfer ? (dsp->host) */
|
||||
static void dsp_core_dsp2host(void)
|
||||
{
|
||||
/* RXDF = 1 ==> host hasn't read the last value yet */
|
||||
if (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_RXDF)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* HTDE = 1 ==> nothing to tranfert from DSP port */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HTDE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dsp_core.hostport[CPU_HOST_RXL] = dsp_core.dsp_host_htx;
|
||||
dsp_core.hostport[CPU_HOST_RXM] = dsp_core.dsp_host_htx>>8;
|
||||
dsp_core.hostport[CPU_HOST_RXH] = dsp_core.dsp_host_htx>>16;
|
||||
|
||||
/* Set HTDE bit to say that DSP can write */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HTDE;
|
||||
|
||||
/* Is there an interrupt to send ? */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HTIE)) {
|
||||
dsp_add_interrupt(DSP_INTER_HOST_TRX_DATA);
|
||||
}
|
||||
|
||||
/* Set RXDF bit to say that host can read */
|
||||
dsp_core.hostport[CPU_HOST_ISR] |= 1<<CPU_HOST_ISR_RXDF;
|
||||
dsp_core_hostport_update_hreq();
|
||||
|
||||
DPRINTF("Dsp: (DSP->Host): Transfer 0x%06x, Dsp HTDE=1, Host RXDF=1\n", dsp_core.dsp_host_htx);
|
||||
}
|
||||
|
||||
/* Host port transfer ? (host->dsp) */
|
||||
static void dsp_core_host2dsp(void)
|
||||
{
|
||||
/* TXDE = 1 ==> nothing to tranfert from host port */
|
||||
if (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_TXDE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* HRDF = 1 ==> DSP hasn't read the last value yet */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HRDF)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dsp_core.dsp_host_rtx = dsp_core.hostport[CPU_HOST_TXL];
|
||||
dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXM]<<8;
|
||||
dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXH]<<16;
|
||||
|
||||
/* Set HRDF bit to say that DSP can read */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HRDF;
|
||||
|
||||
/* Is there an interrupt to send ? */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HRIE)) {
|
||||
dsp_add_interrupt(DSP_INTER_HOST_RCV_DATA);
|
||||
}
|
||||
|
||||
/* Set TXDE bit to say that host can write */
|
||||
dsp_core.hostport[CPU_HOST_ISR] |= 1<<CPU_HOST_ISR_TXDE;
|
||||
dsp_core_hostport_update_hreq();
|
||||
|
||||
DPRINTF("Dsp: (Host->DSP): Transfer 0x%06x, Dsp HRDF=1, Host TXDE=1\n", dsp_core.dsp_host_rtx);
|
||||
|
||||
dsp_core_hostport_update_trdy();
|
||||
}
|
||||
|
||||
void dsp_core_hostport_dspread(void)
|
||||
{
|
||||
/* Clear HRDF bit to say that DSP has read */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff-(1<<DSP_HOST_HSR_HRDF);
|
||||
|
||||
DPRINTF("Dsp: (Host->DSP): Dsp HRDF cleared\n");
|
||||
|
||||
dsp_core_hostport_update_trdy();
|
||||
dsp_core_host2dsp();
|
||||
}
|
||||
|
||||
void dsp_core_hostport_dspwrite(void)
|
||||
{
|
||||
/* Clear HTDE bit to say that DSP has written */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff-(1<<DSP_HOST_HSR_HTDE);
|
||||
|
||||
DPRINTF("Dsp: (DSP->Host): Dsp HTDE cleared\n");
|
||||
|
||||
dsp_core_dsp2host();
|
||||
}
|
||||
|
||||
/* Read/writes on host port */
|
||||
uint8_t dsp_core_read_host(int addr)
|
||||
{
|
||||
uint8_t value;
|
||||
|
||||
value = dsp_core.hostport[addr];
|
||||
if (addr == CPU_HOST_TRXL) {
|
||||
/* Clear RXDF bit to say that CPU has read */
|
||||
dsp_core.hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_RXDF);
|
||||
dsp_core_dsp2host();
|
||||
dsp_core_hostport_update_hreq();
|
||||
|
||||
DPRINTF("Dsp: (DSP->Host): Host RXDF=0\n");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void dsp_core_write_host(int addr, uint8_t value)
|
||||
{
|
||||
switch(addr) {
|
||||
case CPU_HOST_ICR:
|
||||
dsp_core.hostport[CPU_HOST_ICR]=value & 0xfb;
|
||||
/* Set HF1 and HF0 accordingly on the host side */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &=
|
||||
0xff-((1<<DSP_HOST_HSR_HF1)|(1<<DSP_HOST_HSR_HF0));
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |=
|
||||
dsp_core.hostport[CPU_HOST_ICR] & ((1<<DSP_HOST_HSR_HF1)|(1<<DSP_HOST_HSR_HF0));
|
||||
dsp_core_hostport_update_hreq();
|
||||
break;
|
||||
case CPU_HOST_CVR:
|
||||
dsp_core.hostport[CPU_HOST_CVR]=value & 0x9f;
|
||||
/* if bit 7=1, host command . HSR(bit HCP) is set*/
|
||||
if (value & (1<<7)) {
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= (1<<DSP_HOST_HSR_HCP);
|
||||
/* Is there an interrupt to send ? */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HCIE)) {
|
||||
dsp_add_interrupt(DSP_INTER_HOST_COMMAND);
|
||||
}
|
||||
}
|
||||
else{
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff - (1<<DSP_HOST_HSR_HCP);
|
||||
}
|
||||
|
||||
DPRINTF("Dsp: (Host->DSP): Host command = %06x\n", value & 0x9f);
|
||||
|
||||
break;
|
||||
case CPU_HOST_ISR:
|
||||
case CPU_HOST_TRX0:
|
||||
/* Read only */
|
||||
break;
|
||||
case CPU_HOST_IVR:
|
||||
dsp_core.hostport[CPU_HOST_IVR]=value;
|
||||
break;
|
||||
case CPU_HOST_TRXH:
|
||||
dsp_core.hostport[CPU_HOST_TXH]=value;
|
||||
break;
|
||||
case CPU_HOST_TRXM:
|
||||
dsp_core.hostport[CPU_HOST_TXM]=value;
|
||||
break;
|
||||
case CPU_HOST_TRXL:
|
||||
dsp_core.hostport[CPU_HOST_TXL]=value;
|
||||
|
||||
if (!dsp_core.running) {
|
||||
dsp_core.ramint[DSP_SPACE_P][dsp_core.bootstrap_pos] =
|
||||
(dsp_core.hostport[CPU_HOST_TXH]<<16) |
|
||||
(dsp_core.hostport[CPU_HOST_TXM]<<8) |
|
||||
dsp_core.hostport[CPU_HOST_TXL];
|
||||
|
||||
DPRINTF("Dsp: bootstrap p:0x%04x = 0x%06x\n",
|
||||
dsp_core.bootstrap_pos,
|
||||
dsp_core.ramint[DSP_SPACE_P][dsp_core.bootstrap_pos]);
|
||||
|
||||
if (++dsp_core.bootstrap_pos == 0x200) {
|
||||
DPRINTF("Dsp: wait bootstrap done\n");
|
||||
dsp_core.running = 1;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* If TRDY is set, the tranfert is direct to DSP (Burst mode) */
|
||||
if (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_TRDY)){
|
||||
dsp_core.dsp_host_rtx = dsp_core.hostport[CPU_HOST_TXL];
|
||||
dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXM]<<8;
|
||||
dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXH]<<16;
|
||||
|
||||
DPRINTF("Dsp: (Host->DSP): Direct Transfer 0x%06x\n", dsp_core.dsp_host_rtx);
|
||||
|
||||
/* Set HRDF bit to say that DSP can read */
|
||||
dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HRDF;
|
||||
|
||||
/* Is there an interrupt to send ? */
|
||||
if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HRIE)) {
|
||||
dsp_add_interrupt(DSP_INTER_HOST_RCV_DATA);
|
||||
}
|
||||
|
||||
DPRINTF("Dsp: (Host->DSP): Dsp HRDF set\n");
|
||||
}
|
||||
else{
|
||||
/* Clear TXDE to say that CPU has written */
|
||||
dsp_core.hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_TXDE);
|
||||
dsp_core_hostport_update_hreq();
|
||||
|
||||
DPRINTF("Dsp: (Host->DSP): Host TXDE cleared\n");
|
||||
}
|
||||
dsp_core_hostport_update_trdy();
|
||||
dsp_core_host2dsp();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,109 +24,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DSP_RAMSIZE 32768
|
||||
|
||||
/* Host port, CPU side */
|
||||
#define CPU_HOST_ICR 0x00
|
||||
#define CPU_HOST_CVR 0x01
|
||||
#define CPU_HOST_ISR 0x02
|
||||
#define CPU_HOST_IVR 0x03
|
||||
#define CPU_HOST_TRX0 0x04
|
||||
#define CPU_HOST_TRXH 0x05
|
||||
#define CPU_HOST_TRXM 0x06
|
||||
#define CPU_HOST_TRXL 0x07
|
||||
#define CPU_HOST_RX0 0x04
|
||||
#define CPU_HOST_RXH 0x05
|
||||
#define CPU_HOST_RXM 0x06
|
||||
#define CPU_HOST_RXL 0x07
|
||||
#define CPU_HOST_TXH 0x09
|
||||
#define CPU_HOST_TXM 0x0a
|
||||
#define CPU_HOST_TXL 0x0b
|
||||
|
||||
#define CPU_HOST_ICR_RREQ 0x00
|
||||
#define CPU_HOST_ICR_TREQ 0x01
|
||||
#define CPU_HOST_ICR_HF0 0x03
|
||||
#define CPU_HOST_ICR_HF1 0x04
|
||||
#define CPU_HOST_ICR_HM0 0x05
|
||||
#define CPU_HOST_ICR_HM1 0x06
|
||||
#define CPU_HOST_ICR_INIT 0x07
|
||||
|
||||
#define CPU_HOST_CVR_HC 0x07
|
||||
|
||||
#define CPU_HOST_ISR_RXDF 0x00
|
||||
#define CPU_HOST_ISR_TXDE 0x01
|
||||
#define CPU_HOST_ISR_TRDY 0x02
|
||||
#define CPU_HOST_ISR_HF2 0x03
|
||||
#define CPU_HOST_ISR_HF3 0x04
|
||||
#define CPU_HOST_ISR_DMA 0x06
|
||||
#define CPU_HOST_ISR_HREQ 0x07
|
||||
|
||||
/* Host port, DSP side, DSP addresses are 0xffc0+value */
|
||||
#define DSP_PBC 0x20 /* Port B control register */
|
||||
#define DSP_PCC 0x21 /* Port C control register */
|
||||
#define DSP_PBDDR 0x22 /* Port B data direction register */
|
||||
#define DSP_PCDDR 0x23 /* Port C data direction register */
|
||||
#define DSP_PBD 0x24 /* Port B data register */
|
||||
#define DSP_PCD 0x25 /* Port C data register */
|
||||
#define DSP_HOST_HCR 0x28 /* Host control register */
|
||||
#define DSP_HOST_HSR 0x29 /* Host status register */
|
||||
#define DSP_HOST_HRX 0x2b /* Host receive register */
|
||||
#define DSP_HOST_HTX 0x2b /* Host transmit register */
|
||||
#define DSP_SSI_CRA 0x2c /* Ssi control register A */
|
||||
#define DSP_SSI_CRB 0x2d /* Ssi control register B */
|
||||
#define DSP_SSI_SR 0x2e /* Ssi status register */
|
||||
#define DSP_SSI_TSR 0x2e /* Ssi time slot register */
|
||||
#define DSP_SSI_RX 0x2f /* Ssi receive register */
|
||||
#define DSP_SSI_TX 0x2f /* Ssi transmit register */
|
||||
#define DSP_BCR 0x3e /* Port A bus control register */
|
||||
#define DSP_IPR 0x3f /* Interrupt priority register */
|
||||
|
||||
#define DSP_HOST_HCR_HRIE 0x00
|
||||
#define DSP_HOST_HCR_HTIE 0x01
|
||||
#define DSP_HOST_HCR_HCIE 0x02
|
||||
#define DSP_HOST_HCR_HF2 0x03
|
||||
#define DSP_HOST_HCR_HF3 0x04
|
||||
|
||||
#define DSP_HOST_HSR_HRDF 0x00
|
||||
#define DSP_HOST_HSR_HTDE 0x01
|
||||
#define DSP_HOST_HSR_HCP 0x02
|
||||
#define DSP_HOST_HSR_HF0 0x03
|
||||
#define DSP_HOST_HSR_HF1 0x04
|
||||
#define DSP_HOST_HSR_DMA 0x07
|
||||
|
||||
#define DSP_SSI_CRA_DC0 0x8
|
||||
#define DSP_SSI_CRA_DC1 0x9
|
||||
#define DSP_SSI_CRA_DC2 0xa
|
||||
#define DSP_SSI_CRA_DC3 0xb
|
||||
#define DSP_SSI_CRA_DC4 0xc
|
||||
#define DSP_SSI_CRA_WL0 0xd
|
||||
#define DSP_SSI_CRA_WL1 0xe
|
||||
|
||||
#define DSP_SSI_CRB_OF0 0x0
|
||||
#define DSP_SSI_CRB_OF1 0x1
|
||||
#define DSP_SSI_CRB_SCD0 0x2
|
||||
#define DSP_SSI_CRB_SCD1 0x3
|
||||
#define DSP_SSI_CRB_SCD2 0x4
|
||||
#define DSP_SSI_CRB_SCKD 0x5
|
||||
#define DSP_SSI_CRB_SHFD 0x6
|
||||
#define DSP_SSI_CRB_FSL0 0x7
|
||||
#define DSP_SSI_CRB_FSL1 0x8
|
||||
#define DSP_SSI_CRB_SYN 0x9
|
||||
#define DSP_SSI_CRB_GCK 0xa
|
||||
#define DSP_SSI_CRB_MOD 0xb
|
||||
#define DSP_SSI_CRB_TE 0xc
|
||||
#define DSP_SSI_CRB_RE 0xd
|
||||
#define DSP_SSI_CRB_TIE 0xe
|
||||
#define DSP_SSI_CRB_RIE 0xf
|
||||
|
||||
#define DSP_SSI_SR_IF0 0x0
|
||||
#define DSP_SSI_SR_IF1 0x1
|
||||
#define DSP_SSI_SR_TFS 0x2
|
||||
#define DSP_SSI_SR_RFS 0x3
|
||||
#define DSP_SSI_SR_TUE 0x4
|
||||
#define DSP_SSI_SR_ROE 0x5
|
||||
#define DSP_SSI_SR_TDE 0x6
|
||||
#define DSP_SSI_SR_RDF 0x7
|
||||
#include "dsp_cpu.h"
|
||||
|
||||
#define DSP_INTERRUPT_NONE 0x0
|
||||
#define DSP_INTERRUPT_DISABLED 0x1
|
||||
|
@ -146,33 +44,9 @@
|
|||
#define DSP_INTER_SSI_TRX_DATA 0xb
|
||||
|
||||
|
||||
typedef struct dsp_core_ssi_s dsp_core_ssi_t;
|
||||
typedef struct dsp_core_s dsp_core_t;
|
||||
typedef struct dsp_interrupt_s dsp_interrupt_t;
|
||||
|
||||
struct dsp_core_ssi_s {
|
||||
uint16_t cra_word_length;
|
||||
uint32_t cra_word_mask;
|
||||
uint16_t cra_frame_rate_divider;
|
||||
|
||||
uint16_t crb_src_clock;
|
||||
uint16_t crb_shifter;
|
||||
uint16_t crb_synchro;
|
||||
uint16_t crb_mode;
|
||||
uint16_t crb_te;
|
||||
uint16_t crb_re;
|
||||
uint16_t crb_tie;
|
||||
uint16_t crb_rie;
|
||||
|
||||
uint32_t TX;
|
||||
uint32_t RX;
|
||||
uint32_t transmit_value; /* DSP Transmit --> SSI */
|
||||
uint32_t received_value; /* DSP Receive --> SSI */
|
||||
uint16_t waitFrameTX;
|
||||
uint16_t waitFrameRX;
|
||||
uint32_t dspPlay_handshakeMode_frame;
|
||||
};
|
||||
|
||||
struct dsp_interrupt_s {
|
||||
const uint16_t inter;
|
||||
const uint16_t vectorAddr;
|
||||
|
@ -180,7 +54,6 @@ struct dsp_interrupt_s {
|
|||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
struct dsp_core_s {
|
||||
|
||||
/* DSP executing instructions ? */
|
||||
|
@ -190,41 +63,23 @@ struct dsp_core_s {
|
|||
uint16_t instr_cycle;
|
||||
|
||||
/* Registers */
|
||||
uint16_t pc;
|
||||
uint32_t registers[64];
|
||||
uint32_t pc;
|
||||
uint32_t registers[DSP_REG_MAX];
|
||||
|
||||
/* stack[0=ssh], stack[1=ssl] */
|
||||
uint16_t stack[2][16];
|
||||
uint32_t stack[2][16];
|
||||
|
||||
/* External ram[] (mapped to p:) */
|
||||
uint32_t ramext[DSP_RAMSIZE];
|
||||
uint32_t xram[DSP_XRAM_SIZE];
|
||||
uint32_t yram[DSP_YRAM_SIZE];
|
||||
uint32_t pram[DSP_PRAM_SIZE];
|
||||
|
||||
/* rom[0] is x:, rom[1] is y: */
|
||||
uint32_t rom[2][512];
|
||||
|
||||
/* Internal ram[0] is x:, ram[1] is y:, ram[2] is p: */
|
||||
uint32_t ramint[3][512];
|
||||
|
||||
/* peripheral space, [x|y]:0xffc0-0xffff */
|
||||
uint32_t periph[2][64];
|
||||
uint32_t dsp_host_htx;
|
||||
uint32_t dsp_host_rtx;
|
||||
uint16_t dsp_host_isr_HREQ;
|
||||
|
||||
|
||||
/* host port, CPU side */
|
||||
uint8_t hostport[12];
|
||||
|
||||
/* SSI */
|
||||
dsp_core_ssi_t ssi;
|
||||
/* peripheral space, x:0xffff80-0xffffff */
|
||||
uint32_t periph[DSP_PERIPH_SIZE];
|
||||
|
||||
/* Misc */
|
||||
uint32_t loop_rep; /* executing rep ? */
|
||||
uint32_t pc_on_rep; /* True if PC is on REP instruction */
|
||||
|
||||
/* For bootstrap routine */
|
||||
uint16_t bootstrap_pos;
|
||||
|
||||
/* Interruptions */
|
||||
uint16_t interrupt_state; /* NONE, FAST or LONG interrupt */
|
||||
uint16_t interrupt_instr_fetch; /* vector of the current interrupt */
|
||||
|
@ -245,23 +100,4 @@ void dsp_core_init(void (*host_interrupt)(void));
|
|||
void dsp_core_shutdown(void);
|
||||
void dsp_core_reset(void);
|
||||
|
||||
/* host port read/write by emulator, addr is 0-7, not 0xffa200-0xffa207 */
|
||||
uint8_t dsp_core_read_host(int addr);
|
||||
void dsp_core_write_host(int addr, uint8_t value);
|
||||
|
||||
/* dsp_cpu call these to read/write host port */
|
||||
void dsp_core_hostport_dspread(void);
|
||||
void dsp_core_hostport_dspwrite(void);
|
||||
|
||||
/* dsp_cpu call these to read/write/configure SSI port */
|
||||
void dsp_core_ssi_configure(uint32_t address, uint32_t value);
|
||||
void dsp_core_ssi_writeTX(uint32_t value);
|
||||
void dsp_core_ssi_writeTSR(void);
|
||||
uint32_t dsp_core_ssi_readRX(void);
|
||||
void dsp_core_ssi_Receive_SC0(void);
|
||||
void dsp_core_ssi_Receive_SC1(uint32_t value);
|
||||
void dsp_core_ssi_Receive_SC2(uint32_t value);
|
||||
void dsp_core_ssi_Receive_SCK(void);
|
||||
void dsp_core_setPortCDataRegister(uint32_t value);
|
||||
|
||||
#endif /* DSP_CORE_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,96 +25,105 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Defines */
|
||||
#define BITMASK(x) ((1<<(x))-1)
|
||||
#define DSP_OMR_MA 0x00
|
||||
#define DSP_OMR_MB 0x01
|
||||
#define DSP_OMR_DE 0x02
|
||||
#define DSP_OMR_SD 0x06
|
||||
#define DSP_OMR_EA 0x07
|
||||
|
||||
#define DSP_OMR_MA 0x00
|
||||
#define DSP_OMR_MB 0x01
|
||||
#define DSP_OMR_DE 0x02
|
||||
#define DSP_OMR_SD 0x06
|
||||
#define DSP_OMR_EA 0x07
|
||||
#define DSP_SR_C 0x00
|
||||
#define DSP_SR_V 0x01
|
||||
#define DSP_SR_Z 0x02
|
||||
#define DSP_SR_N 0x03
|
||||
#define DSP_SR_U 0x04
|
||||
#define DSP_SR_E 0x05
|
||||
#define DSP_SR_L 0x06
|
||||
|
||||
#define DSP_SR_C 0x00
|
||||
#define DSP_SR_V 0x01
|
||||
#define DSP_SR_Z 0x02
|
||||
#define DSP_SR_N 0x03
|
||||
#define DSP_SR_U 0x04
|
||||
#define DSP_SR_E 0x05
|
||||
#define DSP_SR_L 0x06
|
||||
#define DSP_SR_I0 0x08
|
||||
#define DSP_SR_I1 0x09
|
||||
#define DSP_SR_S0 0x0a
|
||||
#define DSP_SR_S1 0x0b
|
||||
#define DSP_SR_T 0x0d
|
||||
#define DSP_SR_LF 0x0f
|
||||
|
||||
#define DSP_SR_I0 0x08
|
||||
#define DSP_SR_I1 0x09
|
||||
#define DSP_SR_S0 0x0a
|
||||
#define DSP_SR_S1 0x0b
|
||||
#define DSP_SR_T 0x0d
|
||||
#define DSP_SR_LF 0x0f
|
||||
|
||||
#define DSP_SP_SE 0x04
|
||||
#define DSP_SP_UF 0x05
|
||||
#define DSP_SP_SE 0x04
|
||||
#define DSP_SP_UF 0x05
|
||||
|
||||
/* Registers numbers in dsp.registers[] */
|
||||
#define DSP_REG_X0 0x04
|
||||
#define DSP_REG_X1 0x05
|
||||
#define DSP_REG_Y0 0x06
|
||||
#define DSP_REG_Y1 0x07
|
||||
#define DSP_REG_A0 0x08
|
||||
#define DSP_REG_B0 0x09
|
||||
#define DSP_REG_A2 0x0a
|
||||
#define DSP_REG_B2 0x0b
|
||||
#define DSP_REG_A1 0x0c
|
||||
#define DSP_REG_B1 0x0d
|
||||
#define DSP_REG_A 0x0e
|
||||
#define DSP_REG_B 0x0f
|
||||
#define DSP_REG_X0 0x04
|
||||
#define DSP_REG_X1 0x05
|
||||
#define DSP_REG_Y0 0x06
|
||||
#define DSP_REG_Y1 0x07
|
||||
#define DSP_REG_A0 0x08
|
||||
#define DSP_REG_B0 0x09
|
||||
#define DSP_REG_A2 0x0a
|
||||
#define DSP_REG_B2 0x0b
|
||||
#define DSP_REG_A1 0x0c
|
||||
#define DSP_REG_B1 0x0d
|
||||
#define DSP_REG_A 0x0e
|
||||
#define DSP_REG_B 0x0f
|
||||
|
||||
#define DSP_REG_R0 0x10
|
||||
#define DSP_REG_R1 0x11
|
||||
#define DSP_REG_R2 0x12
|
||||
#define DSP_REG_R3 0x13
|
||||
#define DSP_REG_R4 0x14
|
||||
#define DSP_REG_R5 0x15
|
||||
#define DSP_REG_R6 0x16
|
||||
#define DSP_REG_R7 0x17
|
||||
#define DSP_REG_R0 0x10
|
||||
#define DSP_REG_R1 0x11
|
||||
#define DSP_REG_R2 0x12
|
||||
#define DSP_REG_R3 0x13
|
||||
#define DSP_REG_R4 0x14
|
||||
#define DSP_REG_R5 0x15
|
||||
#define DSP_REG_R6 0x16
|
||||
#define DSP_REG_R7 0x17
|
||||
|
||||
#define DSP_REG_N0 0x18
|
||||
#define DSP_REG_N1 0x19
|
||||
#define DSP_REG_N2 0x1a
|
||||
#define DSP_REG_N3 0x1b
|
||||
#define DSP_REG_N4 0x1c
|
||||
#define DSP_REG_N5 0x1d
|
||||
#define DSP_REG_N6 0x1e
|
||||
#define DSP_REG_N7 0x1f
|
||||
#define DSP_REG_N0 0x18
|
||||
#define DSP_REG_N1 0x19
|
||||
#define DSP_REG_N2 0x1a
|
||||
#define DSP_REG_N3 0x1b
|
||||
#define DSP_REG_N4 0x1c
|
||||
#define DSP_REG_N5 0x1d
|
||||
#define DSP_REG_N6 0x1e
|
||||
#define DSP_REG_N7 0x1f
|
||||
|
||||
#define DSP_REG_M0 0x20
|
||||
#define DSP_REG_M1 0x21
|
||||
#define DSP_REG_M2 0x22
|
||||
#define DSP_REG_M3 0x23
|
||||
#define DSP_REG_M4 0x24
|
||||
#define DSP_REG_M5 0x25
|
||||
#define DSP_REG_M6 0x26
|
||||
#define DSP_REG_M7 0x27
|
||||
#define DSP_REG_M0 0x20
|
||||
#define DSP_REG_M1 0x21
|
||||
#define DSP_REG_M2 0x22
|
||||
#define DSP_REG_M3 0x23
|
||||
#define DSP_REG_M4 0x24
|
||||
#define DSP_REG_M5 0x25
|
||||
#define DSP_REG_M6 0x26
|
||||
#define DSP_REG_M7 0x27
|
||||
|
||||
#define DSP_REG_SR 0x39
|
||||
#define DSP_REG_OMR 0x3a
|
||||
#define DSP_REG_SP 0x3b
|
||||
#define DSP_REG_SSH 0x3c
|
||||
#define DSP_REG_SSL 0x3d
|
||||
#define DSP_REG_LA 0x3e
|
||||
#define DSP_REG_LC 0x3f
|
||||
#define DSP_REG_SR 0x39
|
||||
#define DSP_REG_OMR 0x3a
|
||||
#define DSP_REG_SP 0x3b
|
||||
#define DSP_REG_SSH 0x3c
|
||||
#define DSP_REG_SSL 0x3d
|
||||
#define DSP_REG_LA 0x3e
|
||||
#define DSP_REG_LC 0x3f
|
||||
|
||||
#define DSP_REG_NULL 0x00
|
||||
#define DSP_REG_LCSAVE 0x30
|
||||
#define DSP_REG_NULL 0x00
|
||||
#define DSP_REG_LCSAVE 0x30
|
||||
|
||||
#define DSP_REG_MAX 0x40
|
||||
|
||||
/* Memory spaces for dsp.ram[], dsp.rom[] */
|
||||
#define DSP_SPACE_X 0x00
|
||||
#define DSP_SPACE_Y 0x01
|
||||
#define DSP_SPACE_P 0x02
|
||||
#define DSP_SPACE_X 0x00
|
||||
#define DSP_SPACE_Y 0x01
|
||||
#define DSP_SPACE_P 0x02
|
||||
|
||||
#define DSP_XRAM_SIZE 4096
|
||||
#define DSP_YRAM_SIZE 2048
|
||||
#define DSP_PRAM_SIZE 4096
|
||||
|
||||
#define DSP_PERIPH_BASE 0xFFFF80
|
||||
#define DSP_PERIPH_SIZE 128
|
||||
|
||||
/* Functions */
|
||||
void dsp56k_init_cpu(void); /* Set dsp_core to use */
|
||||
void dsp56k_execute_instruction(void); /* Execute 1 instruction */
|
||||
uint16_t dsp56k_execute_one_disasm_instruction(FILE *out, uint16_t pc); /* Execute 1 instruction in disasm mode */
|
||||
uint16_t dsp56k_execute_one_disasm_instruction(FILE *out, uint32_t pc); /* Execute 1 instruction in disasm mode */
|
||||
|
||||
uint32_t dsp56k_read_memory(int space, uint32_t address);
|
||||
void dsp56k_write_memory(int space, uint32_t address, uint32_t value);
|
||||
|
||||
/* Interrupt relative functions */
|
||||
void dsp_add_interrupt(uint16_t inter);
|
||||
void dsp56k_add_interrupt(uint16_t inter);
|
||||
|
||||
#endif /* DSP_CPU_H */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
/**********************************
|
||||
* Defines
|
||||
**********************************/
|
||||
#define BITMASK(x) ((1<<(x))-1)
|
||||
|
||||
/**********************************
|
||||
* Variables
|
||||
|
@ -565,15 +566,7 @@ static void dsp_pm_class2(void) {
|
|||
|
||||
static uint32_t read_memory(uint32_t currPc)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
if (currPc<0x200) {
|
||||
value = dsp_core.ramint[DSP_SPACE_P][currPc];
|
||||
} else {
|
||||
value = dsp_core.ramext[currPc & (DSP_RAMSIZE-1)];
|
||||
}
|
||||
|
||||
return value & BITMASK(24);
|
||||
return dsp56k_read_memory(DSP_SPACE_P, currPc);
|
||||
}
|
||||
|
||||
/**********************************
|
||||
|
|
Loading…
Reference in New Issue