Annotation of previous/src/dsp/dsp_core.c, revision 1.1.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.