Annotation of uae/src/audio.c, revision 1.1.1.13

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * OS specific functions
                      5:   *
                      6:   * Copyright 1995, 1996, 1997 Bernd Schmidt
                      7:   * Copyright 1996 Marcus Sundberg
                      8:   * Copyright 1996 Manfred Thole
                      9:   */
                     10: 
                     11: #include "sysconfig.h"
                     12: #include "sysdeps.h"
                     13: 
                     14: #include "config.h"
                     15: #include "options.h"
                     16: #include "memory.h"
                     17: #include "custom.h"
1.1.1.7   root       18: #include "newcpu.h"
                     19: #include "autoconf.h"
1.1       root       20: #include "gensound.h"
                     21: #include "sounddep/sound.h"
                     22: #include "events.h"
                     23: #include "audio.h"
1.1.1.8   root       24: #include "savestate.h"
1.1       root       25: 
1.1.1.13! root       26: struct audio_channel_data audio_channel[4];
1.1.1.2   root       27: int sound_available = 0;
1.1       root       28: int sound_table[64][256];
1.1.1.2   root       29: void (*sample_handler) (void);
1.1.1.7   root       30: 
                     31: unsigned long sample_evtime, scaled_sample_evtime;
                     32: int scaled_sample_evtime_ok;
                     33: 
1.1.1.2   root       34: static unsigned long last_cycles, next_sample_evtime;
1.1       root       35: 
1.1.1.2   root       36: void init_sound_table16 (void)
1.1       root       37: {
                     38:     int i,j;
                     39: 
                     40:     for (i = 0; i < 256; i++)
                     41:        for (j = 0; j < 64; j++)
1.1.1.13! root       42:            sound_table[j][i] = j * (uae_s8)i * (currprefs.sound_stereo ? 2 : 1);
1.1       root       43: }
                     44: 
                     45: void init_sound_table8 (void)
                     46: {
                     47:     int i,j;
                     48: 
                     49:     for (i = 0; i < 256; i++)
                     50:        for (j = 0; j < 64; j++)
1.1.1.13! root       51:            sound_table[j][i] = (j * (uae_s8)i * (currprefs.sound_stereo ? 2 : 1)) / 256;
1.1       root       52: }
                     53: 
                     54: #define MULTIPLICATION_PROFITABLE
                     55: 
                     56: #ifdef MULTIPLICATION_PROFITABLE
                     57: typedef uae_s8 sample8_t;
                     58: #define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].vol; } while (0)
                     59: #define SBASEVAL8(logn) ((logn) == 1 ? SOUND8_BASE_VAL << 7 : SOUND8_BASE_VAL << 8)
                     60: #define SBASEVAL16(logn) ((logn) == 1 ? SOUND16_BASE_VAL >> 1 : SOUND16_BASE_VAL)
1.1.1.7   root       61: #define FINISH_DATA(data,b,logn) do { if (14 - (b) + (logn) > 0) (data) >>= 14 - (b) + (logn); else (data) <<= (b) - 14 - (logn); } while (0);
1.1       root       62: #else
                     63: typedef uae_u8 sample8_t;
                     64: #define DO_CHANNEL_1(v, c) do { (v) = audio_channel[c].voltbl[(v)]; } while (0)
                     65: #define SBASEVAL8(logn) SOUND8_BASE_VAL
                     66: #define SBASEVAL16(logn) SOUND16_BASE_VAL
                     67: #define FINISH_DATA(b,logn)
                     68: #endif
                     69: 
1.1.1.7   root       70: /* Always put the right word before the left word.  */
                     71: #define DELAY_BUFFER 32
                     72: static uae_u32 right_word_saved[DELAY_BUFFER];
                     73: static uae_u32 left_word_saved[DELAY_BUFFER];
                     74: static int saved_ptr;
1.1       root       75: 
1.1.1.7   root       76: STATIC_INLINE void put_sound_word_right (uae_u32 w)
1.1       root       77: {
1.1.1.7   root       78:     if (currprefs.mixed_stereo) {
                     79:        right_word_saved[saved_ptr] = w;
                     80:        return;
1.1       root       81:     }
                     82: 
1.1.1.7   root       83:     PUT_SOUND_WORD_RIGHT (w);
1.1       root       84: }
                     85: 
1.1.1.7   root       86: STATIC_INLINE void put_sound_word_left (uae_u32 w)
1.1.1.5   root       87: {
1.1.1.7   root       88:     if (currprefs.mixed_stereo) {
                     89:        uae_u32 rold, lold, rnew, lnew, tmp;
1.1.1.5   root       90: 
1.1.1.7   root       91:        left_word_saved[saved_ptr] = w;
                     92:        lnew = w - SOUND16_BASE_VAL;
                     93:        rnew = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
1.1.1.5   root       94: 
1.1.1.7   root       95:        saved_ptr = (saved_ptr + 1) & (DELAY_BUFFER - 1);
                     96:        lold = left_word_saved[saved_ptr] - SOUND16_BASE_VAL;
                     97:        tmp = (rnew * 5 + lold * 3) >> 3;
                     98:        tmp += SOUND16_BASE_VAL;
                     99:        PUT_SOUND_WORD_RIGHT (tmp);
1.1.1.5   root      100: 
1.1.1.7   root      101:        rold = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
                    102:        w = (lnew * 5 + rold * 3) >> 3;
                    103:     }
                    104:     PUT_SOUND_WORD_LEFT (w);
                    105: }
1.1.1.5   root      106: 
1.1.1.7   root      107: #define DO_CHANNEL(v, c) do { (v) &= audio_channel[c].adk_mask; data += v; } while (0);
1.1.1.5   root      108: 
1.1.1.7   root      109: void sample16_handler (void)
                    110: {
1.1.1.13! root      111:     uae_u32 data0 = audio_channel[0].current_sample;
        !           112:     uae_u32 data1 = audio_channel[1].current_sample;
        !           113:     uae_u32 data2 = audio_channel[2].current_sample;
        !           114:     uae_u32 data3 = audio_channel[3].current_sample;
        !           115:     DO_CHANNEL_1 (data0, 0);
        !           116:     DO_CHANNEL_1 (data1, 1);
        !           117:     DO_CHANNEL_1 (data2, 2);
        !           118:     DO_CHANNEL_1 (data3, 3);
        !           119:     data0 &= audio_channel[0].adk_mask;
        !           120:     data1 &= audio_channel[1].adk_mask;
        !           121:     data2 &= audio_channel[2].adk_mask;
        !           122:     data3 &= audio_channel[3].adk_mask;
        !           123:     data0 += data1;
        !           124:     data0 += data2;
        !           125:     data0 += data3;
        !           126:     {
        !           127:        uae_u32 data = SBASEVAL16(2) + data0;
        !           128:        FINISH_DATA (data, 16, 2);
        !           129:        PUT_SOUND_WORD (data);
1.1.1.5   root      130:     }
                    131:     check_sound_buffers ();
                    132: }
                    133: 
1.1.1.7   root      134: void sample16i_rh_handler (void)
1.1.1.6   root      135: {
1.1.1.13! root      136:     unsigned long delta, ratio;
        !           137: 
        !           138:     uae_u32 data0 = audio_channel[0].current_sample;
        !           139:     uae_u32 data1 = audio_channel[1].current_sample;
        !           140:     uae_u32 data2 = audio_channel[2].current_sample;
        !           141:     uae_u32 data3 = audio_channel[3].current_sample;
        !           142:     uae_u32 data0p = audio_channel[0].last_sample;
        !           143:     uae_u32 data1p = audio_channel[1].last_sample;
        !           144:     uae_u32 data2p = audio_channel[2].last_sample;
        !           145:     uae_u32 data3p = audio_channel[3].last_sample;
        !           146:     DO_CHANNEL_1 (data0, 0);
        !           147:     DO_CHANNEL_1 (data1, 1);
        !           148:     DO_CHANNEL_1 (data2, 2);
        !           149:     DO_CHANNEL_1 (data3, 3);
        !           150:     DO_CHANNEL_1 (data0p, 0);
        !           151:     DO_CHANNEL_1 (data1p, 1);
        !           152:     DO_CHANNEL_1 (data2p, 2);
        !           153:     DO_CHANNEL_1 (data3p, 3);
1.1.1.6   root      154: 
1.1.1.13! root      155:     data0 &= audio_channel[0].adk_mask;
        !           156:     data0p &= audio_channel[0].adk_mask;
        !           157:     data1 &= audio_channel[1].adk_mask;
        !           158:     data1p &= audio_channel[1].adk_mask;
        !           159:     data2 &= audio_channel[2].adk_mask;
        !           160:     data2p &= audio_channel[2].adk_mask;
        !           161:     data3 &= audio_channel[3].adk_mask;
        !           162:     data3p &= audio_channel[3].adk_mask;
1.1.1.6   root      163: 
1.1.1.13! root      164:     /* linear interpolation and summing up... */
        !           165:     delta = audio_channel[0].per;
        !           166:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
        !           167:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
        !           168:     delta = audio_channel[1].per;
        !           169:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
        !           170:     data0 += (data1 * (256 - ratio) + data1p * ratio) >> 8;
        !           171:     delta = audio_channel[2].per;
        !           172:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
        !           173:     data0 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
        !           174:     delta = audio_channel[3].per;
        !           175:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
        !           176:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
1.1.1.6   root      177: 
1.1.1.13! root      178:     {
        !           179:        uae_u32 data = SBASEVAL16(2) + data0;
        !           180:        FINISH_DATA (data, 16, 2);
        !           181:        PUT_SOUND_WORD (data);
1.1.1.6   root      182:     }
1.1.1.13! root      183: 
        !           184:     check_sound_buffers ();
1.1.1.7   root      185: }
1.1.1.6   root      186: 
1.1.1.7   root      187: void sample16i_crux_handler (void)
                    188: {
1.1.1.13! root      189:     uae_u32 data0 = audio_channel[0].current_sample;
        !           190:     uae_u32 data1 = audio_channel[1].current_sample;
        !           191:     uae_u32 data2 = audio_channel[2].current_sample;
        !           192:     uae_u32 data3 = audio_channel[3].current_sample;
        !           193:     uae_u32 data0p = audio_channel[0].last_sample;
        !           194:     uae_u32 data1p = audio_channel[1].last_sample;
        !           195:     uae_u32 data2p = audio_channel[2].last_sample;
        !           196:     uae_u32 data3p = audio_channel[3].last_sample;
        !           197:     DO_CHANNEL_1 (data0, 0);
        !           198:     DO_CHANNEL_1 (data1, 1);
        !           199:     DO_CHANNEL_1 (data2, 2);
        !           200:     DO_CHANNEL_1 (data3, 3);
        !           201:     DO_CHANNEL_1 (data0p, 0);
        !           202:     DO_CHANNEL_1 (data1p, 1);
        !           203:     DO_CHANNEL_1 (data2p, 2);
        !           204:     DO_CHANNEL_1 (data3p, 3);
        !           205: 
        !           206:     data0 &= audio_channel[0].adk_mask;
        !           207:     data0p &= audio_channel[0].adk_mask;
        !           208:     data1 &= audio_channel[1].adk_mask;
        !           209:     data1p &= audio_channel[1].adk_mask;
        !           210:     data2 &= audio_channel[2].adk_mask;
        !           211:     data2p &= audio_channel[2].adk_mask;
        !           212:     data3 &= audio_channel[3].adk_mask;
        !           213:     data3p &= audio_channel[3].adk_mask;
        !           214: 
        !           215:     {    
        !           216:        struct audio_channel_data *cdp;
        !           217:        unsigned long ratio, ratio1;
1.1.1.7   root      218: #define INTERVAL (scaled_sample_evtime * 3)
1.1.1.13! root      219:        cdp = audio_channel + 0;
        !           220:        ratio1 = cdp->per - cdp->evtime;
        !           221:        ratio = (ratio1 << 12) / INTERVAL;
        !           222:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           223:            ratio = 4096;
        !           224:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
        !           225: 
        !           226:        cdp = audio_channel + 1;
        !           227:        ratio1 = cdp->per - cdp->evtime;
        !           228:        ratio = (ratio1 << 12) / INTERVAL;
        !           229:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           230:            ratio = 4096;
        !           231:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
        !           232: 
        !           233:        cdp = audio_channel + 2;
        !           234:        ratio1 = cdp->per - cdp->evtime;
        !           235:        ratio = (ratio1 << 12) / INTERVAL;
        !           236:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           237:            ratio = 4096;
        !           238:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
        !           239: 
        !           240:        cdp = audio_channel + 3;
        !           241:        ratio1 = cdp->per - cdp->evtime;
        !           242:        ratio = (ratio1 << 12) / INTERVAL;
        !           243:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           244:            ratio = 4096;
        !           245:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
        !           246:     }
        !           247:     data1 += data2;
        !           248:     data0 += data3;
        !           249:     data0 += data1;
        !           250:     {
        !           251:        uae_u32 data = SBASEVAL16(2) + data0;
        !           252:        FINISH_DATA (data, 16, 2);
        !           253:        PUT_SOUND_WORD (data);
1.1.1.7   root      254:     }
1.1.1.6   root      255:     check_sound_buffers ();
                    256: }
                    257: 
1.1.1.2   root      258: void sample8_handler (void)
1.1       root      259: {
                    260:     uae_u32 data0 = audio_channel[0].current_sample;
                    261:     uae_u32 data1 = audio_channel[1].current_sample;
                    262:     uae_u32 data2 = audio_channel[2].current_sample;
                    263:     uae_u32 data3 = audio_channel[3].current_sample;
                    264:     DO_CHANNEL_1 (data0, 0);
                    265:     DO_CHANNEL_1 (data1, 1);
                    266:     DO_CHANNEL_1 (data2, 2);
                    267:     DO_CHANNEL_1 (data3, 3);
                    268:     data0 &= audio_channel[0].adk_mask;
                    269:     data1 &= audio_channel[1].adk_mask;
                    270:     data2 &= audio_channel[2].adk_mask;
                    271:     data3 &= audio_channel[3].adk_mask;
                    272:     data0 += data1;
                    273:     data0 += data2;
                    274:     data0 += data3;
                    275:     {
                    276:        uae_u32 data = SBASEVAL8(2) + data0;
1.1.1.7   root      277:        FINISH_DATA (data, 8, 2);
1.1       root      278:        PUT_SOUND_BYTE (data);
                    279:     }
                    280: 
                    281:     check_sound_buffers ();
                    282: }
                    283: 
                    284: #ifdef HAVE_STEREO_SUPPORT
1.1.1.2   root      285: void sample16s_handler (void)
1.1       root      286: {
1.1.1.13! root      287:     uae_u32 data0 = audio_channel[0].current_sample;
        !           288:     uae_u32 data1 = audio_channel[1].current_sample;
        !           289:     uae_u32 data2 = audio_channel[2].current_sample;
        !           290:     uae_u32 data3 = audio_channel[3].current_sample;
        !           291:     DO_CHANNEL_1 (data0, 0);
        !           292:     DO_CHANNEL_1 (data1, 1);
        !           293:     DO_CHANNEL_1 (data2, 2);
        !           294:     DO_CHANNEL_1 (data3, 3);
        !           295: 
        !           296:     data0 &= audio_channel[0].adk_mask;
        !           297:     data1 &= audio_channel[1].adk_mask;
        !           298:     data2 &= audio_channel[2].adk_mask;
        !           299:     data3 &= audio_channel[3].adk_mask;
1.1       root      300:     
1.1.1.13! root      301:     data0 += data3;
        !           302:     {
        !           303:        uae_u32 data = SBASEVAL16(1) + data0;
        !           304:        FINISH_DATA (data, 16, 1);
        !           305:        put_sound_word_right (data);
        !           306:     }
1.1       root      307: 
1.1.1.13! root      308:     data1 += data2;
        !           309:     {
        !           310:        uae_u32 data = SBASEVAL16(1) + data1;   
        !           311:        FINISH_DATA (data, 16, 1);
        !           312:        put_sound_word_left (data);
1.1       root      313:     }
1.1.1.7   root      314: 
1.1       root      315:     check_sound_buffers ();
                    316: }
                    317: 
1.1.1.6   root      318: void sample16si_crux_handler (void)
1.1.1.5   root      319: {
1.1.1.13! root      320:     unsigned long delta, ratio;
1.1.1.5   root      321: 
1.1.1.13! root      322:     uae_u32 data0 = audio_channel[0].current_sample;
        !           323:     uae_u32 data1 = audio_channel[1].current_sample;
        !           324:     uae_u32 data2 = audio_channel[2].current_sample;
        !           325:     uae_u32 data3 = audio_channel[3].current_sample;
        !           326:     uae_u32 data0p = audio_channel[0].last_sample;
        !           327:     uae_u32 data1p = audio_channel[1].last_sample;
        !           328:     uae_u32 data2p = audio_channel[2].last_sample;
        !           329:     uae_u32 data3p = audio_channel[3].last_sample;
        !           330: 
        !           331:     DO_CHANNEL_1 (data0, 0);
        !           332:     DO_CHANNEL_1 (data1, 1);
        !           333:     DO_CHANNEL_1 (data2, 2);
        !           334:     DO_CHANNEL_1 (data3, 3);
        !           335:     DO_CHANNEL_1 (data0p, 0);
        !           336:     DO_CHANNEL_1 (data1p, 1);
        !           337:     DO_CHANNEL_1 (data2p, 2);
        !           338:     DO_CHANNEL_1 (data3p, 3);
        !           339: 
        !           340:     data0 &= audio_channel[0].adk_mask;
        !           341:     data0p &= audio_channel[0].adk_mask;
        !           342:     data1 &= audio_channel[1].adk_mask;
        !           343:     data1p &= audio_channel[1].adk_mask;
        !           344:     data2 &= audio_channel[2].adk_mask;
        !           345:     data2p &= audio_channel[2].adk_mask;
        !           346:     data3 &= audio_channel[3].adk_mask;
        !           347:     data3p &= audio_channel[3].adk_mask;
        !           348: 
        !           349:     {    
        !           350:        struct audio_channel_data *cdp;
        !           351:        unsigned long ratio, ratio1;
1.1.1.7   root      352: #define INTERVAL (scaled_sample_evtime * 3)
1.1.1.13! root      353:        cdp = audio_channel + 0;
        !           354:        ratio1 = cdp->per - cdp->evtime;
        !           355:        ratio = (ratio1 << 12) / INTERVAL;
        !           356:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           357:            ratio = 4096;
        !           358:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
        !           359: 
        !           360:        cdp = audio_channel + 1;
        !           361:        ratio1 = cdp->per - cdp->evtime;
        !           362:        ratio = (ratio1 << 12) / INTERVAL;
        !           363:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           364:            ratio = 4096;
        !           365:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
        !           366: 
        !           367:        cdp = audio_channel + 2;
        !           368:        ratio1 = cdp->per - cdp->evtime;
        !           369:        ratio = (ratio1 << 12) / INTERVAL;
        !           370:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           371:            ratio = 4096;
        !           372:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
        !           373: 
        !           374:        cdp = audio_channel + 3;
        !           375:        ratio1 = cdp->per - cdp->evtime;
        !           376:        ratio = (ratio1 << 12) / INTERVAL;
        !           377:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
        !           378:            ratio = 4096;
        !           379:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
        !           380:     }
        !           381:     data1 += data2;
        !           382:     data0 += data3;
        !           383:     {
        !           384:        uae_u32 data = SBASEVAL16 (1) + data0;
        !           385:        FINISH_DATA (data, 16, 1);
        !           386:        put_sound_word_right (data);
        !           387:     }
1.1.1.6   root      388: 
1.1.1.13! root      389:     {
        !           390:        uae_u32 data = SBASEVAL16 (1) + data1;
        !           391:        FINISH_DATA (data, 16, 1);
        !           392:        put_sound_word_left (data);
        !           393:     }
1.1.1.6   root      394:     check_sound_buffers ();
                    395: }
                    396: 
                    397: void sample16si_rh_handler (void)
                    398: {
1.1.1.13! root      399:     unsigned long delta, ratio;
1.1.1.6   root      400: 
1.1.1.13! root      401:     uae_u32 data0 = audio_channel[0].current_sample;
        !           402:     uae_u32 data1 = audio_channel[1].current_sample;
        !           403:     uae_u32 data2 = audio_channel[2].current_sample;
        !           404:     uae_u32 data3 = audio_channel[3].current_sample;
        !           405:     uae_u32 data0p = audio_channel[0].last_sample;
        !           406:     uae_u32 data1p = audio_channel[1].last_sample;
        !           407:     uae_u32 data2p = audio_channel[2].last_sample;
        !           408:     uae_u32 data3p = audio_channel[3].last_sample;
1.1.1.5   root      409: 
1.1.1.13! root      410:     DO_CHANNEL_1 (data0, 0);
        !           411:     DO_CHANNEL_1 (data1, 1);
        !           412:     DO_CHANNEL_1 (data2, 2);
        !           413:     DO_CHANNEL_1 (data3, 3);
        !           414:     DO_CHANNEL_1 (data0p, 0);
        !           415:     DO_CHANNEL_1 (data1p, 1);
        !           416:     DO_CHANNEL_1 (data2p, 2);
        !           417:     DO_CHANNEL_1 (data3p, 3);
        !           418: 
        !           419:     data0 &= audio_channel[0].adk_mask;
        !           420:     data0p &= audio_channel[0].adk_mask;
        !           421:     data1 &= audio_channel[1].adk_mask;
        !           422:     data1p &= audio_channel[1].adk_mask;
        !           423:     data2 &= audio_channel[2].adk_mask;
        !           424:     data2p &= audio_channel[2].adk_mask;
        !           425:     data3 &= audio_channel[3].adk_mask;
        !           426:     data3p &= audio_channel[3].adk_mask;
        !           427: 
        !           428:     /* linear interpolation and summing up... */
        !           429:     delta = audio_channel[0].per;
        !           430:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
        !           431:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
        !           432:     delta = audio_channel[1].per;
        !           433:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
        !           434:     data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
        !           435:     delta = audio_channel[2].per;
        !           436:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
        !           437:     data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
        !           438:     delta = audio_channel[3].per;
        !           439:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
        !           440:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
        !           441:     {
        !           442:        uae_u32 data = SBASEVAL16 (1) + data0;
        !           443:        FINISH_DATA (data, 16, 1);
        !           444:        put_sound_word_right (data);
        !           445:     }
        !           446: 
        !           447:     {
        !           448:        uae_u32 data = SBASEVAL16 (1) + data1;
        !           449:        FINISH_DATA (data, 16, 1);
        !           450:        put_sound_word_left (data);
        !           451:     }
1.1.1.5   root      452:     check_sound_buffers ();
                    453: }
                    454: 
1.1.1.2   root      455: void sample8s_handler (void)
1.1       root      456: {
                    457:     uae_u32 data0 = audio_channel[0].current_sample;
                    458:     uae_u32 data1 = audio_channel[1].current_sample;
                    459:     uae_u32 data2 = audio_channel[2].current_sample;
                    460:     uae_u32 data3 = audio_channel[3].current_sample;
                    461:     DO_CHANNEL_1 (data0, 0);
                    462:     DO_CHANNEL_1 (data1, 1);
                    463:     DO_CHANNEL_1 (data2, 2);
                    464:     DO_CHANNEL_1 (data3, 3);
                    465: 
                    466:     data0 &= audio_channel[0].adk_mask;
                    467:     data1 &= audio_channel[1].adk_mask;
                    468:     data2 &= audio_channel[2].adk_mask;
                    469:     data3 &= audio_channel[3].adk_mask;
                    470: 
                    471:     data0 += data3;
                    472:     {
                    473:        uae_u32 data = SBASEVAL8(1) + data0;
1.1.1.7   root      474:        FINISH_DATA (data, 8, 1);
1.1       root      475:        PUT_SOUND_BYTE_RIGHT (data);
                    476:     }
                    477:     data1 += data2;
                    478:     {
                    479:        uae_u32 data = SBASEVAL8(1) + data1;
1.1.1.7   root      480:        FINISH_DATA (data, 8, 1);
1.1       root      481:        PUT_SOUND_BYTE_LEFT (data);
                    482:     }
                    483: 
                    484:     check_sound_buffers ();
                    485: }
                    486: #else
1.1.1.2   root      487: void sample8s_handler (void)
1.1       root      488: {
                    489:     sample8_handler();
                    490: }
1.1.1.2   root      491: void sample16s_handler (void)
1.1       root      492: {
                    493:     sample16_handler();
                    494: }
1.1.1.6   root      495: void sample16si_crux_handler (void)
                    496: {
                    497:     sample16i_crux_handler();
                    498: }
                    499: void sample16si_rh_handler (void)
                    500: {
                    501:     sample16i_rh_handler();
                    502: }
1.1       root      503: #endif
                    504: 
1.1.1.2   root      505: static uae_u8 int2ulaw (int ch)
1.1       root      506: {
                    507:     int mask;
                    508: 
                    509:     if (ch < 0) {
                    510:       ch = -ch;
                    511:       mask = 0x7f;
                    512:     }
                    513:     else {
                    514:       mask = 0xff;
                    515:     }
                    516: 
                    517:     if (ch < 32) {
                    518:        ch = 0xF0 | ( 15 - (ch/2) );
                    519:     } else if (ch < 96) {
                    520:        ch = 0xE0 | ( 15 - (ch-32)/4 );
                    521:     } else if (ch < 224) {
                    522:        ch = 0xD0 | ( 15 - (ch-96)/8 );
                    523:     } else if (ch < 480) {
                    524:        ch = 0xC0 | ( 15 - (ch-224)/16 );
                    525:     } else if (ch < 992 ) {
                    526:        ch = 0xB0 | ( 15 - (ch-480)/32 );
                    527:     } else if (ch < 2016) {
                    528:        ch = 0xA0 | ( 15 - (ch-992)/64 );
                    529:     } else if (ch < 4064) {
                    530:        ch = 0x90 | ( 15 - (ch-2016)/128 );
                    531:     } else if (ch < 8160) {
                    532:        ch = 0x80 | ( 15 - (ch-4064)/256 );
                    533:     } else {
                    534:        ch = 0x80;
                    535:     }
                    536:     return (uae_u8)(mask & ch);
                    537: }
                    538: 
                    539: void sample_ulaw_handler (void)
                    540: {
                    541:     int nr;
                    542:     uae_u32 data = 0;
                    543: 
                    544:     for (nr = 0; nr < 4; nr++) {
                    545:        if (!(adkcon & (0x11 << nr))) {
                    546:            uae_u32 d = audio_channel[nr].current_sample;
                    547:            DO_CHANNEL_1 (d, nr);
                    548:            data += d;
                    549:        }
                    550:     }
                    551:     PUT_SOUND_BYTE (int2ulaw (data));
                    552:     check_sound_buffers ();
                    553: }
                    554: 
1.1.1.7   root      555: void schedule_audio (void)
                    556: {
                    557:     unsigned long best = ~0ul;
                    558:     int i;
                    559: 
                    560:     eventtab[ev_audio].active = 0;
                    561:     eventtab[ev_audio].oldcycles = get_cycles ();
                    562:     for (i = 0; i < 6; i++) {
                    563:        struct audio_channel_data *cdp = audio_channel + i;
                    564: 
                    565:        if (cdp->state != 0) {
                    566:            if (best > cdp->evtime) {
                    567:                best = cdp->evtime;
                    568:                eventtab[ev_audio].active = 1;
                    569:            }
                    570:        }       
                    571:     }
                    572:     eventtab[ev_audio].evtime = get_cycles () + best;
                    573: }
                    574: 
1.1       root      575: static void audio_handler (int nr)
                    576: {
                    577:     struct audio_channel_data *cdp = audio_channel + nr;
                    578: 
                    579:     switch (cdp->state) {
                    580:      case 0:
1.1.1.11  root      581:        write_log ("Bug in sound code\n");
1.1       root      582:        break;
                    583: 
                    584:      case 1:
                    585:        /* We come here at the first hsync after DMA was turned on. */
1.1.1.7   root      586:        cdp->evtime = maxhpos * CYCLE_UNIT;
1.1       root      587: 
                    588:        cdp->state = 5;
                    589:        INTREQ(0x8000 | (0x80 << nr));
                    590:        if (cdp->wlen != 1)
1.1.1.9   root      591:            cdp->wlen = (cdp->wlen - 1) & 0xFFFF;
1.1.1.10  root      592:        cdp->nextdat = chipmem_wget (cdp->pt);
1.1       root      593: 
                    594:        cdp->pt += 2;
                    595:        break;
                    596: 
                    597:      case 5:
                    598:        /* We come here at the second hsync after DMA was turned on. */
                    599:        if (currprefs.produce_sound == 0)
1.1.1.7   root      600:            cdp->per = PERIOD_MAX;
1.1       root      601: 
1.1.1.2   root      602:        cdp->evtime = cdp->per;
1.1       root      603:        cdp->dat = cdp->nextdat;
1.1.1.5   root      604:        cdp->last_sample = cdp->current_sample;
1.1       root      605:        cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    606: 
                    607:        cdp->state = 2;
                    608:        {
                    609:            int audav = adkcon & (1 << nr);
                    610:            int audap = adkcon & (16 << nr);
                    611:            int napnav = (!audav && !audap) || audav;
                    612:            if (napnav)
                    613:                cdp->data_written = 2;
                    614:        }
                    615:        break;
                    616: 
                    617:      case 2:
                    618:        /* We come here when a 2->3 transition occurs */
                    619:        if (currprefs.produce_sound == 0)
1.1.1.7   root      620:            cdp->per = PERIOD_MAX;
1.1       root      621: 
1.1.1.5   root      622:        cdp->last_sample = cdp->current_sample;
1.1       root      623:        cdp->current_sample = (sample8_t)(cdp->dat & 0xFF);
1.1.1.2   root      624:        cdp->evtime = cdp->per;
1.1       root      625: 
                    626:        cdp->state = 3;
                    627: 
                    628:        /* Period attachment? */
                    629:        if (adkcon & (0x10 << nr)) {
                    630:            if (cdp->intreq2 && cdp->dmaen)
1.1.1.9   root      631:                INTREQ (0x8000 | (0x80 << nr));
1.1       root      632:            cdp->intreq2 = 0;
                    633: 
                    634:            cdp->dat = cdp->nextdat;
                    635:            if (cdp->dmaen)
                    636:                cdp->data_written = 2;
                    637:            if (nr < 3) {
                    638:                if (cdp->dat == 0)
1.1.1.7   root      639:                    (cdp+1)->per = PERIOD_MAX;
                    640:                else if (cdp->dat < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3)
                    641:                    (cdp+1)->per = maxhpos * CYCLE_UNIT / 2;
1.1       root      642:                else
1.1.1.7   root      643:                    (cdp+1)->per = cdp->dat * CYCLE_UNIT;
1.1       root      644:            }
                    645:        }
                    646:        break;
                    647: 
                    648:      case 3:
                    649:        /* We come here when a 3->2 transition occurs */
                    650:        if (currprefs.produce_sound == 0)
1.1.1.7   root      651:            cdp->per = PERIOD_MAX;
1.1       root      652: 
1.1.1.2   root      653:        cdp->evtime = cdp->per;
1.1       root      654: 
                    655:        if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
                    656:            cdp->state = 0;
1.1.1.5   root      657:            cdp->last_sample = 0;
1.1       root      658:            cdp->current_sample = 0;
                    659:            break;
                    660:        } else {
                    661:            int audav = adkcon & (1 << nr);
                    662:            int audap = adkcon & (16 << nr);
                    663:            int napnav = (!audav && !audap) || audav;
                    664:            cdp->state = 2;
                    665: 
                    666:            if ((cdp->intreq2 && cdp->dmaen && napnav)
                    667:                || (napnav && !cdp->dmaen))
                    668:                INTREQ(0x8000 | (0x80 << nr));
                    669:            cdp->intreq2 = 0;
                    670: 
                    671:            cdp->dat = cdp->nextdat;
1.1.1.5   root      672:            cdp->last_sample = cdp->current_sample;
1.1       root      673:            cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    674: 
                    675:            if (cdp->dmaen && napnav)
                    676:                cdp->data_written = 2;
                    677: 
                    678:            /* Volume attachment? */
                    679:            if (audav) {
                    680:                if (nr < 3) {
                    681:                    (cdp+1)->vol = cdp->dat;
                    682: #ifndef MULTIPLICATION_PROFITABLE
                    683:                    (cdp+1)->voltbl = sound_table[cdp->dat];
                    684: #endif
                    685:                }
                    686:            }
                    687:        }
                    688:        break;
                    689: 
                    690:      default:
                    691:        cdp->state = 0;
                    692:        break;
                    693:     }
                    694: }
                    695: 
                    696: void aud0_handler (void)
                    697: {
                    698:     audio_handler (0);
                    699: }
                    700: void aud1_handler (void)
                    701: {
                    702:     audio_handler (1);
                    703: }
                    704: void aud2_handler (void)
                    705: {
                    706:     audio_handler (2);
                    707: }
                    708: void aud3_handler (void)
                    709: {
                    710:     audio_handler (3);
                    711: }
                    712: 
1.1.1.10  root      713: void audio_channel_enable_dma (struct audio_channel_data *cdp)
                    714: {
                    715:     if (cdp->state == 0) {
                    716:        cdp->state = 1;
                    717:        cdp->pt = cdp->lc;
                    718:        cdp->wper = cdp->per;
                    719:        cdp->wlen = cdp->len;
                    720:        cdp->data_written = 2;
                    721:        cdp->evtime = eventtab[ev_hsync].evtime - get_cycles ();
                    722:     }
                    723: }
                    724: 
                    725: void audio_channel_disable_dma (struct audio_channel_data *cdp)
                    726: {
                    727:     if (cdp->state == 1 || cdp->state == 5) {
                    728:        cdp->state = 0;
                    729:        cdp->last_sample = 0;
                    730:        cdp->current_sample = 0;
                    731:     }
                    732: }
                    733: 
1.1       root      734: void audio_reset (void)
                    735: {
1.1.1.8   root      736:     int i;
                    737:     if (savestate_state != STATE_RESTORE) {
                    738:        memset (audio_channel, 0, 4 * sizeof *audio_channel);
                    739:        audio_channel[0].per = PERIOD_MAX;
                    740:        audio_channel[1].per = PERIOD_MAX;
                    741:        audio_channel[2].per = PERIOD_MAX;
                    742:        audio_channel[3].per = PERIOD_MAX;
                    743:        audio_channel[0].voltbl = sound_table[0];
                    744:        audio_channel[1].voltbl = sound_table[0];
                    745:        audio_channel[2].voltbl = sound_table[0];
                    746:        audio_channel[3].voltbl = sound_table[0];
                    747:     } else
                    748:        for (i = 0; i < 4; i++)
                    749:            audio_channel[i].dmaen = (dmacon & 0x200) && (dmacon & (1 << i));
                    750: 
                    751: #ifndef MULTIPLICATION_PROFITABLE
1.1.1.13! root      752:     for (i = 0; i < 4; i++)
1.1.1.8   root      753:        audio_channel[nr].voltbl = sound_table[audio_channel[nr].vol];
                    754: #endif
1.1.1.2   root      755: 
                    756:     last_cycles = 0;
1.1.1.7   root      757:     next_sample_evtime = scaled_sample_evtime;
1.1.1.8   root      758: 
                    759:     schedule_audio ();
1.1.1.2   root      760: }
                    761: 
1.1.1.6   root      762: STATIC_INLINE int sound_prefs_changed (void)
1.1.1.2   root      763: {
                    764:     return (changed_prefs.produce_sound != currprefs.produce_sound
1.1.1.13! root      765:            || changed_prefs.sound_stereo != currprefs.sound_stereo
1.1.1.7   root      766:            || changed_prefs.mixed_stereo != currprefs.mixed_stereo
1.1.1.9   root      767:            || changed_prefs.sound_maxbsiz != currprefs.sound_maxbsiz
1.1.1.4   root      768:            || changed_prefs.sound_freq != currprefs.sound_freq
1.1.1.2   root      769:            || changed_prefs.sound_bits != currprefs.sound_bits);
                    770: }
                    771: 
                    772: void check_prefs_changed_audio (void)
                    773: {
1.1.1.6   root      774:     if (sound_available && sound_prefs_changed ()) {
                    775:        close_sound ();
1.1.1.2   root      776: 
1.1.1.6   root      777:        currprefs.produce_sound = changed_prefs.produce_sound;
1.1.1.13! root      778:        currprefs.sound_stereo = changed_prefs.sound_stereo;
1.1.1.7   root      779:        currprefs.mixed_stereo = changed_prefs.mixed_stereo;
1.1.1.6   root      780:        currprefs.sound_bits = changed_prefs.sound_bits;
                    781:        currprefs.sound_freq = changed_prefs.sound_freq;
1.1.1.9   root      782:        currprefs.sound_maxbsiz = changed_prefs.sound_maxbsiz;
1.1.1.6   root      783:        if (currprefs.produce_sound >= 2) {
1.1.1.7   root      784:            if (init_audio ()) {
                    785:                last_cycles = get_cycles () - 1;
                    786:                next_sample_evtime = scaled_sample_evtime;
1.1.1.6   root      787:            } else
                    788:                if (! sound_available) {
1.1.1.11  root      789:                    write_log ("Sound is not supported.\n");
1.1.1.6   root      790:                } else {
1.1.1.11  root      791:                    write_log ("Sorry, can't initialize sound.\n");
1.1.1.6   root      792:                    currprefs.produce_sound = 0;
                    793:                    /* So we don't do this every frame */
                    794:                    changed_prefs.produce_sound = 0;
                    795:                }
                    796:        }
1.1.1.12  root      797:        compute_vsynctime ();
1.1.1.2   root      798:     }
1.1.1.6   root      799:     /* Select the right interpolation method.  */
                    800:     if (sample_handler == sample16_handler
                    801:        || sample_handler == sample16i_crux_handler
                    802:        || sample_handler == sample16i_rh_handler)
                    803:        sample_handler = (currprefs.sound_interpol == 0 ? sample16_handler
                    804:                          : currprefs.sound_interpol == 1 ? sample16i_rh_handler
                    805:                          : sample16i_crux_handler);
                    806:     else if (sample_handler == sample16s_handler
                    807:             || sample_handler == sample16si_crux_handler
                    808:             || sample_handler == sample16si_rh_handler)
                    809:        sample_handler = (currprefs.sound_interpol == 0 ? sample16s_handler
                    810:                          : currprefs.sound_interpol == 1 ? sample16si_rh_handler
                    811:                          : sample16si_crux_handler);
1.1.1.7   root      812:     if (currprefs.produce_sound == 0) {
                    813:        eventtab[ev_audio].active = 0;
                    814:        events_schedule ();
                    815:     }
1.1.1.2   root      816: }
                    817: 
                    818: void update_audio (void)
                    819: {
                    820:     unsigned long int n_cycles;
                    821: 
1.1.1.8   root      822:     if (currprefs.produce_sound == 0 || savestate_state == STATE_RESTORE)
1.1.1.2   root      823:        return;
                    824: 
1.1.1.7   root      825:     n_cycles = get_cycles () - last_cycles;
1.1.1.2   root      826:     for (;;) {
                    827:        unsigned long int best_evtime = n_cycles + 1;
                    828:        if (audio_channel[0].state != 0 && best_evtime > audio_channel[0].evtime)
1.1.1.10  root      829:            best_evtime = audio_channel[0].evtime;
1.1.1.2   root      830:        if (audio_channel[1].state != 0 && best_evtime > audio_channel[1].evtime)
1.1.1.10  root      831:            best_evtime = audio_channel[1].evtime;
1.1.1.2   root      832:        if (audio_channel[2].state != 0 && best_evtime > audio_channel[2].evtime)
1.1.1.10  root      833:            best_evtime = audio_channel[2].evtime;
1.1.1.2   root      834:        if (audio_channel[3].state != 0 && best_evtime > audio_channel[3].evtime)
1.1.1.10  root      835:            best_evtime = audio_channel[3].evtime;
1.1.1.7   root      836:        if (audio_channel[4].state != 0 && best_evtime > audio_channel[4].evtime)
1.1.1.10  root      837:            best_evtime = audio_channel[4].evtime;
1.1.1.7   root      838:        if (audio_channel[5].state != 0 && best_evtime > audio_channel[5].evtime)
1.1.1.10  root      839:            best_evtime = audio_channel[5].evtime;
1.1.1.7   root      840:        if (currprefs.produce_sound > 1 && best_evtime > next_sample_evtime)
1.1.1.2   root      841:            best_evtime = next_sample_evtime;
                    842: 
                    843:        if (best_evtime > n_cycles)
                    844:            break;
                    845: 
                    846:        next_sample_evtime -= best_evtime;
                    847:        audio_channel[0].evtime -= best_evtime;
                    848:        audio_channel[1].evtime -= best_evtime;
                    849:        audio_channel[2].evtime -= best_evtime;
                    850:        audio_channel[3].evtime -= best_evtime;
1.1.1.7   root      851:        audio_channel[4].evtime -= best_evtime;
                    852:        audio_channel[5].evtime -= best_evtime;
1.1.1.2   root      853:        n_cycles -= best_evtime;
1.1.1.3   root      854:        if (next_sample_evtime == 0 && currprefs.produce_sound > 1) {
1.1.1.7   root      855:            next_sample_evtime = scaled_sample_evtime;
1.1.1.2   root      856:            (*sample_handler) ();
                    857:        }
                    858:        if (audio_channel[0].evtime == 0 && audio_channel[0].state != 0)
                    859:            audio_handler (0);
                    860:        if (audio_channel[1].evtime == 0 && audio_channel[1].state != 0)
                    861:            audio_handler (1);
                    862:        if (audio_channel[2].evtime == 0 && audio_channel[2].state != 0)
                    863:            audio_handler (2);
                    864:        if (audio_channel[3].evtime == 0 && audio_channel[3].state != 0)
                    865:            audio_handler (3);
                    866:     }
1.1.1.7   root      867:     last_cycles = get_cycles () - n_cycles;
                    868: }
                    869: 
                    870: void audio_evhandler (void)
                    871: {
                    872:     if (currprefs.produce_sound == 0)
                    873:        abort ();
                    874: 
                    875:     update_audio ();
                    876:     schedule_audio ();
1.1.1.2   root      877: }
                    878: 
                    879: void AUDxDAT (int nr, uae_u16 v)
                    880: {
                    881:     struct audio_channel_data *cdp = audio_channel + nr;
                    882: 
1.1.1.7   root      883:     if (currprefs.produce_sound == 0)
                    884:        return;
                    885: 
1.1.1.2   root      886:     update_audio ();
                    887: 
                    888:     cdp->dat = v;
                    889:     if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
                    890:        cdp->state = 2;
                    891:        INTREQ(0x8000 | (0x80 << nr));
                    892:        /* data_written = 2 ???? */
                    893:        cdp->evtime = cdp->per;
1.1.1.7   root      894:        schedule_audio ();
                    895:        events_schedule ();
1.1.1.2   root      896:     }
                    897: }
                    898: 
                    899: void AUDxLCH (int nr, uae_u16 v)
                    900: {
                    901:     update_audio ();
                    902: 
                    903:     audio_channel[nr].lc = (audio_channel[nr].lc & 0xffff) | ((uae_u32)v << 16);
                    904: }
                    905: 
                    906: void AUDxLCL (int nr, uae_u16 v)
                    907: {
                    908:     update_audio ();
                    909: 
                    910:     audio_channel[nr].lc = (audio_channel[nr].lc & ~0xffff) | (v & 0xFFFE);
                    911: }
                    912: 
                    913: void AUDxPER (int nr, uae_u16 v)
                    914: {
1.1.1.7   root      915:     unsigned long per = v * CYCLE_UNIT;
1.1.1.2   root      916:     update_audio ();
                    917: 
1.1.1.7   root      918:     if (per == 0)
                    919:        per = PERIOD_MAX;
1.1.1.2   root      920: 
1.1.1.7   root      921:     if (per < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3)
                    922:        per = maxhpos * CYCLE_UNIT / 2;
1.1.1.2   root      923: 
1.1.1.8   root      924:     if (audio_channel[nr].per == PERIOD_MAX
                    925:        && per != PERIOD_MAX)
                    926:     {
                    927:        audio_channel[nr].evtime = CYCLE_UNIT;
1.1.1.9   root      928:        if (currprefs.produce_sound > 0) {
                    929:            schedule_audio ();
                    930:            events_schedule ();
                    931:        }
1.1.1.8   root      932:     }
1.1.1.7   root      933:     audio_channel[nr].per = per;
1.1.1.2   root      934: }
                    935: 
                    936: void AUDxLEN (int nr, uae_u16 v)
                    937: {
                    938:     update_audio ();
                    939:     audio_channel[nr].len = v;
                    940: }
                    941: 
                    942: void AUDxVOL (int nr, uae_u16 v)
                    943: {
                    944:     int v2 = v & 64 ? 63 : v & 63;
                    945: 
                    946:     update_audio ();
                    947: 
                    948:     audio_channel[nr].vol = v2;
                    949: #ifndef MULTIPLICATION_PROFITABLE
                    950:     audio_channel[nr].voltbl = sound_table[v2];
                    951: #endif
1.1       root      952: }
                    953: 
1.1.1.7   root      954: int init_audio (void)
1.1       root      955: {
1.1.1.7   root      956:     int retval;
                    957:     /* Some backward compatibility hacks until every port initializes
                    958:        scaled_sample_evtime...  */
                    959:     scaled_sample_evtime_ok = 0;
                    960:     retval = init_sound ();
                    961:     if (! scaled_sample_evtime_ok)
                    962:        scaled_sample_evtime = sample_evtime * CYCLE_UNIT;
                    963:     return retval;
                    964: }
                    965: 
1.1.1.8   root      966: /* audio save/restore code FIXME: not working correctly */
                    967: /* help needed */
                    968: 
                    969: uae_u8 *restore_audio (uae_u8 *src, int i)
                    970: {
                    971:     struct audio_channel_data *acd;
                    972:     uae_u16 p;
                    973: 
                    974:     acd = audio_channel + i;
                    975:     acd->state = restore_u8 ();
                    976:     acd->vol = restore_u8 ();
                    977:     acd->intreq2 = restore_u8 ();
                    978:     acd->data_written = restore_u8 ();
                    979:     acd->len = restore_u16 ();
                    980:     acd->wlen = restore_u16 ();
                    981:     p = restore_u16 ();
                    982:     acd->per = p ? p * CYCLE_UNIT : PERIOD_MAX;
                    983:     p = restore_u16 ();
                    984:     acd->wper = p ? p * CYCLE_UNIT : PERIOD_MAX;
                    985:     acd->lc = restore_u32 ();
                    986:     acd->pt = restore_u32 ();
                    987:     acd->evtime = restore_u32 ();
                    988: 
                    989:     return src;
                    990: }
                    991: 
                    992: 
                    993: uae_u8 *save_audio (int *len, int i)
                    994: {
                    995:     struct audio_channel_data *acd;
                    996:     uae_u8 *dst = malloc (100);
                    997:     uae_u8 *dstbak = dst;
                    998:     uae_u16 p;
                    999: 
                   1000:     acd = audio_channel + i;
                   1001:     save_u8 ((uae_u8)acd->state);
                   1002:     save_u8 (acd->vol);
                   1003:     save_u8 (acd->intreq2);
                   1004:     save_u8 (acd->data_written);
                   1005:     save_u16 (acd->len);
                   1006:     save_u16 (acd->wlen);
                   1007:     p = acd->per == PERIOD_MAX ? 0 : acd->per / CYCLE_UNIT;
                   1008:     save_u16 (p);
                   1009:     p = acd->per == PERIOD_MAX ? 0 : acd->wper / CYCLE_UNIT;
                   1010:     save_u16 (p);
                   1011:     save_u32 (acd->lc);
                   1012:     save_u32 (acd->pt);
                   1013:     save_u32 (acd->evtime);
                   1014:     *len = dst - dstbak;
                   1015:     return dstbak;
                   1016: }

unix.superglobalmegacorp.com

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