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

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

unix.superglobalmegacorp.com

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