Annotation of hatari/src/falcon/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 <string.h>
                     27: 
                     28: #include "math.h"
                     29: #include "dsp_core.h"
                     30: #include "dsp_cpu.h"
                     31: 
                     32: #ifndef M_PI
                     33: #define M_PI   3.141592653589793238462643383279502
                     34: #endif
                     35: 
                     36: #define DEBUG 0
                     37: 
                     38: /* More disasm infos, if wanted */
                     39: #define DSP_DISASM_HOSTREAD 0  /* Dsp->Host transfer */
                     40: #define DSP_DISASM_HOSTWRITE 0 /* Host->Dsp transfer */
                     41: #define DSP_DISASM_STATE 0             /* State changes */
                     42: 
                     43: /* Execute DSP instructions till the DSP waits for a read/write */
                     44: #define DSP_HOST_FORCEEXEC 1
                     45: 
                     46: /* Init DSP emulation */
                     47: void dsp_core_init(dsp_core_t *dsp_core)
                     48: {
                     49:        int i;
                     50: 
                     51: #if DEBUG
                     52:        fprintf(stderr, "Dsp: core init\n");
                     53: #endif
                     54: 
                     55:        memset(dsp_core->ram, 0,sizeof(dsp_core->ram));
                     56:        memset(dsp_core->ramint, 0,sizeof(dsp_core->ramint));
                     57:        memset(dsp_core->hostport, 0,sizeof(dsp_core->hostport));
                     58: 
                     59:        /* Initialize Y:rom[0x0100-0x01ff] with a sin table */
                     60:        for (i=0;i<256;i++) {
                     61:                float src = (((float) i)*M_PI)/128.0;
                     62:                Sint32 dest = (Sint32) (sin(src) * 8388608.0); /* 1<<23 */
                     63:                if (dest>8388607) {
                     64:                        dest = 8388607;
                     65:                } else if (dest<-8388608) {
                     66:                        dest = -8388608;
                     67:                }
                     68:                dsp_core->rom[DSP_SPACE_Y][0x100+i]=dest & 0x00ffffff;
                     69:        }
                     70: 
                     71:        /* Initialize X:rom[0x0100-0x017f] with a mu-law table */
                     72:        {
                     73:                const Uint16 mulaw_base[8]={
                     74:                        0x7d7c, 0x3e7c, 0x1efc, 0x0f3c, 0x075c, 0x036c, 0x0174, 0x0078
                     75:                };
                     76: 
                     77:                Uint32 position = 0x0100;
                     78:                Uint32 offset = 0x040000;
                     79: 
                     80:                for(i=0;i<8;i++) {
                     81:                        int j;
                     82:                        Uint32 value = mulaw_base[i]<<8;
                     83: 
                     84:                        for (j=0;j<16;j++) {
                     85:                                dsp_core->rom[DSP_SPACE_X][position++]=value;
                     86:                                value -= offset;
                     87:                        }
                     88: 
                     89:                        offset >>= 1;
                     90:                }
                     91:        }
                     92: 
                     93:        /* Initialize X:rom[0x0180-0x01ff] with a a-law table */
                     94:        {
                     95:                const Sint32 multiply_base[8]={
                     96:                        0x1580, 0x0ac0, 0x5600, 0x2b00,
                     97:                        0x1580, 0x0058, 0x0560, 0x02b0
                     98:                };
                     99:                const Sint32 multiply_col[4]={0x10, 0x01, 0x04, 0x02};
                    100:                const Sint32 multiply_line[4]={0x40, 0x04, 0x10, 0x08};
                    101:                const Sint32 base_values[4]={0, -1, 2, 1};
                    102:                Uint32 pos=0x0180;
                    103:                
                    104:                for (i=0;i<8;i++) {
                    105:                        Sint32 alawbase, j;
                    106: 
                    107:                        alawbase = multiply_base[i]<<8;
                    108:                        for (j=0;j<4;j++) {
                    109:                                Sint32 alawbase1, k;
                    110:                                
                    111:                                alawbase1 = alawbase + ((base_values[j]*multiply_line[i & 3])<<12);
                    112: 
                    113:                                for (k=0;k<4;k++) {
                    114:                                        Sint32 alawbase2;
                    115: 
                    116:                                        alawbase2 = alawbase1 + ((base_values[k]*multiply_col[i & 3])<<12);
                    117: 
                    118:                                        dsp_core->rom[DSP_SPACE_X][pos++]=alawbase2;
                    119:                                }
                    120:                        }
                    121:                }
                    122:        }
                    123:        
                    124:        dsp_core->thread = NULL;
                    125:        dsp_core->semaphore = NULL;
                    126:        dsp_core->mutex = NULL;
                    127: 
                    128:        dsp_core->running = 0;
                    129: }
                    130: 
                    131: /* Shutdown DSP emulation */
                    132: void dsp_core_shutdown(dsp_core_t *dsp_core)
                    133: {
                    134: #if DEBUG
                    135:        fprintf(stderr, "Dsp: core shutdown\n");
                    136: #endif
                    137: 
                    138:        dsp_core->running = 0;
                    139: 
                    140:        if (dsp_core->thread) {
                    141:                if (SDL_SemValue(dsp_core->semaphore)==0) {
                    142:                        SDL_SemPost(dsp_core->semaphore);
                    143:                }
                    144:                SDL_WaitThread(dsp_core->thread, NULL);
                    145:                dsp_core->thread = NULL;
                    146:        }
                    147: 
                    148:        /* Destroy the semaphore */
                    149:        if (dsp_core->semaphore) {
                    150:                SDL_DestroySemaphore(dsp_core->semaphore);
                    151:                dsp_core->semaphore = NULL;
                    152:        }
                    153: 
                    154:        /* Destroy mutex */
                    155:        if (dsp_core->mutex) {
                    156:                SDL_DestroyMutex(dsp_core->mutex);
                    157:                dsp_core->mutex = NULL;
                    158:        }
                    159: }
                    160: 
                    161: /* Reset */
                    162: void dsp_core_reset(dsp_core_t *dsp_core)
                    163: {
                    164:        int i;
                    165: 
                    166: #if DEBUG
                    167:        fprintf(stderr, "Dsp: core reset\n");
                    168: #endif
                    169: 
                    170:        /* Kill existing thread and semaphore */
                    171:        dsp_core_shutdown(dsp_core);
                    172: 
                    173:        /* Memory */
                    174:        memset(dsp_core->periph, 0,sizeof(dsp_core->periph));
                    175:        memset(dsp_core->stack, 0,sizeof(dsp_core->stack));
                    176:        memset(dsp_core->registers, 0,sizeof(dsp_core->registers));
                    177: 
                    178:        dsp_core->bootstrap_pos = 0;
                    179:        
                    180:        /* Registers */
                    181:        dsp_core->pc = 0x0000;
                    182:        dsp_core->registers[DSP_REG_OMR]=0x02;
                    183:        for (i=0;i<8;i++) {
                    184:                dsp_core->registers[DSP_REG_M0+i]=0x00ffff;
                    185:        }
                    186: 
                    187:        /* host port init, dsp side */
                    188:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR]=(1<<DSP_HOST_HSR_HTDE);
                    189: 
                    190:        /* host port init, cpu side */
                    191:        dsp_core->hostport[CPU_HOST_CVR]=0x12;
                    192:        dsp_core->hostport[CPU_HOST_ISR]=(1<<CPU_HOST_ISR_TRDY)|(1<<CPU_HOST_ISR_TXDE);
                    193:        dsp_core->hostport[CPU_HOST_IVR]=0x0f;
                    194: 
                    195:        /* Other hardware registers */
                    196:        dsp_core->periph[DSP_SPACE_X][DSP_IPR]=0;
                    197:        dsp_core->periph[DSP_SPACE_X][DSP_BCR]=0xffff;
                    198: 
                    199:        /* Misc */
                    200:        dsp_core->loop_rep = 0;
                    201: 
                    202: #if DEBUG
                    203:        fprintf(stderr, "Dsp: reset done\n");
                    204: #endif
                    205: 
                    206:        /* Create thread, semaphore, mutex if needed */
                    207:        if (dsp_core->semaphore == NULL) {
                    208:                dsp_core->semaphore = SDL_CreateSemaphore(0);
                    209:        }
                    210:        if (dsp_core->mutex == NULL) {
                    211:                dsp_core->mutex = SDL_CreateMutex();
                    212:        }
                    213:        if (dsp_core->thread == NULL) {
                    214:                dsp_core->thread = SDL_CreateThread(dsp56k_do_execute, dsp_core);
                    215:        }
                    216: }
                    217: 
                    218: /* Force execution of DSP instructions, till cpu has read/written host port
                    219:        Should not be needed at all, as it slows down host cpu emulation
                    220: */
                    221: 
                    222: #if DSP_HOST_FORCEEXEC
                    223: static void dsp_core_force_exec(dsp_core_t *dsp_core)
                    224: {
                    225:        Uint32 start = SDL_GetTicks();
                    226: 
                    227:        while (dsp_core->running                                                /* DSP thread running */
                    228:                && (SDL_SemValue(dsp_core->semaphore)!=0)       /* and executing instructions */
                    229:                && (SDL_GetTicks()-start<200))
                    230:        {
                    231:                SDL_Delay(1);
                    232:        }
                    233: }
                    234: #endif
                    235: 
                    236: static void dsp_core_hostport_update_trdy(dsp_core_t *dsp_core)
                    237: {
                    238:        int trdy;
                    239: 
                    240:        /* Clear/set TRDY bit */
                    241:        dsp_core->hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_TRDY);
                    242:        trdy = (dsp_core->hostport[CPU_HOST_ISR]>>CPU_HOST_ISR_TXDE)
                    243:                & ~(dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR]>>DSP_HOST_HSR_HRDF);
                    244:        dsp_core->hostport[CPU_HOST_ISR] |= (trdy & 1)<< CPU_HOST_ISR_TRDY;
                    245: }
                    246: 
                    247: /* Host port transfer ? (dsp->host) */
                    248: static void dsp_core_dsp2host(dsp_core_t *dsp_core)
                    249: {
                    250:        if (dsp_core->hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_RXDF)) {
                    251:                return;
                    252:        }
                    253:        if (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HTDE)) {
                    254:                return;
                    255:        }
                    256: 
                    257:        dsp_core->hostport[CPU_HOST_RXL] = dsp_core->periph[DSP_SPACE_X][DSP_HOST_HTX];
                    258:        dsp_core->hostport[CPU_HOST_RXM] = dsp_core->periph[DSP_SPACE_X][DSP_HOST_HTX]>>8;
                    259:        dsp_core->hostport[CPU_HOST_RXH] = dsp_core->periph[DSP_SPACE_X][DSP_HOST_HTX]>>16;
                    260: #if DSP_DISASM_HOSTWRITE
                    261:        fprintf(stderr, "Dsp: (D->H): Transfer 0x%06x\n", dsp_core->periph[DSP_SPACE_X][DSP_HOST_HTX]);
                    262: #endif
                    263: 
                    264:        /* Set HTDE bit to say that DSP can write */
                    265:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HTDE;
                    266: #if DSP_DISASM_HOSTWRITE
                    267:        fprintf(stderr, "Dsp: (D->H): Dsp HTDE set\n");
                    268: #endif
                    269: 
                    270:        /* Set RXDF bit to say that host can read */
                    271:        dsp_core->hostport[CPU_HOST_ISR] |= 1<<CPU_HOST_ISR_RXDF;
                    272: #if DSP_DISASM_HOSTWRITE
                    273:        fprintf(stderr, "Dsp: (D->H): Host RXDF set\n");
                    274: #endif
                    275: }
                    276: 
                    277: /* Host port transfer ? (host->dsp) */
                    278: static void dsp_core_host2dsp(dsp_core_t *dsp_core)
                    279: {
                    280:        if (dsp_core->hostport[CPU_HOST_ISR] & (1<<CPU_HOST_ISR_TXDE)) {
                    281:                return;
                    282:        }
                    283:        if (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<<DSP_HOST_HSR_HRDF)) {
                    284:                return;
                    285:        }
                    286: 
                    287:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HRX] = dsp_core->hostport[CPU_HOST_TXL];
                    288:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HRX] |= dsp_core->hostport[CPU_HOST_TXM]<<8;
                    289:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HRX] |= dsp_core->hostport[CPU_HOST_TXH]<<16;
                    290: #if DSP_DISASM_HOSTREAD
                    291:        fprintf(stderr, "Dsp: (H->D): Transfer 0x%06x\n", dsp_core->periph[DSP_SPACE_X][DSP_HOST_HRX]);
                    292: #endif
                    293: 
                    294:        /* Set HRDF bit to say that DSP can read */
                    295:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HRDF;
                    296: #if DSP_DISASM_HOSTREAD
                    297:        fprintf(stderr, "Dsp: (H->D): Dsp HRDF set\n");
                    298: #endif
                    299: 
                    300:        /* Set TXDE bit to say that host can write */
                    301:        dsp_core->hostport[CPU_HOST_ISR] |= 1<<CPU_HOST_ISR_TXDE;
                    302: # if DSP_DISASM_HOSTREAD
                    303:        fprintf(stderr, "Dsp: (H->D): Host TXDE set\n");
                    304: # endif
                    305: 
                    306:        dsp_core_hostport_update_trdy(dsp_core);
                    307: }
                    308: 
                    309: void dsp_core_hostport_dspread(dsp_core_t *dsp_core)
                    310: {
                    311:        /* Clear HRDF bit to say that DSP has read */
                    312:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff-(1<<DSP_HOST_HSR_HRDF);
                    313: #if DSP_DISASM_HOSTREAD
                    314:        fprintf(stderr, "Dsp: (H->D): Dsp HRDF cleared\n");
                    315: #endif
                    316:        dsp_core_hostport_update_trdy(dsp_core);
                    317:        dsp_core_host2dsp(dsp_core);
                    318: }
                    319: 
                    320: void dsp_core_hostport_dspwrite(dsp_core_t *dsp_core)
                    321: {
                    322:        /* Clear HTDE bit to say that DSP has written */
                    323:        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff-(1<<DSP_HOST_HSR_HTDE);
                    324: #if DSP_DISASM_HOSTWRITE
                    325:        fprintf(stderr, "Dsp: (D->H): Dsp HTDE cleared\n");
                    326: #endif
                    327: 
                    328:        dsp_core_dsp2host(dsp_core);
                    329: }
                    330: 
                    331: static void dsp_core_hostport_cpuread(dsp_core_t *dsp_core)
                    332: {
                    333:        /* Clear RXDF bit to say that CPU has read */
                    334:        dsp_core->hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_RXDF);
                    335: #if DSP_DISASM_HOSTWRITE
                    336:        fprintf(stderr, "Dsp: (D->H): Host RXDF cleared\n");
                    337: #endif
                    338:        dsp_core_dsp2host(dsp_core);
                    339: }
                    340: 
                    341: static void dsp_core_hostport_cpuwrite(dsp_core_t *dsp_core)
                    342: {
                    343:        /* Clear TXDE to say that CPU has written */
                    344:        dsp_core->hostport[CPU_HOST_ISR] &= 0xff-(1<<CPU_HOST_ISR_TXDE);
                    345: #if DSP_DISASM_HOSTREAD
                    346:        fprintf(stderr, "Dsp: (H->D): Host TXDE cleared\n");
                    347: #endif
                    348: 
                    349:        dsp_core_hostport_update_trdy(dsp_core);
                    350:        dsp_core_host2dsp(dsp_core);
                    351: }
                    352: 
                    353: /* Read/writes on host port */
                    354: 
                    355: Uint8 dsp_core_read_host(dsp_core_t *dsp_core, int addr)
                    356: {
                    357: #if 0 /* DSP_HOST_FORCEEXEC */
                    358:        switch(addr) {
                    359:                case CPU_HOST_RXH:
                    360:                case CPU_HOST_RXM:
                    361:                case CPU_HOST_RXL:
                    362:                        dsp_core_force_exec(dsp_core);
                    363:                        break;
                    364:        }
                    365: #endif
                    366: 
                    367:        SDL_LockMutex(dsp_core->mutex);
                    368:        Uint8 value = dsp_core->hostport[addr];
                    369:        if (addr == CPU_HOST_RXL) {
                    370:                dsp_core_hostport_cpuread(dsp_core);
                    371: 
                    372:                /* Wake up DSP if it was waiting our read */
                    373: #if DSP_DISASM_STATE
                    374:                fprintf(stderr, "Dsp: WAIT_HOSTREAD done\n");
                    375: #endif
                    376:                SDL_SemPost(dsp_core->semaphore);
                    377:        }
                    378:        SDL_UnlockMutex(dsp_core->mutex);
                    379: 
                    380:        return value;
                    381: }
                    382: 
                    383: void dsp_core_write_host(dsp_core_t *dsp_core, int addr, Uint8 value)
                    384: {
                    385: #if DSP_HOST_FORCEEXEC
                    386:        switch(addr) {
                    387:                case CPU_HOST_TXH:
                    388:                case CPU_HOST_TXM:
                    389:                case CPU_HOST_TXL:
                    390:                        dsp_core_force_exec(dsp_core);
                    391:                        break;
                    392:        }
                    393: #endif
                    394: 
                    395:        SDL_LockMutex(dsp_core->mutex);
                    396:        switch(addr) {
                    397:                case CPU_HOST_ICR:
                    398:                        dsp_core->hostport[CPU_HOST_ICR]=value & 0xfb;
                    399:                        /* Set HF1 and HF0 accordingly on the host side */
                    400:                        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] &=
                    401:                                        0xff-((1<<DSP_HOST_HSR_HF1)|(1<<DSP_HOST_HSR_HF0));
                    402:                        dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] |=
                    403:                                        dsp_core->hostport[CPU_HOST_ICR] & ((1<<DSP_HOST_HSR_HF1)|(1<<DSP_HOST_HSR_HF0));
                    404:                        break;
                    405:                case CPU_HOST_CVR:
                    406:                        dsp_core->hostport[CPU_HOST_CVR]=value & 0x9f;
                    407:                        /* if bit 7=1, host command */
                    408:                        if (value & (1<<7)) {
                    409:                                dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<<DSP_HOST_HSR_HCP;
                    410:                        }
                    411:                        break;
                    412:                case CPU_HOST_ISR:
                    413:                case CPU_HOST_TX0:
                    414:                        /* Read only */
                    415:                        break;
                    416:                case CPU_HOST_IVR:
                    417:                case CPU_HOST_TXH:
                    418:                case CPU_HOST_TXM:
                    419:                        dsp_core->hostport[addr]=value;
                    420:                        break;
                    421:                case CPU_HOST_TXL:
                    422:                        dsp_core->hostport[CPU_HOST_TXL]=value;
                    423: 
                    424:                        if (!dsp_core->running) {
                    425:                                dsp_core->ramint[DSP_SPACE_P][dsp_core->bootstrap_pos] =
                    426:                                        (dsp_core->hostport[CPU_HOST_TXH]<<16) |
                    427:                                        (dsp_core->hostport[CPU_HOST_TXM]<<8) |
                    428:                                        dsp_core->hostport[CPU_HOST_TXL];
                    429: #if DEBUG
                    430:                                fprintf(stderr, "Dsp: bootstrap p:0x%04x = 0x%06x\n",
                    431:                                        dsp_core->bootstrap_pos,
                    432:                                        dsp_core->ramint[DSP_SPACE_P][dsp_core->bootstrap_pos]);
                    433: #endif
                    434:                                if (++dsp_core->bootstrap_pos == 0x200) {
                    435: #if DSP_DISASM_STATE
                    436:                                        fprintf(stderr, "Dsp: WAIT_BOOTSTRAP done\n");
                    437: #endif
                    438:                                        dsp_core->running = 1;
                    439:                                        SDL_SemPost(dsp_core->semaphore);
                    440:                                }               
                    441:                        } else {
                    442:                                dsp_core_hostport_cpuwrite(dsp_core);
                    443: 
                    444:                                /* Wake up DSP if it was waiting our write */
                    445: #if DSP_DISASM_STATE
                    446:                                fprintf(stderr, "Dsp: WAIT_HOSTWRITE done\n");
                    447: #endif
                    448:                                SDL_SemPost(dsp_core->semaphore);
                    449:                        }
                    450:                        break;
                    451:        }
                    452:        SDL_UnlockMutex(dsp_core->mutex);
                    453: }
                    454: 
                    455: /*
                    456: vim:ts=4:sw=4:
                    457: */

unix.superglobalmegacorp.com

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