Annotation of previous/src/dsp/dsp_core.c, revision 1.1

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

unix.superglobalmegacorp.com

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