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

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

unix.superglobalmegacorp.com

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