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

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

unix.superglobalmegacorp.com

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