Annotation of hatari/src/falcon/dsp_core.c, revision 1.1.1.8

1.1       root        1: /*
                      2:        DSP M56001 emulation
                      3:        Host/Emulator <-> DSP glue
                      4: 
                      5:        (C) 2003-2008 ARAnyM developer team
                      6: 
                      7:        This program is free software; you can redistribute it and/or modify
                      8:        it under the terms of the GNU General Public License as published by
                      9:        the Free Software Foundation; either version 2 of the License, or
                     10:        (at your option) any later version.
                     11: 
                     12:        This program is distributed in the hope that it will be useful,
                     13:        but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:        GNU General Public License for more details.
                     16: 
                     17:        You should have received a copy of the GNU General Public License
                     18:        along with this program; if not, write to the Free Software
                     19:        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     20: */
                     21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: #include "config.h"
                     24: #endif
                     25: 
1.1.1.7   root       26: #include <stdio.h>
1.1       root       27: #include <string.h>
1.1.1.4   root       28: #include <math.h>
1.1       root       29: 
                     30: #include "dsp_core.h"
                     31: #include "dsp_cpu.h"
1.1.1.3   root       32: #include "ioMem.h"
                     33: #include "dsp.h"
1.1.1.4   root       34: #include "log.h"
1.1.1.3   root       35: 
1.1.1.4   root       36: /*--- the DSP core itself ---*/
                     37: dsp_core_t dsp_core;
1.1       root       38: 
1.1.1.2   root       39: /*--- Defines ---*/
1.1       root       40: #ifndef M_PI
                     41: #define M_PI   3.141592653589793238462643383279502
                     42: #endif
                     43: 
1.1.1.2   root       44: /*--- Functions prototypes ---*/
1.1.1.4   root       45: static void dsp_core_dsp2host(void);
                     46: static void dsp_core_host2dsp(void);
1.1       root       47: 
1.1.1.8 ! root       48: static void (*dsp_host_interrupt)(int);   /* Function to set/clear host interrupt */
1.1.1.3   root       49: 
1.1       root       50: /* Init DSP emulation */
1.1.1.8 ! root       51: void dsp_core_init(void (*host_interrupt)(int))
1.1       root       52: {
                     53:        int i;
                     54: 
1.1.1.4   root       55:        LOG_TRACE(TRACE_DSP_STATE, "Dsp: core init\n");
1.1       root       56: 
1.1.1.3   root       57:        dsp_host_interrupt = host_interrupt;
1.1.1.4   root       58:        memset(&dsp_core, 0, sizeof(dsp_core_t));
1.1       root       59: 
                     60:        /* Initialize Y:rom[0x0100-0x01ff] with a sin table */
                     61:        for (i=0;i<256;i++) {
                     62:                float src = (((float) i)*M_PI)/128.0;
                     63:                Sint32 dest = (Sint32) (sin(src) * 8388608.0); /* 1<<23 */
                     64:                if (dest>8388607) {
                     65:                        dest = 8388607;
                     66:                } else if (dest<-8388608) {
                     67:                        dest = -8388608;
                     68:                }
1.1.1.4   root       69:                dsp_core.rom[DSP_SPACE_Y][0x100+i]=dest & 0x00ffffff;
1.1       root       70:        }
                     71: 
                     72:        /* Initialize X:rom[0x0100-0x017f] with a mu-law table */
                     73:        {
                     74:                const Uint16 mulaw_base[8]={
                     75:                        0x7d7c, 0x3e7c, 0x1efc, 0x0f3c, 0x075c, 0x036c, 0x0174, 0x0078
                     76:                };
                     77: 
                     78:                Uint32 position = 0x0100;
                     79:                Uint32 offset = 0x040000;
                     80: 
                     81:                for(i=0;i<8;i++) {
                     82:                        int j;
                     83:                        Uint32 value = mulaw_base[i]<<8;
                     84: 
                     85:                        for (j=0;j<16;j++) {
1.1.1.4   root       86:                                dsp_core.rom[DSP_SPACE_X][position++]=value;
1.1       root       87:                                value -= offset;
                     88:                        }
                     89: 
                     90:                        offset >>= 1;
                     91:                }
                     92:        }
                     93: 
                     94:        /* Initialize X:rom[0x0180-0x01ff] with a a-law table */
                     95:        {
                     96:                const Sint32 multiply_base[8]={
                     97:                        0x1580, 0x0ac0, 0x5600, 0x2b00,
                     98:                        0x1580, 0x0058, 0x0560, 0x02b0
                     99:                };
                    100:                const Sint32 multiply_col[4]={0x10, 0x01, 0x04, 0x02};
                    101:                const Sint32 multiply_line[4]={0x40, 0x04, 0x10, 0x08};
                    102:                const Sint32 base_values[4]={0, -1, 2, 1};
                    103:                Uint32 pos=0x0180;
1.1.1.8 ! root      104: 
1.1       root      105:                for (i=0;i<8;i++) {
                    106:                        Sint32 alawbase, j;
                    107: 
                    108:                        alawbase = multiply_base[i]<<8;
                    109:                        for (j=0;j<4;j++) {
                    110:                                Sint32 alawbase1, k;
1.1.1.8 ! root      111: 
1.1       root      112:                                alawbase1 = alawbase + ((base_values[j]*multiply_line[i & 3])<<12);
                    113: 
                    114:                                for (k=0;k<4;k++) {
                    115:                                        Sint32 alawbase2;
                    116: 
                    117:                                        alawbase2 = alawbase1 + ((base_values[k]*multiply_col[i & 3])<<12);
                    118: 
1.1.1.4   root      119:                                        dsp_core.rom[DSP_SPACE_X][pos++]=alawbase2;
1.1       root      120:                                }
                    121:                        }
                    122:                }
                    123:        }
                    124: }
                    125: 
                    126: /* Shutdown DSP emulation */
1.1.1.4   root      127: void dsp_core_shutdown(void)
1.1       root      128: {
1.1.1.4   root      129:        dsp_core.running = 0;
                    130:        LOG_TRACE(TRACE_DSP_STATE, "Dsp: core shutdown\n");
1.1       root      131: }
                    132: 
                    133: /* Reset */
1.1.1.4   root      134: void dsp_core_reset(void)
1.1       root      135: {
                    136:        int i;
                    137: 
1.1.1.4   root      138:        LOG_TRACE(TRACE_DSP_STATE, "Dsp: core reset\n");
                    139:        dsp_core_shutdown();
1.1       root      140: 
                    141:        /* Memory */
1.1.1.4   root      142:        memset((void*)dsp_core.periph, 0, sizeof(dsp_core.periph));
                    143:        memset(dsp_core.stack, 0, sizeof(dsp_core.stack));
                    144:        memset(dsp_core.registers, 0, sizeof(dsp_core.registers));
                    145:        dsp_core.dsp_host_rtx = 0;
                    146:        dsp_core.dsp_host_htx = 0;
1.1       root      147: 
1.1.1.4   root      148:        dsp_core.bootstrap_pos = 0;
1.1.1.8 ! root      149: 
1.1       root      150:        /* Registers */
1.1.1.4   root      151:        dsp_core.pc = 0x0000;
                    152:        dsp_core.registers[DSP_REG_OMR]=0x02;
1.1       root      153:        for (i=0;i<8;i++) {
1.1.1.4   root      154:                dsp_core.registers[DSP_REG_M0+i]=0x00ffff;
1.1       root      155:        }
                    156: 
1.1.1.2   root      157:        /* Interruptions */
1.1.1.4   root      158:        memset((void*)dsp_core.interrupt_isPending, 0, sizeof(dsp_core.interrupt_isPending));
                    159:        dsp_core.interrupt_state = DSP_INTERRUPT_NONE;
                    160:        dsp_core.interrupt_instr_fetch = -1;
                    161:        dsp_core.interrupt_save_pc = -1;
                    162:        dsp_core.interrupt_counter = 0;
                    163:        dsp_core.interrupt_pipeline_count = 0;
1.1.1.3   root      164:        for (i=0;i<5;i++) {
1.1.1.4   root      165:                dsp_core.interrupt_ipl[i] = 3;
1.1.1.3   root      166:        }
                    167:        for (i=5;i<12;i++) {
1.1.1.4   root      168:                dsp_core.interrupt_ipl[i] = -1;
1.1.1.3   root      169:        }
1.1.1.2   root      170: 
1.1       root      171:        /* host port init, dsp side */
1.1.1.4   root      172:        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR]=(1<<DSP_HOST_HSR_HTDE);
1.1       root      173: 
                    174:        /* host port init, cpu side */
1.1.1.5   root      175:        dsp_core.hostport[CPU_HOST_ICR] = 0x0;
                    176:        dsp_core.hostport[CPU_HOST_CVR] = 0x12;
                    177:        dsp_core.hostport[CPU_HOST_ISR] = (1<<CPU_HOST_ISR_TRDY)|(1<<CPU_HOST_ISR_TXDE);
                    178:        dsp_core.hostport[CPU_HOST_IVR] = 0x0f;
                    179:        dsp_core.hostport[CPU_HOST_RX0] = 0x0;
1.1       root      180: 
1.1.1.2   root      181:        /* SSI registers */
1.1.1.4   root      182:        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR]=1<<DSP_SSI_SR_TDE;
                    183:        dsp_core.ssi.waitFrameTX = 1;
                    184:        dsp_core.ssi.waitFrameRX = 1;
                    185:        dsp_core.ssi.TX = 0;
                    186:        dsp_core.ssi.RX = 0;
                    187:        dsp_core.ssi.dspPlay_handshakeMode_frame = 0;
1.1.1.5   root      188:        dsp_core_ssi_configure(DSP_SSI_CRA, 0);
                    189:        dsp_core_ssi_configure(DSP_SSI_CRB, 0);
                    190: 
1.1       root      191:        /* Other hardware registers */
1.1.1.4   root      192:        dsp_core.periph[DSP_SPACE_X][DSP_IPR]=0;
                    193:        dsp_core.periph[DSP_SPACE_X][DSP_BCR]=0xffff;
1.1       root      194: 
                    195:        /* Misc */
1.1.1.4   root      196:        dsp_core.loop_rep = 0;
1.1       root      197: 
1.1.1.4   root      198:        LOG_TRACE(TRACE_DSP_STATE, "Dsp: reset done\n");
                    199:        dsp56k_init_cpu();
1.1.1.2   root      200: }
                    201: 
1.1.1.8 ! root      202: /*
1.1.1.2   root      203:        SSI INTERFACE processing
                    204: */
                    205: 
1.1.1.3   root      206: /* Set PortC data register : send a frame order to the DMA in handshake mode */
1.1.1.4   root      207: void dsp_core_setPortCDataRegister(Uint32 value)
1.1.1.2   root      208: {
1.1.1.3   root      209:        /* if DSP Record is in handshake mode with DMA Play */
1.1.1.4   root      210:        if ((dsp_core.periph[DSP_SPACE_X][DSP_PCDDR] & 0x10) == 0x10) {
1.1.1.3   root      211:                if ((value & 0x10) == 0x10) {
1.1.1.4   root      212:                        dsp_core.ssi.waitFrameRX = 0;
1.1.1.3   root      213:                        DSP_SsiTransmit_SC1();
1.1.1.4   root      214:                        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp record in handshake mode: SSI send SC1 to crossbar\n");
1.1.1.3   root      215:                }
                    216:        }
                    217: 
                    218:        /* if DSP Play is in handshake mode with DMA Record, high or low frame sync */
                    219:        /* to allow / disable transfer of the data */
1.1.1.4   root      220:        if ((dsp_core.periph[DSP_SPACE_X][DSP_PCDDR] & 0x20) == 0x20) {
1.1.1.3   root      221:                if ((value & 0x20) == 0x20) {
1.1.1.4   root      222:                        dsp_core.ssi.dspPlay_handshakeMode_frame = 1;
                    223:                        dsp_core.ssi.waitFrameTX = 0;
                    224:                        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp play in handshake mode: frame = 1\n");
1.1.1.3   root      225:                }
                    226:                else {
1.1.1.4   root      227:                        dsp_core.ssi.dspPlay_handshakeMode_frame = 0;
1.1.1.3   root      228:                        DSP_SsiTransmit_SC2(0);
1.1.1.4   root      229:                        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp play in handshake mode: SSI send SC2 to crossbar, frame sync = 0\n");
1.1.1.3   root      230:                }
                    231:        }
1.1.1.2   root      232: }
                    233: 
                    234: /* SSI set TX register */
1.1.1.4   root      235: void dsp_core_ssi_writeTX(Uint32 value)
1.1.1.2   root      236: {
                    237:        /* Clear SSI TDE bit */
1.1.1.4   root      238:        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_TDE);
                    239:        dsp_core.ssi.TX = value;
                    240:        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp set TX register: 0x%06x\n", value);
1.1.1.3   root      241: 
                    242:        /* if DSP Play is in handshake mode with DMA Record, send frame sync */
                    243:        /* to allow transfer of the data */
1.1.1.4   root      244:        if (dsp_core.ssi.dspPlay_handshakeMode_frame) {
1.1.1.3   root      245:                DSP_SsiTransmit_SC2(1);
1.1.1.4   root      246:                LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp play in handshake mode: SSI send SC2 to crossbar, frame sync = 1\n");
1.1.1.3   root      247:        }
1.1.1.2   root      248: }
                    249: 
                    250: /* SSI set TDE register (dummy write) */
1.1.1.4   root      251: void dsp_core_ssi_writeTSR(void)
1.1.1.2   root      252: {
                    253:        /* Dummy write : Just clear SSI TDE bit */
1.1.1.4   root      254:        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_TDE);
1.1.1.2   root      255: }
                    256: 
                    257: /* SSI get RX register */
1.1.1.4   root      258: Uint32 dsp_core_ssi_readRX(void)
1.1.1.2   root      259: {
1.1.1.3   root      260:        /* Clear SSI RDF bit */
1.1.1.4   root      261:        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_RDF);
                    262:        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp read RX register: 0x%06x\n", dsp_core.ssi.RX);
                    263:        return dsp_core.ssi.RX;
1.1.1.2   root      264: }
                    265: 
1.1       root      266: 
1.1.1.3   root      267: /**
                    268:  * SSI receive serial clock.
                    269:  *
                    270:  */
1.1.1.4   root      271: void dsp_core_ssi_Receive_SC0(void)
1.1.1.3   root      272: {
                    273:        Uint32 value, i, temp=0;
1.1.1.2   root      274: 
                    275:        /* Receive data from crossbar to SSI */
1.1.1.4   root      276:        value = dsp_core.ssi.received_value;
1.1.1.2   root      277: 
                    278:        /* adjust value to receive size word */
1.1.1.4   root      279:        value <<= (24 - dsp_core.ssi.cra_word_length);
1.1.1.2   root      280:        value &= 0xffffff;
                    281: 
                    282:        /* if bit SHFD in CRB is set, swap received data */
1.1.1.4   root      283:        if (dsp_core.ssi.crb_shifter) {
1.1.1.2   root      284:                temp=0;
1.1.1.4   root      285:                for (i=0; i<dsp_core.ssi.cra_word_length; i++) {
1.1.1.2   root      286:                        temp += value & 1;
                    287:                        temp <<= 1;
                    288:                        value >>= 1;
                    289:                }
                    290:                value = temp;
                    291:        }
                    292: 
1.1.1.4   root      293:        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp SSI received value from crossbar: 0x%06x\n", value);
                    294: 
                    295:        if (dsp_core.ssi.crb_re && dsp_core.ssi.waitFrameRX == 0) {
1.1.1.3   root      296:                /* Send value to DSP receive */
1.1.1.4   root      297:                dsp_core.ssi.RX = value;
1.1.1.3   root      298: 
                    299:                /* generate interrupt ? */
1.1.1.4   root      300:                if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_RIE)) {
                    301:                        if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] & (1<<DSP_SSI_SR_RDF)) {
1.1.1.3   root      302:                                dsp_add_interrupt(DSP_INTER_SSI_RCV_DATA);
                    303:                        } else {
                    304:                                dsp_add_interrupt(DSP_INTER_SSI_RCV_DATA);
                    305:                        }
1.1.1.2   root      306:                }
1.1.1.3   root      307:        }else{
1.1.1.4   root      308:                dsp_core.ssi.RX = 0;
1.1       root      309:        }
1.1.1.3   root      310: 
                    311:        /* set RDF */
1.1.1.4   root      312:        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= 1<<DSP_SSI_SR_RDF;
1.1       root      313: }
                    314: 
1.1.1.3   root      315: /**
                    316:  * SSI receive SC1 bit : frame sync for receiver
                    317:  *     value = 1 : beginning of a new frame
                    318:  *     value = 0 : not beginning of a new frame
                    319:  */
1.1.1.4   root      320: void dsp_core_ssi_Receive_SC1(Uint32 value)
1.1.1.2   root      321: {
1.1.1.3   root      322:        /* SSI runs in network mode ? */
1.1.1.4   root      323:        if (dsp_core.ssi.crb_mode) {
1.1.1.3   root      324:                if (value) {
                    325:                        /* Beginning of a new frame */
1.1.1.4   root      326:                        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_RFS);
                    327:                        dsp_core.ssi.waitFrameRX = 0;
1.1.1.3   root      328:                }else{
1.1.1.4   root      329:                        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_RFS);
1.1.1.3   root      330:                }
                    331:        }else{
                    332:                /* SSI runs in normal mode */
1.1.1.4   root      333:                dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_RFS);
1.1.1.3   root      334:        }
1.1.1.4   root      335: 
                    336:        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp SSI receive frame sync: 0x%01x\n", value);
1.1.1.2   root      337: }
1.1       root      338: 
1.1.1.3   root      339: /**
                    340:  * SSI receive SC2 bit : frame sync for transmitter
                    341:  *     value = 1 : beginning of a new frame
                    342:  *     value = 0 : not beginning of a new frame
                    343:  */
1.1.1.4   root      344: void dsp_core_ssi_Receive_SC2(Uint32 value)
1.1       root      345: {
1.1.1.2   root      346:        /* SSI runs in network mode ? */
1.1.1.4   root      347:        if (dsp_core.ssi.crb_mode) {
1.1.1.3   root      348:                if (value) {
                    349:                        /* Beginning of a new frame */
1.1.1.4   root      350:                        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_TFS);
                    351:                        dsp_core.ssi.waitFrameTX = 0;
1.1.1.2   root      352:                }else{
1.1.1.4   root      353:                        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<<DSP_SSI_SR_TFS);
1.1.1.2   root      354:                }
                    355:        }else{
                    356:                /* SSI runs in normal mode */
1.1.1.4   root      357:                dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_TFS);
1.1       root      358:        }
1.1.1.4   root      359: 
                    360:        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp SSI transmit frame sync: 0x%01x\n", value);
1.1       root      361: }
1.1.1.2   root      362: 
1.1.1.3   root      363: /**
                    364:  * SSI transmit serial clock.
                    365:  *
                    366:  */
1.1.1.4   root      367: void dsp_core_ssi_Receive_SCK(void)
1.1.1.3   root      368: {
                    369:        Uint32 value, i, temp=0;
                    370: 
1.1.1.4   root      371:        value = dsp_core.ssi.TX;
1.1.1.3   root      372: 
                    373:        /* Transfer data from SSI to crossbar*/
                    374: 
                    375:        /* adjust value to transnmit size word */
1.1.1.4   root      376:        value >>= (24 - dsp_core.ssi.cra_word_length);
                    377:        value &= dsp_core.ssi.cra_word_mask;
1.1.1.3   root      378: 
                    379:        /* if bit SHFD in CRB is set, swap data to transmit */
1.1.1.4   root      380:        if (dsp_core.ssi.crb_shifter) {
                    381:                for (i=0; i<dsp_core.ssi.cra_word_length; i++) {
1.1.1.3   root      382:                        temp += value & 1;
                    383:                        temp <<= 1;
                    384:                        value >>= 1;
                    385:                }
                    386:                value = temp;
                    387:        }
                    388: 
1.1.1.4   root      389:        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp SSI transmit value to crossbar: 0x%06x\n", value);
                    390: 
1.1.1.3   root      391:        /* Transmit the data */
1.1.1.4   root      392:        if (dsp_core.ssi.crb_te && dsp_core.ssi.waitFrameTX == 0) {
1.1.1.3   root      393:                /* Send value to crossbar */
1.1.1.4   root      394:                dsp_core.ssi.transmit_value = value;
1.1.1.3   root      395: 
                    396:                /* generate interrupt ? */
1.1.1.4   root      397:                if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_TIE)) {
                    398:                        if (dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] & (1<<DSP_SSI_SR_TDE)) {
1.1.1.3   root      399:                                dsp_add_interrupt(DSP_INTER_SSI_TRX_DATA);
                    400:                        } else {
                    401:                                dsp_add_interrupt(DSP_INTER_SSI_TRX_DATA);
                    402:                        }
                    403:                }
                    404:        }else{
1.1.1.4   root      405:                dsp_core.ssi.transmit_value = 0;
1.1.1.3   root      406:        }
                    407: 
                    408:        /* set TDE */
1.1.1.4   root      409:        dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] |= (1<<DSP_SSI_SR_TDE);
1.1.1.3   root      410: }
                    411: 
                    412: 
                    413: /* SSI initialisations and state management */
1.1.1.6   root      414: void dsp_core_ssi_configure(Uint32 address, Uint32 value)
1.1.1.2   root      415: {
1.1.1.3   root      416:        Uint32 crb_te, crb_re;
1.1.1.2   root      417: 
1.1.1.6   root      418:        switch (address) {
1.1.1.2   root      419:                case DSP_SSI_CRA:
1.1.1.4   root      420:                        dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRA] = value;
1.1.1.2   root      421:                        /* get word size for transfers */
                    422:                        switch ((value>>DSP_SSI_CRA_WL0) & 3) {
                    423:                                case 0:
1.1.1.4   root      424:                                        dsp_core.ssi.cra_word_length = 8;
                    425:                                        dsp_core.ssi.cra_word_mask = 0xff;
1.1.1.2   root      426:                                        break;
                    427:                                case 1:
1.1.1.4   root      428:                                        dsp_core.ssi.cra_word_length = 12;
                    429:                                        dsp_core.ssi.cra_word_mask = 0xfff;
1.1.1.2   root      430:                                        break;
                    431:                                case 2:
1.1.1.4   root      432:                                        dsp_core.ssi.cra_word_length = 16;
                    433:                                        dsp_core.ssi.cra_word_mask = 0xffff;
1.1.1.2   root      434:                                        break;
                    435:                                case 3:
1.1.1.4   root      436:                                        dsp_core.ssi.cra_word_length = 24;
                    437:                                        dsp_core.ssi.cra_word_mask = 0xffffff;
1.1.1.2   root      438:                                        break;
                    439:                        }
                    440: 
1.1.1.4   root      441:                        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp SSI CRA write: 0x%06x\n", value);
                    442: 
1.1.1.2   root      443:                        /* Get the Frame rate divider ( 2 < value <32) */
1.1.1.4   root      444:                        dsp_core.ssi.cra_frame_rate_divider = ((value >> DSP_SSI_CRA_DC0) & 0x1f)+1;
1.1.1.2   root      445:                        break;
                    446:                case DSP_SSI_CRB:
1.1.1.4   root      447:                        crb_te = dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_TE);
                    448:                        crb_re = dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] & (1<<DSP_SSI_CRB_RE);
                    449:                        dsp_core.periph[DSP_SPACE_X][DSP_SSI_CRB] = value;
1.1.1.8 ! root      450: 
1.1.1.4   root      451:                        dsp_core.ssi.crb_src_clock = (value>>DSP_SSI_CRB_SCKD) & 1;
                    452:                        dsp_core.ssi.crb_shifter   = (value>>DSP_SSI_CRB_SHFD) & 1;
                    453:                        dsp_core.ssi.crb_synchro   = (value>>DSP_SSI_CRB_SYN) & 1;
                    454:                        dsp_core.ssi.crb_mode      = (value>>DSP_SSI_CRB_MOD) & 1;
                    455:                        dsp_core.ssi.crb_te        = (value>>DSP_SSI_CRB_TE) & 1;
                    456:                        dsp_core.ssi.crb_re        = (value>>DSP_SSI_CRB_RE) & 1;
                    457:                        dsp_core.ssi.crb_tie       = (value>>DSP_SSI_CRB_TIE) & 1;
                    458:                        dsp_core.ssi.crb_rie       = (value>>DSP_SSI_CRB_RIE) & 1;
1.1.1.2   root      459: 
1.1.1.4   root      460:                        if (crb_te == 0 && dsp_core.ssi.crb_te) {
                    461:                                dsp_core.ssi.waitFrameTX = 1;
1.1.1.3   root      462:                        }
1.1.1.4   root      463:                        if (crb_re == 0 && dsp_core.ssi.crb_re) {
                    464:                                dsp_core.ssi.waitFrameRX = 1;
1.1.1.2   root      465:                        }
1.1.1.4   root      466: 
                    467:                        LOG_TRACE(TRACE_DSP_HOST_SSI, "Dsp SSI CRB write: 0x%06x\n", value);
                    468: 
1.1.1.2   root      469:                        break;
                    470:        }
                    471: }
                    472: 
1.1.1.3   root      473: 
1.1.1.8 ! root      474: /*
1.1.1.2   root      475:        HOST INTERFACE processing
                    476: */
                    477: 
1.1.1.4   root      478: static void dsp_core_hostport_update_trdy(void)
1.1       root      479: {
                    480:        int trdy;
                    481: 
                    482:        /* Clear/set TRDY bit */
1.1.1.4   root      483:        dsp_core.hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_TRDY);
                    484:        trdy = (dsp_core.hostport[CPU_HOST_ISR]>>CPU_HOST_ISR_TXDE)
                    485:                & ~(dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR]>>DSP_HOST_HSR_HRDF);
                    486:        dsp_core.hostport[CPU_HOST_ISR] |= (trdy & 1)<< CPU_HOST_ISR_TRDY;
1.1       root      487: }
                    488: 
1.1.1.4   root      489: static void dsp_core_hostport_update_hreq(void)
1.1.1.2   root      490: {
                    491:        int hreq;
                    492: 
1.1.1.8 ! root      493: #if 0
1.1.1.4   root      494:        hreq = (dsp_core.hostport[CPU_HOST_ICR] & dsp_core.hostport[CPU_HOST_ISR]) & 0x3;
1.1.1.3   root      495: 
                    496:        /* Trigger host interrupt? */
1.1.1.4   root      497:        if (hreq && (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_HREQ)) == 0) {
1.1.1.3   root      498:                dsp_host_interrupt();
                    499:        }
                    500: 
                    501:        /* Set HREQ bit in hostport */
1.1.1.4   root      502:        dsp_core.hostport[CPU_HOST_ISR] &= 0x7f;
                    503:        dsp_core.hostport[CPU_HOST_ISR] |= (hreq?1:0) << CPU_HOST_ISR_HREQ;
1.1.1.8 ! root      504: #else
        !           505:        hreq = (dsp_core.hostport[CPU_HOST_ICR] & dsp_core.hostport[CPU_HOST_ISR]) & 0x3;
        !           506: 
        !           507:     if ( hreq != 0 )
        !           508:                hreq = 1 << CPU_HOST_ISR_HREQ;
        !           509: 
        !           510:        /* If hreq doesn't change, we do nothing */
        !           511:     if ( hreq == ( dsp_core.hostport[CPU_HOST_ISR] & 0x80 ) )
        !           512:                return;
        !           513: 
        !           514:        if ( hreq )                                                             /* 0->1 transition */
        !           515:                dsp_host_interrupt ( 1 );                       /* set host interrupt */
        !           516:        else                                                                    /* 1->0 transition */
        !           517:                dsp_host_interrupt ( 0 );                       /* unset host interrupt */
        !           518: 
        !           519:        /* Set/clear HREQ bit in hostport */
        !           520:        dsp_core.hostport[CPU_HOST_ISR] &= 0x7f;
        !           521:        dsp_core.hostport[CPU_HOST_ISR] |= hreq;
        !           522: //fprintf ( stderr , "dsp_core_hostport_update_hreq %x\n" , hreq );
        !           523: #endif
        !           524: }
1.1.1.2   root      525: 
1.1       root      526: /* Host port transfer ? (dsp->host) */
1.1.1.4   root      527: static void dsp_core_dsp2host(void)
1.1       root      528: {
1.1.1.2   root      529:        /* RXDF = 1 ==> host hasn't read the last value yet */
1.1.1.4   root      530:        if (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_RXDF)) {
1.1       root      531:                return;
                    532:        }
1.1.1.2   root      533: 
                    534:        /* HTDE = 1 ==> nothing to tranfert from DSP port */
1.1.1.4   root      535:        if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HTDE)) {
1.1       root      536:                return;
                    537:        }
                    538: 
1.1.1.4   root      539:        dsp_core.hostport[CPU_HOST_RXL] = dsp_core.dsp_host_htx;
                    540:        dsp_core.hostport[CPU_HOST_RXM] = dsp_core.dsp_host_htx>>8;
                    541:        dsp_core.hostport[CPU_HOST_RXH] = dsp_core.dsp_host_htx>>16;
1.1       root      542: 
                    543:        /* Set HTDE bit to say that DSP can write */
1.1.1.4   root      544:        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HTDE;
1.1.1.2   root      545: 
                    546:        /* Is there an interrupt to send ? */
1.1.1.4   root      547:        if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HTIE)) {
1.1.1.3   root      548:                dsp_add_interrupt(DSP_INTER_HOST_TRX_DATA);
1.1.1.2   root      549:        }
1.1       root      550: 
                    551:        /* Set RXDF bit to say that host can read */
1.1.1.4   root      552:        dsp_core.hostport[CPU_HOST_ISR] |= 1<<CPU_HOST_ISR_RXDF;
                    553:        dsp_core_hostport_update_hreq();
1.1.1.2   root      554: 
1.1.1.4   root      555:        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (DSP->Host): Transfer 0x%06x, Dsp HTDE=1, Host RXDF=1\n", dsp_core.dsp_host_htx);
1.1       root      556: }
                    557: 
                    558: /* Host port transfer ? (host->dsp) */
1.1.1.4   root      559: static void dsp_core_host2dsp(void)
1.1       root      560: {
1.1.1.2   root      561:        /* TXDE = 1 ==> nothing to tranfert from host port */
1.1.1.4   root      562:        if (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_TXDE)) {
1.1       root      563:                return;
                    564:        }
1.1.1.8 ! root      565: 
1.1.1.2   root      566:        /* HRDF = 1 ==> DSP hasn't read the last value yet */
1.1.1.4   root      567:        if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HRDF)) {
1.1       root      568:                return;
                    569:        }
                    570: 
1.1.1.4   root      571:        dsp_core.dsp_host_rtx = dsp_core.hostport[CPU_HOST_TXL];
                    572:        dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXM]<<8;
                    573:        dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXH]<<16;
1.1       root      574: 
                    575:        /* Set HRDF bit to say that DSP can read */
1.1.1.4   root      576:        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HRDF;
1.1.1.2   root      577: 
                    578:        /* Is there an interrupt to send ? */
1.1.1.4   root      579:        if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HRIE)) {
1.1.1.3   root      580:                dsp_add_interrupt(DSP_INTER_HOST_RCV_DATA);
1.1.1.2   root      581:        }
1.1       root      582: 
                    583:        /* Set TXDE bit to say that host can write */
1.1.1.4   root      584:        dsp_core.hostport[CPU_HOST_ISR] |= 1<<CPU_HOST_ISR_TXDE;
                    585:        dsp_core_hostport_update_hreq();
1.1.1.2   root      586: 
1.1.1.4   root      587:        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (Host->DSP): Transfer 0x%06x, Dsp HRDF=1, Host TXDE=1\n", dsp_core.dsp_host_rtx);
1.1       root      588: 
1.1.1.4   root      589:        dsp_core_hostport_update_trdy();
1.1       root      590: }
                    591: 
1.1.1.4   root      592: void dsp_core_hostport_dspread(void)
1.1       root      593: {
                    594:        /* Clear HRDF bit to say that DSP has read */
1.1.1.4   root      595:        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff-(1<<DSP_HOST_HSR_HRDF);
                    596: 
                    597:        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (Host->DSP): Dsp HRDF cleared\n");
                    598: 
                    599:        dsp_core_hostport_update_trdy();
                    600:        dsp_core_host2dsp();
1.1       root      601: }
                    602: 
1.1.1.4   root      603: void dsp_core_hostport_dspwrite(void)
1.1       root      604: {
                    605:        /* Clear HTDE bit to say that DSP has written */
1.1.1.4   root      606:        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff-(1<<DSP_HOST_HSR_HTDE);
                    607: 
                    608:        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (DSP->Host): Dsp HTDE cleared\n");
1.1.1.3   root      609: 
1.1.1.4   root      610:        dsp_core_dsp2host();
1.1       root      611: }
                    612: 
                    613: /* Read/writes on host port */
1.1.1.4   root      614: Uint8 dsp_core_read_host(int addr)
1.1       root      615: {
1.1.1.2   root      616:        Uint8 value;
1.1       root      617: 
1.1.1.4   root      618:        value = dsp_core.hostport[addr];
1.1.1.2   root      619:        if (addr == CPU_HOST_TRXL) {
                    620:                /* Clear RXDF bit to say that CPU has read */
1.1.1.4   root      621:                dsp_core.hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_RXDF);
                    622:                dsp_core_dsp2host();
                    623:                dsp_core_hostport_update_hreq();
1.1.1.8 ! root      624: 
1.1.1.4   root      625:                LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (DSP->Host): Host RXDF=0\n");
1.1       root      626:        }
                    627:        return value;
                    628: }
                    629: 
1.1.1.4   root      630: void dsp_core_write_host(int addr, Uint8 value)
1.1       root      631: {
                    632:        switch(addr) {
                    633:                case CPU_HOST_ICR:
1.1.1.4   root      634:                        dsp_core.hostport[CPU_HOST_ICR]=value & 0xfb;
1.1       root      635:                        /* Set HF1 and HF0 accordingly on the host side */
1.1.1.4   root      636:                        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &=
1.1       root      637:                                        0xff-((1<<DSP_HOST_HSR_HF1)|(1<<DSP_HOST_HSR_HF0));
1.1.1.4   root      638:                        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |=
                    639:                                        dsp_core.hostport[CPU_HOST_ICR] & ((1<<DSP_HOST_HSR_HF1)|(1<<DSP_HOST_HSR_HF0));
                    640:                        dsp_core_hostport_update_hreq();
1.1       root      641:                        break;
                    642:                case CPU_HOST_CVR:
1.1.1.4   root      643:                        dsp_core.hostport[CPU_HOST_CVR]=value & 0x9f;
1.1.1.2   root      644:                        /* if bit 7=1, host command . HSR(bit HCP) is set*/
1.1       root      645:                        if (value & (1<<7)) {
1.1.1.4   root      646:                                dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= (1<<DSP_HOST_HSR_HCP);
1.1.1.2   root      647:                                /* Is there an interrupt to send ? */
1.1.1.4   root      648:                                if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HCIE)) {
1.1.1.3   root      649:                                        dsp_add_interrupt(DSP_INTER_HOST_COMMAND);
1.1.1.2   root      650:                                }
1.1       root      651:                        }
1.1.1.2   root      652:                        else{
1.1.1.4   root      653:                                dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff - (1<<DSP_HOST_HSR_HCP);
1.1.1.2   root      654:                        }
1.1.1.4   root      655: 
                    656:                        LOG_TRACE(TRACE_DSP_HOST_COMMAND, "Dsp: (Host->DSP): Host command = %06x\n", value & 0x9f);
                    657: 
1.1       root      658:                        break;
                    659:                case CPU_HOST_ISR:
1.1.1.2   root      660:                case CPU_HOST_TRX0:
1.1       root      661:                        /* Read only */
                    662:                        break;
                    663:                case CPU_HOST_IVR:
1.1.1.4   root      664:                        dsp_core.hostport[CPU_HOST_IVR]=value;
1.1       root      665:                        break;
1.1.1.2   root      666:                case CPU_HOST_TRXH:
1.1.1.4   root      667:                        dsp_core.hostport[CPU_HOST_TXH]=value;
1.1.1.2   root      668:                        break;
                    669:                case CPU_HOST_TRXM:
1.1.1.4   root      670:                        dsp_core.hostport[CPU_HOST_TXM]=value;
1.1.1.2   root      671:                        break;
                    672:                case CPU_HOST_TRXL:
1.1.1.4   root      673:                        dsp_core.hostport[CPU_HOST_TXL]=value;
1.1       root      674: 
1.1.1.4   root      675:                        if (!dsp_core.running) {
                    676:                                dsp_core.ramint[DSP_SPACE_P][dsp_core.bootstrap_pos] =
                    677:                                        (dsp_core.hostport[CPU_HOST_TXH]<<16) |
                    678:                                        (dsp_core.hostport[CPU_HOST_TXM]<<8) |
                    679:                                         dsp_core.hostport[CPU_HOST_TXL];
1.1.1.8 ! root      680: 
1.1.1.4   root      681:                                LOG_TRACE(TRACE_DSP_STATE, "Dsp: bootstrap p:0x%04x = 0x%06x\n",
                    682:                                                                dsp_core.bootstrap_pos,
                    683:                                                                dsp_core.ramint[DSP_SPACE_P][dsp_core.bootstrap_pos]);
                    684: 
                    685:                                if (++dsp_core.bootstrap_pos == 0x200) {
                    686:                                        LOG_TRACE(TRACE_DSP_STATE, "Dsp: wait bootstrap done\n");
                    687:                                        dsp_core.running = 1;
1.1.1.2   root      688:                                }
1.1       root      689:                        } else {
                    690: 
1.1.1.2   root      691:                                /* If TRDY is set, the tranfert is direct to DSP (Burst mode) */
1.1.1.4   root      692:                                if (dsp_core.hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_TRDY)){
                    693:                                        dsp_core.dsp_host_rtx = dsp_core.hostport[CPU_HOST_TXL];
                    694:                                        dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXM]<<8;
                    695:                                        dsp_core.dsp_host_rtx |= dsp_core.hostport[CPU_HOST_TXH]<<16;
                    696: 
                    697:                                        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (Host->DSP): Direct Transfer 0x%06x\n", dsp_core.dsp_host_rtx);
1.1.1.2   root      698: 
                    699:                                        /* Set HRDF bit to say that DSP can read */
1.1.1.4   root      700:                                        dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HRDF;
1.1.1.2   root      701: 
                    702:                                        /* Is there an interrupt to send ? */
1.1.1.4   root      703:                                        if (dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<<DSP_HOST_HCR_HRIE)) {
1.1.1.3   root      704:                                                dsp_add_interrupt(DSP_INTER_HOST_RCV_DATA);
1.1.1.2   root      705:                                        }
1.1.1.4   root      706: 
                    707:                                        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (Host->DSP): Dsp HRDF set\n");
1.1.1.2   root      708:                                }
                    709:                                else{
                    710:                                        /* Clear TXDE to say that CPU has written */
1.1.1.4   root      711:                                        dsp_core.hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_TXDE);
                    712:                                        dsp_core_hostport_update_hreq();
                    713: 
                    714:                                        LOG_TRACE(TRACE_DSP_HOST_INTERFACE, "Dsp: (Host->DSP): Host TXDE cleared\n");
1.1.1.2   root      715:                                }
1.1.1.4   root      716:                                dsp_core_hostport_update_trdy();
                    717:                                dsp_core_host2dsp();
1.1       root      718:                        }
                    719:                        break;
                    720:        }
                    721: }
                    722: 
                    723: /*
                    724: vim:ts=4:sw=4:
                    725: */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.